{"version":3,"file":"Recaptcha.C7PsRcko.mjs","names":["useRef","useState"],"sources":["https:/framerusercontent.com/modules/W6GFEb4IdS6J14qUISyc/aT3FG670XO5EJMfaNbeK/Recaptcha.js"],"sourcesContent":["import{jsx as _jsx,jsxs as _jsxs}from\"react/jsx-runtime\";import{useEffect,useRef,useState,useCallback,startTransition}from\"react\";import{addPropertyControls,ControlType}from\"framer\";/**\n * Google reCAPTCHA Component\n *\n * Supports reCAPTCHA v2 checkbox and invisible variants.\n * Prevents form submission if reCAPTCHA is not verified.\n * Removes g-recaptcha-response from form submission data.\n *\n * When using v2 Invisible with the badge hidden, you MUST include\n * the following text visible on your page (Google ToS requirement):\n *\n * \"This site is protected by reCAPTCHA and the Google\n * <a href=\"https://policies.google.com/privacy\">Privacy Policy</a> and\n * <a href=\"https://policies.google.com/terms\">Terms of Service</a> apply.\"\n *\n * For v2 Invisible, set the component's position to Absolute in\n * Framer's layout settings to remove it from the document flow.\n *\n * @framerIntrinsicWidth 304\n * @framerIntrinsicHeight 78\n *\n * @framerSupportedLayoutWidth fixed\n * @framerSupportedLayoutHeight fixed\n */export default function Recaptcha(props){const{siteKey,version=\"v2-checkbox\",theme=\"light\",size=\"normal\",badgePosition=\"bottomright\",hideBadge=false,onVerify,onError,onExpire}=props;const containerRef=useRef(null);const widgetIdRef=useRef(null);const formRef=useRef(null);const isVerifiedRef=useRef(false);const onVerifyRef=useRef(onVerify);const onErrorRef=useRef(onError);const onExpireRef=useRef(onExpire);const[isLoaded,setIsLoaded]=useState(false);const[hasError,setHasError]=useState(false);const[isVerified,setIsVerified]=useState(false);// Keep callback refs in sync\nuseEffect(()=>{onVerifyRef.current=onVerify;},[onVerify]);useEffect(()=>{onErrorRef.current=onError;},[onError]);useEffect(()=>{onExpireRef.current=onExpire;},[onExpire]);const isInvisible=version===\"v2-invisible\";// Keep ref in sync with state\nuseEffect(()=>{isVerifiedRef.current=isVerified;},[isVerified]);// Inject global CSS to hide reCAPTCHA badge when hideBadge is enabled\nuseEffect(()=>{if(!isInvisible||!hideBadge)return;const styleId=\"recaptcha-hide-badge\";if(document.getElementById(styleId))return;const style=document.createElement(\"style\");style.id=styleId;style.textContent=\".grecaptcha-badge { visibility: hidden !important; }\";document.head.appendChild(style);return()=>{const existing=document.getElementById(styleId);if(existing)existing.remove();};},[isInvisible,hideBadge]);// Find parent form and attach submit handler\nuseEffect(()=>{if(typeof window===\"undefined\")return;// Find the parent form element\nconst findParentForm=element=>{if(!element)return null;if(element.tagName===\"FORM\")return element;return findParentForm(element.parentElement);};if(containerRef.current){formRef.current=findParentForm(containerRef.current);}const handleSubmit=e=>{// Check actual reCAPTCHA response FIRST, before touching the DOM.\n// This ensures the widget's textarea is still present so\n// getResponse() can read the token on retry attempts.\nlet hasValidResponse=false;if(widgetIdRef.current!==null&&window.grecaptcha){try{const response=window.grecaptcha.getResponse(widgetIdRef.current);hasValidResponse=response&&response.length>0;}catch(err){// Widget not ready yet\nhasValidResponse=false;}}// For checkbox version, prevent submission if not verified\nif(!isInvisible&&!hasValidResponse){e.preventDefault();e.stopPropagation();alert(\"Please complete the reCAPTCHA verification.\");return false;}// For invisible version, execute reCAPTCHA if not yet verified\nif(isInvisible&&!hasValidResponse&&widgetIdRef.current!==null&&window.grecaptcha){e.preventDefault();e.stopPropagation();window.grecaptcha.execute(widgetIdRef.current);return false;}// Only remove g-recaptcha-response fields AFTER validation passes,\n// right before the form actually submits. This keeps the widget's\n// textarea intact between failed and successful attempts.\nconst form=e.target;const responseFields=form.querySelectorAll('textarea[name=\"g-recaptcha-response\"]');responseFields.forEach(field=>field.remove());const hiddenFields=form.querySelectorAll('input[name=\"g-recaptcha-response\"]');hiddenFields.forEach(field=>field.remove());};if(formRef.current){formRef.current.addEventListener(\"submit\",handleSubmit,true);}return()=>{if(formRef.current){formRef.current.removeEventListener(\"submit\",handleSubmit,true);}};},[isInvisible]);// Load reCAPTCHA script\nuseEffect(()=>{if(typeof window===\"undefined\")return;if(!siteKey)return;const existingScript=document.querySelector('script[src*=\"recaptcha/api.js\"]');if(existingScript){if(window.grecaptcha&&window.grecaptcha.ready){startTransition(()=>setIsLoaded(true));}return;}window.onRecaptchaLoad=()=>{startTransition(()=>setIsLoaded(true));};const script=document.createElement(\"script\");script.src=`https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoad&render=explicit`;script.async=true;script.defer=true;script.onerror=()=>{startTransition(()=>setHasError(true));};document.head.appendChild(script);return()=>{if(window.onRecaptchaLoad){delete window.onRecaptchaLoad;}};},[siteKey]);// Initialize reCAPTCHA widget\n// Uses callback refs (onVerifyRef etc.) so the widget doesn't get\n// unnecessarily destroyed and re-rendered on parent re-renders.\nuseEffect(()=>{if(!isLoaded||!siteKey||!containerRef.current||!window.grecaptcha)return;try{if(widgetIdRef.current!==null){window.grecaptcha.reset(widgetIdRef.current);}const options={sitekey:siteKey,theme,size:isInvisible?\"invisible\":size,badge:isInvisible?badgePosition:undefined,callback:token=>{startTransition(()=>setIsVerified(true));onVerifyRef.current?.(token);// For invisible reCAPTCHA, auto-submit the form after verification\nif(isInvisible&&formRef.current){setTimeout(()=>{formRef.current?.requestSubmit();},100);}},\"error-callback\":()=>{startTransition(()=>{setHasError(true);setIsVerified(false);});onErrorRef.current?.();},\"expired-callback\":()=>{startTransition(()=>setIsVerified(false));onExpireRef.current?.();}};Object.keys(options).forEach(key=>{if(options[key]===undefined){delete options[key];}});widgetIdRef.current=window.grecaptcha.render(containerRef.current,options);}catch(error){console.error(\"reCAPTCHA initialization error:\",error);startTransition(()=>setHasError(true));}},[isLoaded,siteKey,theme,size,badgePosition,isInvisible]);// Reset reCAPTCHA\nconst reset=useCallback(()=>{if(widgetIdRef.current!==null&&window.grecaptcha){window.grecaptcha.reset(widgetIdRef.current);startTransition(()=>setIsVerified(false));}},[]);if(!siteKey){return /*#__PURE__*/_jsx(\"div\",{style:{...props.style,display:\"flex\",alignItems:\"center\",justifyContent:\"center\",padding:16,backgroundColor:\"#FFF3CD\",border:\"1px solid #FFEAA7\",borderRadius:4,color:\"#856404\",fontSize:12,fontFamily:\"system-ui, -apple-system, sans-serif\"},children:\"Please enter your reCAPTCHA site key in the properties panel\"});}if(hasError){return /*#__PURE__*/_jsx(\"div\",{style:{...props.style,display:\"flex\",alignItems:\"center\",justifyContent:\"center\",padding:16,backgroundColor:\"#F8D7DA\",border:\"1px solid #F5C6CB\",borderRadius:4,color:\"#721C24\",fontSize:12,fontFamily:\"system-ui, -apple-system, sans-serif\"},children:\"Error loading reCAPTCHA. Please check your site key.\"});}return /*#__PURE__*/_jsxs(\"div\",{style:{...props.style,position:\"relative\"},children:[/*#__PURE__*/_jsx(\"div\",{ref:containerRef}),!isLoaded&&!isInvisible&&/*#__PURE__*/_jsx(\"div\",{style:{position:\"absolute\",top:0,left:0,right:0,bottom:0,display:\"flex\",alignItems:\"center\",justifyContent:\"center\",backgroundColor:\"#F9F9F9\",border:\"1px solid #D3D3D3\",borderRadius:3},children:/*#__PURE__*/_jsx(\"span\",{style:{fontSize:12,color:\"#666\",fontFamily:\"system-ui, -apple-system, sans-serif\"},children:\"Loading reCAPTCHA...\"})})]});}addPropertyControls(Recaptcha,{siteKey:{type:ControlType.String,title:\"Site Key\",placeholder:\"Enter your reCAPTCHA site key...\",description:\"Get this from Google reCAPTCHA admin console. Note: v2 Checkbox and v2 Invisible require separate keys.\",defaultValue:\"\"},version:{type:ControlType.Enum,title:\"Version\",options:[\"v2-checkbox\",\"v2-invisible\"],optionTitles:[\"v2 Checkbox\",\"v2 Invisible\"],defaultValue:\"v2-checkbox\",displaySegmentedControl:true},theme:{type:ControlType.Enum,title:\"Theme\",options:[\"light\",\"dark\"],defaultValue:\"light\",displaySegmentedControl:true,hidden:({version})=>version===\"v2-invisible\"},size:{type:ControlType.Enum,title:\"Size\",options:[\"normal\",\"compact\"],defaultValue:\"normal\",displaySegmentedControl:true,hidden:({version})=>version===\"v2-invisible\"},badgePosition:{type:ControlType.Enum,title:\"Badge\",options:[\"bottomright\",\"bottomleft\",\"inline\"],optionTitles:[\"Bottom Right\",\"Bottom Left\",\"Inline\"],defaultValue:\"bottomright\",hidden:({version,hideBadge})=>version!==\"v2-invisible\"||hideBadge},hideBadge:{type:ControlType.Boolean,title:\"Hide Badge\",defaultValue:false,description:'Hides the reCAPTCHA badge. When enabled, you MUST add a visible text line near your form: \"This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.\" — with links to policies.google.com/privacy and policies.google.com/terms. This is a Google ToS requirement.',hidden:({version})=>version!==\"v2-invisible\"}});Recaptcha.displayName=\"reCAPTCHA\";\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"Recaptcha\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\",\"framerIntrinsicWidth\":\"304\",\"framerSupportedLayoutHeight\":\"fixed\",\"framerIntrinsicHeight\":\"78\",\"framerSupportedLayoutWidth\":\"fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./Recaptcha.map"],"mappings":"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"}