Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@formbricks/js

Package Overview
Dependencies
Maintainers
1
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@formbricks/js - npm Package Compare versions

Comparing version 1.6.2 to 1.6.3

2

dist/index.iife.js

@@ -1,2 +0,2 @@

var formbricks=function(){"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){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")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let w=f;const y="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}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(y);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(y,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(y)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.2";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let P=!1,T=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(T=!1),!T&&e/(n-t)>=.5){T=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",R),P=!1)},z=m.getInstance(),j=l.getInstance(),q=w.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),P=!0)},Z=()=>{A(),J(),G(),U(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(w.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(y,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),we=w.getInstance();let ye=!1,me=e=>{},Ie=e=>{};const be=e=>{ye=e},ke=async e=>{if(ye)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){we.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.1/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=w.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&w.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Ue=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()};return{init:async e=>{w.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Ue("email",e),await Oe.wait()},setAttribute:Ue,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}();
var formbricks=function(){"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){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")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let w=f;const y="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}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(y);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(y,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(y)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.3";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let P=!1,T=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(T=!1),!T&&e/(n-t)>=.5){T=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",R),P=!1)},z=m.getInstance(),j=l.getInstance(),q=w.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),P=!0)},Z=()=>{A(),J(),G(),U(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(w.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(y,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),we=w.getInstance();let ye=!1,me=e=>{},Ie=e=>{};const be=e=>{ye=e},ke=async e=>{if(ye)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){we.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=w.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&w.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Ue=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()};return{init:async e=>{w.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Ue("email",e),await Oe.wait()},setAttribute:Ue,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}();
//# sourceMappingURL=index.iife.js.map

@@ -1,2 +0,2 @@

"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){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")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let w=f;const y="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}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(y);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(y,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(y)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.2";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let P=!1,T=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(T=!1),!T&&e/(n-t)>=.5){T=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",R),P=!1)},z=m.getInstance(),j=l.getInstance(),q=w.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),P=!0)},Z=()=>{A(),J(),G(),U(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(w.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(y,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),we=w.getInstance();let ye=!1,me=e=>{},Ie=e=>{};const be=e=>{ye=e},ke=async e=>{if(ye)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){we.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.1/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=w.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&w.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Ue=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()},Pe={init:async e=>{w.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Ue("email",e),await Oe.wait()},setAttribute:Ue,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}};module.exports=Pe;
"use strict";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){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")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let w=f;const y="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}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(y);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(y,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(y)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.3";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let P=!1,T=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(T=!1),!T&&e/(n-t)>=.5){T=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",R),P=!1)},z=m.getInstance(),j=l.getInstance(),q=w.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),P=!0)},Z=()=>{A(),J(),G(),U(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(w.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),U(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(y,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),we=w.getInstance();let ye=!1,me=e=>{},Ie=e=>{};const be=e=>{ye=e},ke=async e=>{if(ye)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){we.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=w.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&w.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Ue=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()},Pe={init:async e=>{w.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Ue("email",e),await Oe.wait()},setAttribute:Ue,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}};module.exports=Pe;
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

!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";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){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")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let y=f;const w="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}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(w);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(w,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(w)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.2";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const T=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let U=!1,P=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(P=!1),!P&&e/(n-t)>=.5){P=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{U&&(window.removeEventListener("scroll",R),U=!1)},z=m.getInstance(),j=l.getInstance(),q=y.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||U||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),U=!0)},Z=()=>{A(),J(),G(),T(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),T(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),T(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(w,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),ye=y.getInstance();let we=!1,me=e=>{},Ie=e=>{};const be=e=>{we=e},ke=async e=>{if(we)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){ye.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.1/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=y.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&y.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Te=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()};return{init:async e=>{y.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Te("email",e),await Oe.wait()},setAttribute:Te,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}));
!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";var e=Object.defineProperty,t=(t,n,s)=>(((t,n,s)=>{n in t?e(t,n,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[n]=s})(t,"symbol"!=typeof n?n+"":n,s),s);const n=e=>({ok:!1,error:e});async function s(e,t,s,i){const r=new URL(t,e),o=JSON.stringify(i),a=(d=fetch,(...e)=>{try{return{ok:!0,data:d(...e)}}catch(t){return{ok:!1,error:t}}})(r.toString(),{method:s,headers:{"Content-Type":"application/json"},body:o});var d;if(!1===a.ok)return n(a.error);const c=await a.data,{data:u}=await c.json();return c.ok?(e=>({ok:!0,data:e}))(u):n({code:"network_error",message:c.statusText,status:c.status,url:r})}class i{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/actions`,"POST",e)}}class r{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays`,"POST",e)}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/displays/${e}`,"PUT",t)}}class o{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people`,"POST",{environmentId:this.environmentId,userId:e})}async update(e,t){return s(this.apiHost,`/api/v1/client/${this.environmentId}/people/${e}`,"POST",t)}}class a{constructor(e,t){this.apiHost=e,this.environmentId=t}async create(e){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses`,"POST",e)}async update({responseId:e,finished:t,data:n,ttc:i}){return s(this.apiHost,`/api/v1/client/${this.environmentId}/responses/${e}`,"PUT",{finished:t,data:n,ttc:i})}}class d{constructor(e,t){this.apiHost=e,this.environmentId=t}async uploadFile(e,{allowedFileExtensions:t,surveyId:n}={}){if(!(e instanceof Blob&&e instanceof File))throw new Error("Invalid file type. Expected Blob or File, but received "+typeof e);const s={fileName:e.name,fileType:e.type,allowedFileExtensions:t,surveyId:n},i=await fetch(`${this.apiHost}/api/v1/client/${this.environmentId}/storage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok)throw new Error(`Upload failed with status: ${i.status}`);const r=await i.json(),{data:o}=r,{signedUrl:a,fileUrl:d,signingData:c,presignedFields:u,updatedFileName:l}=o;let g={};if(c){const{signature:t,timestamp:s,uuid:i}=c;g={"X-File-Type":e.type,"X-File-Name":encodeURIComponent(l),"X-Survey-ID":n??"","X-Signature":t,"X-Timestamp":String(s),"X-UUID":i}}const p=new FormData;u&&Object.keys(u).forEach((e=>{p.append(e,u[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...c?{headers:g}:{},body:p});if(!h.ok){if(c){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(u&&e&&e.includes("EntityTooLarge")){const e=new Error("File size exceeds the size limit for your plan");throw e.name="FileTooLargeError",e}throw new Error(`Upload failed with status: ${h.status}`)}return d}}class c{constructor(e){const{apiHost:t,environmentId:n}=e;this.response=new a(t,n),this.display=new r(t,n),this.action=new i(t,n),this.people=new o(t,n),this.storage=new d(t,n)}}class u{constructor(e){this.client=new c(e)}}class l{constructor(){this.logLevel="error"}static getInstance(){return l.instance||(l.instance=new l),l.instance}configure(e){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")}}const g=e=>({ok:!0,value:e}),p=e=>({ok:!1,error:e});const h=e=>(...t)=>{try{return{ok:!0,value:e(...t)}}catch(n){return{ok:!1,error:n}}},v=l.getInstance(),f=class e{constructor(e){this.customized=!1,e?(this.handleError=e,this.customized=!0):this.handleError=e=>l.getInstance().error(JSON.stringify(e))}static getInstance(){return e.instance||(e.instance=new e),e.instance}static init(t){this.initialized=!0,e.instance=new e(t)}printStatus(){v.debug("Custom error handler: "+(this.customized?"yes":"no"))}handle(e){console.warn("🧱 Formbricks - Global error: ",e),this.handleError(e)}};f.initialized=!1;let y=f;const w="formbricks-js";class m{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return m.instance||(m.instance=new m),m.instance}update(e){if(e){const t=new Date((new Date).getTime()+12e4);this.config={...this.config,...e,status:e.status||"success",expiresAt:t},this.saveToLocalStorage()}}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(w);if(e){const t=JSON.parse(e);return t.expiresAt&&new Date(t.expiresAt)<=new Date?p(new Error("Config in local storage has expired")):g(JSON.parse(e))}}return p(new Error("No or invalid config in local storage"))}saveToLocalStorage(){return h((()=>localStorage.setItem(w,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(w)))()}}const I=(e,t)=>{const n=Math.abs(t.getTime()-e.getTime());return Math.floor(n/864e5)},b=()=>window.location.search.includes("formbricksDebug=true"),k=m.getInstance(),S=l.getInstance();let E=null;const H=async(e,t=!1)=>{var n;try{const i=await(async({apiHost:e,environmentId:t,userId:n},s)=>{try{const i=`${e}/api/v1/client/${t}/in-app/sync`,r="?version=1.6.3";let o={};if((s||b())&&(o.cache="no-cache",S.debug("No cache option set for sync")),!n){const e=i+r,t=await fetch(e,o);if(!t.ok){const n=await t.json();return p({code:"network_error",status:t.status,message:"Error syncing with backend",url:e,responseMessage:n.message})}return g((await t.json()).data)}const a=`${i}/${n}${r}`,d=await fetch(a,o);if(!d.ok){const e=await d.json();return p({code:"network_error",status:d.status,message:"Error syncing with backend",url:a,responseMessage:e.message})}const c=await d.json(),{data:u}=c;return g(u)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=k.get().state}catch(s){}let o={surveys:i.value.surveys,noCodeActionClasses:i.value.noCodeActionClasses,product:i.value.product,attributes:(null==(n=i.value.person)?void 0:n.attributes)||{}};if(e.userId){const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=C(o);const e=o.surveys.map((e=>e.name));S.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}k.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o})}catch(i){throw S.error(`Error during sync: ${i}`),i}},C=e=>{const{displays:t,product:n}=e;let{surveys:s}=e;if(!t)return e;let i=s.filter((e=>{if("respondMultiple"===e.displayOption)return!0;if("displayOnce"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id)).length;if("displayMultiple"===e.displayOption)return 0===t.filter((t=>t.surveyId===e.id&&t.responded)).length;throw Error("Invalid displayOption")}));const r=t.length>0?t[t.length-1]:void 0;return i=i.filter((e=>{if(r){if(null!==e.recontactDays){const n=t.filter((t=>t.surveyId===e.id))[0];return!n||I(new Date,new Date(n.createdAt))>=e.recontactDays}return null===n.recontactDays||I(new Date,new Date(r.createdAt))>=n.recontactDays}return!0})),{...e,surveys:i}},A=()=>{"undefined"!=typeof window&&null!==E&&(window.clearInterval(E),E=null)},F=e=>new Promise((t=>setTimeout(t,e)));class ${constructor(e,n){t(this,"queue",[]),t(this,"config"),t(this,"surveyState"),t(this,"isRequestInProgress",!1),t(this,"api"),this.config=e,this.surveyState=n,this.api=new u({apiHost:e.apiHost,environmentId:e.environmentId})}add(e){this.surveyState.accumulateResponse(e),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState),this.queue.push(e),this.processQueue()}async processQueue(){if(this.isRequestInProgress)return;if(0===this.queue.length)return;this.isRequestInProgress=!0;const e=this.queue[0];let t=0;for(;t<this.config.retryAttempts;){if(await this.sendResponse(e)){this.queue.shift();break}console.error("Formbricks: Failed to send response. Retrying...",t),await F(1e3),t++}t>=this.config.retryAttempts?(console.error("Failed to send response after 2 attempts."),this.config.onResponseSendingFailed&&this.config.onResponseSendingFailed(e),this.isRequestInProgress=!1):(e.finished&&this.config.onResponseSendingFinished&&this.config.onResponseSendingFinished(),this.isRequestInProgress=!1,this.processQueue())}async sendResponse(e){try{if(null!==this.surveyState.responseId)await this.api.client.response.update({...e,responseId:this.surveyState.responseId});else{const n=await this.api.client.response.create({...e,surveyId:this.surveyState.surveyId,userId:this.surveyState.userId||null,singleUseId:this.surveyState.singleUseId||null});if(!n.ok)throw new Error("Could not create response");if(this.surveyState.displayId)try{await this.api.client.display.update(this.surveyState.displayId,{responseId:n.data.id})}catch(t){console.error("Failed to update display, proceeding with the response.",t)}this.surveyState.updateResponseId(n.data.id),this.config.setSurveyState&&this.config.setSurveyState(this.surveyState)}return!0}catch(t){return console.error(t),!1}}updateSurveyState(e){this.surveyState=e}}class D{constructor(e,n,s,i){t(this,"responseId",null),t(this,"displayId",null),t(this,"userId",null),t(this,"surveyId"),t(this,"responseAcc",{finished:!1,data:{},ttc:{}}),t(this,"singleUseId"),this.surveyId=e,this.userId=i??null,this.singleUseId=n??null,this.responseId=s??null}setSurveyId(e){this.surveyId=e,this.clear()}copy(){const e=new D(this.surveyId,this.singleUseId??void 0,this.responseId??void 0,this.userId??void 0);return e.responseId=this.responseId,e.responseAcc=this.responseAcc,e}updateResponseId(e){this.responseId=e}updateDisplayId(e){this.displayId=e}updateUserId(e){this.userId=e}accumulateResponse(e){this.responseAcc={finished:e.finished,ttc:e.ttc,data:{...this.responseAcc.data,...e.data}}}isResponseFinished(){return this.responseAcc.finished}clear(){this.responseId=null,this.responseAcc={finished:!1,data:{},ttc:{}}}}const x=D;let L=!1,O=async function(e){if(e.clientY<=0){const e=await De("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const T=()=>{L&&(document.removeEventListener("mouseleave",O),L=!1)};let U=!1,P=!1,R=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(P=!1),!P&&e/(n-t)>=.5){P=!0;const e=await De("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{U&&(window.removeEventListener("scroll",R),U=!1)},z=m.getInstance(),j=l.getInstance(),q=y.getInstance(),M=async()=>{var e;j.debug(`Checking page url: ${window.location.href}`);const{state:t}=z.get(),{noCodeActionClasses:n=[],surveys:s=[]}=t??{},i=n.filter((e=>{const{innerHtml:t,cssSelector:n,pageUrl:s}=e.noCodeConfig||{};return s&&!t&&!n})),r=s.filter((e=>{var t;const{pageUrl:n,cssSelector:s,innerHtml:i}=(null==(t=e.inlineTriggers)?void 0:t.noCodeConfig)||{};return n&&!s&&!i}));if(i.length>0)for(const o of i){if(!(null==(e=o.noCodeConfig)?void 0:e.pageUrl))continue;const{noCodeConfig:{pageUrl:t}}=o,n=X(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await De(o.name);if(!0!==s.ok)return p(s.error)}return r.length>0&&r.forEach((e=>{const{noCodeConfig:t}=e.inlineTriggers??{},{pageUrl:n}=t??{};if(n){const t=X(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);ke(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=()=>{"undefined"!=typeof window&&_&&(window.removeEventListener("hashchange",B),window.removeEventListener("popstate",B),window.removeEventListener("pushstate",B),window.removeEventListener("replacestate",B),window.removeEventListener("load",B),_=!1)};function X(e,t,n){switch(n){case"exactMatch":return g(e===t);case"contains":return g(e.includes(t));case"startsWith":return g(e.startsWith(t));case"endsWith":return g(e.endsWith(t));case"notMatch":return g(e!==t);case"notContains":return g(!e.includes(t));default:return p({code:"invalid_match_type",message:"Invalid match type"})}}const Q=(e,t)=>{var n,s,i,r,o,a,d,c;const u=null==(s=null==(n=t.noCodeConfig)?void 0:n.innerHtml)?void 0:s.value,l=null==(r=null==(i=t.noCodeConfig)?void 0:i.cssSelector)?void 0:r.value,g=null==(a=null==(o=t.noCodeConfig)?void 0:o.pageUrl)?void 0:a.value,p=null==(c=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:c.rule;if(!u&&!l&&!g)return!1;if(u&&e.innerHTML!==u)return!1;if(l){const t=l.split(/\s*(?=[.#])/);for(let n of t)if(!e.matches(n))return!1}if(g&&p){const e=X(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let W=!1;const Y=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Q(s,e)&&De(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{q.handle(e)},!0===(t=e).ok?n(t.value):s(t.error)}))}));const i=t.surveys;i&&0!==i.length&&i.forEach((e=>{const{inlineTriggers:t}=e;t&&Q(s,t)&&ke(e)}))})(e),G=()=>{W&&(document.removeEventListener("click",Y),W=!1)};let K=!1;const V=()=>{"undefined"!=typeof window&&null===E&&(E=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await H({apiHost:k.get().apiHost,environmentId:k.get().environmentId,userId:k.get().userId})}catch(e){S.error(`Error during expiry check: ${e}`),S.debug("Extending config and try again later.");const t=k.get();k.update(t)}}),3e4)),"undefined"==typeof window||_||(window.addEventListener("hashchange",B),window.addEventListener("popstate",B),window.addEventListener("pushstate",B),window.addEventListener("replacestate",B),window.addEventListener("load",B),_=!0),"undefined"==typeof window||W||(document.addEventListener("click",Y),W=!0),"undefined"==typeof document||L||(document.querySelector("body").addEventListener("mouseleave",O),L=!0),"undefined"==typeof window||U||(window.addEventListener("load",(()=>{window.addEventListener("scroll",R)})),U=!0)},Z=()=>{A(),J(),G(),T(),N(),K&&(window.removeEventListener("beforeunload",(()=>{A(),J(),G(),T(),N()})),K=!1)},ee=m.getInstance(),te=l.getInstance(),ne=async()=>(te.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),se=async(e,t)=>{if(te.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ee.get().state.attributes[e]===t)(e,t.toString()))return te.debug("Attribute already set to this value. Skipping update."),{ok:!0,value:void 0};const n=await(async(e,t)=>{const{apiHost:n,environmentId:s,userId:i}=ee.get();if(!i)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const r={attributes:{[e]:t}},o=new u({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&te.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ee.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ee.update({environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId,state:{...ee.get().state,attributes:{...ee.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},ie=async()=>{ge(),ee.resetConfig()},re=async()=>{te.debug("Resetting state & getting new state from backend"),Se();const e={environmentId:ee.get().environmentId,apiHost:ee.get().apiHost,userId:ee.get().userId};await ie();try{return await ue(e),{ok:!0,value:void 0}}catch(t){return p(t)}},oe=m.getInstance(),ae=l.getInstance();let de=!1;const ce=e=>{de=e},ue=async e=>{if(b()&&ae.configure({logLevel:"debug"}),de)return ae.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=oe.get(),ae.debug("Found existing configuration.")}catch(s){ae.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ae.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ae.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ae.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),ae.debug("Start initialize"),!e.environmentId)return ae.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ae.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(ae.debug("Adding widget container to DOM"),Ee(),!e.userId&&e.attributes)return ae.error("No userId provided but attributes. Cannot update attributes without userId."),p({code:"missing_field",field:"userId"});let n=null;if(e.userId&&e.attributes){const t=await(async(e,t,n,i)=>{var r,o;if(!n)return p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."});const a={...i};try{const e=null==(o=null==(r=ee.get())?void 0:r.state)?void 0:o.attributes;if(e)for(const[t,n]of Object.entries(e))a[t]===n&&delete a[t]}catch(s){te.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return te.debug("No attributes to update. Skipping update."),g(a);te.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},c=new u({apiHost:e,environmentId:t}),l=await c.client.people.update(n,d);return l.ok?g(a):p({code:"network_error",status:500,message:`Error updating person with userId ${n}`,url:`${e}/api/v1/client/${t}/people/${n}`,responseMessage:l.error.message})})(e.apiHost,e.environmentId,e.userId,e.attributes);if(!0!==t.ok)return p(t.error);n=t.value}if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ae.debug("Configuration fits init parameters."),t.expiresAt<new Date){ae.debug("Configuration expired.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}}else ae.debug("Configuration not expired. Extending expiration."),oe.update(t);else{ae.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),oe.resetConfig(),ae.debug("Syncing.");try{await H({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){le()}await De("New Session")}return n&&Object.keys(n).length>0&&oe.update({environmentId:oe.get().environmentId,apiHost:oe.get().apiHost,userId:oe.get().userId,state:{...oe.get().state,attributes:{...oe.get().state.attributes,...e.attributes}}}),ae.debug("Adding event listeners"),V(),K||(window.addEventListener("beforeunload",(()=>{A(),J(),G(),T(),N()})),K=!0),ce(!0),ae.debug("Initialized"),M(),{ok:!0,value:void 0}},le=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(w,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},ge=()=>{ae.debug("Deinitializing"),He(),be(!1),Z(),ce(!1)},pe=()=>{ae.debug("Putting formbricks in error state"),oe.update({...oe.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),ge()},he="formbricks-web-container",ve=m.getInstance(),fe=l.getInstance(),ye=y.getInstance();let we=!1,me=e=>{},Ie=e=>{};const be=e=>{we=e},ke=async e=>{if(we)return void fe.debug("A survey is already running. Skipping.");be(!0),e.delay&&fe.debug(`Delaying survey by ${e.delay} seconds.`);const t=ve.get().state.product,n=new x(e.id,null,null,ve.get().userId),s=new $({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{me(!0)},onResponseSendingFinished:()=>{Ie(!0)}},n),i=e.productOverwrites??{},r=i.brandColor??t.brandColor,o=i.highlightBorderColor??t.highlightBorderColor,a=i.clickOutsideClose??t.clickOutsideClose,d=i.darkOverlay??t.darkOverlay,c=i.placement??t.placement,l=t.inAppSurveyBranding,g=await Ce();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{me=e},getSetIsResponseSendingFinished:e=>{Ie=e},onDisplay:async()=>{const{userId:t}=ve.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ve.get().state.displays,s=n?[...n,t]:[t],i=ve.get();let r=C({...i.state,displays:s});ve.update({...i,state:r})}const i=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId}),r=await i.client.display.create({surveyId:e.id,userId:t});if(!r.ok)throw new Error("Could not create display");const{id:o}=r.data;n.updateDisplayId(o),s.updateSurveyState(n)},onResponse:e=>{const{userId:t}=ve.get();if(!t){const e=ve.get().state.displays,t=e&&e[e.length-1];if(!t)throw new Error("No lastDisplay found");if(!t.responded){t.responded=!0;const n=ve.get();let s=C({...n.state,displays:e});ve.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:Se,onFileUpload:async(e,t)=>{const n=new u({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{me(!1),s.processQueue()}})}),1e3*e.delay)},Se=async()=>{if(He(),Ee(),!ve.get().userId){const e=ve.get().state,t=C(e);return ve.update({...ve.get(),state:t}),void be(!1)}try{await H({apiHost:ve.get().apiHost,environmentId:ve.get().environmentId,userId:ve.get().userId},!0),be(!1)}catch(e){ye.handle(e),pe()}},Ee=()=>{const e=document.createElement("div");e.id=he,document.body.appendChild(e)},He=()=>{var e;null==(e=document.getElementById(he))||e.remove()},Ce=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.6.2/dist/index.umd.js",n.async=!0,n.onload=()=>e(window.formbricksSurveys),n.onerror=e=>{console.error("Failed to load Formbricks Surveys library:",e),t(e)},document.head.appendChild(n)}})),Ae=l.getInstance(),Fe=m.getInstance(),$e=["Exit Intent (Desktop)","50% Scroll"],De=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=Fe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await ke(t)}));const i={environmentId:Fe.get().environmentId,userId:n,name:e};if(n&&!$e.includes(e)){Ae.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:Fe.get().apiHost,environmentId:Fe.get().environmentId}),s=await t.client.action.create({...i,userId:n});if(!s.ok)return p({code:"network_error",message:`Error tracking action ${e}`,status:500,url:`${Fe.get().apiHost}/api/v1/client/${Fe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await H({environmentId:Fe.get().environmentId,apiHost:Fe.get().apiHost,userId:n},!0)}Ae.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=Fe.get().state)?void 0:t.surveys;return r&&r.length>0?await xe(e,r):Ae.debug("No active surveys to display"),{ok:!0,value:void 0}},xe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Ae.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Ae.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await ke(s))}var n},Le=e=>async(...t)=>{try{return{ok:!0,data:await e(...t)}}catch(n){return{ok:!1,error:n}}};l.getInstance().debug("Create command queue");const Oe=new class{constructor(){this.queue=[],this.running=!1,this.resolvePromise=null,this.commandPromise=null}add(e=!0,t,...n){this.queue.push({command:t,checkInitialized:e,commandArgs:n}),this.running||(this.commandPromise=new Promise((e=>{this.resolvePromise=e,this.run()})))}async wait(){this.running&&await this.commandPromise}async run(){for(this.running=!0;this.queue.length>0;){const e=y.getInstance(),t=this.queue.shift();if(!t)continue;if(t.checkInitialized){const t=(ae.debug("Check if initialized"),de&&y.initialized?{ok:!0,value:void 0}:p({code:"not_initialized",message:"Formbricks not initialized. Call initialize() first."}));if(t&&!0!==t.ok){e.handle(t.error);continue}}const n=async()=>await(null==t?void 0:t.command.apply(null,null==t?void 0:t.commandArgs)),s=await Le(n)();s&&(s.ok&&s.data&&!s.data.ok&&e.handle(s.data.error),!0!==s.ok&&e.handle(s.error))}this.running=!1,this.resolvePromise&&(this.resolvePromise(),this.resolvePromise=null,this.commandPromise=null)}},Te=async(e,t)=>{Oe.add(!0,se,e,t),await Oe.wait()};return{init:async e=>{y.init(e.errorHandler),Oe.add(!1,ue,e),await Oe.wait()},setUserId:async()=>{Oe.add(!0,ne),await Oe.wait()},setEmail:async e=>{Te("email",e),await Oe.wait()},setAttribute:Te,track:async(e,t={})=>{Oe.add(!0,De,e,t),await Oe.wait()},logout:async()=>{Oe.add(!0,ie),await Oe.wait()},reset:async()=>{Oe.add(!0,re),await Oe.wait()},registerRouteChange:async()=>{Oe.add(!0,M),await Oe.wait()},getApi:()=>{const e=m.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new u({apiHost:n,environmentId:t})}}}));
//# sourceMappingURL=index.umd.js.map
{
"name": "@formbricks/js",
"license": "MIT",
"version": "1.6.2",
"version": "1.6.3",
"description": "Formbricks-js allows you to connect your app to Formbricks, display surveys and trigger events.",

@@ -37,20 +37,17 @@ "homepage": "https://formbricks.com",

"@babel/preset-typescript": "^7.23.3",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"cross-env": "^7.0.3",
"eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "1.10.12",
"eslint-config-turbo": "1.12.5",
"isomorphic-fetch": "^3.0.0",
"terser": "^5.28.1",
"vite": "^5.1.4",
"terser": "^5.29.1",
"vite": "^5.1.6",
"vite-plugin-dts": "^3.7.3",
"@formbricks/api": "1.6.0",
"@formbricks/surveys": "1.6.1",
"@formbricks/lib": "0.0.0",
"@formbricks/surveys": "1.6.2",
"@formbricks/tsconfig": "1.0.0",
"@formbricks/types": "0.0.0",
"@formbricks/tsconfig": "1.0.0"
"@formbricks/lib": "0.0.0"
},
"dependencies": {
"@t3-oss/env-nextjs": "^0.9.2"
},
"scripts": {

@@ -57,0 +54,0 @@ "dev": "vite build --watch --mode dev",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc