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.4 to 1.7.0

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 y=f;const m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.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(m);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(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}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=w.getInstance(),S=l.getInstance();let H=null;const C=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.4";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=E(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}},E=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!==H&&(window.clearInterval(H),H=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 O=!1,U=async function(e){if(e.clientY<=0){const e=await xe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const P=()=>{O&&(document.removeEventListener("mouseleave",U),O=!1)};let T=!1,R=!1,L=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(R=!1),!R&&e/(n-t)>=.5){R=!0;const e=await xe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{T&&(window.removeEventListener("scroll",L),T=!1)},z=w.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=Q(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await xe(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=Q(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;Se(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=["hashchange","popstate","pushstate","replacestate","load"],X=()=>{"undefined"!=typeof window&&_&&(J.forEach((e=>window.removeEventListener(e,B))),_=!1)};function Q(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 W=(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=Q(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let Y=!1;const G=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{W(s,e)&&xe(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&&W(s,t)&&Se(e)}))})(e),K=()=>{Y&&(document.removeEventListener("click",G),Y=!1)};let V=!1;const Z=()=>{"undefined"!=typeof window&&null===H&&(H=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await C({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||_||(J.forEach((e=>window.addEventListener(e,B))),_=!0),"undefined"==typeof window||Y||(document.addEventListener("click",G),Y=!0),"undefined"==typeof document||O||(document.querySelector("body").addEventListener("mouseleave",U),O=!0),"undefined"==typeof window||T||(window.addEventListener("load",(()=>{window.addEventListener("scroll",L)})),T=!0)},ee=()=>{A(),X(),K(),P(),N(),V&&(window.removeEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!1)},te=w.getInstance(),ne=l.getInstance(),se=async()=>(ne.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),ie=async(e,t)=>{if(ne.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>te.get().state.attributes[e]===t)(e,t.toString()))return ne.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}=te.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&&ne.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${te.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(te.update({environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId,state:{...te.get().state,attributes:{...te.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},re=async()=>{pe(),te.resetConfig()},oe=async()=>{ne.debug("Resetting state & getting new state from backend"),He();const e={environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId};await re();try{return await le(e),{ok:!0,value:void 0}}catch(t){return p(t)}},ae=w.getInstance(),de=l.getInstance();let ce=!1;const ue=e=>{ce=e},le=async e=>{if(b()&&de.configure({logLevel:"debug"}),ce)return de.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=ae.get(),de.debug("Found existing configuration.")}catch(s){de.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(de.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return de.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};de.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),de.debug("Start initialize"),!e.environmentId)return de.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return de.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(de.debug("Adding widget container to DOM"),Ce(),!e.userId&&e.attributes)return de.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=te.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){ne.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return ne.debug("No attributes to update. Skipping update."),g(a);ne.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(de.debug("Configuration fits init parameters."),t.expiresAt<new Date){de.debug("Configuration expired.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){he()}}else de.debug("Configuration not expired. Extending expiration."),ae.update(t);else{de.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),ae.resetConfig(),de.debug("Syncing.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ge()}await xe("New Session")}return n&&Object.keys(n).length>0&&ae.update({environmentId:ae.get().environmentId,apiHost:ae.get().apiHost,userId:ae.get().userId,state:{...ae.get().state,attributes:{...ae.get().state.attributes,...e.attributes}}}),de.debug("Adding event listeners"),Z(),V||(window.addEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!0),ue(!0),de.debug("Initialized"),M(),{ok:!0,value:void 0}},ge=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},pe=()=>{de.debug("Deinitializing"),Ee(),ke(!1),ee(),ue(!1)},he=()=>{de.debug("Putting formbricks in error state"),ae.update({...ae.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),pe()},ve="formbricks-web-container",fe=w.getInstance(),ye=l.getInstance(),me=y.getInstance();let we=!1,Ie=e=>{},be=e=>{};const ke=e=>{we=e},Se=async e=>{if(we)return void ye.debug("A survey is already running. Skipping.");ke(!0),e.delay&&ye.debug(`Delaying survey by ${e.delay} seconds.`);const t=fe.get().state.product,n=new x(e.id,null,null,fe.get().userId),s=new $({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{Ie(!0)},onResponseSendingFinished:()=>{be(!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 Ae();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{Ie=e},getSetIsResponseSendingFinished:e=>{be=e},onDisplay:async()=>{const{userId:t}=fe.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=fe.get().state.displays,s=n?[...n,t]:[t],i=fe.get();let r=E({...i.state,displays:s});fe.update({...i,state:r})}const i=new u({apiHost:fe.get().apiHost,environmentId:fe.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}=fe.get();if(!t){const e=fe.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=fe.get();let s=E({...n.state,displays:e});fe.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:He,onFileUpload:async(e,t)=>{const n=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{Ie(!1),s.processQueue()}})}),1e3*e.delay)},He=async()=>{if(Ee(),Ce(),!fe.get().userId){const e=fe.get().state,t=E(e);return fe.update({...fe.get(),state:t}),void ke(!1)}try{await C({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,userId:fe.get().userId},!0),ke(!1)}catch(e){me.handle(e),he()}},Ce=()=>{const e=document.createElement("div");e.id=ve,document.body.appendChild(e)},Ee=()=>{var e;null==(e=document.getElementById(ve))||e.remove()},Ae=()=>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)}})),Fe=l.getInstance(),$e=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],xe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=$e.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await Se(t)}));const i={environmentId:$e.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){Fe.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:$e.get().apiHost,environmentId:$e.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:`${$e.get().apiHost}/api/v1/client/${$e.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await C({environmentId:$e.get().environmentId,apiHost:$e.get().apiHost,userId:n},!0)}Fe.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=$e.get().state)?void 0:t.surveys;return r&&r.length>0?await Oe(e,r):Fe.debug("No active surveys to display"),{ok:!0,value:void 0}},Oe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Fe.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Fe.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await Se(s))}var n},Ue=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 Pe=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=(de.debug("Check if initialized"),ce&&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 Ue(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)=>{Pe.add(!0,ie,e,t),await Pe.wait()};return{init:async e=>{y.init(e.errorHandler),Pe.add(!1,le,e),await Pe.wait()},setUserId:async()=>{Pe.add(!0,se),await Pe.wait()},setEmail:async e=>{Te("email",e),await Pe.wait()},setAttribute:Te,track:async(e,t={})=>{Pe.add(!0,xe,e,t),await Pe.wait()},logout:async()=>{Pe.add(!0,re),await Pe.wait()},reset:async()=>{Pe.add(!0,oe),await Pe.wait()},registerRouteChange:async()=>{Pe.add(!0,M),await Pe.wait()},getApi:()=>{const e=w.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 u=await a.data,{data:c}=await u.json();return u.ok?(e=>({ok:!0,data:e}))(c):n({code:"network_error",message:u.statusText,status:u.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:u,presignedFields:c,updatedFileName:l}=o;let g={};if(u){const{signature:t,timestamp:s,uuid:i}=u;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;c&&Object.keys(c).forEach((e=>{p.append(e,c[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...u?{headers:g}:{},body:p});if(!h.ok){if(u){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(c&&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 u{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 c{constructor(e){this.client=new u(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 m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.instance}update(e){e&&(this.config={...this.config,...e,status:e.status||"success"},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(m);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(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}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=e=>{var t;const n=null==(t=e.languages)?void 0:t.find((e=>!0===e.default));if(n)return n.language.code},S=w.getInstance(),H=l.getInstance();let C=null;const E=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.7.0";let o={};if((s||b())&&(o.cache="no-cache",H.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 u=await d.json(),{data:c}=u;return g(c)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=S.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));H.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=A(o);const e=o.surveys.map((e=>e.name));H.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}S.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o,expiresAt:new Date((new Date).getTime()+12e4)})}catch(i){throw H.error(`Error during sync: ${i}`),i}},A=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}},F=()=>{"undefined"!=typeof window&&null!==C&&(window.clearInterval(C),C=null)},$=e=>new Promise((t=>setTimeout(t,e)));class x{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 c({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 $(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 O=D;let P=!1,T=async function(e){if(e.clientY<=0){const e=await Oe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{P&&(document.removeEventListener("mouseleave",T),P=!1)};let R=!1,L=!1,z=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(L=!1),!L&&e/(n-t)>=.5){L=!0;const e=await Oe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{R&&(window.removeEventListener("scroll",z),R=!1)},j=w.getInstance(),q=l.getInstance(),M=y.getInstance(),_=async()=>{var e;q.debug(`Checking page url: ${window.location.href}`);const{state:t}=j.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=W(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await Oe(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=W(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;He(e)}})),{ok:!0,value:void 0}};let B=!1;const J=()=>_(),X=["hashchange","popstate","pushstate","replacestate","load"],Q=()=>{"undefined"!=typeof window&&B&&(X.forEach((e=>window.removeEventListener(e,J))),B=!1)};function W(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 Y=(e,t)=>{var n,s,i,r,o,a,d,u;const c=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==(u=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:u.rule;if(!c&&!l&&!g)return!1;if(c&&e.innerHTML!==c)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=W(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let G=!1;const K=e=>(e=>{const{state:t}=j.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Y(s,e)&&Oe(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{M.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&&Y(s,t)&&He(e)}))})(e),V=()=>{G&&(document.removeEventListener("click",K),G=!1)};let Z=!1;const ee=()=>{"undefined"!=typeof window&&null===C&&(C=window.setInterval((async()=>{try{if(S.get().expiresAt&&new Date(S.get().expiresAt)>=new Date)return;H.debug("Config has expired. Starting sync."),await E({apiHost:S.get().apiHost,environmentId:S.get().environmentId,userId:S.get().userId})}catch(e){H.error(`Error during expiry check: ${e}`),H.debug("Extending config and try again later.");const t=S.get();S.update(t)}}),3e4)),"undefined"==typeof window||B||(X.forEach((e=>window.addEventListener(e,J))),B=!0),"undefined"==typeof window||G||(document.addEventListener("click",K),G=!0),"undefined"==typeof document||P||(document.querySelector("body").addEventListener("mouseleave",T),P=!0),"undefined"==typeof window||R||(window.addEventListener("load",(()=>{window.addEventListener("scroll",z)})),R=!0)},te=()=>{F(),Q(),V(),U(),N(),Z&&(window.removeEventListener("beforeunload",(()=>{F(),Q(),V(),U(),N()})),Z=!1)},ne=w.getInstance(),se=l.getInstance(),ie=async()=>(se.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),re=async(e,t)=>{if(se.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ne.get().state.attributes[e]===t)(e,t.toString()))return se.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}=ne.get();if(!i){const n=ne.get();return"language"===e?(ne.update({...n,state:{...n.state,attributes:{...n.state.attributes,language:t}}}),{ok:!0,value:void 0}):p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."})}const r={attributes:{[e]:t}},o=new c({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&se.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ne.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ne.update({environmentId:ne.get().environmentId,apiHost:ne.get().apiHost,userId:ne.get().userId,state:{...ne.get().state,attributes:{...ne.get().state.attributes,[e]:t.toString()}},expiresAt:ne.get().expiresAt}),{ok:!0,value:void 0}):p(n.error)},oe=async()=>{he(),ne.resetConfig()},ae=async()=>{se.debug("Resetting state & getting new state from backend"),Ce();const e={environmentId:ne.get().environmentId,apiHost:ne.get().apiHost,userId:ne.get().userId,attributes:ne.get().state.attributes};await oe();try{return await ge(e),{ok:!0,value:void 0}}catch(t){return p(t)}},de=w.getInstance(),ue=l.getInstance();let ce=!1;const le=e=>{ce=e},ge=async e=>{if(b()&&ue.configure({logLevel:"debug"}),ce)return ue.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=de.get(),ue.debug("Found existing configuration.")}catch(s){ue.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ue.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ue.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ue.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),ue.debug("Start initialize"),!e.environmentId)return ue.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ue.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});ue.debug("Adding widget container to DOM"),Ee();let n=null;if(e.attributes)if(e.userId){const t=await(async(e,t,n,i)=>{var r,o;const a={...i};try{const e=null==(o=null==(r=ne.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){se.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return se.debug("No attributes to update. Skipping update."),g(a);se.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},u=new c({apiHost:e,environmentId:t}),l=await u.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}else n={...e.attributes};if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ue.debug("Configuration fits init parameters."),t.expiresAt<new Date){ue.debug("Configuration expired.");try{await E({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ve()}}else ue.debug("Configuration not expired. Extending expiration."),de.update(t);else{ue.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),de.resetConfig(),ue.debug("Syncing.");try{await E({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}await Oe("New Session")}return n&&Object.keys(n).length>0&&de.update({environmentId:de.get().environmentId,apiHost:de.get().apiHost,userId:de.get().userId,state:{...de.get().state,attributes:{...de.get().state.attributes,...e.attributes}},expiresAt:de.get().expiresAt}),ue.debug("Adding event listeners"),ee(),Z||(window.addEventListener("beforeunload",(()=>{F(),Q(),V(),U(),N()})),Z=!0),le(!0),ue.debug("Initialized"),_(),{ok:!0,value:void 0}},pe=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},he=()=>{ue.debug("Deinitializing"),Ae(),Se(!1),te(),le(!1)},ve=()=>{ue.debug("Putting formbricks in error state"),de.update({...de.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),he()},fe="formbricks-web-container",ye=w.getInstance(),me=l.getInstance(),we=y.getInstance();let Ie=!1,be=e=>{},ke=e=>{};const Se=e=>{Ie=e},He=async e=>{if(Ie)return void me.debug("A survey is already running. Skipping.");Se(!0),e.delay&&me.debug(`Delaying survey by ${e.delay} seconds.`);const t=ye.get().state.product,n=ye.get().state.attributes,s=e.languages.length>1;let i="default";if(s){const t=((e,t)=>{const n=t.language,s=e.languages.map((e=>e.language.code));if(n){const t=e.languages.find((e=>e.language.code===n||e.language.alias===n));if(null==t?void 0:t.default)return"default";if(!t||!(null==t?void 0:t.enabled)||!s.includes(t.language.code))return;return t.language.code}return"default"})(e,n);if(!t)return me.debug("Survey not available in specified language."),void Se(!0);i=t}const r=new O(e.id,null,null,ye.get().userId),o=new x({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{be(!0)},onResponseSendingFinished:()=>{ke(!0)}},r),a=e.productOverwrites??{},d=a.brandColor??t.brandColor,u=a.highlightBorderColor??t.highlightBorderColor,l=a.clickOutsideClose??t.clickOutsideClose,g=a.darkOverlay??t.darkOverlay,p=a.placement??t.placement,h=t.inAppSurveyBranding,v=await Fe();setTimeout((()=>{v.renderSurveyModal({survey:e,brandColor:d,isBrandingEnabled:h,clickOutside:l,darkOverlay:g,languageCode:i,highlightBorderColor:u,placement:p,getSetIsError:e=>{be=e},getSetIsResponseSendingFinished:e=>{ke=e},onDisplay:async()=>{const{userId:t}=ye.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ye.get().state.displays,s=n?[...n,t]:[t],i=ye.get();let r=A({...i.state,displays:s});ye.update({...i,state:r})}const n=new c({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId}),s=await n.client.display.create({surveyId:e.id,userId:t});if(!s.ok)throw new Error("Could not create display");const{id:i}=s.data;r.updateDisplayId(i),o.updateSurveyState(r)},onResponse:t=>{const{userId:n}=ye.get();if(!n){const e=ye.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=ye.get();let s=A({...n.state,displays:e});ye.update({...n,state:s})}}n&&r.updateUserId(n),o.updateSurveyState(r),o.add({data:t.data,ttc:t.ttc,finished:t.finished,language:"default"===i?k(e):i})},onClose:Ce,onFileUpload:async(e,t)=>{const n=new c({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{be(!1),o.processQueue()}})}),1e3*e.delay)},Ce=async()=>{if(Ae(),Ee(),!ye.get().userId){const e=ye.get().state,t=A(e);return ye.update({...ye.get(),state:t}),void Se(!1)}try{await E({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId,userId:ye.get().userId},!0),Se(!1)}catch(e){we.handle(e),ve()}},Ee=()=>{const e=document.createElement("div");e.id=fe,document.body.appendChild(e)},Ae=()=>{var e;null==(e=document.getElementById(fe))||e.remove()},Fe=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.7.0/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)}})),$e=l.getInstance(),xe=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],Oe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=xe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await He(t)}));const i={environmentId:xe.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){$e.debug(`Sending action "${e}" to backend`);const t=new c({apiHost:xe.get().apiHost,environmentId:xe.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:`${xe.get().apiHost}/api/v1/client/${xe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await E({environmentId:xe.get().environmentId,apiHost:xe.get().apiHost,userId:n},!0)}$e.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=xe.get().state)?void 0:t.surveys;return r&&r.length>0?await Pe(e,r):$e.debug("No active surveys to display"),{ok:!0,value:void 0}},Pe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){$e.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return $e.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await He(s))}var n},Te=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 Ue=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=(ue.debug("Check if initialized"),ce&&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 Te(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)}},Re=async(e,t)=>{Ue.add(!0,re,e,t),await Ue.wait()};return{init:async e=>{y.init(e.errorHandler),Ue.add(!1,ge,e),await Ue.wait()},setUserId:async()=>{Ue.add(!0,ie),await Ue.wait()},setEmail:async e=>{Re("email",e),await Ue.wait()},setAttribute:Re,track:async(e,t={})=>{Ue.add(!0,Oe,e,t),await Ue.wait()},logout:async()=>{Ue.add(!0,oe),await Ue.wait()},reset:async()=>{Ue.add(!0,ae),await Ue.wait()},registerRouteChange:async()=>{Ue.add(!0,_),await Ue.wait()},getApi:()=>{const e=w.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new c({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 y=f;const m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.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(m);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(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}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=w.getInstance(),S=l.getInstance();let H=null;const C=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.4";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=E(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}},E=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!==H&&(window.clearInterval(H),H=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 O=!1,U=async function(e){if(e.clientY<=0){const e=await xe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const P=()=>{O&&(document.removeEventListener("mouseleave",U),O=!1)};let T=!1,R=!1,L=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(R=!1),!R&&e/(n-t)>=.5){R=!0;const e=await xe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{T&&(window.removeEventListener("scroll",L),T=!1)},z=w.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=Q(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await xe(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=Q(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;Se(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=["hashchange","popstate","pushstate","replacestate","load"],X=()=>{"undefined"!=typeof window&&_&&(J.forEach((e=>window.removeEventListener(e,B))),_=!1)};function Q(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 W=(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=Q(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let Y=!1;const G=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{W(s,e)&&xe(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&&W(s,t)&&Se(e)}))})(e),K=()=>{Y&&(document.removeEventListener("click",G),Y=!1)};let V=!1;const Z=()=>{"undefined"!=typeof window&&null===H&&(H=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await C({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||_||(J.forEach((e=>window.addEventListener(e,B))),_=!0),"undefined"==typeof window||Y||(document.addEventListener("click",G),Y=!0),"undefined"==typeof document||O||(document.querySelector("body").addEventListener("mouseleave",U),O=!0),"undefined"==typeof window||T||(window.addEventListener("load",(()=>{window.addEventListener("scroll",L)})),T=!0)},ee=()=>{A(),X(),K(),P(),N(),V&&(window.removeEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!1)},te=w.getInstance(),ne=l.getInstance(),se=async()=>(ne.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),ie=async(e,t)=>{if(ne.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>te.get().state.attributes[e]===t)(e,t.toString()))return ne.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}=te.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&&ne.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${te.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(te.update({environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId,state:{...te.get().state,attributes:{...te.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},re=async()=>{pe(),te.resetConfig()},oe=async()=>{ne.debug("Resetting state & getting new state from backend"),He();const e={environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId};await re();try{return await le(e),{ok:!0,value:void 0}}catch(t){return p(t)}},ae=w.getInstance(),de=l.getInstance();let ce=!1;const ue=e=>{ce=e},le=async e=>{if(b()&&de.configure({logLevel:"debug"}),ce)return de.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=ae.get(),de.debug("Found existing configuration.")}catch(s){de.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(de.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return de.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};de.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),de.debug("Start initialize"),!e.environmentId)return de.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return de.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(de.debug("Adding widget container to DOM"),Ce(),!e.userId&&e.attributes)return de.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=te.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){ne.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return ne.debug("No attributes to update. Skipping update."),g(a);ne.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(de.debug("Configuration fits init parameters."),t.expiresAt<new Date){de.debug("Configuration expired.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){he()}}else de.debug("Configuration not expired. Extending expiration."),ae.update(t);else{de.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),ae.resetConfig(),de.debug("Syncing.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ge()}await xe("New Session")}return n&&Object.keys(n).length>0&&ae.update({environmentId:ae.get().environmentId,apiHost:ae.get().apiHost,userId:ae.get().userId,state:{...ae.get().state,attributes:{...ae.get().state.attributes,...e.attributes}}}),de.debug("Adding event listeners"),Z(),V||(window.addEventListener("beforeunload",(()=>{A(),X(),K(),P(),N()})),V=!0),ue(!0),de.debug("Initialized"),M(),{ok:!0,value:void 0}},ge=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},pe=()=>{de.debug("Deinitializing"),Ee(),ke(!1),ee(),ue(!1)},he=()=>{de.debug("Putting formbricks in error state"),ae.update({...ae.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),pe()},ve="formbricks-web-container",fe=w.getInstance(),ye=l.getInstance(),me=y.getInstance();let we=!1,Ie=e=>{},be=e=>{};const ke=e=>{we=e},Se=async e=>{if(we)return void ye.debug("A survey is already running. Skipping.");ke(!0),e.delay&&ye.debug(`Delaying survey by ${e.delay} seconds.`);const t=fe.get().state.product,n=new x(e.id,null,null,fe.get().userId),s=new $({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{Ie(!0)},onResponseSendingFinished:()=>{be(!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 Ae();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{Ie=e},getSetIsResponseSendingFinished:e=>{be=e},onDisplay:async()=>{const{userId:t}=fe.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=fe.get().state.displays,s=n?[...n,t]:[t],i=fe.get();let r=E({...i.state,displays:s});fe.update({...i,state:r})}const i=new u({apiHost:fe.get().apiHost,environmentId:fe.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}=fe.get();if(!t){const e=fe.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=fe.get();let s=E({...n.state,displays:e});fe.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:He,onFileUpload:async(e,t)=>{const n=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{Ie(!1),s.processQueue()}})}),1e3*e.delay)},He=async()=>{if(Ee(),Ce(),!fe.get().userId){const e=fe.get().state,t=E(e);return fe.update({...fe.get(),state:t}),void ke(!1)}try{await C({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,userId:fe.get().userId},!0),ke(!1)}catch(e){me.handle(e),he()}},Ce=()=>{const e=document.createElement("div");e.id=ve,document.body.appendChild(e)},Ee=()=>{var e;null==(e=document.getElementById(ve))||e.remove()},Ae=()=>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)}})),Fe=l.getInstance(),$e=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],xe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=$e.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await Se(t)}));const i={environmentId:$e.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){Fe.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:$e.get().apiHost,environmentId:$e.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:`${$e.get().apiHost}/api/v1/client/${$e.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await C({environmentId:$e.get().environmentId,apiHost:$e.get().apiHost,userId:n},!0)}Fe.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=$e.get().state)?void 0:t.surveys;return r&&r.length>0?await Oe(e,r):Fe.debug("No active surveys to display"),{ok:!0,value:void 0}},Oe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Fe.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Fe.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await Se(s))}var n},Ue=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 Pe=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=(de.debug("Check if initialized"),ce&&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 Ue(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)=>{Pe.add(!0,ie,e,t),await Pe.wait()},Re={init:async e=>{y.init(e.errorHandler),Pe.add(!1,le,e),await Pe.wait()},setUserId:async()=>{Pe.add(!0,se),await Pe.wait()},setEmail:async e=>{Te("email",e),await Pe.wait()},setAttribute:Te,track:async(e,t={})=>{Pe.add(!0,xe,e,t),await Pe.wait()},logout:async()=>{Pe.add(!0,re),await Pe.wait()},reset:async()=>{Pe.add(!0,oe),await Pe.wait()},registerRouteChange:async()=>{Pe.add(!0,M),await Pe.wait()},getApi:()=>{const e=w.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=Re;
"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 u=await a.data,{data:c}=await u.json();return u.ok?(e=>({ok:!0,data:e}))(c):n({code:"network_error",message:u.statusText,status:u.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:u,presignedFields:c,updatedFileName:l}=o;let g={};if(u){const{signature:t,timestamp:s,uuid:i}=u;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;c&&Object.keys(c).forEach((e=>{p.append(e,c[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...u?{headers:g}:{},body:p});if(!h.ok){if(u){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(c&&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 u{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 c{constructor(e){this.client=new u(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 m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.instance}update(e){e&&(this.config={...this.config,...e,status:e.status||"success"},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(m);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(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}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=e=>{var t;const n=null==(t=e.languages)?void 0:t.find((e=>!0===e.default));if(n)return n.language.code},S=w.getInstance(),H=l.getInstance();let C=null;const E=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.7.0";let o={};if((s||b())&&(o.cache="no-cache",H.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 u=await d.json(),{data:c}=u;return g(c)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=S.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));H.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=A(o);const e=o.surveys.map((e=>e.name));H.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}S.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o,expiresAt:new Date((new Date).getTime()+12e4)})}catch(i){throw H.error(`Error during sync: ${i}`),i}},A=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}},F=()=>{"undefined"!=typeof window&&null!==C&&(window.clearInterval(C),C=null)},$=e=>new Promise((t=>setTimeout(t,e)));class x{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 c({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 $(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 O=D;let P=!1,T=async function(e){if(e.clientY<=0){const e=await Oe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{P&&(document.removeEventListener("mouseleave",T),P=!1)};let R=!1,L=!1,z=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(L=!1),!L&&e/(n-t)>=.5){L=!0;const e=await Oe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{R&&(window.removeEventListener("scroll",z),R=!1)},j=w.getInstance(),q=l.getInstance(),M=y.getInstance(),_=async()=>{var e;q.debug(`Checking page url: ${window.location.href}`);const{state:t}=j.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=W(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await Oe(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=W(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;He(e)}})),{ok:!0,value:void 0}};let B=!1;const J=()=>_(),X=["hashchange","popstate","pushstate","replacestate","load"],Q=()=>{"undefined"!=typeof window&&B&&(X.forEach((e=>window.removeEventListener(e,J))),B=!1)};function W(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 Y=(e,t)=>{var n,s,i,r,o,a,d,u;const c=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==(u=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:u.rule;if(!c&&!l&&!g)return!1;if(c&&e.innerHTML!==c)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=W(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let G=!1;const K=e=>(e=>{const{state:t}=j.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Y(s,e)&&Oe(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{M.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&&Y(s,t)&&He(e)}))})(e),V=()=>{G&&(document.removeEventListener("click",K),G=!1)};let Z=!1;const ee=()=>{"undefined"!=typeof window&&null===C&&(C=window.setInterval((async()=>{try{if(S.get().expiresAt&&new Date(S.get().expiresAt)>=new Date)return;H.debug("Config has expired. Starting sync."),await E({apiHost:S.get().apiHost,environmentId:S.get().environmentId,userId:S.get().userId})}catch(e){H.error(`Error during expiry check: ${e}`),H.debug("Extending config and try again later.");const t=S.get();S.update(t)}}),3e4)),"undefined"==typeof window||B||(X.forEach((e=>window.addEventListener(e,J))),B=!0),"undefined"==typeof window||G||(document.addEventListener("click",K),G=!0),"undefined"==typeof document||P||(document.querySelector("body").addEventListener("mouseleave",T),P=!0),"undefined"==typeof window||R||(window.addEventListener("load",(()=>{window.addEventListener("scroll",z)})),R=!0)},te=()=>{F(),Q(),V(),U(),N(),Z&&(window.removeEventListener("beforeunload",(()=>{F(),Q(),V(),U(),N()})),Z=!1)},ne=w.getInstance(),se=l.getInstance(),ie=async()=>(se.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),re=async(e,t)=>{if(se.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ne.get().state.attributes[e]===t)(e,t.toString()))return se.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}=ne.get();if(!i){const n=ne.get();return"language"===e?(ne.update({...n,state:{...n.state,attributes:{...n.state.attributes,language:t}}}),{ok:!0,value:void 0}):p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."})}const r={attributes:{[e]:t}},o=new c({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&se.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ne.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ne.update({environmentId:ne.get().environmentId,apiHost:ne.get().apiHost,userId:ne.get().userId,state:{...ne.get().state,attributes:{...ne.get().state.attributes,[e]:t.toString()}},expiresAt:ne.get().expiresAt}),{ok:!0,value:void 0}):p(n.error)},oe=async()=>{he(),ne.resetConfig()},ae=async()=>{se.debug("Resetting state & getting new state from backend"),Ce();const e={environmentId:ne.get().environmentId,apiHost:ne.get().apiHost,userId:ne.get().userId,attributes:ne.get().state.attributes};await oe();try{return await ge(e),{ok:!0,value:void 0}}catch(t){return p(t)}},de=w.getInstance(),ue=l.getInstance();let ce=!1;const le=e=>{ce=e},ge=async e=>{if(b()&&ue.configure({logLevel:"debug"}),ce)return ue.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=de.get(),ue.debug("Found existing configuration.")}catch(s){ue.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ue.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ue.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ue.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),ue.debug("Start initialize"),!e.environmentId)return ue.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ue.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});ue.debug("Adding widget container to DOM"),Ee();let n=null;if(e.attributes)if(e.userId){const t=await(async(e,t,n,i)=>{var r,o;const a={...i};try{const e=null==(o=null==(r=ne.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){se.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return se.debug("No attributes to update. Skipping update."),g(a);se.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},u=new c({apiHost:e,environmentId:t}),l=await u.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}else n={...e.attributes};if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ue.debug("Configuration fits init parameters."),t.expiresAt<new Date){ue.debug("Configuration expired.");try{await E({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ve()}}else ue.debug("Configuration not expired. Extending expiration."),de.update(t);else{ue.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),de.resetConfig(),ue.debug("Syncing.");try{await E({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}await Oe("New Session")}return n&&Object.keys(n).length>0&&de.update({environmentId:de.get().environmentId,apiHost:de.get().apiHost,userId:de.get().userId,state:{...de.get().state,attributes:{...de.get().state.attributes,...e.attributes}},expiresAt:de.get().expiresAt}),ue.debug("Adding event listeners"),ee(),Z||(window.addEventListener("beforeunload",(()=>{F(),Q(),V(),U(),N()})),Z=!0),le(!0),ue.debug("Initialized"),_(),{ok:!0,value:void 0}},pe=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},he=()=>{ue.debug("Deinitializing"),Ae(),Se(!1),te(),le(!1)},ve=()=>{ue.debug("Putting formbricks in error state"),de.update({...de.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),he()},fe="formbricks-web-container",ye=w.getInstance(),me=l.getInstance(),we=y.getInstance();let Ie=!1,be=e=>{},ke=e=>{};const Se=e=>{Ie=e},He=async e=>{if(Ie)return void me.debug("A survey is already running. Skipping.");Se(!0),e.delay&&me.debug(`Delaying survey by ${e.delay} seconds.`);const t=ye.get().state.product,n=ye.get().state.attributes,s=e.languages.length>1;let i="default";if(s){const t=((e,t)=>{const n=t.language,s=e.languages.map((e=>e.language.code));if(n){const t=e.languages.find((e=>e.language.code===n||e.language.alias===n));if(null==t?void 0:t.default)return"default";if(!t||!(null==t?void 0:t.enabled)||!s.includes(t.language.code))return;return t.language.code}return"default"})(e,n);if(!t)return me.debug("Survey not available in specified language."),void Se(!0);i=t}const r=new O(e.id,null,null,ye.get().userId),o=new x({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{be(!0)},onResponseSendingFinished:()=>{ke(!0)}},r),a=e.productOverwrites??{},d=a.brandColor??t.brandColor,u=a.highlightBorderColor??t.highlightBorderColor,l=a.clickOutsideClose??t.clickOutsideClose,g=a.darkOverlay??t.darkOverlay,p=a.placement??t.placement,h=t.inAppSurveyBranding,v=await Fe();setTimeout((()=>{v.renderSurveyModal({survey:e,brandColor:d,isBrandingEnabled:h,clickOutside:l,darkOverlay:g,languageCode:i,highlightBorderColor:u,placement:p,getSetIsError:e=>{be=e},getSetIsResponseSendingFinished:e=>{ke=e},onDisplay:async()=>{const{userId:t}=ye.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ye.get().state.displays,s=n?[...n,t]:[t],i=ye.get();let r=A({...i.state,displays:s});ye.update({...i,state:r})}const n=new c({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId}),s=await n.client.display.create({surveyId:e.id,userId:t});if(!s.ok)throw new Error("Could not create display");const{id:i}=s.data;r.updateDisplayId(i),o.updateSurveyState(r)},onResponse:t=>{const{userId:n}=ye.get();if(!n){const e=ye.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=ye.get();let s=A({...n.state,displays:e});ye.update({...n,state:s})}}n&&r.updateUserId(n),o.updateSurveyState(r),o.add({data:t.data,ttc:t.ttc,finished:t.finished,language:"default"===i?k(e):i})},onClose:Ce,onFileUpload:async(e,t)=>{const n=new c({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{be(!1),o.processQueue()}})}),1e3*e.delay)},Ce=async()=>{if(Ae(),Ee(),!ye.get().userId){const e=ye.get().state,t=A(e);return ye.update({...ye.get(),state:t}),void Se(!1)}try{await E({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId,userId:ye.get().userId},!0),Se(!1)}catch(e){we.handle(e),ve()}},Ee=()=>{const e=document.createElement("div");e.id=fe,document.body.appendChild(e)},Ae=()=>{var e;null==(e=document.getElementById(fe))||e.remove()},Fe=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.7.0/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)}})),$e=l.getInstance(),xe=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],Oe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=xe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await He(t)}));const i={environmentId:xe.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){$e.debug(`Sending action "${e}" to backend`);const t=new c({apiHost:xe.get().apiHost,environmentId:xe.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:`${xe.get().apiHost}/api/v1/client/${xe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await E({environmentId:xe.get().environmentId,apiHost:xe.get().apiHost,userId:n},!0)}$e.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=xe.get().state)?void 0:t.surveys;return r&&r.length>0?await Pe(e,r):$e.debug("No active surveys to display"),{ok:!0,value:void 0}},Pe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){$e.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return $e.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await He(s))}var n},Te=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 Ue=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=(ue.debug("Check if initialized"),ce&&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 Te(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)}},Re=async(e,t)=>{Ue.add(!0,re,e,t),await Ue.wait()},Le={init:async e=>{y.init(e.errorHandler),Ue.add(!1,ge,e),await Ue.wait()},setUserId:async()=>{Ue.add(!0,ie),await Ue.wait()},setEmail:async e=>{Re("email",e),await Ue.wait()},setAttribute:Re,track:async(e,t={})=>{Ue.add(!0,Oe,e,t),await Ue.wait()},logout:async()=>{Ue.add(!0,oe),await Ue.wait()},reset:async()=>{Ue.add(!0,ae),await Ue.wait()},registerRouteChange:async()=>{Ue.add(!0,_),await Ue.wait()},getApi:()=>{const e=w.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new c({apiHost:n,environmentId:t})}};module.exports=Le;
//# 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 m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.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(m);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(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}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=w.getInstance(),S=l.getInstance();let H=null;const C=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.4";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=E(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}},E=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!==H&&(window.clearInterval(H),H=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 O=!1,T=async function(e){if(e.clientY<=0){const e=await xe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{O&&(document.removeEventListener("mouseleave",T),O=!1)};let P=!1,R=!1,L=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(R=!1),!R&&e/(n-t)>=.5){R=!0;const e=await xe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{P&&(window.removeEventListener("scroll",L),P=!1)},z=w.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=Q(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await xe(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=Q(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;Se(e)}})),{ok:!0,value:void 0}};let _=!1;const B=()=>M(),J=["hashchange","popstate","pushstate","replacestate","load"],X=()=>{"undefined"!=typeof window&&_&&(J.forEach((e=>window.removeEventListener(e,B))),_=!1)};function Q(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 W=(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=Q(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let Y=!1;const G=e=>(e=>{const{state:t}=z.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{W(s,e)&&xe(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&&W(s,t)&&Se(e)}))})(e),K=()=>{Y&&(document.removeEventListener("click",G),Y=!1)};let V=!1;const Z=()=>{"undefined"!=typeof window&&null===H&&(H=window.setInterval((async()=>{try{if(k.get().expiresAt&&new Date(k.get().expiresAt)>=new Date)return;S.debug("Config has expired. Starting sync."),await C({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||_||(J.forEach((e=>window.addEventListener(e,B))),_=!0),"undefined"==typeof window||Y||(document.addEventListener("click",G),Y=!0),"undefined"==typeof document||O||(document.querySelector("body").addEventListener("mouseleave",T),O=!0),"undefined"==typeof window||P||(window.addEventListener("load",(()=>{window.addEventListener("scroll",L)})),P=!0)},ee=()=>{A(),X(),K(),U(),N(),V&&(window.removeEventListener("beforeunload",(()=>{A(),X(),K(),U(),N()})),V=!1)},te=w.getInstance(),ne=l.getInstance(),se=async()=>(ne.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),ie=async(e,t)=>{if(ne.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>te.get().state.attributes[e]===t)(e,t.toString()))return ne.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}=te.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&&ne.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${te.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(te.update({environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId,state:{...te.get().state,attributes:{...te.get().state.attributes,[e]:t.toString()}}}),{ok:!0,value:void 0}):p(n.error)},re=async()=>{pe(),te.resetConfig()},oe=async()=>{ne.debug("Resetting state & getting new state from backend"),He();const e={environmentId:te.get().environmentId,apiHost:te.get().apiHost,userId:te.get().userId};await re();try{return await le(e),{ok:!0,value:void 0}}catch(t){return p(t)}},ae=w.getInstance(),de=l.getInstance();let ce=!1;const ue=e=>{ce=e},le=async e=>{if(b()&&de.configure({logLevel:"debug"}),ce)return de.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=ae.get(),de.debug("Found existing configuration.")}catch(s){de.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(de.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return de.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};de.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),de.debug("Start initialize"),!e.environmentId)return de.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return de.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});if(de.debug("Adding widget container to DOM"),Ce(),!e.userId&&e.attributes)return de.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=te.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){ne.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return ne.debug("No attributes to update. Skipping update."),g(a);ne.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(de.debug("Configuration fits init parameters."),t.expiresAt<new Date){de.debug("Configuration expired.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){he()}}else de.debug("Configuration not expired. Extending expiration."),ae.update(t);else{de.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),ae.resetConfig(),de.debug("Syncing.");try{await C({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ge()}await xe("New Session")}return n&&Object.keys(n).length>0&&ae.update({environmentId:ae.get().environmentId,apiHost:ae.get().apiHost,userId:ae.get().userId,state:{...ae.get().state,attributes:{...ae.get().state.attributes,...e.attributes}}}),de.debug("Adding event listeners"),Z(),V||(window.addEventListener("beforeunload",(()=>{A(),X(),K(),U(),N()})),V=!0),ue(!0),de.debug("Initialized"),M(),{ok:!0,value:void 0}},ge=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},pe=()=>{de.debug("Deinitializing"),Ee(),ke(!1),ee(),ue(!1)},he=()=>{de.debug("Putting formbricks in error state"),ae.update({...ae.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),pe()},ve="formbricks-web-container",fe=w.getInstance(),ye=l.getInstance(),me=y.getInstance();let we=!1,Ie=e=>{},be=e=>{};const ke=e=>{we=e},Se=async e=>{if(we)return void ye.debug("A survey is already running. Skipping.");ke(!0),e.delay&&ye.debug(`Delaying survey by ${e.delay} seconds.`);const t=fe.get().state.product,n=new x(e.id,null,null,fe.get().userId),s=new $({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{Ie(!0)},onResponseSendingFinished:()=>{be(!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 Ae();setTimeout((()=>{g.renderSurveyModal({survey:e,brandColor:r,isBrandingEnabled:l,clickOutside:a,darkOverlay:d,highlightBorderColor:o,placement:c,getSetIsError:e=>{Ie=e},getSetIsResponseSendingFinished:e=>{be=e},onDisplay:async()=>{const{userId:t}=fe.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=fe.get().state.displays,s=n?[...n,t]:[t],i=fe.get();let r=E({...i.state,displays:s});fe.update({...i,state:r})}const i=new u({apiHost:fe.get().apiHost,environmentId:fe.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}=fe.get();if(!t){const e=fe.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=fe.get();let s=E({...n.state,displays:e});fe.update({...n,state:s})}}t&&n.updateUserId(t),s.updateSurveyState(n),s.add({data:e.data,ttc:e.ttc,finished:e.finished})},onClose:He,onFileUpload:async(e,t)=>{const n=new u({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{Ie(!1),s.processQueue()}})}),1e3*e.delay)},He=async()=>{if(Ee(),Ce(),!fe.get().userId){const e=fe.get().state,t=E(e);return fe.update({...fe.get(),state:t}),void ke(!1)}try{await C({apiHost:fe.get().apiHost,environmentId:fe.get().environmentId,userId:fe.get().userId},!0),ke(!1)}catch(e){me.handle(e),he()}},Ce=()=>{const e=document.createElement("div");e.id=ve,document.body.appendChild(e)},Ee=()=>{var e;null==(e=document.getElementById(ve))||e.remove()},Ae=()=>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)}})),Fe=l.getInstance(),$e=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],xe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=$e.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await Se(t)}));const i={environmentId:$e.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){Fe.debug(`Sending action "${e}" to backend`);const t=new u({apiHost:$e.get().apiHost,environmentId:$e.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:`${$e.get().apiHost}/api/v1/client/${$e.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await C({environmentId:$e.get().environmentId,apiHost:$e.get().apiHost,userId:n},!0)}Fe.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=$e.get().state)?void 0:t.surveys;return r&&r.length>0?await Oe(e,r):Fe.debug("No active surveys to display"),{ok:!0,value:void 0}},Oe=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){Fe.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return Fe.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await Se(s))}var n},Te=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 Ue=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=(de.debug("Check if initialized"),ce&&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 Te(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)}},Pe=async(e,t)=>{Ue.add(!0,ie,e,t),await Ue.wait()};return{init:async e=>{y.init(e.errorHandler),Ue.add(!1,le,e),await Ue.wait()},setUserId:async()=>{Ue.add(!0,se),await Ue.wait()},setEmail:async e=>{Pe("email",e),await Ue.wait()},setAttribute:Pe,track:async(e,t={})=>{Ue.add(!0,xe,e,t),await Ue.wait()},logout:async()=>{Ue.add(!0,re),await Ue.wait()},reset:async()=>{Ue.add(!0,oe),await Ue.wait()},registerRouteChange:async()=>{Ue.add(!0,M),await Ue.wait()},getApi:()=>{const e=w.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 u=await a.data,{data:c}=await u.json();return u.ok?(e=>({ok:!0,data:e}))(c):n({code:"network_error",message:u.statusText,status:u.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:u,presignedFields:c,updatedFileName:l}=o;let g={};if(u){const{signature:t,timestamp:s,uuid:i}=u;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;c&&Object.keys(c).forEach((e=>{p.append(e,c[e])})),p.append("file",e);const h=await fetch(a,{method:"POST",...u?{headers:g}:{},body:p});if(!h.ok){if(u){const e=await h.json(),t=new Error(e.message);throw t.name="FileTooLargeError",t}const e=await h.text();if(c&&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 u{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 c{constructor(e){this.client=new u(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 m="formbricks-js";class w{constructor(){this.config=null;const e=this.loadFromLocalStorage();e.ok&&(this.config=e.value)}static getInstance(){return w.instance||(w.instance=new w),w.instance}update(e){e&&(this.config={...this.config,...e,status:e.status||"success"},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(m);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(m,JSON.stringify(this.config))))()}resetConfig(){return this.config=null,h((()=>localStorage.removeItem(m)))()}}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=e=>{var t;const n=null==(t=e.languages)?void 0:t.find((e=>!0===e.default));if(n)return n.language.code},S=w.getInstance(),H=l.getInstance();let C=null;const E=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.7.0";let o={};if((s||b())&&(o.cache="no-cache",H.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 u=await d.json(),{data:c}=u;return g(c)}catch(i){return p(i)}})(e,t);if(!0!==(null==i?void 0:i.ok))throw i.error;let r;try{r=S.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));H.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}else{o={...o,displays:(null==r?void 0:r.displays)||[]},o=A(o);const e=o.surveys.map((e=>e.name));H.debug("Fetched "+e.length+" surveys during sync: "+e.join(", "))}S.update({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId,state:o,expiresAt:new Date((new Date).getTime()+12e4)})}catch(i){throw H.error(`Error during sync: ${i}`),i}},A=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}},F=()=>{"undefined"!=typeof window&&null!==C&&(window.clearInterval(C),C=null)},$=e=>new Promise((t=>setTimeout(t,e)));class x{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 c({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 $(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 O=D;let T=!1,P=async function(e){if(e.clientY<=0){const e=await Oe("Exit Intent (Desktop)");if(!0!==e.ok)return p(e.error)}};const U=()=>{T&&(document.removeEventListener("mouseleave",P),T=!1)};let R=!1,L=!1,z=async()=>{const e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(0===e&&(L=!1),!L&&e/(n-t)>=.5){L=!0;const e=await Oe("50% Scroll");if(!0!==e.ok)return p(e.error)}};const N=()=>{R&&(window.removeEventListener("scroll",z),R=!1)},j=w.getInstance(),q=l.getInstance(),M=y.getInstance(),_=async()=>{var e;q.debug(`Checking page url: ${window.location.href}`);const{state:t}=j.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=W(window.location.href,t.value,t.rule);if(!0!==n.ok)return p(n.error);if(!1===n.value)continue;const s=await Oe(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=W(window.location.href,n.value,n.rule);if(!0!==t.ok)return p(t.error);if(!1===t.value)return;He(e)}})),{ok:!0,value:void 0}};let B=!1;const J=()=>_(),X=["hashchange","popstate","pushstate","replacestate","load"],Q=()=>{"undefined"!=typeof window&&B&&(X.forEach((e=>window.removeEventListener(e,J))),B=!1)};function W(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 Y=(e,t)=>{var n,s,i,r,o,a,d,u;const c=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==(u=null==(d=t.noCodeConfig)?void 0:d.pageUrl)?void 0:u.rule;if(!c&&!l&&!g)return!1;if(c&&e.innerHTML!==c)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=W(window.location.href,g,p);if(!e.ok||!e.value)return!1}return!0};let G=!1;const K=e=>(e=>{const{state:t}=j.get();if(!t)return;const{noCodeActionClasses:n}=t;if(!n)return;const s=e.target;n.forEach((e=>{Y(s,e)&&Oe(e.name).then((e=>{var t,n,s;n=e=>{},s=e=>{M.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&&Y(s,t)&&He(e)}))})(e),V=()=>{G&&(document.removeEventListener("click",K),G=!1)};let Z=!1;const ee=()=>{"undefined"!=typeof window&&null===C&&(C=window.setInterval((async()=>{try{if(S.get().expiresAt&&new Date(S.get().expiresAt)>=new Date)return;H.debug("Config has expired. Starting sync."),await E({apiHost:S.get().apiHost,environmentId:S.get().environmentId,userId:S.get().userId})}catch(e){H.error(`Error during expiry check: ${e}`),H.debug("Extending config and try again later.");const t=S.get();S.update(t)}}),3e4)),"undefined"==typeof window||B||(X.forEach((e=>window.addEventListener(e,J))),B=!0),"undefined"==typeof window||G||(document.addEventListener("click",K),G=!0),"undefined"==typeof document||T||(document.querySelector("body").addEventListener("mouseleave",P),T=!0),"undefined"==typeof window||R||(window.addEventListener("load",(()=>{window.addEventListener("scroll",z)})),R=!0)},te=()=>{F(),Q(),V(),U(),N(),Z&&(window.removeEventListener("beforeunload",(()=>{F(),Q(),V(),U(),N()})),Z=!1)},ne=w.getInstance(),se=l.getInstance(),ie=async()=>(se.error("'setUserId' is no longer supported. Please set the userId in the init call instead."),{ok:!0,value:void 0}),re=async(e,t)=>{if(se.debug("Setting attribute: "+e+" to value: "+t),((e,t)=>ne.get().state.attributes[e]===t)(e,t.toString()))return se.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}=ne.get();if(!i){const n=ne.get();return"language"===e?(ne.update({...n,state:{...n.state,attributes:{...n.state.attributes,language:t}}}),{ok:!0,value:void 0}):p({code:"missing_person",message:"Unable to update attribute. User identification deactivated. No userId set."})}const r={attributes:{[e]:t}},o=new c({apiHost:n,environmentId:s}),a=await o.client.people.update(i,r);return a.ok?(a.data.changed&&se.debug("Attribute updated in Formbricks"),{ok:!0,value:void 0}):p({code:"network_error",status:500,message:`Error updating person with userId ${i}`,url:`${ne.get().apiHost}/api/v1/client/${s}/people/${i}`,responseMessage:a.error.message})})(e,t.toString());return n.ok?(ne.update({environmentId:ne.get().environmentId,apiHost:ne.get().apiHost,userId:ne.get().userId,state:{...ne.get().state,attributes:{...ne.get().state.attributes,[e]:t.toString()}},expiresAt:ne.get().expiresAt}),{ok:!0,value:void 0}):p(n.error)},oe=async()=>{he(),ne.resetConfig()},ae=async()=>{se.debug("Resetting state & getting new state from backend"),Ce();const e={environmentId:ne.get().environmentId,apiHost:ne.get().apiHost,userId:ne.get().userId,attributes:ne.get().state.attributes};await oe();try{return await ge(e),{ok:!0,value:void 0}}catch(t){return p(t)}},de=w.getInstance(),ue=l.getInstance();let ce=!1;const le=e=>{ce=e},ge=async e=>{if(b()&&ue.configure({logLevel:"debug"}),ce)return ue.debug("Already initialized, skipping initialization."),{ok:!0,value:void 0};let t;try{t=de.get(),ue.debug("Found existing configuration.")}catch(s){ue.debug("No existing configuration found.")}if("error"===(null==t?void 0:t.status)){if(ue.debug("Formbricks was set to an error state."),(null==t?void 0:t.expiresAt)&&new Date(t.expiresAt)>new Date)return ue.debug("Error state is not expired, skipping initialization"),{ok:!0,value:void 0};ue.debug("Error state is expired. Continue with initialization.")}if(y.getInstance().printStatus(),ue.debug("Start initialize"),!e.environmentId)return ue.debug("No environmentId provided"),p({code:"missing_field",field:"environmentId"});if(!e.apiHost)return ue.debug("No apiHost provided"),p({code:"missing_field",field:"apiHost"});ue.debug("Adding widget container to DOM"),Ee();let n=null;if(e.attributes)if(e.userId){const t=await(async(e,t,n,i)=>{var r,o;const a={...i};try{const e=null==(o=null==(r=ne.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){se.debug("config not set; sending all attributes to backend")}if(0===Object.keys(a).length)return se.debug("No attributes to update. Skipping update."),g(a);se.debug("Updating attributes: "+JSON.stringify(a));const d={attributes:a},u=new c({apiHost:e,environmentId:t}),l=await u.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}else n={...e.attributes};if(t&&t.state&&t.environmentId===e.environmentId&&t.apiHost===e.apiHost&&t.userId===e.userId&&t.expiresAt)if(ue.debug("Configuration fits init parameters."),t.expiresAt<new Date){ue.debug("Configuration expired.");try{await E({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){ve()}}else ue.debug("Configuration not expired. Extending expiration."),de.update(t);else{ue.debug("No valid configuration found or it has been expired. Resetting config and creating new one."),de.resetConfig(),ue.debug("Syncing.");try{await E({apiHost:e.apiHost,environmentId:e.environmentId,userId:e.userId})}catch(s){pe()}await Oe("New Session")}return n&&Object.keys(n).length>0&&de.update({environmentId:de.get().environmentId,apiHost:de.get().apiHost,userId:de.get().userId,state:{...de.get().state,attributes:{...de.get().state.attributes,...e.attributes}},expiresAt:de.get().expiresAt}),ue.debug("Adding event listeners"),ee(),Z||(window.addEventListener("beforeunload",(()=>{F(),Q(),V(),U(),N()})),Z=!0),le(!0),ue.debug("Initialized"),_(),{ok:!0,value:void 0}},pe=()=>{const e={status:"error",expiresAt:new Date((new Date).getTime()+6e5)};throw h((()=>localStorage.setItem(m,JSON.stringify(e))))(),new Error("Could not initialize formbricks")},he=()=>{ue.debug("Deinitializing"),Ae(),Se(!1),te(),le(!1)},ve=()=>{ue.debug("Putting formbricks in error state"),de.update({...de.get(),status:"error",expiresAt:new Date((new Date).getTime()+6e5)}),he()},fe="formbricks-web-container",ye=w.getInstance(),me=l.getInstance(),we=y.getInstance();let Ie=!1,be=e=>{},ke=e=>{};const Se=e=>{Ie=e},He=async e=>{if(Ie)return void me.debug("A survey is already running. Skipping.");Se(!0),e.delay&&me.debug(`Delaying survey by ${e.delay} seconds.`);const t=ye.get().state.product,n=ye.get().state.attributes,s=e.languages.length>1;let i="default";if(s){const t=((e,t)=>{const n=t.language,s=e.languages.map((e=>e.language.code));if(n){const t=e.languages.find((e=>e.language.code===n||e.language.alias===n));if(null==t?void 0:t.default)return"default";if(!t||!(null==t?void 0:t.enabled)||!s.includes(t.language.code))return;return t.language.code}return"default"})(e,n);if(!t)return me.debug("Survey not available in specified language."),void Se(!0);i=t}const r=new O(e.id,null,null,ye.get().userId),o=new x({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId,retryAttempts:2,onResponseSendingFailed:()=>{be(!0)},onResponseSendingFinished:()=>{ke(!0)}},r),a=e.productOverwrites??{},d=a.brandColor??t.brandColor,u=a.highlightBorderColor??t.highlightBorderColor,l=a.clickOutsideClose??t.clickOutsideClose,g=a.darkOverlay??t.darkOverlay,p=a.placement??t.placement,h=t.inAppSurveyBranding,v=await Fe();setTimeout((()=>{v.renderSurveyModal({survey:e,brandColor:d,isBrandingEnabled:h,clickOutside:l,darkOverlay:g,languageCode:i,highlightBorderColor:u,placement:p,getSetIsError:e=>{be=e},getSetIsResponseSendingFinished:e=>{ke=e},onDisplay:async()=>{const{userId:t}=ye.get();if(!t){const t={createdAt:new Date,surveyId:e.id,responded:!1},n=ye.get().state.displays,s=n?[...n,t]:[t],i=ye.get();let r=A({...i.state,displays:s});ye.update({...i,state:r})}const n=new c({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId}),s=await n.client.display.create({surveyId:e.id,userId:t});if(!s.ok)throw new Error("Could not create display");const{id:i}=s.data;r.updateDisplayId(i),o.updateSurveyState(r)},onResponse:t=>{const{userId:n}=ye.get();if(!n){const e=ye.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=ye.get();let s=A({...n.state,displays:e});ye.update({...n,state:s})}}n&&r.updateUserId(n),o.updateSurveyState(r),o.add({data:t.data,ttc:t.ttc,finished:t.finished,language:"default"===i?k(e):i})},onClose:Ce,onFileUpload:async(e,t)=>{const n=new c({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId});return await n.client.storage.uploadFile(e,t)},onRetry:()=>{be(!1),o.processQueue()}})}),1e3*e.delay)},Ce=async()=>{if(Ae(),Ee(),!ye.get().userId){const e=ye.get().state,t=A(e);return ye.update({...ye.get(),state:t}),void Se(!1)}try{await E({apiHost:ye.get().apiHost,environmentId:ye.get().environmentId,userId:ye.get().userId},!0),Se(!1)}catch(e){we.handle(e),ve()}},Ee=()=>{const e=document.createElement("div");e.id=fe,document.body.appendChild(e)},Ae=()=>{var e;null==(e=document.getElementById(fe))||e.remove()},Fe=()=>new Promise(((e,t)=>{if(window.formbricksSurveys)e(window.formbricksSurveys);else{const n=document.createElement("script");n.src="https://unpkg.com/@formbricks/surveys@^1.7.0/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)}})),$e=l.getInstance(),xe=w.getInstance(),De=["Exit Intent (Desktop)","50% Scroll"],Oe=async e=>{var t;const{userId:n,state:{surveys:s=[]}}=xe.get();s.forEach((async t=>{const{inlineTriggers:n}=t,{codeConfig:s}=n??{};e!==(null==s?void 0:s.identifier)||await He(t)}));const i={environmentId:xe.get().environmentId,userId:n,name:e};if(n&&!De.includes(e)){$e.debug(`Sending action "${e}" to backend`);const t=new c({apiHost:xe.get().apiHost,environmentId:xe.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:`${xe.get().apiHost}/api/v1/client/${xe.get().environmentId}/actions`,responseMessage:s.error.message});b()&&await E({environmentId:xe.get().environmentId,apiHost:xe.get().apiHost,userId:n},!0)}$e.debug(`Formbricks: Action "${e}" tracked`);const r=null==(t=xe.get().state)?void 0:t.surveys;return r&&r.length>0?await Te(e,r):$e.debug("No active surveys to display"),{ok:!0,value:void 0}},Te=async(e,t)=>{for(const s of t){if(s.displayPercentage){if(!(n=s.displayPercentage,Math.floor(100*Math.random())+1<=n)){$e.debug("Survey display skipped based on displayPercentage.");continue}}for(const t of s.triggers)if(t===e)return $e.debug(`Formbricks: survey ${s.id} triggered by action "${e}"`),void(await He(s))}var n},Pe=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 Ue=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=(ue.debug("Check if initialized"),ce&&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 Pe(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)}},Re=async(e,t)=>{Ue.add(!0,re,e,t),await Ue.wait()};return{init:async e=>{y.init(e.errorHandler),Ue.add(!1,ge,e),await Ue.wait()},setUserId:async()=>{Ue.add(!0,ie),await Ue.wait()},setEmail:async e=>{Re("email",e),await Ue.wait()},setAttribute:Re,track:async(e,t={})=>{Ue.add(!0,Oe,e,t),await Ue.wait()},logout:async()=>{Ue.add(!0,oe),await Ue.wait()},reset:async()=>{Ue.add(!0,ae),await Ue.wait()},registerRouteChange:async()=>{Ue.add(!0,_),await Ue.wait()},getApi:()=>{const e=w.getInstance(),{environmentId:t,apiHost:n}=e.get();if(!t||!n)throw new Error("formbricks.init() must be called before getApi()");return new c({apiHost:n,environmentId:t})}}}));
//# sourceMappingURL=index.umd.js.map
{
"name": "@formbricks/js",
"license": "MIT",
"version": "1.6.4",
"version": "1.7.0",
"description": "Formbricks-js allows you to connect your app to Formbricks, display surveys and trigger events.",

@@ -46,7 +46,7 @@ "homepage": "https://formbricks.com",

"vite-plugin-dts": "^3.7.3",
"@formbricks/api": "1.6.0",
"@formbricks/surveys": "1.7.0",
"@formbricks/tsconfig": "1.0.0",
"@formbricks/lib": "0.0.0",
"@formbricks/surveys": "1.6.2",
"@formbricks/api": "1.6.0",
"@formbricks/types": "0.0.0",
"@formbricks/tsconfig": "1.0.0"
"@formbricks/types": "0.0.0"
},

@@ -53,0 +53,0 @@ "scripts": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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