!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).formbricks=t()}(this,function(){"use strict";class e{static instance;logLevel="error";static getInstance(){return e.instance||(e.instance=new e),e.instance}configure(e){void 0!==e.logLevel&&(this.logLevel=e.logLevel)}logger(e,t){if("debug"===t&&"debug"!==this.logLevel)return;const n=`🧱 Formbricks - ${(new Date).toISOString()} [${t.toUpperCase()}] - ${e}`;"error"===t?console.error(n):console.log(n)}debug(e){this.logger(e,"debug")}error(e){this.logger(e,"error")}resetInstance(){e.instance=void 0}}const t=e=>({ok:!0,data:e}),n=e=>({ok:!1,error:e});let r=!1;const s=()=>(e.getInstance().debug("Check if set up"),r?{ok:!0,data:void 0}:n({code:"not_setup",message:"Formbricks is not set up. Call setup() first."})),o=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},a=e=>(...t)=>{try{return{ok:!0,data:e(...t)}}catch(n){return{ok:!1,error:n}}},i=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}},c=(e,t)=>{const{project:n,surveys:r}=e.data,{displays:s,responses:a,lastDisplayAt:i,segments:c,userId:d}=t.data;let u=r.filter(e=>{switch(e.displayOption){case"respondMultiple":return!0;case"displayOnce":return 0===s.filter(t=>t.surveyId===e.id).length;case"displayMultiple":return 0===a.filter(t=>t===e.id).length;case"displaySome":return null===e.displayLimit||!a.filter(t=>t===e.id).length&&s.filter(t=>t.surveyId===e.id).length<e.displayLimit;default:throw Error("Invalid displayOption")}});return u=u.filter(e=>!i||(null!==e.recontactDays?o(new Date,new Date(i))>=e.recontactDays:!n.recontactDays||o(new Date,new Date(i))>=n.recontactDays)),d?c.length?u.filter(e=>e.segment?.id&&c.includes(e.segment.id)):[]:u.filter(e=>0===(e.segment?.filters.length??0))},d=(e,t)=>e.styling.allowStyleOverwrite&&t.styling?.overwriteThemeStyling?t.styling:e.styling,u=e=>Math.floor(1e4*(()=>{const e=new Uint32Array(1);return crypto.getRandomValues(e),e[0]/2**32})())/100<=e,l=e=>new Date>=e,g=(e,t,n)=>{let r;switch(n){case"exactMatch":return e===t;case"contains":return e.includes(t);case"startsWith":return e.startsWith(t);case"endsWith":return e.endsWith(t);case"notMatch":return e!==t;case"notContains":return!e.includes(t);case"matchesRegex":try{r=new RegExp(t)}catch{return!1}return r.test(e);default:return!1}},p=(e,t="or")=>{if(0===e.length)return!0;const n=window.location.href;if("and"===t){return e.every(e=>g(n,e.value,e.rule))}return e.some(e=>g(n,e.value,e.rule))},m=(e,t)=>{if("click"!==t.noCodeConfig?.type)return!1;const n=t.noCodeConfig.elementSelector.innerHtml,r=t.noCodeConfig.elementSelector.cssSelector,s=t.noCodeConfig.urlFilters;if(!n&&!r)return!1;let o=e;if(r){let t=!1;try{t=e.matches(r)}catch{t=!1}if(!t){const t=e.closest(r);if(!t)return!1;o=t}}if(n&&o.innerHTML!==n)return!1;const a=t.noCodeConfig.urlFiltersConnector??"or";return!!p(s,a)},f=()=>window.location.search.includes("formbricksDebug=true"),h="formbricks-js",y="formbricks-recaptcha-script";class w{static instance=null;config=null;constructor(){const e=this.loadFromLocalStorage();e.ok&&(this.config=e.data)}static getInstance(){return w.instance??=new w,w.instance}update(e){this.config={...this.config,...e,status:{value:e.status?.value??"success",expiresAt:e.status?.expiresAt??null}},this.saveToStorage()}get(){if(!this.config)throw new Error("config is null, maybe the init function was not called?");return this.config}loadFromLocalStorage(){if("undefined"!=typeof window){const e=localStorage.getItem(h);if(e){const n=JSON.parse(e);return t(n)}}return n(new Error("No or invalid config in local storage"))}saveToStorage(){return a(()=>{localStorage.setItem(h,JSON.stringify(this.config))})()}resetConfig(){return this.config=null,a(()=>{localStorage.removeItem(h)})()}}const v=async(e,r,s,o,a=!1)=>{const c=new URL(e+r),d=o?JSON.stringify(o):void 0,u=await i(fetch)(c.toString(),{method:s,headers:{"Content-Type":"application/json",...a&&{"Cache-Control":"no-cache"}},body:d});if(!u.ok)return n({code:"network_error",status:500,message:"Something went wrong"});const l=u.data,g=await l.json();if(!l.ok){const e=g;return n({code:"forbidden"===e.code?"forbidden":"network_error",status:l.status,message:e.message||"Something went wrong",url:c,...Object.keys(e.details??{}).length>0&&{details:e.details}})}return t(g.data)};class b{appUrl;environmentId;isDebug;constructor({appUrl:e,environmentId:t,isDebug:n=!1}){this.appUrl=e,this.environmentId=t,this.isDebug=n}async createOrUpdateUser(e){return v(this.appUrl,`/api/v2/client/${this.environmentId}/user`,"POST",{userId:e.userId,attributes:e.attributes},this.isDebug)}async getEnvironmentState(){return v(this.appUrl,`/api/v1/client/${this.environmentId}/environment`,"GET",void 0,this.isDebug)}}const I=async({appUrl:e,environmentId:r,updates:s})=>{const o=`${e}/api/v1/client/${r}/user`;try{const a=new b({appUrl:e,environmentId:r,isDebug:f()}),i=await a.createOrUpdateUser({userId:s.userId,attributes:s.attributes});return i.ok?t(i.data):n({code:i.error.code,status:i.error.status,message:`Error updating user with userId ${s.userId}`,url:new URL(o),responseMessage:i.error.message})}catch(a){const e=a;return n({code:"network_error",message:e.message??"Error fetching the person state",status:500,url:new URL(o),responseMessage:e.message??"Unknown error"})}};class k{static instance=null;updates=null;debounceTimeout=null;pendingFlush=null;DEBOUNCE_DELAY=500;PENDING_WORK_TIMEOUT=5e3;constructor(){}static getInstance(){return k.instance??=new k,k.instance}updateUserId(e){this.updates?this.updates={...this.updates,userId:e}:this.updates={userId:e,attributes:{}}}updateAttributes(e){const t=w.getInstance(),n=this.updates?.userId??t.get().user.data.userId??"";this.updates?this.updates={...this.updates,userId:n,attributes:{...this.updates.attributes,...e}}:this.updates={userId:n,attributes:e}}getUpdates(){return this.updates}clearUpdates(){this.updates=null}isEmpty(){return!this.updates}hasPendingWork(){return null!==this.updates||null!==this.pendingFlush}async waitForPendingWork(){if(!this.hasPendingWork())return!0;const e=this.pendingFlush??this.processUpdates();try{return await Promise.race([e.then(()=>!0),new Promise(e=>{setTimeout(()=>{e(!1)},this.PENDING_WORK_TIMEOUT)})])}catch{return!1}}async processUpdates(){const r=e.getInstance();if(!this.updates)return;if(this.pendingFlush)return this.pendingFlush;this.debounceTimeout&&clearTimeout(this.debounceTimeout);const s=new Promise((s,o)=>{const a=async()=>{try{let o={...this.updates};const a=w.getInstance();if(Object.keys(o).length>0){const s=o.userId??a.get().user.data.userId,i=o.attributes?.language;if(!s&&i){a.update({...a.get(),user:{...a.get().user,data:{...a.get().user.data,language:o.attributes?.language}}}),r.debug("Updated language successfully");const{language:e,...t}=o.attributes??{};o={...o,attributes:t}}if(Object.keys(o.attributes??{}).length>0&&!s){const e="Formbricks can't set attributes without a userId! Please set a userId first with the setUserId function";r.error(e),this.clearUpdates()}if(s){const i=a.get().user.data.userId,d=o.userId&&o.userId!==i,u=Object.keys(o.attributes??{}).length>0,l=await(async({updates:r})=>{const s=w.getInstance(),o=e.getInstance(),{appUrl:a,environmentId:i}=s.get(),d=`${a}/api/v1/client/${i}/user`;try{const e=await I({appUrl:a,environmentId:i,updates:r});if(!e.ok)return n(e.error);const d=e.data.state,u=c(s.get().environment,d),{messages:l,errors:g}=e.data;return g?.forEach(e=>{o.error(e)}),l?.forEach(e=>{o.debug(`User update message: ${e}`)}),s.update({...s.get(),user:{...d},filteredSurveys:u}),t({hasWarnings:Boolean(g?.length)})}catch(u){if(console.error("error in sending updates: ",u),"code"in u){const e=u;return n({code:e.code,message:e.message,status:e.status,url:new URL(d),responseMessage:e.responseMessage})}return n({code:"network_error",message:"Error sending updates",status:500,url:new URL(d),responseMessage:"Unknown error"})}})({updates:{userId:s,attributes:o.attributes??{}}});if(l.ok){if(d&&r.debug(`User successfully identified: ${s}`),u&&!l.data.hasWarnings){const e=Object.keys(o.attributes??{}).join(", ");r.debug(`Attributes successfully set: ${e}`)}}else r.error(`Failed to send updates: ${l.error.responseMessage??l.error.message}`)}}this.clearUpdates(),this.pendingFlush=null,s()}catch(a){this.pendingFlush=null,r.error(`Failed to process updates: ${a instanceof Error?a.message:"Unknown error"}`),o(a)}};this.debounceTimeout=setTimeout(()=>{a()},this.DEBOUNCE_DELAY)});return this.pendingFlush=s,s}}var S=(e=>(e[e.Setup=0]="Setup",e[e.UserAction=1]="UserAction",e[e.GeneralAction=2]="GeneralAction",e))(S||{});class C{queue=[];running=!1;resolvePromise=null;commandPromise=null;static instance=null;static getInstance(){return C.instance??=new C,C.instance}add(e,t,n=!0,...r){return new Promise(s=>{try{const o={command:e,type:t,checkSetup:n,commandArgs:r};this.queue.push(o),this.running||(this.commandPromise=new Promise(e=>{this.resolvePromise=e,this.run()})),s({ok:!0,data:void 0})}catch(o){s({ok:!1,error:o})}})}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=this.queue.shift();if(!e)continue;if(e.checkSetup){if(!s().ok){console.warn("🧱 Formbricks - Setup not complete.");continue}}if(2===e.type){const e=k.getInstance();e.isEmpty()||(console.log("🧱 Formbricks - Waiting for pending updates to complete before executing command"),await e.processUpdates())}const t=async()=>await e.command.apply(null,e.commandArgs),n=await i(t)();n.ok?n.data.ok||console.error("🧱 Formbricks - Global error: ",n.data.error):console.error("🧱 Formbricks - Global error: ",n.error)}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}}let U=null;const E=async({appUrl:e,environmentId:r})=>{const s=`${e}/api/v1/client/${r}/environment`,o=new b({appUrl:e,environmentId:r,isDebug:f()});try{const e=await o.getEnvironmentState();return e.ok?t(e.data):n({code:e.error.code,status:e.error.status,message:"Error syncing with backend",url:new URL(s),responseMessage:e.error.message})}catch(a){const e=a;return n({code:"network_error",message:e.message,status:500,url:new URL(s),responseMessage:e.responseMessage??"Network error"})}};class A{static instance=null;timeouts=[];constructor(){}static getInstance(){return A.instance||(A.instance=new A),A.instance}add(e,t){this.timeouts.push({event:e,timeoutId:t})}remove(e){clearTimeout(e),this.timeouts=this.timeouts.filter(t=>t.timeoutId!==e)}clear(){for(const e of this.timeouts)clearTimeout(e.timeoutId);this.timeouts=[]}getTimeouts(){return this.timeouts}}const T=t=>{const n=e.getInstance();return new Promise((e,r)=>{if(document.getElementById(y))return n.debug("reCAPTCHA script already loaded"),void e();if(!t)return n.debug("reCAPTCHA site key not found"),void r(new Error("reCAPTCHA site key not found"));const s=document.createElement("script");s.id=y,s.src=`https://www.google.com/recaptcha/api.js?render=${t}`,s.async=!0,s.defer=!0,s.onload=()=>{n.debug("reCAPTCHA script loaded successfully"),e()},s.onerror=()=>{n.debug("Error loading reCAPTCHA script:"),r(new Error("Error loading reCAPTCHA script"))},document.head.appendChild(s)})};let $=!1;const F=e=>{$=e},D=async(t,n,r)=>{const s=e.getInstance();if(t.displayPercentage){if(!u(t.displayPercentage))return void s.debug(`Survey display of "${t.name}" skipped based on displayPercentage.`)}const o=((t,n)=>{const r=e.getInstance(),{enabled:s,fieldIds:o}=t;let a={};if(s){if(o&&n){const e=[];a=Object.keys(n).reduce((t,r)=>(o.includes(r)?t[r]=n[r]:e.push(r),t),{}),e.length>0&&r.error(`Unknown hidden fields: ${e.join(", ")}. Please add them to the survey hidden fields.`)}}else r.error("Hidden fields are not enabled for this survey");return a})(t.hiddenFields,r?.hiddenFields);await P(t,n,o)},P=async(t,n,r)=>{const s=e.getInstance(),o=w.getInstance(),a=A.getInstance();if($)return void s.debug("A survey is already running. Skipping.");F(!0);const i=k.getInstance();if(i.hasPendingWork()){s.debug("Waiting for pending user identification before rendering survey");if(!(await i.waitForPendingWork())){if(Array.isArray(t.segment?.filters)&&t.segment.filters.length>0)return s.debug("User identification failed. Skipping survey with segment filters."),void F(!1);s.debug("User identification failed but survey has no segment filters. Proceeding.")}}t.delay&&s.debug(`Delaying survey "${t.name}" by ${t.delay.toString()} seconds.`);const{project:u}=o.get().environment.data,{language:l}=o.get().user.data,g=t.languages.length>1;let p="default";if(g){const e=((e,t)=>{const n=e.languages.map(e=>e.language.code);if(!t)return"default";const r=e.languages.find(e=>e.language.code.toLowerCase()===t.toLowerCase()||e.language.alias?.toLowerCase()===t.toLowerCase());return r?.default?"default":r&&r.enabled&&n.includes(r.language.code)?r.language.code:void 0})(t,l);if(!e)return s.debug(`Survey "${t.name}" is not available in specified language.`),void F(!1);p=e}const m=t.projectOverwrites??{},f=m.clickOutsideClose??u.clickOutsideClose,h=m.overlay??u.overlay,y=m.placement??u.placement,v=u.inAppSurveyBranding;let b;try{b=await M()}catch(E){return s.error(`Failed to load surveys library: ${String(E)}`),void F(!1)}const I=o.get().environment.data.recaptchaSiteKey,S=Boolean(I&&t.recaptcha?.enabled),C=()=>(async(t,n="submit_response")=>{const r=e.getInstance();if(!t)return r.debug("reCAPTCHA site key not found"),null;try{return await T(t),window.grecaptcha?await new Promise((e,r)=>{window.grecaptcha.ready(async()=>{try{const r=await window.grecaptcha.execute(t,{action:n});e(r)}catch(E){r(new Error(String(E)))}})}):(r.debug("reCAPTCHA API not available"),null)}catch(E){const t=E instanceof Error?E.message:"Unknown error";return r.debug(`Error during reCAPTCHA execution: ${t}`),null}})(I);S&&I&&await T(I);const U=setTimeout(()=>{b.renderSurvey({appUrl:o.get().appUrl,environmentId:o.get().environmentId,contactId:o.get().user.data.contactId??void 0,action:n,survey:t,isBrandingEnabled:v,clickOutside:f,overlay:h,languageCode:p,placement:y,styling:d(u,t),hiddenFieldsRecord:r,recaptchaSiteKey:I,isSpamProtectionEnabled:S,getRecaptchaToken:C,onDisplayCreated:()=>{const e=o.get().user.data.displays,n={surveyId:t.id,createdAt:new Date},r=e.length?[...e,n]:[n],s=o.get(),a={...s.user,data:{...s.user.data,displays:r,lastDisplayAt:new Date}},i=c(s.environment,a);o.update({...s,environment:s.environment,user:a,filteredSurveys:i})},onResponseCreated:()=>{const e=o.get().user.data.responses,n={...o.get().user,data:{...o.get().user.data,responses:e.length?[...e,t.id]:[t.id]}},r=c(o.get().environment,n);o.update({...o.get(),environment:o.get().environment,user:n,filteredSurveys:r})},onClose:L,getSetIsResponseSendingFinished:e=>{}})},1e3*t.delay);n&&a.add(n,U)},L=()=>{const e=w.getInstance();x();const{environment:t,user:n}=e.get(),r=c(t,n);e.update({...e.get(),environment:t,user:n,filteredSurveys:r}),F(!1)},x=()=>{document.getElementById("formbricks-modal-container")?.remove()};let O=null;const M=()=>globalThis.window.formbricksSurveys?Promise.resolve(globalThis.window.formbricksSurveys):O||(O=new Promise((e,t)=>{const n=w.getInstance(),r=document.createElement("script");r.src=`${n.get().appUrl}/js/surveys.umd.cjs`,r.async=!0,r.onload=()=>{new Promise((e,t)=>{const n=Date.now(),r=()=>{if(globalThis.window.formbricksSurveys){const t=globalThis.window.__formbricksNonce;return t&&globalThis.window.formbricksSurveys.setNonce(t),void e(globalThis.window.formbricksSurveys)}Date.now()-n>=1e4?t(new Error("Formbricks Surveys library did not become available within timeout")):setTimeout(r,200)};r()}).then(e).catch(e=>{O=null,console.error("Failed to load Formbricks Surveys library:",e),t(new Error("Failed to load Formbricks Surveys library"))})},r.onerror=e=>{O=null,console.error("Failed to load Formbricks Surveys library:",e),t(new Error("Failed to load Formbricks Surveys library"))},document.head.appendChild(r)}),O);let j=!1;const N=async(t,n,r)=>{const s=e.getInstance(),o=w.getInstance(),a=n??t;s.debug(`Formbricks: Action "${a}" tracked`);const i=o.get().filteredSurveys;if(Boolean(i)&&i.length>0)for(const e of i)for(const n of e.triggers)n.actionClass.name===t&&await D(e,t,r);else s.debug("No active surveys to display");return{ok:!0,data:void 0}},_=async(e,t)=>{const r=w.getInstance(),{environment:{data:{actionClasses:s=[]}}}=r.get(),o=s.filter(e=>"code"===e.type).find(t=>t.key===e);return o?N(o.name,e,t):n({code:"invalid_code",message:`Action with identifier '${e}' is unknown. Please add this action in Formbricks in order to use it via the SDK action tracking.`})},R=e=>async t=>{const n=await(r=t,N(r));var r;if(!n.ok){const r=n.error,s=r.message??"An unknown error occurred.";console.error(`🧱 Formbricks - Error in no-code ${e} action '${t}': ${s}`,r)}return n},H=R("page view"),W=R("click"),G=R("exit intent"),B=R("scroll"),K=R("time on page"),q=new Map,J=["hashchange","popstate","pushstate","replacestate","load"];let Y=!1,z=!1;const V=async()=>{const t=C.getInstance(),n=w.getInstance(),r=e.getInstance(),s=A.getInstance();r.debug(`Checking page url: ${window.location.href}`);const o=n.get().environment.data.actionClasses,a=o.filter(e=>"noCode"===e.type&&"pageView"===e.noCodeConfig?.type);for(const e of a){const n=e.noCodeConfig?.urlFilters??[],r=e.noCodeConfig?.urlFiltersConnector??"or";if(p(n,r))await t.add(H,S.GeneralAction,!0,e.name);else{const t=s.getTimeouts().find(t=>t.event===e.name);t&&(s.remove(t.timeoutId),F(!1))}}return(t=>{const n=C.getInstance(),r=e.getInstance(),s=A.getInstance(),o=t.filter(e=>"noCode"===e.type&&"pageDwell"===e.noCodeConfig?.type),a=window.location.href,i=new Set;for(const e of o){const t=e.noCodeConfig,{urlFilters:s,urlFiltersConnector:o}=t;if(!p(s,o??"or"))continue;i.add(e.name);const c=q.get(e.name);if(c?.pageKey===a)continue;"running"===c?.status&&(r.debug(`Time on page timer for "${e.name}" restarting — page changed to ${a}`),clearTimeout(c.timerId));const{timeInSeconds:d}=t,u=e.name;r.debug(`Starting time on page timer for "${u}" (${d.toString()}s)`);const l=globalThis.setTimeout(()=>{r.debug(`Time on page timer for "${u}" completed after ${d.toString()}s — firing action`),q.set(u,{status:"fired",pageKey:a}),n.add(K,S.GeneralAction,!0,u)},1e3*d);q.set(u,{status:"running",pageKey:a,timerId:l})}for(const[e,c]of q){if(i.has(e))continue;"running"===c.status&&(r.debug(`Time on page timer for "${e}" interrupted — user navigated away before completion`),clearTimeout(c.timerId)),q.delete(e);const t=s.getTimeouts().find(t=>t.event===e);t&&(s.remove(t.timeoutId),F(!1))}})(o),{ok:!0,data:void 0}},Q=()=>{V()},X=()=>{if("undefined"!=typeof window&&!Y){if(!z){const e=history.pushState;history.pushState=function(...t){e.apply(this,t);const n=new Event("pushstate");window.dispatchEvent(n)};const t=history.replaceState;history.replaceState=function(...e){t.apply(this,e);const n=new Event("replacestate");window.dispatchEvent(n)},z=!0}J.forEach(e=>{window.addEventListener(e,Q)}),Y=!0}};let Z=!1;const ee=e=>{(async e=>{const t=C.getInstance(),n=w.getInstance(),{environment:r}=n.get(),{actionClasses:s=[]}=r.data,o=s.filter(e=>"noCode"===e.type&&"click"===e.noCodeConfig?.type),a=e.target;for(const i of o)m(a,i)&&await t.add(W,S.GeneralAction,!0,i.name)})(e)};let te=!1;const ne=e=>{(async e=>{const t=C.getInstance(),n=w.getInstance(),{environment:r}=n.get(),{actionClasses:s=[]}=r.data,o=s.filter(e=>"noCode"===e.type&&"exitIntent"===e.noCodeConfig?.type);if(e.clientY<=0&&o.length>0)for(const a of o){const e=a.noCodeConfig?.urlFilters??[],n=a.noCodeConfig?.urlFiltersConnector??"or";p(e,n)&&await t.add(G,S.GeneralAction,!0,a.name)}})(e)};let re=!1,se=!1;const oe=()=>{(async()=>{const e=C.getInstance(),t=w.getInstance(),n=window.scrollY,r=window.innerHeight,s=document.documentElement.scrollHeight;if(0===n&&(se=!1),!se&&n/(s-r)>=.5){se=!0;const{environment:n}=t.get(),{actionClasses:r=[]}=n.data,s=r.filter(e=>"noCode"===e.type&&"fiftyPercentScroll"===e.noCodeConfig?.type);for(const t of s){const n=t.noCodeConfig?.urlFilters??[],r=t.noCodeConfig?.urlFiltersConnector??"or";p(n,r)&&await e.add(B,S.GeneralAction,!0,t.name)}}})()};let ae=null;const ie={expiresAt:null,data:{userId:null,contactId:null,segments:[],displays:[],responses:[],lastDisplayAt:null}};let ce=!1;const de=()=>{(()=>{const t=w.getInstance(),n=e.getInstance();if("undefined"!=typeof window&&null===U){const e=async()=>{const e=t.get().environment.expiresAt;try{if(e&&new Date(e)>=new Date)return;n.debug("Environment State has expired. Starting sync.");const r=t.get().user,s=await E({appUrl:t.get().appUrl,environmentId:t.get().environmentId});if(!s.ok)throw s.error;{const{data:e}=s,n=c(e,r);t.update({...t.get(),environment:e,filteredSurveys:n})}}catch(r){console.error("Error during expiry check: ",r),n.debug("Extending config and try again later.");const e=t.get();t.update({...e,environment:{...e.environment,expiresAt:new Date((new Date).getTime()+18e5)}})}};U=window.setInterval(()=>{e()},6e4)}})(),(()=>{const e=w.getInstance();"undefined"!=typeof window&&null===ae&&(ae=setInterval(()=>{e.get().user.data.userId&&e.update({...e.get(),user:{...e.get().user,expiresAt:new Date((new Date).getTime()+18e5)}})},6e4))})(),X(),"undefined"==typeof window||Z||(document.addEventListener("click",ee),Z=!0),"undefined"==typeof document||te||(document.querySelector("body")?.addEventListener("mouseleave",ne),te=!0),"undefined"==typeof window||re||("complete"===document.readyState?window.addEventListener("scroll",oe):window.addEventListener("load",()=>{window.addEventListener("scroll",oe)}),re=!0)},ue=()=>{ce||(window.addEventListener("beforeunload",()=>{U&&(clearInterval(U),U=null),ae&&(clearInterval(ae),ae=null),"undefined"!=typeof window&&Y&&(J.forEach(e=>{window.removeEventListener(e,Q)}),Y=!1),Z&&(document.removeEventListener("click",ee),Z=!1),te&&(document.removeEventListener("mouseleave",ne),te=!1),re&&(window.removeEventListener("scroll",oe),re=!1),(()=>{for(const[,e]of q)"running"===e.status&&clearTimeout(e.timerId);q.clear()})()}),ce=!0)},le=async t=>{const s=f(),o=e.getInstance();s&&o.configure({logLevel:"debug"});let a=w.getInstance();const{changed:i,newState:d}=(()=>{const e=localStorage.getItem(h);if(e){const t=JSON.parse(e);if(t.environmentState){const{apiHost:e,environmentState:n,personState:r,attributes:s,...o}=t;return{changed:!0,newState:{...o,...e&&{appUrl:e},environment:n,...r&&{user:{...r,data:{...r.data,...s?.language&&{language:s.language}}}}}}}}return{changed:!1}})();if(i&&(a.resetConfig(),a=w.getInstance(),d&&!d.user?.data?.userId&&a.update(d)),r)return o.debug("Already set up, skipping setup."),{ok:!0,data:void 0};let u;try{u=a.get(),o.debug("Found existing configuration.")}catch{o.debug("No existing configuration found.")}if("error"===u?.status.value){if(s)return o.debug("Formbricks is in error state, but debug mode is active. Resetting config and continuing."),a.resetConfig(),{ok:!0,data:void 0};console.error("🧱 Formbricks - Formbricks was set to an error state.");const e=u.status.expiresAt;if(e&&!l(new Date(e)))return console.error("🧱 Formbricks - Error state is not expired, skipping initialization"),{ok:!0,data:void 0};console.error("🧱 Formbricks - Error state is expired. Continuing with initialization.")}if(o.debug("Start setup"),!t.environmentId)return o.debug("No environmentId provided"),n({code:"missing_field",field:"environmentId"});if(!t.appUrl)return o.debug("No appUrl provided"),n({code:"missing_field",field:"appUrl"});if(u?.environment&&u.environmentId===t.environmentId&&u.appUrl===t.appUrl){o.debug("Configuration fits setup parameters.");let e=!1,r=!1;const i=new Date(u.environment.expiresAt);l(i)&&(o.debug("Environment state expired. Syncing."),e=!0),u.user.expiresAt&&l(new Date(u.user.expiresAt))&&(o.debug("User state expired. Syncing."),r=!0);try{let i=u.environment,d=u.user;if(e||s){s&&o.debug("Debug mode is active, refetching environment state");const e=await E({appUrl:t.appUrl,environmentId:t.environmentId});if(!e.ok)return o.error(`Error fetching environment state: ${e.error.code} - ${e.error.responseMessage??""}`),n({code:"network_error",message:"Error fetching environment state",status:500,url:new URL(`${t.appUrl}/api/v1/client/${t.environmentId}/environment`),responseMessage:e.error.message});i=e.data,o.debug(`Fetched ${i.data.surveys.length.toString()} surveys from the backend`)}if(r||s)if(s&&o.debug("Debug mode is active, refetching user state"),d.data.userId){const e=await I({appUrl:t.appUrl,environmentId:t.environmentId,updates:{userId:d.data.userId}});if(!e.ok)return o.error(`Error updating user state: ${e.error.code} - ${e.error.responseMessage??""}`),n({code:"network_error",message:"Error updating user state",status:500,url:new URL(`${t.appUrl}/api/v1/client/${t.environmentId}/update/contacts/${d.data.userId}`),responseMessage:"Unknown error"});d=e.data.state}else s||(d=ie);const l=c(i,d);a.update({...u,environment:i,user:d,filteredSurveys:l});const g=l.map(e=>e.name);o.debug(`${g.length.toString()} surveys could be shown to current user on trigger: ${g.join(", ")}`)}catch{o.debug("Error during sync. Please try again.")}}else{o.debug("No valid configuration found. Resetting config and creating new one."),a.resetConfig(),o.debug("Syncing.");try{const e=await E({appUrl:t.appUrl,environmentId:t.environmentId});if(!e.ok)throw e.error;let n=ie;if("userId"in t&&t.userId){const e=await I({appUrl:t.appUrl,environmentId:t.environmentId,updates:{userId:t.userId,attributes:t.attributes}});e.ok?n=e.data.state:o.error(`Error updating user state: ${e.error.code} - ${e.error.responseMessage??""}`)}const r=e.data;o.debug(`Fetched ${r.data.surveys.length.toString()} surveys from the backend`);const s=c(r,n);a.update({appUrl:t.appUrl,environmentId:t.environmentId,user:n,environment:r,filteredSurveys:s});const i=s.map(e=>e.name);o.debug(`${i.length.toString()} surveys could be shown to current user on trigger: ${i.join(", ")}`)}catch(g){await pe(g)}}return o.debug("Adding event listeners"),de(),ue(),(e=>{if(globalThis.window.formbricksSurveys)return;if(j)return;j=!0;const t=document.createElement("link");t.rel="preload",t.as="script",t.href=`${e}/js/surveys.umd.cjs`,document.head.appendChild(t)})(t.appUrl),r=!0,o.debug("Set up complete"),{ok:!0,data:void 0}},ge=()=>{const t=e.getInstance(),n=w.getInstance(),{environment:r}=n.get(),s=c(r,ie);t.debug("Setting user state to default"),n.update({...n.get(),user:ie,filteredSurveys:s}),L()},pe=t=>{const n=e.getInstance();"forbidden"===t.code?n.error(`Authorization error: ${t.responseMessage}`):n.error(`Error during first setup: ${t.code} - ${t.responseMessage}. Please try again later.`);const r={status:{value:"error",expiresAt:new Date((new Date).getTime()+6e5)}};throw a(()=>{localStorage.setItem(h,JSON.stringify(r))})(),new Error("Could not set up formbricks")},me=async e=>{const t={};for(const[r,s]of Object.entries(e))s instanceof Date?t[r]=s.toISOString():t[r]=s;const n=k.getInstance();return n.updateAttributes(t),n.processUpdates(),{ok:!0,data:void 0}},fe=async t=>{const n=w.getInstance(),r=e.getInstance(),s=k.getInstance(),{data:{userId:o}}=n.get().user;if(o===t)return r.debug("UserId is already set to the same value, skipping"),{ok:!0,data:void 0};o&&(r.debug("Different userId is being set, cleaning up previous user state"),ge());return t.length>255?(r.error(`UserId exceeds maximum length of ${String(255)} characters`),{ok:!0,data:void 0}):(s.updateUserId(t),s.processUpdates(),{ok:!0,data:void 0})},he=()=>{try{return e.getInstance().debug("Logging out and cleaning user state"),ge(),{ok:!0,data:void 0}}catch{return{ok:!1,error:new Error("Failed to logout")}}},ye=C.getInstance(),we=async e=>{if(e.userId||e.attributes||e.apiHost){f()&&console.warn("🧱 Formbricks - Warning: Using legacy init"),await ye.add(le,S.Setup,!1,{...e,...e.apiHost&&{appUrl:e.apiHost}})}else await ye.add(le,S.Setup,!1,e);await ye.wait(),setTimeout(()=>{V()},0)},ve={init:e=>we(e),setup:we,setEmail:async e=>{await ye.add(me,S.UserAction,!0,{email:e})},setAttribute:async(e,t)=>{await ye.add(me,S.UserAction,!0,{[e]:t})},setAttributes:async e=>{await ye.add(me,S.UserAction,!0,e)},setLanguage:async e=>{await ye.add(me,S.UserAction,!0,{language:e})},setUserId:async e=>{await ye.add(fe,S.UserAction,!0,e)},track:async(e,t)=>{await ye.add(_,S.GeneralAction,!0,e,t)},logout:async()=>{await ye.add(he,S.GeneralAction)},registerRouteChange:async()=>{await ye.add(V,S.GeneralAction)},setNonce:e=>{globalThis.window.__formbricksNonce=e,globalThis.window.formbricksSurveys?.setNonce?.(e)}};return globalThis.formbricks=ve,ve});
