@datalyr/web 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- var Datalyr=function(){"use strict";function t(t,e,i,s){return new(i||(i=Promise))(function(n,o){function r(t){try{c(s.next(t))}catch(t){o(t)}}function a(t){try{c(s.throw(t))}catch(t){o(t)}}function c(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i(function(t){t(e)})).then(r,a)}c((s=s.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;const e=new class{constructor(){this.key=null,this.salt=null}initialize(e,i){return t(this,void 0,void 0,function*(){if(!crypto.subtle){const t=new Error("Web Crypto API not available - encryption cannot be initialized");throw console.error("[Datalyr Encryption]",t.message),t}try{const t=new TextEncoder,s="dl_encryption_salt";let n=localStorage.getItem(s);n?this.salt=this.base64ToArrayBuffer(n):(this.salt=crypto.getRandomValues(new Uint8Array(32)),n=this.arrayBufferToBase64(this.salt),localStorage.setItem(s,n));const o=`datalyr:${e}:${i}`,r=t.encode(o),a=yield crypto.subtle.importKey("raw",r,"PBKDF2",!1,["deriveKey"]);this.key=yield crypto.subtle.deriveKey({name:"PBKDF2",salt:this.salt,iterations:1e5,hash:"SHA-256"},a,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw console.error("[Datalyr Encryption] Failed to initialize:",t),this.key=null,t}})}encrypt(e){return t(this,void 0,void 0,function*(){if(!this.key||!crypto.subtle)throw new Error("Encryption not initialized - cannot encrypt sensitive data");try{const t="string"==typeof e?e:JSON.stringify(e),i=(new TextEncoder).encode(t),s=crypto.getRandomValues(new Uint8Array(12)),n=yield crypto.subtle.encrypt({name:"AES-GCM",iv:s},this.key,i),o=new Uint8Array(s.length+n.byteLength);return o.set(s,0),o.set(new Uint8Array(n),s.length),this.arrayBufferToBase64(o)}catch(t){throw console.error("[Datalyr Encryption] Encryption failed:",t),t}})}decrypt(e){return t(this,void 0,void 0,function*(){if(!this.key||!crypto.subtle){console.warn("[Datalyr Encryption] Decryption not available - reading potentially unencrypted data");try{return JSON.parse(e)}catch(t){return e}}try{const t=this.base64ToArrayBuffer(e),i=t.slice(0,12),s=t.slice(12),n=yield crypto.subtle.decrypt({name:"AES-GCM",iv:i},this.key,s),o=(new TextDecoder).decode(n);try{return JSON.parse(o)}catch(t){return o}}catch(t){console.warn("[Datalyr Encryption] Decryption failed - attempting to read as unencrypted data (migration mode)");try{return JSON.parse(e)}catch(t){return e}}})}isAvailable(){return null!==this.key&&void 0!==crypto.subtle}arrayBufferToBase64(t){let e="";const i=new Uint8Array(t),s=i.byteLength;for(let t=0;t<s;t++)e+=String.fromCharCode(i[t]);return btoa(e)}base64ToArrayBuffer(t){const e=atob(t),i=e.length,s=new Uint8Array(i);for(let t=0;t<i;t++)s[t]=e.charCodeAt(t);return s}destroy(){this.key=null,this.salt=null}};class i{constructor(t){this.memory=new Map,this.prefix="dl_";try{const e="dl_test__"+Math.random();t.setItem(e,"1"),t.removeItem(e),this.storage=t}catch(t){this.storage=null,console.warn("[Datalyr] Storage not available, using memory fallback")}}get(t,e=null){const i=this.prefix+t;try{if(this.storage){const t=this.storage.getItem(i);if(null===t)return e;try{return JSON.parse(t)}catch(e){return t}}else{const t=this.memory.get(i);if(void 0===t)return e;try{return JSON.parse(t)}catch(e){return t}}}catch(t){return e}}set(t,e){const i=this.prefix+t,s="string"==typeof e?e:JSON.stringify(e);try{return this.storage?(this.storage.setItem(i,s),!0):(this.memory.set(i,s),!0)}catch(e){return console.warn("[Datalyr] Failed to store:",t,e),this.memory.set(i,s),!1}}remove(t){const e=this.prefix+t;try{return this.storage?(this.storage.removeItem(e),!0):(this.memory.delete(e),!0)}catch(t){return!1}}keys(){try{if(this.storage){const t=[];for(let e=0;e<this.storage.length;e++){const i=this.storage.key(e);i&&i.startsWith(this.prefix)&&t.push(i.slice(this.prefix.length))}return t}return Array.from(this.memory.keys()).filter(t=>t.startsWith(this.prefix)).map(t=>t.slice(this.prefix.length))}catch(t){return[]}}migrateFromLegacyPrefix(){if(!this.storage)return 0;let t=0;try{const e=[];for(let t=0;t<this.storage.length;t++){const i=this.storage.key(t);i&&i.startsWith("__dl_dl_")&&e.push(i)}e.forEach(e=>{try{const i=this.storage.getItem(e);if(i){const s=e.slice(5);this.storage.getItem(s)||(this.storage.setItem(s,i),t++),this.storage.removeItem(e)}}catch(t){console.warn(`[Datalyr Storage] Failed to migrate legacy key: ${e}`,t)}}),t>0&&console.log(`[Datalyr Storage] Migrated ${t} keys from legacy prefix`)}catch(t){console.warn("[Datalyr Storage] Error during legacy key migration:",t)}return t}getEncrypted(i){return t(this,arguments,void 0,function*(t,i=null){const s=this.prefix+t;try{let t=null;if(t=this.storage?this.storage.getItem(s):this.memory.get(s)||null,!t)return i;return yield e.decrypt(t)}catch(e){return console.warn("[Datalyr Storage] Failed to decrypt:",t,e),i}})}setEncrypted(i,s){return t(this,void 0,void 0,function*(){const t=this.prefix+i,n=yield e.encrypt(s);return this.storage?(this.storage.setItem(t,n),!0):(this.memory.set(t,n),!0)})}}class s{constructor(t={}){this.domain=t.domain||"auto",this.maxAge=t.maxAge||365,this.sameSite=t.sameSite||"Lax",this.secure=t.secure||"auto"}get(t){var e;const i=`; ${document.cookie}`.split(`; ${t}=`);if(2===i.length){const t=(null===(e=i.pop())||void 0===e?void 0:e.split(";").shift())||null;if(t)try{return decodeURIComponent(t)}catch(e){return t}}return null}set(t,e,i){try{const s=86400*(i||this.maxAge),n="auto"===this.secure?"https:"===location.protocol:this.secure;let o="";"auto"===this.domain?o=this.getAutoDomain():this.domain&&(o=`;domain=${this.domain}`);const r=[`${t}=${encodeURIComponent(e)}`,`max-age=${s}`,"path=/",`SameSite=${this.sameSite}`,n?"Secure":"",o].filter(Boolean).join(";");return document.cookie=r,!0}catch(e){return console.warn("[Datalyr] Failed to set cookie:",t,e),!1}}remove(t){try{const e=["",location.hostname],i=location.hostname.split(".");return i.length>2&&(e.push(`.${i.slice(-2).join(".")}`),e.push(`.${location.hostname}`)),e.forEach(e=>{const i=e?`;domain=${e}`:"";document.cookie=`${t}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/${i}`}),!0}catch(t){return!1}}getAutoDomain(){const t=location.hostname;if("localhost"===t||/^[\d.]+$/.test(t)||/^\[[\d:]+\]$/.test(t))return"";const e=t.split(".");for(let t=e.length-2;t>=0;t--){const i="."+e.slice(t).join("."),s="__dl_test_"+Math.random();if(document.cookie=`${s}=1;domain=${i};path=/`,-1!==document.cookie.indexOf(s))return document.cookie=`${s}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;domain=${i};path=/`,`;domain=${i}`}return""}}const n=new i(window.localStorage);new i(window.sessionStorage);const o=new s;function r(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)})}function a(t=window.location.search){const e={};try{if("URLSearchParams"in window){return new URLSearchParams(t).forEach((t,i)=>{e[i]=t}),e}}catch(t){}const i=(t||"").replace(/^\?/,"").split("&");for(const t of i){const[i,s=""]=t.split("=");try{const t=decodeURIComponent((i||"").replace(/\+/g," ")),n=decodeURIComponent((s||"").replace(/\+/g," "));t&&(e[t]=n)}catch(t){}}return e}function c(t,e=5,i=0){if(i>=e)return"[Max depth reached]";if(null==t)return t;if("undefined"!=typeof Element&&t instanceof Element||"undefined"!=typeof Document&&t instanceof Document||"function"==typeof t)return"[Removed]";if(Array.isArray(t))return t.map(t=>c(t,e,i+1));if("object"==typeof t){const s={},n=/pass|pwd|token|secret|auth|bearer|session|cookie|signature|api[-_]?key|private[-_]?key|access[-_]?token|refresh[-_]?token/i;for(const o in t)if(Object.prototype.hasOwnProperty.call(t,o)){if(n.test(o))continue;s[o]=c(t[o],e,i+1)}return s}return"string"==typeof t?t.length>1e3?t.slice(0,1e3)+"...[truncated]":t.match(/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+$/)||t.match(/^[a-f0-9]{32,}$/i)?"[Redacted]":t:t}function l(t,...e){if(!e.length)return t;const i=e.shift();if(h(t)&&h(i))for(const e in i)h(i[e])?(t[e]||Object.assign(t,{[e]:{}}),l(t[e],i[e])):Object.assign(t,{[e]:i[e]});return l(t,...e)}function h(t){return t&&"object"==typeof t&&!Array.isArray(t)}function d(t){const e={google:["google.com","google."],facebook:["facebook.com","fb.com"],twitter:["twitter.com","t.co","x.com"],linkedin:["linkedin.com","lnkd.in"],instagram:["instagram.com"],youtube:["youtube.com","youtu.be"],tiktok:["tiktok.com"],reddit:["reddit.com"],pinterest:["pinterest.com"],bing:["bing.com"],yahoo:["yahoo.com"],duckduckgo:["duckduckgo.com"],baidu:["baidu.com"]};for(const[i,s]of Object.entries(e))if(s.some(e=>t.includes(e)))return i;return"other"}class u{constructor(){this.userId=null,this.sessionId=null,this.anonymousId=this.getOrCreateAnonymousId(),this.userId=this.getStoredUserId()}getOrCreateAnonymousId(){let t=o.get("__dl_visitor_id");return t?(n.set("dl_anonymous_id",t),t):(t=n.get("dl_anonymous_id"),t?(this.setRootDomainCookie("__dl_visitor_id",t),t):(t=`anon_${r()}`,this.setRootDomainCookie("__dl_visitor_id",t),n.set("dl_anonymous_id",t),t))}setRootDomainCookie(t,e){try{const i=function(){const t=window.location.hostname;if("localhost"===t||t.match(/^[0-9]{1,3}\./)||t.match(/^\[?[0-9a-fA-F:]+\]?$/))return t;const e=t.split(".");if(e.length>=2){const t=e[e.length-1],i=`${e[e.length-2]}.${t}`;return["co.uk","com.au","co.nz","co.jp","co.in","co.za"].includes(i)&&e.length>=3?"."+e.slice(-3).join("."):"."+e.slice(-2).join(".")}return t}(),s="https:"===location.protocol?"; Secure":"",n=encodeURIComponent(e);document.cookie=`${t}=${n}; domain=${i}; path=/; max-age=31536000; SameSite=Lax${s}`;o.get(t)!==e&&(document.cookie=`${t}=${n}; path=/; max-age=31536000; SameSite=Lax${s}`)}catch(i){console.error("[Datalyr] Error setting root domain cookie:",i);try{const i="https:"===location.protocol?"; Secure":"",s=encodeURIComponent(e);document.cookie=`${t}=${s}; path=/; max-age=31536000; SameSite=Lax${i}`}catch(t){console.error("[Datalyr] Failed to set cookie even without domain:",t)}}}getStoredUserId(){return n.get("dl_user_id")}getAnonymousId(){return this.anonymousId}getUserId(){return this.userId}getDistinctId(){return this.userId||this.anonymousId}getCanonicalId(){return this.getDistinctId()}setSessionId(t){this.sessionId=t}getSessionId(){return this.sessionId}identify(t,e={}){if(!t)return console.warn("[Datalyr] identify() called without userId"),{};const i=this.userId;return this.userId=t,n.set("dl_user_id",t),{anonymous_id:this.anonymousId,user_id:t,previous_id:i,traits:e,identified_at:(new Date).toISOString(),resolution_method:"identify_call"}}alias(t,e){const i={userId:t,previousId:e||this.anonymousId,aliased_at:(new Date).toISOString()};return e&&e!==this.anonymousId||(this.userId=t,n.set("dl_user_id",t)),i}reset(){this.userId=null,n.remove("dl_user_id"),n.remove("dl_user_traits"),this.anonymousId=`anon_${r()}`,n.set("dl_anonymous_id",this.anonymousId),this.setRootDomainCookie("__dl_visitor_id",this.anonymousId)}getIdentityFields(){return{distinct_id:this.getDistinctId(),anonymous_id:this.anonymousId,user_id:this.userId,visitor_id:this.anonymousId,visitorId:this.anonymousId,canonical_id:this.getCanonicalId(),session_id:this.sessionId,sessionId:this.sessionId,resolution_method:"browser_sdk",resolution_confidence:1}}}class g{constructor(t=36e5){this.sessionId=null,this.sessionData=null,this.lastActivity=Date.now(),this.SESSION_KEY="dl_session_data",this.activityCheckInterval=null,this.activityListeners=[],this.sessionCreationLock=!1,this.sessionTimeout=t,this.initSession(),this.setupActivityMonitor()}initSession(){const t=n.get(this.SESSION_KEY),e=Date.now();t&&this.isSessionValid(t,e)?(this.sessionData=t,this.sessionId=t.id,this.lastActivity=e):this.createNewSession()}isSessionValid(t,e){return e-t.lastActivity<this.sessionTimeout&&t.isActive}createNewSession(){if(this.sessionCreationLock)return console.log("[Datalyr Session] Session creation already in progress, returning existing ID"),this.sessionId||"";this.sessionCreationLock=!0;try{const t=Date.now();return this.sessionId=`sess_${r()}`,this.sessionData={id:this.sessionId,startTime:t,lastActivity:t,pageViews:0,events:0,duration:0,isActive:!0},this.saveSession(),this.incrementSessionCount(),this.sessionId}finally{this.sessionCreationLock=!1}}rotateSessionId(){const t=Date.now(),e=this.sessionId;return this.sessionId=`sess_${r()}`,this.sessionData?(this.sessionData.id=this.sessionId,this.sessionData.lastActivity=t,this.saveSession(),e&&n.remove(`dl_session_${e}_attribution`),console.log(`[Datalyr Session] Rotated session ID from ${e} to ${this.sessionId}`)):this.createNewSession(),this.sessionId}getSessionId(){return this.sessionId&&this.isSessionActive()||this.createNewSession(),this.sessionId}getSessionData(){return this.sessionData}updateActivity(t){const e=Date.now();this.sessionData&&this.isSessionValid(this.sessionData,e)?(this.lastActivity=e,this.sessionData.lastActivity=e,this.sessionData.duration=e-this.sessionData.startTime,"pageview"!==t&&"page_view"!==t||this.sessionData.pageViews++,this.sessionData.events++,this.saveSession()):this.createNewSession()}isSessionActive(){if(!this.sessionData)return!1;const t=Date.now();return this.isSessionValid(this.sessionData,t)}endSession(){this.sessionData&&(this.sessionData.isActive=!1,this.saveSession()),this.sessionId=null,this.sessionData=null,this.destroy()}saveSession(){this.sessionData&&n.set(this.SESSION_KEY,this.sessionData)}getTimeout(){return this.sessionTimeout}setTimeout(t){this.sessionTimeout=t}storeAttribution(t){n.set("dl_current_session_attribution",Object.assign(Object.assign({},t),{sessionId:this.sessionId,timestamp:Date.now()}))}getAttribution(){if(!this.sessionId)return null;if(!this.isSessionActive())return null;const t=n.get("dl_current_session_attribution");return t&&t.sessionId===this.sessionId?t:null}getMetrics(){return this.sessionData?{session_id:this.sessionId,session_duration:this.sessionData.duration,session_page_views:this.sessionData.pageViews,session_events:this.sessionData.events,session_start:this.sessionData.startTime,time_since_session_start:Date.now()-this.sessionData.startTime}:{}}setupActivityMonitor(){const t=()=>{const t=Date.now();this.sessionData&&t-this.lastActivity>1e3&&this.updateActivity()};["mousedown","keydown","scroll","touchstart"].forEach(e=>{window.addEventListener(e,t,{passive:!0,capture:!0}),this.activityListeners.push({event:e,handler:t})}),this.activityCheckInterval=setInterval(()=>{this.sessionData&&!this.isSessionActive()&&this.createNewSession()},6e4)}destroy(){this.activityListeners.forEach(({event:t,handler:e})=>{window.removeEventListener(t,e)}),this.activityListeners=[],this.activityCheckInterval&&(clearInterval(this.activityCheckInterval),this.activityCheckInterval=null)}getSessionNumber(){return n.get("dl_session_count",0)+1}incrementSessionCount(){const t=n.get("dl_session_count",0);n.set("dl_session_count",t+1)}}class p{constructor(t={}){this.queryParamsCache=null,this.UTM_PARAMS=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],this.CLICK_IDS=["fbclid","gclid","gbraid","wbraid","ttclid","msclkid","twclid","li_fat_id","sclid","dclid","epik","rdt_cid","obclid","irclid","ko_click_id"],this.DEFAULT_TRACKED_PARAMS=["lyr","ref","source","campaign","medium","gad_source"],this.attributionWindow=t.attributionWindow||7776e6,this.trackedParams=[...this.DEFAULT_TRACKED_PARAMS,...t.trackedParams||[]]}clearCache(){this.queryParamsCache=null}captureAttribution(){const t=this.queryParamsCache||a();this.queryParamsCache||(this.queryParamsCache=t);const e={timestamp:Date.now()};for(const i of this.UTM_PARAMS){const s=t[i];if(s){e[i.replace("utm_","")]=s}}for(const i of this.CLICK_IDS){const s=t[i];if(s){e.clickId=s,e.clickIdType=i;break}}for(const i of this.trackedParams){const s=t[i];s&&(e[i]=s)}return document.referrer&&(e.referrer=document.referrer,e.referrerHost=this.extractHostname(document.referrer)),e.landingPage=window.location.href,e.landingPath=window.location.pathname,e.source||(e.source=this.determineSource(e)),e.medium||(e.medium=this.determineMedium(e)),e}storeFirstTouch(t){const e=n.get("dl_first_touch");let i=!1;e?e.expires_at&&Date.now()>=e.expires_at&&(i=!0):i=!0,i&&n.set("dl_first_touch",Object.assign(Object.assign({},t),{captured_at:Date.now(),expires_at:Date.now()+this.attributionWindow}))}getFirstTouch(){const t=n.get("dl_first_touch");return t&&t.expires_at&&Date.now()>=t.expires_at?(n.remove("dl_first_touch"),null):t}storeLastTouch(t){n.set("dl_last_touch",Object.assign(Object.assign({},t),{captured_at:Date.now(),expires_at:Date.now()+this.attributionWindow}))}getLastTouch(){const t=n.get("dl_last_touch");return t&&t.expires_at&&Date.now()>=t.expires_at?(n.remove("dl_last_touch"),null):t}addTouchpoint(t,e){const i=this.getJourney(),s={timestamp:Date.now(),sessionId:t,source:e.source||void 0,medium:e.medium||void 0,campaign:e.campaign||void 0};i.push(s),i.length>30&&i.shift(),n.set("dl_journey",i)}getJourney(){return n.get("dl_journey",[])}captureAdCookies(){const t={};if(t._fbp=o.get("_fbp"),t._fbc=o.get("_fbc"),t._gcl_aw=o.get("_gcl_aw"),t._gcl_dc=o.get("_gcl_dc"),t._gcl_gb=o.get("_gcl_gb"),t._gcl_ha=o.get("_gcl_ha"),t._gac=o.get("_gac"),t._ga=o.get("_ga"),t._gid=o.get("_gid"),t._ttp=o.get("_ttp"),t._ttc=o.get("_ttc"),!t._fbp&&(this.hasClickId("fbclid")||t._fbc)){const e=Date.now(),i=Math.random().toString(36).substring(2,15);t._fbp=`fb.1.${e}.${i}`,o.set("_fbp",t._fbp,90)}const e=this.getCurrentFbclid();if(e&&!t._fbc){const i=Math.floor(Date.now()/1e3);t._fbc=`fb.1.${i}.${e}`,o.set("_fbc",t._fbc,90)}return Object.fromEntries(Object.entries(t).filter(([t,e])=>null!==e))}hasClickId(t){return!!(this.queryParamsCache||a())[t]}getCurrentFbclid(){return(this.queryParamsCache||a()).fbclid||null}getAttributionData(){const t=this.getFirstTouch(),e=this.getLastTouch(),i=this.getJourney();let s=this.captureAttribution();!!!(s.source||s.medium||s.clickId||s.campaign)&&t&&(!t.expires_at||Date.now()<t.expires_at)&&(s=Object.assign(Object.assign({},t),{referrer:s.referrer,referrerHost:s.referrerHost,landingPage:s.landingPage,landingPath:s.landingPath}));const n=this.captureAdCookies();return!t&&Object.keys(s).length>1&&this.storeFirstTouch(s),Object.keys(s).length>1&&this.storeLastTouch(s),Object.assign(Object.assign(Object.assign({},s),n),{first_touch_source:null==t?void 0:t.source,first_touch_medium:null==t?void 0:t.medium,first_touch_campaign:null==t?void 0:t.campaign,first_touch_timestamp:null==t?void 0:t.timestamp,firstTouchSource:null==t?void 0:t.source,firstTouchMedium:null==t?void 0:t.medium,firstTouchCampaign:null==t?void 0:t.campaign,last_touch_source:null==e?void 0:e.source,last_touch_medium:null==e?void 0:e.medium,last_touch_campaign:null==e?void 0:e.campaign,last_touch_timestamp:null==e?void 0:e.timestamp,lastTouchSource:null==e?void 0:e.source,lastTouchMedium:null==e?void 0:e.medium,lastTouchCampaign:null==e?void 0:e.campaign,touchpoint_count:i.length,touchpointCount:i.length,days_since_first_touch:(null==t?void 0:t.timestamp)?Math.floor((Date.now()-t.timestamp)/864e5):0,daysSinceFirstTouch:(null==t?void 0:t.timestamp)?Math.floor((Date.now()-t.timestamp)/864e5):0})}determineSource(t){if(t.clickIdType){return{fbclid:"facebook",gclid:"google",ttclid:"tiktok",msclkid:"bing",twclid:"twitter",li_fat_id:"linkedin",sclid:"snapchat",dclid:"doubleclick",epik:"pinterest"}[t.clickIdType]||"paid"}if(t.referrerHost){const e=t.referrerHost.toLowerCase();return e.includes("facebook.com")||e.includes("fb.com")?"facebook":e.includes("twitter.com")||e.includes("t.co")||e.includes("x.com")?"twitter":e.includes("linkedin.com")||e.includes("lnkd.in")?"linkedin":e.includes("instagram.com")?"instagram":e.includes("youtube.com")||e.includes("youtu.be")?"youtube":e.includes("tiktok.com")?"tiktok":e.includes("reddit.com")?"reddit":e.includes("pinterest.com")?"pinterest":e.includes("google.")?"google":e.includes("bing.com")?"bing":e.includes("yahoo.com")?"yahoo":e.includes("duckduckgo.com")?"duckduckgo":e.includes("baidu.com")?"baidu":"referral"}return"direct"}determineMedium(t){if(t.clickId)return"cpc";const e=t.source;if(!e||"direct"===e)return"none";if(["facebook","twitter","linkedin","instagram","youtube","tiktok","reddit","pinterest"].includes(e))return"social";return["google","bing","yahoo","duckduckgo","baidu"].includes(e)?"organic":"referral"}extractHostname(t){try{return new URL(t).hostname}catch(t){return""}}isAttributionExpired(t){return!t.timestamp||Date.now()-t.timestamp>this.attributionWindow}clearExpiredAttribution(){const t=this.getFirstTouch(),e=this.getLastTouch();t&&this.isAttributionExpired(t)&&n.remove("dl_first_touch"),e&&this.isAttributionExpired(e)&&n.remove("dl_last_touch")}}const f=["purchase","signup","subscribe","lead","conversion"],m=["add_to_cart","begin_checkout","view_item","search"];class y{constructor(t){this.queue=[],this.offlineQueue=[],this.batchTimer=null,this.periodicFlushInterval=null,this.flushPromise=null,this.recentEventIds=new Set,this.MAX_RECENT_EVENT_IDS=1e3,this.OFFLINE_QUEUE_KEY="dl_offline_queue",this.flushLock=!1,this.offlineQueueLock=!1,this.config={batchSize:t.batchSize||10,flushInterval:t.flushInterval||5e3,maxRetries:t.maxRetries||5,retryDelay:t.retryDelay||1e3,endpoint:t.endpoint||"https://ingest.datalyr.com",fallbackEndpoints:t.fallbackEndpoints||[],workspaceId:t.workspaceId,debug:t.debug||!1,criticalEvents:t.criticalEvents||f,highPriorityEvents:t.highPriorityEvents||m,maxOfflineQueueSize:t.maxOfflineQueueSize||100},this.networkStatus={isOnline:!1!==navigator.onLine,lastOfflineAt:null,lastOnlineAt:null},this.loadOfflineQueue(),this.setupNetworkListeners(),this.startPeriodicFlush()}enqueue(t){const e=t.event_name;if(this.isDuplicateEvent(t))this.log("Duplicate event suppressed:",e);else{if(this.config.criticalEvents.includes(e))return this.log("Critical event, sending immediately:",e),void this.sendBatch([t]).catch(i=>{this.log("Critical event send failed, adding to offline queue:",e,i),this.moveToOfflineQueue([t])});this.queue.push(t),this.log("Event queued:",e),this.shouldFlush(e)&&this.flush()}}isDuplicateEvent(t){const e=this.createEventHash(t);if(this.recentEventIds.has(e))return!0;if(this.recentEventIds.add(e),this.recentEventIds.size>this.MAX_RECENT_EVENT_IDS){const t=this.recentEventIds.size-this.MAX_RECENT_EVENT_IDS,e=this.recentEventIds.values();for(let i=0;i<t;i++){const t=e.next();t.done||this.recentEventIds.delete(t.value)}}return!1}createEventHash(t){const e=[t.event_name,t.timestamp,JSON.stringify(t.event_data||{})].join("|");let i=0;for(let t=0;t<e.length;t++){i=(i<<5)-i+e.charCodeAt(t),i&=i}return i.toString(36)}shouldFlush(t){return this.queue.length>=this.config.batchSize||(t&&this.config.highPriorityEvents.includes(t)?(this.batchTimer&&clearTimeout(this.batchTimer),this.batchTimer=setTimeout(()=>this.flush(),1e3),!1):(this.batchTimer||(this.batchTimer=setTimeout(()=>this.flush(),this.config.flushInterval)),!1))}flush(){return t(this,void 0,void 0,function*(){if(this.flushPromise||this.flushLock)return this.flushPromise||Promise.resolve();this.flushLock=!0;try{this.flushPromise=this._flush(),yield this.flushPromise}finally{this.flushPromise=null,this.flushLock=!1}})}_flush(){return t(this,void 0,void 0,function*(){if(this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),0===this.queue.length)return;if(!this.networkStatus.isOnline)return this.log("Network offline, queuing events"),void this.moveToOfflineQueue();const t=Math.min(this.config.batchSize,this.queue.length),e=this.queue.slice(0,t);try{yield this.sendBatch(e),this.queue.splice(0,t),this.log(`Successfully sent and removed ${t} events from queue`)}catch(t){this.log("Failed to send batch:",t),this.moveToOfflineQueue(e)}})}sendBatch(e){return t(this,arguments,void 0,function*(t,e=0,i=0){const s={events:t,batchId:r(),timestamp:(new Date).toISOString()},n=[this.config.endpoint,...this.config.fallbackEndpoints],o=n[i]||this.config.endpoint;try{const e=yield fetch(o,{method:"POST",headers:{"Content-Type":"application/json","X-Batch-Size":t.length.toString()},body:JSON.stringify(s),keepalive:!0});if(!e.ok){if(429===e.status){const t=parseInt(e.headers.get("Retry-After")||"60");throw this.log(`Rate limited, retrying after ${t}s`),setTimeout(()=>{this.flush()},1e3*t),new Error(`Rate limited (429), retry after ${t}s`)}throw new Error(`HTTP ${e.status}: ${e.statusText}`)}this.log(`Batch sent successfully to ${o}: ${t.length} events`)}catch(s){if(i<n.length-1)return this.log(`Failed on ${o}, trying fallback ${i+1}`),this.sendBatch(t,0,i+1);if(e<this.config.maxRetries){const s=function(t,e=1e3){const i=.1*Math.random();return Math.min(e*Math.pow(2,t)*(1+i),3e4)}(e,this.config.retryDelay);return this.log(`Retrying batch in ${s}ms (attempt ${e+1}/${this.config.maxRetries})`),yield new Promise(t=>setTimeout(t,s)),this.sendBatch(t,e+1,i)}throw s}})}setupNetworkListeners(){window.addEventListener("online",()=>{this.networkStatus.isOnline=!0,this.networkStatus.lastOnlineAt=Date.now(),this.log("Network connection restored"),setTimeout(()=>this.processOfflineQueue(),1e3)}),window.addEventListener("offline",()=>{this.networkStatus.isOnline=!1,this.networkStatus.lastOfflineAt=Date.now(),this.log("Network connection lost")})}startPeriodicFlush(){this.periodicFlushInterval=setInterval(()=>{this.queue.length>0&&this.flush()},this.config.flushInterval)}stopPeriodicFlush(){this.periodicFlushInterval&&(clearInterval(this.periodicFlushInterval),this.periodicFlushInterval=null)}moveToOfflineQueue(t){if(this.offlineQueueLock)console.warn("[Datalyr Queue] Offline queue operation already in progress");else{this.offlineQueueLock=!0;try{if(t?this.offlineQueue.push(...t):(this.offlineQueue.push(...this.queue),this.queue=[]),this.offlineQueue.length>this.config.maxOfflineQueueSize){const t=this.offlineQueue.length-this.config.maxOfflineQueueSize;this.offlineQueue.splice(0,t)}this.saveOfflineQueue()}finally{this.offlineQueueLock=!1}}}loadOfflineQueue(){const t=n.get(this.OFFLINE_QUEUE_KEY,[]);Array.isArray(t)&&(this.offlineQueue=t,this.log(`Loaded ${this.offlineQueue.length} offline events`))}saveOfflineQueue(){const t=this.offlineQueue.slice(-this.config.maxOfflineQueueSize);n.set(this.OFFLINE_QUEUE_KEY,t)}processOfflineQueue(){return t(this,void 0,void 0,function*(){if(0!==this.offlineQueue.length){for(this.log(`Processing ${this.offlineQueue.length} offline events`);this.offlineQueue.length>0;){const t=this.offlineQueue.splice(0,this.config.batchSize);try{yield this.sendBatch(t),this.saveOfflineQueue()}catch(e){this.log("Failed to send offline batch:",e),this.offlineQueue.unshift(...t),this.saveOfflineQueue();break}}0===this.offlineQueue.length&&n.remove(this.OFFLINE_QUEUE_KEY)}})}getQueueSize(){return this.queue.length}getOfflineQueueSize(){return this.offlineQueue.length}getNetworkStatus(){return Object.assign({},this.networkStatus)}forceFlush(){return t(this,void 0,void 0,function*(){if(navigator.sendBeacon&&this.queue.length>0){const t={events:this.queue,batchId:r(),timestamp:(new Date).toISOString()},e=new Blob([JSON.stringify(t)],{type:"application/json"});if(navigator.sendBeacon(this.config.endpoint,e))return this.log("Events sent via sendBeacon"),void(this.queue=[])}yield this.flush()})}clear(){this.queue=[],this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null)}log(...t){this.config.debug&&console.log("[Datalyr Queue]",...t)}destroy(){this.stopPeriodicFlush(),this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.queue.length>0&&this.moveToOfflineQueue()}}class v{constructor(t={}){this.privacyMode=t.privacyMode||"standard",this.enableFingerprinting=!1!==t.enableFingerprinting}collect(){return"strict"!==this.privacyMode&&this.enableFingerprinting?this.collectStandard():this.collectMinimal()}collectMinimal(){const t={timezone:this.getTimezone(),language:navigator.language||null,screen_bucket:this.getScreenBucket(),dnt:"1"===navigator.doNotTrack||!0===window.globalPrivacyControl||null,userAgent:navigator.userAgent||null};if("userAgentData"in navigator){const e=navigator.userAgentData;t.userAgentData={brands:e.brands||[],mobile:e.mobile||!1,platform:e.platform||null}}return t}collectStandard(){const t={};try{if(t.timezone=this.getTimezone(),t.language=navigator.language||null,t.screen_bucket=this.getScreenBucket(),t.dnt="1"===navigator.doNotTrack||!0===window.globalPrivacyControl||null,t.userAgent=navigator.userAgent||null,"userAgentData"in navigator){const e=navigator.userAgentData;t.userAgentData={brands:e.brands||[],mobile:e.mobile||!1,platform:e.platform||null}}}catch(t){console.warn("[Datalyr] Error collecting fingerprint:",t)}return t}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||null}catch(t){return null}}getScreenBucket(){try{if(!window.screen)return null;const t=100*Math.round(screen.width/100);return`${t}x${100*Math.round(screen.height/100)}`}catch(t){return null}}generateHash(e){return t(this,void 0,void 0,function*(){try{const t=Object.keys(e).sort().reduce((t,i)=>(t[i]=e[i],t),{}),i=JSON.stringify(t);if(window.crypto&&window.crypto.subtle){const t=(new TextEncoder).encode(i),e=yield crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}let s=0;for(let t=0;t<i.length;t++){s=(s<<5)-s+i.charCodeAt(t),s&=s}return Math.abs(s).toString(16)}catch(t){return""}})}}class _{constructor(t){this.scripts=[],this.loadedScripts=new Set,this.sessionLoadedScripts=new Set,this.pixels=null,this.initialized=!1,this.sandboxedIframes=[],this.iframeCleanupTimeouts=new Map,this.messageHandler=null,this.workspaceId=t.workspaceId,this.endpoint=t.endpoint||"https://ingest.datalyr.com",this.debug=t.debug||!1;const e=n.get("dl_session_scripts",[]);this.sessionLoadedScripts=new Set(e),this.messageHandler=t=>{if(t.data&&"datalyr_script_complete"===t.data.type){const e=t.data.scriptId;this.log("Received script completion signal:",e);const i=this.sandboxedIframes.find(t=>t.dataset.datalyrScript===e);i&&this.cleanupIframe(i)}},window.addEventListener("message",this.messageHandler)}init(){return t(this,void 0,void 0,function*(){if(!this.initialized)try{const t=yield fetch(`${this.endpoint}/container-scripts`,{method:"POST",headers:{"Content-Type":"application/json","X-Container-Version":"1.0"},body:JSON.stringify({workspaceId:this.workspaceId})});if(!t.ok)throw new Error(`Failed to fetch container scripts: ${t.status}`);const e=yield t.json();this.scripts=e.scripts||[],this.pixels=e.pixels||null,this.pixels&&this.initializePixels(),this.loadScriptsByTrigger("page_load"),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{this.loadScriptsByTrigger("dom_ready")}):this.loadScriptsByTrigger("dom_ready"),window.addEventListener("load",()=>{this.loadScriptsByTrigger("window_load")}),this.initialized=!0,this.log("Container manager initialized with",this.scripts.length,"scripts")}catch(t){this.log("Error initializing container:",t)}})}loadScriptsByTrigger(t){this.scripts.filter(e=>e.enabled&&e.trigger===t&&this.shouldLoadScript(e)).forEach(t=>this.loadScript(t))}shouldLoadScript(t){return("once_per_page"!==t.frequency||!this.loadedScripts.has(t.id))&&(("once_per_session"!==t.frequency||!this.sessionLoadedScripts.has(t.id))&&(!(t.conditions&&t.conditions.length>0)||this.evaluateConditions(t.conditions)))}evaluateConditions(t){return t.every(t=>{try{const{type:e,operator:i,value:s}=t;switch(e){case"url_path":return this.evaluateStringCondition(window.location.pathname,i,s);case"url_host":return this.evaluateStringCondition(window.location.hostname,i,s);case"url_parameter":const e=new URLSearchParams(window.location.search);return this.evaluateStringCondition(e.get(t.parameter)||"",i,s);case"referrer":return this.evaluateStringCondition(document.referrer,i,s);case"device_type":const n=/Mobile|Android|iPhone|iPad/i.test(navigator.userAgent);return this.evaluateStringCondition(n?"mobile":"desktop",i,s);default:return!0}}catch(t){return!1}})}evaluateStringCondition(t,e,i){switch(e){case"equals":return t===i;case"not_equals":return t!==i;case"contains":return t.includes(i);case"not_contains":return!t.includes(i);case"starts_with":return t.startsWith(i);case"ends_with":return t.endsWith(i);case"matches_regex":try{return new RegExp(i).test(t)}catch(t){return!1}default:return!1}}loadScript(t){try{switch(t.type){case"inline":this.loadInlineScript(t);break;case"external":this.loadExternalScript(t);break;case"pixel":this.loadPixel(t)}this.loadedScripts.add(t.id),"once_per_session"===t.frequency&&(this.sessionLoadedScripts.add(t.id),n.set("dl_session_scripts",Array.from(this.sessionLoadedScripts))),this.log("Loaded script:",t.name)}catch(e){this.log("Error loading script:",t.name,e)}}loadInlineScript(t){const e=document.createElement("iframe");e.style.display="none",e.setAttribute("sandbox","allow-scripts"),e.dataset.datalyrScript=t.id,this.sandboxedIframes.push(e);const i=`\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset="UTF-8">\n </head>\n <body>\n <script>\n // User-provided script runs here in isolation\n try {\n ${t.content}\n } catch (error) {\n console.error('[Datalyr Container] Script execution error:', error);\n }\n\n // FIXED (ISSUE-02): Signal completion for cleanup\n // Scripts have 5 seconds to execute before iframe is removed\n setTimeout(function() {\n try {\n parent.postMessage({ type: 'datalyr_script_complete', scriptId: '${t.id}' }, '*');\n } catch (e) {\n // Ignore postMessage errors from sandbox\n }\n }, 5000);\n <\/script>\n </body>\n </html>\n `;document.body.appendChild(e),e.contentDocument&&(e.contentDocument.open(),e.contentDocument.write(i),e.contentDocument.close());const s=window.setTimeout(()=>{this.cleanupIframe(e)},3e4);this.iframeCleanupTimeouts.set(e,s),this.log("Loaded inline script in sandbox:",t.id)}cleanupIframe(t){try{const e=this.iframeCleanupTimeouts.get(t);e&&(clearTimeout(e),this.iframeCleanupTimeouts.delete(t));const i=this.sandboxedIframes.indexOf(t);i>-1&&this.sandboxedIframes.splice(i,1),t.parentNode&&(t.parentNode.removeChild(t),this.log("Cleaned up sandboxed iframe:",t.dataset.datalyrScript))}catch(t){this.log("Error cleaning up iframe:",t)}}cleanupAllIframes(){const t=[...this.sandboxedIframes];t.forEach(t=>this.cleanupIframe(t)),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.iframeCleanupTimeouts.forEach(t=>clearTimeout(t)),this.iframeCleanupTimeouts.clear(),this.log(`Cleaned up ${t.length} sandboxed iframes`)}loadExternalScript(t){var e;if(!this.isValidScriptUrl(t.content))return void this.log("Blocked invalid script URL:",t.content);if(!(null===(e=t.settings)||void 0===e?void 0:e.integrity))return void console.error(`[Datalyr Container] SECURITY: External script "${t.id}" blocked - missing SRI hash.\nAll external scripts MUST include an integrity hash to prevent CDN compromise attacks.\nGenerate SRI hash at: https://www.srihash.org/\nExample: { integrity: "sha384-..." }`);const i=document.createElement("script");i.src=t.content,i.dataset.datalyrScript=t.id,t.settings?(i.integrity=t.settings.integrity,i.crossOrigin=t.settings.crossorigin||"anonymous",!1!==t.settings.async&&(i.async=!0),t.settings.defer&&(i.defer=!0)):i.async=!0,document.head.appendChild(i)}loadPixel(t){const e=new Image;e.src=t.content,e.style.display="none",e.dataset.datalyrPixel=t.id,document.body.appendChild(e)}initializePixels(){var t,e,i;this.pixels&&((null===(t=this.pixels.meta)||void 0===t?void 0:t.enabled)&&this.pixels.meta.pixel_id&&this.initializeMetaPixel(this.pixels.meta),(null===(e=this.pixels.google)||void 0===e?void 0:e.enabled)&&this.pixels.google.tag_id&&this.initializeGoogleTag(this.pixels.google),(null===(i=this.pixels.tiktok)||void 0===i?void 0:i.enabled)&&this.pixels.tiktok.pixel_id&&this.initializeTikTokPixel(this.pixels.tiktok))}initializeMetaPixel(t){try{e=window,i=document,s="script",e.fbq||(n=e.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)},e._fbq||(e._fbq=n),n.push=n,n.loaded=!0,n.version="2.0",n.queue=[],(o=i.createElement(s)).async=!0,o.src="https://connect.facebook.net/en_US/fbevents.js",(r=i.getElementsByTagName(s)[0]).parentNode.insertBefore(o,r)),window.fbq("init",t.pixel_id),window.fbq("track","PageView"),this.log("Meta Pixel initialized:",t.pixel_id)}catch(t){this.log("Error initializing Meta Pixel:",t)}var e,i,s,n,o,r}initializeGoogleTag(t){try{const e=document.createElement("script");function i(...t){window.dataLayer.push(t)}e.async=!0,e.src=`https://www.googletagmanager.com/gtag/js?id=${t.tag_id}`,document.head.appendChild(e),window.dataLayer=window.dataLayer||[],window.gtag=i,i("js",new Date),i("config",t.tag_id,{allow_enhanced_conversions:!1!==t.enhanced_conversions}),this.log("Google Tag initialized:",t.tag_id)}catch(s){this.log("Error initializing Google Tag:",s)}}initializeTikTokPixel(t){try{!function(t,e,i){t.TiktokAnalyticsObject=i;var s=t[i]=t[i]||[];s.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"],s.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var n=0;n<s.methods.length;n++)s.setAndDefer(s,s.methods[n]);s.instance=function(t){for(var e=s._i[t]||[],i=0;i<s.methods.length;i++)s.setAndDefer(e,s.methods[i]);return e},s.load=function(t,e){var n;s._i=s._i||{},s._i[t]=[],s._o=s._o||{},s._o[t]=e||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src="https://analytics.tiktok.com/i18n/pixel/events.js?sdkid="+t+"&lib="+i;var r=document.getElementsByTagName("script")[0];null===(n=r.parentNode)||void 0===n||n.insertBefore(o,r)}}(window,document,"ttq"),window.ttq.load(t.pixel_id),window.ttq.page(),this.log("TikTok Pixel initialized:",t.pixel_id)}catch(t){this.log("Error initializing TikTok Pixel:",t)}}trackToPixels(t,e={}){var i,s,n,o,r,a;const c=this.sanitizeEventName(t),l=this.sanitizeProperties(e);if((null===(s=null===(i=this.pixels)||void 0===i?void 0:i.meta)||void 0===s?void 0:s.enabled)&&window.fbq)try{window.fbq("track",c,l)}catch(t){this.log("Error tracking Meta Pixel event:",t)}if((null===(o=null===(n=this.pixels)||void 0===n?void 0:n.google)||void 0===o?void 0:o.enabled)&&window.gtag)try{window.gtag("event",c,l)}catch(t){this.log("Error tracking Google Tag event:",t)}if((null===(a=null===(r=this.pixels)||void 0===r?void 0:r.tiktok)||void 0===a?void 0:a.enabled)&&window.ttq)try{const t={Purchase:"CompletePayment",AddToCart:"AddToCart",InitiateCheckout:"InitiateCheckout",ViewContent:"ViewContent",Search:"Search",Lead:"SubmitForm"}[c]||c;window.ttq.track(t,l)}catch(t){this.log("Error tracking TikTok Pixel event:",t)}}triggerCustomScript(t){const e=this.scripts.find(e=>e.id===t&&"custom"===e.trigger);e&&this.shouldLoadScript(e)&&this.loadScript(e)}getLoadedScripts(){return Array.from(this.loadedScripts)}isValidScriptUrl(t){try{const e=new URL(t);return!("https:"!==e.protocol&&!e.hostname.includes("localhost"))&&!["data:","javascript:","file:"].includes(e.protocol)}catch(t){return!1}}sanitizeEventName(t){return"string"!=typeof t?"unknown_event":t.replace(/[^a-zA-Z0-9_$ ]/g,"").substring(0,100)}sanitizeProperties(t){if(null==t)return{};if("object"!=typeof t)return this.sanitizeValue(t);if(Array.isArray(t))return t.map(t=>this.sanitizeValue(t));const e={};for(const[i,s]of Object.entries(t)){const t=i.replace(/[^a-zA-Z0-9_]/g,"").substring(0,100);t&&(e[t]=this.sanitizeValue(s))}return e}sanitizeValue(t){return null==t?t:"string"==typeof t?t.replace(/<script[^>]*>.*?<\/script>/gi,"").replace(/<[^>]+>/g,"").replace(/javascript:/gi,"").replace(/on\w+\s*=/gi,"").substring(0,1e3):"number"==typeof t||"boolean"==typeof t?t:"object"==typeof t?this.sanitizeProperties(t):String(t).substring(0,1e3)}log(...t){this.debug&&console.log("[Datalyr Container]",...t)}}class w{constructor(t={}){this.formListeners=[],this.lastIdentifyTime=0,this.RATE_LIMIT_MS=5e3,this.config={enabled:!1!==t.enabled,captureFromForms:!1!==t.captureFromForms,captureFromAPI:!1!==t.captureFromAPI,captureFromShopify:!1!==t.captureFromShopify,trustedDomains:t.trustedDomains||[],debug:t.debug||!1}}initialize(t){if(!this.config.enabled)return void this.log("Auto-identify disabled");this.identifyCallback=t;const e=n.get("dl_auto_identified_email");e?this.log("User already auto-identified:",e):(this.config.captureFromForms&&this.setupFormMonitoring(),this.config.captureFromAPI&&(this.setupFetchInterception(),this.setupXHRInterception()),this.config.captureFromShopify&&this.setupShopifyMonitoring(),this.log("Auto-identify initialized"))}setupFormMonitoring(){this.scanForEmailForms();new MutationObserver(()=>{this.scanForEmailForms()}).observe(document.body,{childList:!0,subtree:!0}),this.log("Form monitoring active")}scanForEmailForms(){document.querySelectorAll("form").forEach(t=>{if(this.formListeners.some(e=>e.element===t))return;if(t.querySelector('input[type="email"], input[name*="email" i], input[id*="email" i]')){const e=e=>this.handleFormSubmit(e,t);t.addEventListener("submit",e),this.formListeners.push({element:t,handler:e}),this.log("Monitoring form:",t)}})}handleFormSubmit(t,e){try{const t=e.querySelector('input[type="email"], input[name*="email" i], input[id*="email" i]');if(!t)return;const i=t.value.trim();this.isValidEmail(i)&&(this.log("Email captured from form:",i),this.triggerIdentify(i,"form"))}catch(t){this.log("Error handling form submit:",t)}}setupFetchInterception(){if("function"!=typeof window.fetch)return;this.originalFetch=window.fetch;const e=this;window.fetch=function(i,s){return t(this,void 0,void 0,function*(){const n="string"==typeof i?i:i instanceof URL?i.href:i.url;if(!e.isTrustedDomain(n))return e.originalFetch.call(window,i,s);try{(null==s?void 0:s.body)&&e.extractEmailFromData(s.body,"api-request");const n=e.originalFetch.call(window,i,s);return n.then(i=>t(this,void 0,void 0,function*(){var t;if(i.ok&&(null===(t=i.headers.get("content-type"))||void 0===t?void 0:t.includes("application/json")))try{const t=i.clone(),s=yield t.json();e.extractEmailFromData(s,"api-response")}catch(t){}})).catch(()=>{}),n}catch(t){return e.log("Error intercepting fetch:",t),e.originalFetch.call(window,i,s)}})},this.log("Fetch interception active")}setupXHRInterception(){if("undefined"==typeof XMLHttpRequest)return;const t=this;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.open=function(e,i,...s){return this._datalyrUrl="string"==typeof i?i:i.href,t.originalXHROpen.apply(this,[e,i,...s])},XMLHttpRequest.prototype.send=function(e){const i=this._datalyrUrl;return i&&t.isTrustedDomain(i)&&(e&&t.extractEmailFromData(e,"api-request"),this.addEventListener("load",function(){if(this.status>=200&&this.status<300)try{const e=this.getResponseHeader("content-type");if(null==e?void 0:e.includes("application/json")){const e=JSON.parse(this.responseText);t.extractEmailFromData(e,"api-response")}}catch(t){}})),t.originalXHRSend.call(this,e)},this.log("XHR interception active")}setupShopifyMonitoring(){this.isShopify()&&(this.log("Shopify detected, setting up monitoring"),this.checkShopifyCustomer(),this.shopifyCheckInterval=setInterval(()=>{this.checkShopifyCustomer()},1e4),this.log("Shopify monitoring active"))}isShopify(){return!!(window.Shopify||document.querySelector('meta[name="shopify-checkout-api-token"]')||window.location.hostname.includes(".myshopify.com"))}checkShopifyCustomer(){return t(this,void 0,void 0,function*(){var t;try{const e=yield fetch("/account.json",{credentials:"same-origin"});if(e.ok){const i=yield e.json();(null===(t=null==i?void 0:i.customer)||void 0===t?void 0:t.email)&&(this.log("Email captured from Shopify:",i.customer.email),this.triggerIdentify(i.customer.email,"shopify"),this.shopifyCheckInterval&&(clearInterval(this.shopifyCheckInterval),this.shopifyCheckInterval=void 0))}}catch(t){this.log("Shopify customer check failed:",t)}})}extractEmailFromData(t,e){try{let i=[];if("string"==typeof t)try{const e=JSON.parse(t);i=this.findEmailsInObject(e)}catch(e){const s=/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,n=t.match(s);n&&(i=n)}else t instanceof FormData?t.forEach(t=>{"string"==typeof t&&this.isValidEmail(t)&&i.push(t)}):"object"==typeof t&&null!==t&&(i=this.findEmailsInObject(t));if(i.length>0){const t=i[0];this.log(`Email found in ${e}:`,t),this.triggerIdentify(t,"api")}}catch(t){this.log("Error extracting email from data:",t)}}findEmailsInObject(t,e=0){if(e>5)return[];const i=[];for(const s in t){if(!t.hasOwnProperty(s))continue;const n=t[s];/email/i.test(s)&&"string"==typeof n&&this.isValidEmail(n)?i.push(n):"object"==typeof n&&null!==n&&i.push(...this.findEmailsInObject(n,e+1))}return i}isTrustedDomain(t){try{const e=new URL(t,window.location.origin);return e.origin===window.location.origin||0!==this.config.trustedDomains.length&&this.config.trustedDomains.some(t=>e.hostname===t||e.hostname.endsWith(`.${t}`))}catch(t){return!1}}isValidEmail(t){if(!t||"string"!=typeof t)return!1;if(!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(t))return!1;return![/test@/i,/example@/i,/demo@/i,/fake@/i,/@test\./i,/@example\./i].some(e=>e.test(t))}triggerIdentify(t,e){const i=Date.now();if(i-this.lastIdentifyTime<this.RATE_LIMIT_MS)return void this.log("Rate limited, skipping identify");n.get("dl_auto_identified_email")!==t?(n.set("dl_auto_identified_email",t),this.lastIdentifyTime=i,this.identifyCallback&&(this.log(`Auto-identifying user: ${t} (source: ${e})`),this.identifyCallback(t,e))):this.log("Already identified with this email")}destroy(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=void 0),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=void 0),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=void 0),this.formListeners.forEach(({element:t,handler:e})=>{t.removeEventListener("submit",e)}),this.formListeners=[],this.shopifyCheckInterval&&(clearInterval(this.shopifyCheckInterval),this.shopifyCheckInterval=void 0),this.log("Auto-identify destroyed")}log(...t){this.config.debug&&console.log("[Datalyr Auto-Identify]",...t)}}const b=new class{constructor(){this.superProperties={},this.userProperties={},this.optedOut=!1,this.initialized=!1,this.errors=[],this.MAX_ERRORS=50,this.initializationPromise=null}init(t){if(this.initialized)return void console.warn("[Datalyr] SDK already initialized");if(!t.workspaceId)throw new Error("[Datalyr] workspaceId is required");this.config=Object.assign({endpoint:"https://ingest.datalyr.com",debug:!1,batchSize:10,flushInterval:5e3,flushAt:10,criticalEvents:void 0,highPriorityEvents:void 0,sessionTimeout:36e5,trackSessions:!0,attributionWindow:7776e6,trackedParams:[],respectDoNotTrack:!1,respectGlobalPrivacyControl:!0,privacyMode:"standard",cookieDomain:"auto",cookieExpires:365,secureCookie:"auto",sameSite:"Lax",cookiePrefix:"__dl_",enablePerformanceTracking:!0,enableFingerprinting:!0,maxRetries:5,retryDelay:1e3,maxOfflineQueueSize:100,trackSPA:!0,trackPageViews:!0,fallbackEndpoints:[],plugins:[]},t),this.cookies=new s({domain:this.config.cookieDomain,maxAge:this.config.cookieExpires,sameSite:this.config.sameSite,secure:this.config.secureCookie}),n.migrateFromLegacyPrefix(),this.optedOut="true"===this.cookies.get("__dl_opt_out"),this.identity=new u,this.session=new g(this.config.sessionTimeout),this.attribution=new p({attributionWindow:this.config.attributionWindow,trackedParams:this.config.trackedParams}),this.queue=new y(this.config),this.fingerprint=new v({privacyMode:this.config.privacyMode,enableFingerprinting:this.config.enableFingerprinting});const e=this.session.getSessionId();if(this.identity.setSessionId(e),this.initializeAsync(),this.setupUnloadHandler(),this.config.plugins)for(const t of this.config.plugins)try{t.initialize(this),this.log(`Plugin initialized: ${t.name}`)}catch(e){console.warn(`[Datalyr] Plugin '${t.name}' failed to initialize:`,e),this.trackError(e,{plugin:t.name})}this.initialized=!0,this.log("SDK initialized")}initializeAsync(){return t(this,void 0,void 0,function*(){return this.initializationPromise||(this.initializationPromise=(()=>t(this,void 0,void 0,function*(){try{const t=this.identity.getAnonymousId();yield e.initialize(this.config.workspaceId,t),this.userProperties=yield n.getEncrypted("dl_user_traits",{}),this.log("Encryption initialized, user properties loaded"),this.config.trackSPA&&this.setupSPATracking(),!1!==this.config.enableContainer&&(this.container=new _({workspaceId:this.config.workspaceId,endpoint:this.config.endpoint,debug:this.config.debug}),yield this.container.init().catch(t=>{this.log("Container initialization failed:",t)})),!0===this.config.autoIdentify&&(this.autoIdentify=new w({enabled:!0,captureFromForms:this.config.autoIdentifyForms,captureFromAPI:this.config.autoIdentifyAPI,captureFromShopify:this.config.autoIdentifyShopify,trustedDomains:this.config.autoIdentifyTrustedDomains,debug:this.config.debug}),this.autoIdentify.initialize((t,e)=>{this.log(`Auto-identified user: ${t} from ${e}`),this.track("$auto_identify",{email:t,source:e,timestamp:Date.now()}),this.identify(t,{email:t})})),this.config.trackPageViews&&this.page(),this.log("Async initialization complete")}catch(t){console.error("[Datalyr] Async initialization failed:",t),this.userProperties=n.get("dl_user_traits",{})}}))()),this.initializationPromise})}ready(){return t(this,void 0,void 0,function*(){if(!this.initialized)throw new Error("[Datalyr] SDK not initialized. Call init() first.");return this.initializationPromise||Promise.resolve()})}track(t,e={}){if(this.initialized){if(this.shouldTrack())try{this.session.updateActivity(t);const i=this.createEventPayload(t,e);if(this.queue.enqueue(i),this.container&&this.container.trackToPixels(t,e),this.config.plugins)for(const i of this.config.plugins)if(i.track)try{i.track(t,e)}catch(e){this.trackError(e,{plugin:i.name,event:t})}this.log("Event tracked:",t)}catch(e){this.trackError(e,{event:t})}}else console.warn("[Datalyr] SDK not initialized. Call init() first.")}identify(t,e={}){if(this.initialized){if(this.shouldTrack())if(t)try{this.session&&this.session.rotateSessionId();const i=this.identity.identify(t,e);if(this.userProperties=Object.assign(Object.assign({},this.userProperties),e),n.setEncrypted("dl_user_traits",this.userProperties).catch(t=>{console.error("[Datalyr] Failed to encrypt user traits - NOT storing unencrypted PII:",t),console.error("[Datalyr] User traits will only persist in memory until page reload")}),this.track("$identify",Object.assign(Object.assign({},i),{traits:e})),this.config.plugins)for(const i of this.config.plugins)if(i.identify)try{i.identify(t,e)}catch(t){this.trackError(t,{plugin:i.name})}this.log("User identified:",t)}catch(e){this.trackError(e,{userId:t})}else console.warn("[Datalyr] identify() called without userId")}else console.warn("[Datalyr] SDK not initialized. Call init() first.")}page(t={}){if(!this.initialized)return void console.warn("[Datalyr] SDK not initialized. Call init() first.");if(!this.shouldTrack())return;const e=Object.assign({title:document.title,url:window.location.href,path:window.location.pathname,search:window.location.search,referrer:document.referrer},t),i=function(){const t=document.referrer;if(!t)return{};try{const e=new URL(t);return{referrer:t,referrer_host:e.hostname,referrer_path:e.pathname,referrer_search:e.search,referrer_source:d(e.hostname)}}catch(e){return{referrer:t}}}();if(Object.assign(e,i),this.config.enablePerformanceTracking){const t=this.getPerformanceMetrics();t&&(e.performance=t)}if(this.track("pageview",e),this.config.plugins)for(const t of this.config.plugins)if(t.page)try{t.page(e)}catch(e){this.trackError(e,{plugin:t.name})}}screen(t,e={}){this.track("screen_view",Object.assign({screen_name:t},e))}group(t,e={}){this.initialized?this.track("$group",{group_id:t,traits:e}):console.warn("[Datalyr] SDK not initialized. Call init() first.")}alias(t,e){if(!this.initialized)return void console.warn("[Datalyr] SDK not initialized. Call init() first.");const i=this.identity.alias(t,e);this.track("$alias",i)}reset(){this.initialized?(this.identity.reset(),this.userProperties={},n.remove("dl_user_traits"),this.session.createNewSession(),this.log("User reset")):console.warn("[Datalyr] SDK not initialized. Call init() first.")}getAnonymousId(){return this.identity.getAnonymousId()}getUserId(){return this.identity.getUserId()}getDistinctId(){return this.identity.getDistinctId()}getSessionId(){return this.session.getSessionId()}startNewSession(){const t=this.session.createNewSession();return this.identity.setSessionId(t),t}getSessionData(){return this.session.getSessionData()}getAttribution(){return this.attribution.captureAttribution()}getJourney(){return this.attribution.getJourney()}setAttribution(t){const e=this.attribution.captureAttribution(),i=Object.assign(Object.assign({},e),t);this.session.storeAttribution(i)}optOut(){this.initialized?(this.optedOut=!0,this.cookies.set("__dl_opt_out","true",this.config.cookieExpires),this.queue.clear(),this.log("User opted out")):console.warn("[Datalyr] SDK not initialized. Call init() first.")}optIn(){this.initialized?(this.optedOut=!1,this.cookies.set("__dl_opt_out","false",this.config.cookieExpires),this.log("User opted in")):console.warn("[Datalyr] SDK not initialized. Call init() first.")}isOptedOut(){return this.optedOut}setConsent(t){n.set("dl_consent",t),this.log("Consent updated:",t)}flush(){return t(this,void 0,void 0,function*(){yield this.queue.flush()})}setSuperProperties(t){this.superProperties=Object.assign(Object.assign({},this.superProperties),t),this.log("Super properties set:",t)}unsetSuperProperty(t){delete this.superProperties[t],this.log("Super property unset:",t)}getSuperProperties(){return Object.assign({},this.superProperties)}createEventPayload(t,e){const i=c(e),s=l({},this.superProperties,i),n=this.attribution.getAttributionData();Object.assign(s,n);const o=this.session.getMetrics();if(Object.assign(s,o),this.config.enableFingerprinting){const t=this.fingerprint.collect();Object.assign(s,{device_fingerprint:t})}Object.assign(s,{url:window.location.href,path:window.location.pathname,referrer:document.referrer,title:document.title,screen_width:screen.width,screen_height:screen.height,viewport_width:window.innerWidth,viewport_height:window.innerHeight});const a=this.identity.getIdentityFields(),h=r(),d=a.distinct_id,u=a.anonymous_id,g=a.visitor_id||u,p=a.session_id;return{workspace_id:this.config.workspaceId,event_id:h,event_name:t,event_data:s,source:"web",timestamp:(new Date).toISOString(),distinct_id:d,anonymous_id:u,visitor_id:g,user_id:a.user_id,canonical_id:a.canonical_id,session_id:p,resolution_method:"browser_sdk",resolution_confidence:1,sdk_version:"1.2.0",sdk_name:"datalyr-web-sdk"}}shouldTrack(){return!this.optedOut&&((!this.config.respectDoNotTrack||"1"!==navigator.doNotTrack&&"1"!==window.doNotTrack&&"yes"!==navigator.doNotTrack)&&(!this.config.respectGlobalPrivacyControl||!0!==navigator.globalPrivacyControl&&!0!==window.globalPrivacyControl))}setupSPATracking(){this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;const t=this;history.pushState=function(...e){t.originalPushState.apply(history,e),setTimeout(()=>{t.attribution.clearCache(),t.page()},0)},history.replaceState=function(...e){t.originalReplaceState.apply(history,e),setTimeout(()=>{t.attribution.clearCache(),t.page()},0)},this.popstateHandler=()=>{setTimeout(()=>{t.attribution.clearCache(),t.page()},0)},window.addEventListener("popstate",this.popstateHandler),this.hashchangeHandler=()=>{t.attribution.clearCache(),t.page()},window.addEventListener("hashchange",this.hashchangeHandler)}setupUnloadHandler(){const t=()=>{this.queue.forceFlush()};window.addEventListener("beforeunload",t),window.addEventListener("pagehide",t),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&t()})}getPerformanceMetrics(){if(!this.config.enablePerformanceTracking)return null;const t={};try{if(performance&&"function"==typeof performance.getEntriesByType){const e=performance.getEntriesByType("navigation"),i=e&&e[0];i&&(t.pageLoadTime=Math.round(i.loadEventEnd),t.domReadyTime=Math.round(i.domContentLoadedEventEnd),t.firstByteTime=Math.round(i.responseStart),t.dnsTime=Math.round(i.domainLookupEnd-i.domainLookupStart),t.tcpTime=Math.round(i.connectEnd-i.connectStart),t.requestTime=Math.round(i.responseEnd-i.requestStart),t.timeOnPage=Math.round(performance.now()))}}catch(t){this.trackError(t,{context:"performance_metrics"})}return Object.keys(t).length>0?t:null}trackError(t,e){const i={message:t.message||String(t),stack:t.stack,context:e,timestamp:(new Date).toISOString(),url:window.location.href};this.errors.push(i),this.errors.length>this.MAX_ERRORS&&(this.errors=this.errors.slice(-this.MAX_ERRORS)),this.config.debug&&console.error("[Datalyr Error]",i)}getErrors(){return[...this.errors]}getNetworkStatus(){return this.queue.getNetworkStatus()}loadScript(t){this.container&&this.container.triggerCustomScript(t)}getLoadedScripts(){return this.container?this.container.getLoadedScripts():[]}log(...t){this.config.debug&&console.log("[Datalyr]",...t)}destroy(){this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.popstateHandler&&window.removeEventListener("popstate",this.popstateHandler),this.hashchangeHandler&&window.removeEventListener("hashchange",this.hashchangeHandler),this.queue&&this.queue.destroy(),this.session&&this.session.destroy(),this.container&&this.container.cleanupAllIframes(),this.autoIdentify&&this.autoIdentify.destroy(),e.destroy(),this.superProperties={},this.userProperties={},this.errors=[],this.initialized=!1,this.log("SDK destroyed")}};return"undefined"!=typeof window&&(window.datalyr=b),b}();
1
+ var Datalyr=function(){"use strict";function t(t,e,i,s){return new(i||(i=Promise))(function(n,o){function r(t){try{c(s.next(t))}catch(t){o(t)}}function a(t){try{c(s.throw(t))}catch(t){o(t)}}function c(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i(function(t){t(e)})).then(r,a)}c((s=s.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;const e=new class{constructor(){this.key=null,this.salt=null}initialize(e,i){return t(this,void 0,void 0,function*(){if(!crypto.subtle){const t=new Error("Web Crypto API not available - encryption cannot be initialized");throw console.error("[Datalyr Encryption]",t.message),t}try{const t=new TextEncoder,s="dl_encryption_salt";let n=localStorage.getItem(s);n?this.salt=this.base64ToArrayBuffer(n):(this.salt=crypto.getRandomValues(new Uint8Array(32)),n=this.arrayBufferToBase64(this.salt),localStorage.setItem(s,n));const o=`datalyr:${e}:${i}`,r=t.encode(o),a=yield crypto.subtle.importKey("raw",r,"PBKDF2",!1,["deriveKey"]);this.key=yield crypto.subtle.deriveKey({name:"PBKDF2",salt:this.salt,iterations:1e5,hash:"SHA-256"},a,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw console.error("[Datalyr Encryption] Failed to initialize:",t),this.key=null,t}})}encrypt(e){return t(this,void 0,void 0,function*(){if(!this.key||!crypto.subtle)throw new Error("Encryption not initialized - cannot encrypt sensitive data");try{const t="string"==typeof e?e:JSON.stringify(e),i=(new TextEncoder).encode(t),s=crypto.getRandomValues(new Uint8Array(12)),n=yield crypto.subtle.encrypt({name:"AES-GCM",iv:s},this.key,i),o=new Uint8Array(s.length+n.byteLength);return o.set(s,0),o.set(new Uint8Array(n),s.length),this.arrayBufferToBase64(o)}catch(t){throw console.error("[Datalyr Encryption] Encryption failed:",t),t}})}decrypt(e){return t(this,void 0,void 0,function*(){if(!this.key||!crypto.subtle){console.warn("[Datalyr Encryption] Decryption not available - reading potentially unencrypted data");try{return JSON.parse(e)}catch(t){return e}}try{const t=this.base64ToArrayBuffer(e),i=t.slice(0,12),s=t.slice(12),n=yield crypto.subtle.decrypt({name:"AES-GCM",iv:i},this.key,s),o=(new TextDecoder).decode(n);try{return JSON.parse(o)}catch(t){return o}}catch(t){console.warn("[Datalyr Encryption] Decryption failed - attempting to read as unencrypted data (migration mode)");try{return JSON.parse(e)}catch(t){return e}}})}isAvailable(){return null!==this.key&&void 0!==crypto.subtle}arrayBufferToBase64(t){let e="";const i=new Uint8Array(t),s=i.byteLength;for(let t=0;t<s;t++)e+=String.fromCharCode(i[t]);return btoa(e)}base64ToArrayBuffer(t){const e=atob(t),i=e.length,s=new Uint8Array(i);for(let t=0;t<i;t++)s[t]=e.charCodeAt(t);return s}destroy(){this.key=null,this.salt=null}};class i{constructor(t){this.memory=new Map,this.prefix="dl_";try{const e="dl_test__"+Math.random();t.setItem(e,"1"),t.removeItem(e),this.storage=t}catch(t){this.storage=null,console.warn("[Datalyr] Storage not available, using memory fallback")}}get(t,e=null){const i=this.prefix+t;try{if(this.storage){const t=this.storage.getItem(i);if(null===t)return e;try{return JSON.parse(t)}catch(e){return t}}else{const t=this.memory.get(i);if(void 0===t)return e;try{return JSON.parse(t)}catch(e){return t}}}catch(t){return e}}set(t,e){const i=this.prefix+t,s="string"==typeof e?e:JSON.stringify(e);try{return this.storage?(this.storage.setItem(i,s),!0):(this.memory.set(i,s),!0)}catch(e){return console.warn("[Datalyr] Failed to store:",t,e),this.memory.set(i,s),!1}}remove(t){const e=this.prefix+t;try{return this.storage?(this.storage.removeItem(e),!0):(this.memory.delete(e),!0)}catch(t){return!1}}keys(){try{if(this.storage){const t=[];for(let e=0;e<this.storage.length;e++){const i=this.storage.key(e);i&&i.startsWith(this.prefix)&&t.push(i.slice(this.prefix.length))}return t}return Array.from(this.memory.keys()).filter(t=>t.startsWith(this.prefix)).map(t=>t.slice(this.prefix.length))}catch(t){return[]}}migrateFromLegacyPrefix(){if(!this.storage)return 0;let t=0;try{const e=[];for(let t=0;t<this.storage.length;t++){const i=this.storage.key(t);i&&i.startsWith("__dl_dl_")&&e.push(i)}e.forEach(e=>{try{const i=this.storage.getItem(e);if(i){const s=e.slice(5);this.storage.getItem(s)||(this.storage.setItem(s,i),t++),this.storage.removeItem(e)}}catch(t){console.warn(`[Datalyr Storage] Failed to migrate legacy key: ${e}`,t)}}),t>0&&console.log(`[Datalyr Storage] Migrated ${t} keys from legacy prefix`)}catch(t){console.warn("[Datalyr Storage] Error during legacy key migration:",t)}return t}getEncrypted(i){return t(this,arguments,void 0,function*(t,i=null){const s=this.prefix+t;try{let t=null;if(t=this.storage?this.storage.getItem(s):this.memory.get(s)||null,!t)return i;return yield e.decrypt(t)}catch(e){return console.warn("[Datalyr Storage] Failed to decrypt:",t,e),i}})}setEncrypted(i,s){return t(this,void 0,void 0,function*(){const t=this.prefix+i,n=yield e.encrypt(s);return this.storage?(this.storage.setItem(t,n),!0):(this.memory.set(t,n),!0)})}}class s{constructor(t={}){this.domain=t.domain||"auto",this.maxAge=t.maxAge||365,this.sameSite=t.sameSite||"Lax",this.secure=t.secure||"auto"}get(t){var e;const i=`; ${document.cookie}`.split(`; ${t}=`);if(2===i.length){const t=(null===(e=i.pop())||void 0===e?void 0:e.split(";").shift())||null;if(t)try{return decodeURIComponent(t)}catch(e){return t}}return null}set(t,e,i){try{const s=86400*(i||this.maxAge),n="auto"===this.secure?"https:"===location.protocol:this.secure;let o="";"auto"===this.domain?o=this.getAutoDomain():this.domain&&(o=`;domain=${this.domain}`);const r=[`${t}=${encodeURIComponent(e)}`,`max-age=${s}`,"path=/",`SameSite=${this.sameSite}`,n?"Secure":"",o].filter(Boolean).join(";");return document.cookie=r,!0}catch(e){return console.warn("[Datalyr] Failed to set cookie:",t,e),!1}}remove(t){try{const e=["",location.hostname],i=location.hostname.split(".");return i.length>2&&(e.push(`.${i.slice(-2).join(".")}`),e.push(`.${location.hostname}`)),e.forEach(e=>{const i=e?`;domain=${e}`:"";document.cookie=`${t}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/${i}`}),!0}catch(t){return!1}}getAutoDomain(){const t=location.hostname;if("localhost"===t||/^[\d.]+$/.test(t)||/^\[[\d:]+\]$/.test(t))return"";const e=t.split(".");for(let t=e.length-2;t>=0;t--){const i="."+e.slice(t).join("."),s="__dl_test_"+Math.random();if(document.cookie=`${s}=1;domain=${i};path=/`,-1!==document.cookie.indexOf(s))return document.cookie=`${s}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;domain=${i};path=/`,`;domain=${i}`}return""}}const n=new i(window.localStorage);new i(window.sessionStorage);const o=new s;function r(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)})}function a(t=window.location.search){const e={};try{if("URLSearchParams"in window){return new URLSearchParams(t).forEach((t,i)=>{e[i]=t}),e}}catch(t){}const i=(t||"").replace(/^\?/,"").split("&");for(const t of i){const[i,s=""]=t.split("=");try{const t=decodeURIComponent((i||"").replace(/\+/g," ")),n=decodeURIComponent((s||"").replace(/\+/g," "));t&&(e[t]=n)}catch(t){}}return e}function c(t,e=5,i=0){if(i>=e)return"[Max depth reached]";if(null==t)return t;if("undefined"!=typeof Element&&t instanceof Element||"undefined"!=typeof Document&&t instanceof Document||"function"==typeof t)return"[Removed]";if(Array.isArray(t))return t.map(t=>c(t,e,i+1));if("object"==typeof t){const s={},n=/pass|pwd|token|secret|auth|bearer|session|cookie|signature|api[-_]?key|private[-_]?key|access[-_]?token|refresh[-_]?token/i;for(const o in t)if(Object.prototype.hasOwnProperty.call(t,o)){if(n.test(o))continue;s[o]=c(t[o],e,i+1)}return s}return"string"==typeof t?t.length>1e3?t.slice(0,1e3)+"...[truncated]":t.match(/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+$/)||t.match(/^[a-f0-9]{32,}$/i)?"[Redacted]":t:t}function l(t,...e){if(!e.length)return t;const i=e.shift();if(h(t)&&h(i))for(const e in i)h(i[e])?(t[e]||Object.assign(t,{[e]:{}}),l(t[e],i[e])):Object.assign(t,{[e]:i[e]});return l(t,...e)}function h(t){return t&&"object"==typeof t&&!Array.isArray(t)}function d(t){const e={google:["google.com","google."],facebook:["facebook.com","fb.com"],twitter:["twitter.com","t.co","x.com"],linkedin:["linkedin.com","lnkd.in"],instagram:["instagram.com"],youtube:["youtube.com","youtu.be"],tiktok:["tiktok.com"],reddit:["reddit.com"],pinterest:["pinterest.com"],bing:["bing.com"],yahoo:["yahoo.com"],duckduckgo:["duckduckgo.com"],baidu:["baidu.com"]};for(const[i,s]of Object.entries(e))if(s.some(e=>t.includes(e)))return i;return"other"}class u{constructor(){this.userId=null,this.sessionId=null,this.anonymousId=this.getOrCreateAnonymousId(),this.userId=this.getStoredUserId()}getOrCreateAnonymousId(){let t=o.get("__dl_visitor_id");return t?(n.set("dl_anonymous_id",t),t):(t=n.get("dl_anonymous_id"),t?(this.setRootDomainCookie("__dl_visitor_id",t),t):(t=`anon_${r()}`,this.setRootDomainCookie("__dl_visitor_id",t),n.set("dl_anonymous_id",t),t))}setRootDomainCookie(t,e){try{const i=function(){const t=window.location.hostname;if("localhost"===t||t.match(/^[0-9]{1,3}\./)||t.match(/^\[?[0-9a-fA-F:]+\]?$/))return t;const e=t.split(".");if(e.length>=2){const t=e[e.length-1],i=`${e[e.length-2]}.${t}`;return["co.uk","com.au","co.nz","co.jp","co.in","co.za"].includes(i)&&e.length>=3?"."+e.slice(-3).join("."):"."+e.slice(-2).join(".")}return t}(),s="https:"===location.protocol?"; Secure":"",n=encodeURIComponent(e);document.cookie=`${t}=${n}; domain=${i}; path=/; max-age=31536000; SameSite=Lax${s}`;o.get(t)!==e&&(document.cookie=`${t}=${n}; path=/; max-age=31536000; SameSite=Lax${s}`)}catch(i){console.error("[Datalyr] Error setting root domain cookie:",i);try{const i="https:"===location.protocol?"; Secure":"",s=encodeURIComponent(e);document.cookie=`${t}=${s}; path=/; max-age=31536000; SameSite=Lax${i}`}catch(t){console.error("[Datalyr] Failed to set cookie even without domain:",t)}}}getStoredUserId(){return n.get("dl_user_id")}getAnonymousId(){return this.anonymousId}getUserId(){return this.userId}getDistinctId(){return this.userId||this.anonymousId}getCanonicalId(){return this.getDistinctId()}setSessionId(t){this.sessionId=t}getSessionId(){return this.sessionId}identify(t,e={}){if(!t)return console.warn("[Datalyr] identify() called without userId"),{};const i=this.userId;return this.userId=t,n.set("dl_user_id",t),{anonymous_id:this.anonymousId,user_id:t,previous_id:i,traits:e,identified_at:(new Date).toISOString(),resolution_method:"identify_call"}}alias(t,e){const i={userId:t,previousId:e||this.anonymousId,aliased_at:(new Date).toISOString()};return e&&e!==this.anonymousId||(this.userId=t,n.set("dl_user_id",t)),i}reset(){this.userId=null,n.remove("dl_user_id"),n.remove("dl_user_traits"),this.anonymousId=`anon_${r()}`,n.set("dl_anonymous_id",this.anonymousId),this.setRootDomainCookie("__dl_visitor_id",this.anonymousId)}getIdentityFields(){return{distinct_id:this.getDistinctId(),anonymous_id:this.anonymousId,user_id:this.userId,visitor_id:this.anonymousId,visitorId:this.anonymousId,canonical_id:this.getCanonicalId(),session_id:this.sessionId,sessionId:this.sessionId,resolution_method:"browser_sdk",resolution_confidence:1}}}class g{constructor(t=36e5){this.sessionId=null,this.sessionData=null,this.lastActivity=Date.now(),this.SESSION_KEY="dl_session_data",this.activityCheckInterval=null,this.activityListeners=[],this.sessionCreationLock=!1,this.sessionTimeout=t,this.initSession(),this.setupActivityMonitor()}initSession(){const t=n.get(this.SESSION_KEY),e=Date.now();t&&this.isSessionValid(t,e)?(this.sessionData=t,this.sessionId=t.id,this.lastActivity=e):this.createNewSession()}isSessionValid(t,e){return e-t.lastActivity<this.sessionTimeout&&t.isActive}createNewSession(){if(this.sessionCreationLock)return console.log("[Datalyr Session] Session creation already in progress, returning existing ID"),this.sessionId||"";this.sessionCreationLock=!0;try{const t=Date.now();return this.sessionId=`sess_${r()}`,this.sessionData={id:this.sessionId,startTime:t,lastActivity:t,pageViews:0,events:0,duration:0,isActive:!0},this.saveSession(),this.incrementSessionCount(),this.sessionId}finally{this.sessionCreationLock=!1}}rotateSessionId(){const t=Date.now(),e=this.sessionId;return this.sessionId=`sess_${r()}`,this.sessionData?(this.sessionData.id=this.sessionId,this.sessionData.lastActivity=t,this.saveSession(),e&&n.remove(`dl_session_${e}_attribution`),console.log(`[Datalyr Session] Rotated session ID from ${e} to ${this.sessionId}`)):this.createNewSession(),this.sessionId}getSessionId(){return this.sessionId&&this.isSessionActive()||this.createNewSession(),this.sessionId}getSessionData(){return this.sessionData}updateActivity(t){const e=Date.now();this.sessionData&&this.isSessionValid(this.sessionData,e)?(this.lastActivity=e,this.sessionData.lastActivity=e,this.sessionData.duration=e-this.sessionData.startTime,"pageview"!==t&&"page_view"!==t||this.sessionData.pageViews++,this.sessionData.events++,this.saveSession()):this.createNewSession()}isSessionActive(){if(!this.sessionData)return!1;const t=Date.now();return this.isSessionValid(this.sessionData,t)}endSession(){this.sessionData&&(this.sessionData.isActive=!1,this.saveSession()),this.sessionId=null,this.sessionData=null,this.destroy()}saveSession(){this.sessionData&&n.set(this.SESSION_KEY,this.sessionData)}getTimeout(){return this.sessionTimeout}setTimeout(t){this.sessionTimeout=t}storeAttribution(t){n.set("dl_current_session_attribution",Object.assign(Object.assign({},t),{sessionId:this.sessionId,timestamp:Date.now()}))}getAttribution(){if(!this.sessionId)return null;if(!this.isSessionActive())return null;const t=n.get("dl_current_session_attribution");return t&&t.sessionId===this.sessionId?t:null}getMetrics(){return this.sessionData?{session_id:this.sessionId,session_duration:this.sessionData.duration,session_page_views:this.sessionData.pageViews,session_events:this.sessionData.events,session_start:this.sessionData.startTime,time_since_session_start:Date.now()-this.sessionData.startTime}:{}}setupActivityMonitor(){const t=()=>{const t=Date.now();this.sessionData&&t-this.lastActivity>1e3&&this.updateActivity()};["mousedown","keydown","scroll","touchstart"].forEach(e=>{window.addEventListener(e,t,{passive:!0,capture:!0}),this.activityListeners.push({event:e,handler:t})}),this.activityCheckInterval=setInterval(()=>{this.sessionData&&!this.isSessionActive()&&this.createNewSession()},6e4)}destroy(){this.activityListeners.forEach(({event:t,handler:e})=>{window.removeEventListener(t,e)}),this.activityListeners=[],this.activityCheckInterval&&(clearInterval(this.activityCheckInterval),this.activityCheckInterval=null)}getSessionNumber(){return n.get("dl_session_count",0)+1}incrementSessionCount(){const t=n.get("dl_session_count",0);n.set("dl_session_count",t+1)}}class p{constructor(t={}){this.queryParamsCache=null,this.UTM_PARAMS=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],this.CLICK_IDS=["fbclid","gclid","gbraid","wbraid","ttclid","msclkid","twclid","li_fat_id","sclid","dclid","epik","rdt_cid","obclid","irclid","ko_click_id"],this.DEFAULT_TRACKED_PARAMS=["lyr","ref","source","campaign","medium","gad_source"],this.attributionWindow=t.attributionWindow||7776e6,this.trackedParams=[...this.DEFAULT_TRACKED_PARAMS,...t.trackedParams||[]]}clearCache(){this.queryParamsCache=null}captureAttribution(){const t=this.queryParamsCache||a();this.queryParamsCache||(this.queryParamsCache=t);const e={timestamp:Date.now()};for(const i of this.UTM_PARAMS){const s=t[i];if(s){e[i.replace("utm_","")]=s}}for(const i of this.CLICK_IDS){const s=t[i];if(s){e.clickId=s,e.clickIdType=i;break}}for(const i of this.trackedParams){const s=t[i];s&&(e[i]=s)}return document.referrer&&(e.referrer=document.referrer,e.referrerHost=this.extractHostname(document.referrer)),e.landingPage=window.location.href,e.landingPath=window.location.pathname,e.source||(e.source=this.determineSource(e)),e.medium||(e.medium=this.determineMedium(e)),e}storeFirstTouch(t){const e=n.get("dl_first_touch");let i=!1;e?e.expires_at&&Date.now()>=e.expires_at&&(i=!0):i=!0,i&&n.set("dl_first_touch",Object.assign(Object.assign({},t),{captured_at:Date.now(),expires_at:Date.now()+this.attributionWindow}))}getFirstTouch(){const t=n.get("dl_first_touch");return t&&t.expires_at&&Date.now()>=t.expires_at?(n.remove("dl_first_touch"),null):t}storeLastTouch(t){n.set("dl_last_touch",Object.assign(Object.assign({},t),{captured_at:Date.now(),expires_at:Date.now()+this.attributionWindow}))}getLastTouch(){const t=n.get("dl_last_touch");return t&&t.expires_at&&Date.now()>=t.expires_at?(n.remove("dl_last_touch"),null):t}addTouchpoint(t,e){const i=this.getJourney(),s={timestamp:Date.now(),sessionId:t,source:e.source||void 0,medium:e.medium||void 0,campaign:e.campaign||void 0};i.push(s),i.length>30&&i.shift(),n.set("dl_journey",i)}getJourney(){return n.get("dl_journey",[])}captureAdCookies(){const t={};if(t._fbp=o.get("_fbp"),t._fbc=o.get("_fbc"),t._gcl_aw=o.get("_gcl_aw"),t._gcl_dc=o.get("_gcl_dc"),t._gcl_gb=o.get("_gcl_gb"),t._gcl_ha=o.get("_gcl_ha"),t._gac=o.get("_gac"),t._ga=o.get("_ga"),t._gid=o.get("_gid"),t._ttp=o.get("_ttp"),t._ttc=o.get("_ttc"),!t._fbp&&(this.hasClickId("fbclid")||t._fbc)){const e=Date.now(),i=Math.random().toString(36).substring(2,15);t._fbp=`fb.1.${e}.${i}`,o.set("_fbp",t._fbp,90)}const e=this.getCurrentFbclid();if(e&&!t._fbc){const i=Math.floor(Date.now()/1e3);t._fbc=`fb.1.${i}.${e}`,o.set("_fbc",t._fbc,90)}return Object.fromEntries(Object.entries(t).filter(([t,e])=>null!==e))}hasClickId(t){return!!(this.queryParamsCache||a())[t]}getCurrentFbclid(){return(this.queryParamsCache||a()).fbclid||null}getAttributionData(){const t=this.getFirstTouch(),e=this.getLastTouch(),i=this.getJourney();let s=this.captureAttribution();!!!(s.source||s.medium||s.clickId||s.campaign)&&t&&(!t.expires_at||Date.now()<t.expires_at)&&(s=Object.assign(Object.assign({},t),{referrer:s.referrer,referrerHost:s.referrerHost,landingPage:s.landingPage,landingPath:s.landingPath}));const n=this.captureAdCookies();return!t&&Object.keys(s).length>1&&this.storeFirstTouch(s),Object.keys(s).length>1&&this.storeLastTouch(s),Object.assign(Object.assign(Object.assign({},s),n),{first_touch_source:null==t?void 0:t.source,first_touch_medium:null==t?void 0:t.medium,first_touch_campaign:null==t?void 0:t.campaign,first_touch_timestamp:null==t?void 0:t.timestamp,firstTouchSource:null==t?void 0:t.source,firstTouchMedium:null==t?void 0:t.medium,firstTouchCampaign:null==t?void 0:t.campaign,last_touch_source:null==e?void 0:e.source,last_touch_medium:null==e?void 0:e.medium,last_touch_campaign:null==e?void 0:e.campaign,last_touch_timestamp:null==e?void 0:e.timestamp,lastTouchSource:null==e?void 0:e.source,lastTouchMedium:null==e?void 0:e.medium,lastTouchCampaign:null==e?void 0:e.campaign,touchpoint_count:i.length,touchpointCount:i.length,days_since_first_touch:(null==t?void 0:t.timestamp)?Math.floor((Date.now()-t.timestamp)/864e5):0,daysSinceFirstTouch:(null==t?void 0:t.timestamp)?Math.floor((Date.now()-t.timestamp)/864e5):0})}determineSource(t){if(t.clickIdType){return{fbclid:"facebook",gclid:"google",ttclid:"tiktok",msclkid:"bing",twclid:"twitter",li_fat_id:"linkedin",sclid:"snapchat",dclid:"doubleclick",epik:"pinterest"}[t.clickIdType]||"paid"}if(t.referrerHost){const e=t.referrerHost.toLowerCase();return e.includes("facebook.com")||e.includes("fb.com")?"facebook":e.includes("twitter.com")||e.includes("t.co")||e.includes("x.com")?"twitter":e.includes("linkedin.com")||e.includes("lnkd.in")?"linkedin":e.includes("instagram.com")?"instagram":e.includes("youtube.com")||e.includes("youtu.be")?"youtube":e.includes("tiktok.com")?"tiktok":e.includes("reddit.com")?"reddit":e.includes("pinterest.com")?"pinterest":e.includes("google.")?"google":e.includes("bing.com")?"bing":e.includes("yahoo.com")?"yahoo":e.includes("duckduckgo.com")?"duckduckgo":e.includes("baidu.com")?"baidu":"referral"}return"direct"}determineMedium(t){if(t.clickId)return"cpc";const e=t.source;if(!e||"direct"===e)return"none";if(["facebook","twitter","linkedin","instagram","youtube","tiktok","reddit","pinterest"].includes(e))return"social";return["google","bing","yahoo","duckduckgo","baidu"].includes(e)?"organic":"referral"}extractHostname(t){try{return new URL(t).hostname}catch(t){return""}}isAttributionExpired(t){return!t.timestamp||Date.now()-t.timestamp>this.attributionWindow}clearExpiredAttribution(){const t=this.getFirstTouch(),e=this.getLastTouch();t&&this.isAttributionExpired(t)&&n.remove("dl_first_touch"),e&&this.isAttributionExpired(e)&&n.remove("dl_last_touch")}}const f=["purchase","signup","subscribe","lead","conversion"],m=["add_to_cart","begin_checkout","view_item","search"];class y{constructor(t){this.queue=[],this.offlineQueue=[],this.batchTimer=null,this.periodicFlushInterval=null,this.flushPromise=null,this.recentEventIds=new Set,this.MAX_RECENT_EVENT_IDS=1e3,this.OFFLINE_QUEUE_KEY="dl_offline_queue",this.flushLock=!1,this.offlineQueueLock=!1,this.config={batchSize:t.batchSize||10,flushInterval:t.flushInterval||5e3,maxRetries:t.maxRetries||5,retryDelay:t.retryDelay||1e3,endpoint:t.endpoint||"https://ingest.datalyr.com",fallbackEndpoints:t.fallbackEndpoints||[],workspaceId:t.workspaceId,debug:t.debug||!1,criticalEvents:t.criticalEvents||f,highPriorityEvents:t.highPriorityEvents||m,maxOfflineQueueSize:t.maxOfflineQueueSize||100},this.networkStatus={isOnline:!1!==navigator.onLine,lastOfflineAt:null,lastOnlineAt:null},this.loadOfflineQueue(),this.setupNetworkListeners(),this.startPeriodicFlush()}enqueue(t){const e=t.event_name;if(this.isDuplicateEvent(t))this.log("Duplicate event suppressed:",e);else{if(this.config.criticalEvents.includes(e))return this.log("Critical event, sending immediately:",e),void this.sendBatch([t]).catch(i=>{this.log("Critical event send failed, adding to offline queue:",e,i),this.moveToOfflineQueue([t])});this.queue.push(t),this.log("Event queued:",e),this.shouldFlush(e)&&this.flush()}}isDuplicateEvent(t){const e=this.createEventHash(t);if(this.recentEventIds.has(e))return!0;if(this.recentEventIds.add(e),this.recentEventIds.size>this.MAX_RECENT_EVENT_IDS){const t=this.recentEventIds.size-this.MAX_RECENT_EVENT_IDS,e=this.recentEventIds.values();for(let i=0;i<t;i++){const t=e.next();t.done||this.recentEventIds.delete(t.value)}}return!1}createEventHash(t){const e=[t.event_name,t.timestamp,JSON.stringify(t.event_data||{})].join("|");let i=0;for(let t=0;t<e.length;t++){i=(i<<5)-i+e.charCodeAt(t),i&=i}return i.toString(36)}shouldFlush(t){return this.queue.length>=this.config.batchSize||(t&&this.config.highPriorityEvents.includes(t)?(this.batchTimer&&clearTimeout(this.batchTimer),this.batchTimer=setTimeout(()=>this.flush(),1e3),!1):(this.batchTimer||(this.batchTimer=setTimeout(()=>this.flush(),this.config.flushInterval)),!1))}flush(){return t(this,void 0,void 0,function*(){if(this.flushPromise||this.flushLock)return this.flushPromise||Promise.resolve();this.flushLock=!0;try{this.flushPromise=this._flush(),yield this.flushPromise}finally{this.flushPromise=null,this.flushLock=!1}})}_flush(){return t(this,void 0,void 0,function*(){if(this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),0===this.queue.length)return;if(!this.networkStatus.isOnline)return this.log("Network offline, queuing events"),void this.moveToOfflineQueue();const t=Math.min(this.config.batchSize,this.queue.length),e=this.queue.slice(0,t);try{yield this.sendBatch(e),this.queue.splice(0,t),this.log(`Successfully sent and removed ${t} events from queue`)}catch(t){this.log("Failed to send batch:",t),this.moveToOfflineQueue(e)}})}sendBatch(e){return t(this,arguments,void 0,function*(t,e=0,i=0){const s={events:t,batchId:r(),timestamp:(new Date).toISOString()},n=[this.config.endpoint,...this.config.fallbackEndpoints],o=n[i]||this.config.endpoint;try{const e=yield fetch(o,{method:"POST",headers:{"Content-Type":"application/json","X-Batch-Size":t.length.toString()},body:JSON.stringify(s),keepalive:!0});if(!e.ok){if(429===e.status){const t=parseInt(e.headers.get("Retry-After")||"60");throw this.log(`Rate limited, retrying after ${t}s`),setTimeout(()=>{this.flush()},1e3*t),new Error(`Rate limited (429), retry after ${t}s`)}throw new Error(`HTTP ${e.status}: ${e.statusText}`)}this.log(`Batch sent successfully to ${o}: ${t.length} events`)}catch(s){if(i<n.length-1)return this.log(`Failed on ${o}, trying fallback ${i+1}`),this.sendBatch(t,0,i+1);if(e<this.config.maxRetries){const s=function(t,e=1e3){const i=.1*Math.random();return Math.min(e*Math.pow(2,t)*(1+i),3e4)}(e,this.config.retryDelay);return this.log(`Retrying batch in ${s}ms (attempt ${e+1}/${this.config.maxRetries})`),yield new Promise(t=>setTimeout(t,s)),this.sendBatch(t,e+1,i)}throw s}})}setupNetworkListeners(){window.addEventListener("online",()=>{this.networkStatus.isOnline=!0,this.networkStatus.lastOnlineAt=Date.now(),this.log("Network connection restored"),setTimeout(()=>this.processOfflineQueue(),1e3)}),window.addEventListener("offline",()=>{this.networkStatus.isOnline=!1,this.networkStatus.lastOfflineAt=Date.now(),this.log("Network connection lost")})}startPeriodicFlush(){this.periodicFlushInterval=setInterval(()=>{this.queue.length>0&&this.flush()},this.config.flushInterval)}stopPeriodicFlush(){this.periodicFlushInterval&&(clearInterval(this.periodicFlushInterval),this.periodicFlushInterval=null)}moveToOfflineQueue(t){if(this.offlineQueueLock)console.warn("[Datalyr Queue] Offline queue operation already in progress");else{this.offlineQueueLock=!0;try{if(t?this.offlineQueue.push(...t):(this.offlineQueue.push(...this.queue),this.queue=[]),this.offlineQueue.length>this.config.maxOfflineQueueSize){const t=this.offlineQueue.length-this.config.maxOfflineQueueSize;this.offlineQueue.splice(0,t)}this.saveOfflineQueue()}finally{this.offlineQueueLock=!1}}}loadOfflineQueue(){const t=n.get(this.OFFLINE_QUEUE_KEY,[]);Array.isArray(t)&&(this.offlineQueue=t,this.log(`Loaded ${this.offlineQueue.length} offline events`))}saveOfflineQueue(){const t=this.offlineQueue.slice(-this.config.maxOfflineQueueSize);n.set(this.OFFLINE_QUEUE_KEY,t)}processOfflineQueue(){return t(this,void 0,void 0,function*(){if(0!==this.offlineQueue.length){for(this.log(`Processing ${this.offlineQueue.length} offline events`);this.offlineQueue.length>0;){const t=this.offlineQueue.splice(0,this.config.batchSize);try{yield this.sendBatch(t),this.saveOfflineQueue()}catch(e){this.log("Failed to send offline batch:",e),this.offlineQueue.unshift(...t),this.saveOfflineQueue();break}}0===this.offlineQueue.length&&n.remove(this.OFFLINE_QUEUE_KEY)}})}getQueueSize(){return this.queue.length}getOfflineQueueSize(){return this.offlineQueue.length}getNetworkStatus(){return Object.assign({},this.networkStatus)}forceFlush(){return t(this,void 0,void 0,function*(){if(navigator.sendBeacon&&this.queue.length>0){const t={events:this.queue,batchId:r(),timestamp:(new Date).toISOString()},e=new Blob([JSON.stringify(t)],{type:"application/json"});if(navigator.sendBeacon(this.config.endpoint,e))return this.log("Events sent via sendBeacon"),void(this.queue=[])}yield this.flush()})}clear(){this.queue=[],this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null)}log(...t){this.config.debug&&console.log("[Datalyr Queue]",...t)}destroy(){this.stopPeriodicFlush(),this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.queue.length>0&&this.moveToOfflineQueue()}}class v{constructor(t={}){this.privacyMode=t.privacyMode||"standard",this.enableFingerprinting=!1!==t.enableFingerprinting}collect(){return"strict"!==this.privacyMode&&this.enableFingerprinting?this.collectStandard():this.collectMinimal()}collectMinimal(){const t={timezone:this.getTimezone(),language:navigator.language||null,screen_bucket:this.getScreenBucket(),dnt:"1"===navigator.doNotTrack||!0===window.globalPrivacyControl||null,userAgent:navigator.userAgent||null};if("userAgentData"in navigator){const e=navigator.userAgentData;t.userAgentData={brands:e.brands||[],mobile:e.mobile||!1,platform:e.platform||null}}return t}collectStandard(){const t={};try{if(t.timezone=this.getTimezone(),t.language=navigator.language||null,t.screen_bucket=this.getScreenBucket(),t.dnt="1"===navigator.doNotTrack||!0===window.globalPrivacyControl||null,t.userAgent=navigator.userAgent||null,"userAgentData"in navigator){const e=navigator.userAgentData;t.userAgentData={brands:e.brands||[],mobile:e.mobile||!1,platform:e.platform||null}}}catch(t){console.warn("[Datalyr] Error collecting fingerprint:",t)}return t}getTimezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||null}catch(t){return null}}getScreenBucket(){try{if(!window.screen)return null;const t=100*Math.round(screen.width/100);return`${t}x${100*Math.round(screen.height/100)}`}catch(t){return null}}generateHash(e){return t(this,void 0,void 0,function*(){try{const t=Object.keys(e).sort().reduce((t,i)=>(t[i]=e[i],t),{}),i=JSON.stringify(t);if(window.crypto&&window.crypto.subtle){const t=(new TextEncoder).encode(i),e=yield crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(e)).map(t=>t.toString(16).padStart(2,"0")).join("")}let s=0;for(let t=0;t<i.length;t++){s=(s<<5)-s+i.charCodeAt(t),s&=s}return Math.abs(s).toString(16)}catch(t){return""}})}}class _{constructor(t){this.scripts=[],this.loadedScripts=new Set,this.sessionLoadedScripts=new Set,this.pixels=null,this.initialized=!1,this.sandboxedIframes=[],this.iframeCleanupTimeouts=new Map,this.messageHandler=null,this.workspaceId=t.workspaceId,this.endpoint=t.endpoint||"https://ingest.datalyr.com",this.debug=t.debug||!1;const e=n.get("dl_session_scripts",[]);this.sessionLoadedScripts=new Set(e),this.messageHandler=t=>{if(t.data&&"datalyr_script_complete"===t.data.type){const e=t.data.scriptId;this.log("Received script completion signal:",e);const i=this.sandboxedIframes.find(t=>t.dataset.datalyrScript===e);i&&this.cleanupIframe(i)}},window.addEventListener("message",this.messageHandler)}init(){return t(this,void 0,void 0,function*(){if(!this.initialized)try{const t=yield fetch(`${this.endpoint}/container-scripts`,{method:"POST",headers:{"Content-Type":"application/json","X-Container-Version":"1.0"},body:JSON.stringify({workspaceId:this.workspaceId})});if(!t.ok)throw new Error(`Failed to fetch container scripts: ${t.status}`);const e=yield t.json();this.scripts=e.scripts||[],this.pixels=e.pixels||null,this.pixels&&this.initializePixels(),this.loadScriptsByTrigger("page_load"),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{this.loadScriptsByTrigger("dom_ready")}):this.loadScriptsByTrigger("dom_ready"),window.addEventListener("load",()=>{this.loadScriptsByTrigger("window_load")}),this.initialized=!0,this.log("Container manager initialized with",this.scripts.length,"scripts")}catch(t){this.log("Error initializing container:",t)}})}loadScriptsByTrigger(t){this.scripts.filter(e=>e.enabled&&e.trigger===t&&this.shouldLoadScript(e)).forEach(t=>this.loadScript(t))}shouldLoadScript(t){return("once_per_page"!==t.frequency||!this.loadedScripts.has(t.id))&&(("once_per_session"!==t.frequency||!this.sessionLoadedScripts.has(t.id))&&(!(t.conditions&&t.conditions.length>0)||this.evaluateConditions(t.conditions)))}evaluateConditions(t){return t.every(t=>{try{const{type:e,operator:i,value:s}=t;switch(e){case"url_path":return this.evaluateStringCondition(window.location.pathname,i,s);case"url_host":return this.evaluateStringCondition(window.location.hostname,i,s);case"url_parameter":const e=new URLSearchParams(window.location.search);return this.evaluateStringCondition(e.get(t.parameter)||"",i,s);case"referrer":return this.evaluateStringCondition(document.referrer,i,s);case"device_type":const n=/Mobile|Android|iPhone|iPad/i.test(navigator.userAgent);return this.evaluateStringCondition(n?"mobile":"desktop",i,s);default:return!0}}catch(t){return!1}})}evaluateStringCondition(t,e,i){switch(e){case"equals":return t===i;case"not_equals":return t!==i;case"contains":return t.includes(i);case"not_contains":return!t.includes(i);case"starts_with":return t.startsWith(i);case"ends_with":return t.endsWith(i);case"matches_regex":try{return new RegExp(i).test(t)}catch(t){return!1}default:return!1}}loadScript(t){try{switch(t.type){case"inline":this.loadInlineScript(t);break;case"external":this.loadExternalScript(t);break;case"pixel":this.loadPixel(t)}this.loadedScripts.add(t.id),"once_per_session"===t.frequency&&(this.sessionLoadedScripts.add(t.id),n.set("dl_session_scripts",Array.from(this.sessionLoadedScripts))),this.log("Loaded script:",t.name)}catch(e){this.log("Error loading script:",t.name,e)}}loadInlineScript(t){const e=document.createElement("iframe");e.style.display="none",e.setAttribute("sandbox","allow-scripts"),e.dataset.datalyrScript=t.id,this.sandboxedIframes.push(e);const i=`\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset="UTF-8">\n </head>\n <body>\n <script>\n // User-provided script runs here in isolation\n try {\n ${t.content}\n } catch (error) {\n console.error('[Datalyr Container] Script execution error:', error);\n }\n\n // FIXED (ISSUE-02): Signal completion for cleanup\n // Scripts have 5 seconds to execute before iframe is removed\n setTimeout(function() {\n try {\n parent.postMessage({ type: 'datalyr_script_complete', scriptId: '${t.id}' }, '*');\n } catch (e) {\n // Ignore postMessage errors from sandbox\n }\n }, 5000);\n <\/script>\n </body>\n </html>\n `;document.body.appendChild(e),e.contentDocument&&(e.contentDocument.open(),e.contentDocument.write(i),e.contentDocument.close());const s=window.setTimeout(()=>{this.cleanupIframe(e)},3e4);this.iframeCleanupTimeouts.set(e,s),this.log("Loaded inline script in sandbox:",t.id)}cleanupIframe(t){try{const e=this.iframeCleanupTimeouts.get(t);e&&(clearTimeout(e),this.iframeCleanupTimeouts.delete(t));const i=this.sandboxedIframes.indexOf(t);i>-1&&this.sandboxedIframes.splice(i,1),t.parentNode&&(t.parentNode.removeChild(t),this.log("Cleaned up sandboxed iframe:",t.dataset.datalyrScript))}catch(t){this.log("Error cleaning up iframe:",t)}}cleanupAllIframes(){const t=[...this.sandboxedIframes];t.forEach(t=>this.cleanupIframe(t)),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.iframeCleanupTimeouts.forEach(t=>clearTimeout(t)),this.iframeCleanupTimeouts.clear(),this.log(`Cleaned up ${t.length} sandboxed iframes`)}loadExternalScript(t){var e;if(!this.isValidScriptUrl(t.content))return void this.log("Blocked invalid script URL:",t.content);if(!(null===(e=t.settings)||void 0===e?void 0:e.integrity))return void console.error(`[Datalyr Container] SECURITY: External script "${t.id}" blocked - missing SRI hash.\nAll external scripts MUST include an integrity hash to prevent CDN compromise attacks.\nGenerate SRI hash at: https://www.srihash.org/\nExample: { integrity: "sha384-..." }`);const i=document.createElement("script");i.src=t.content,i.dataset.datalyrScript=t.id,t.settings?(i.integrity=t.settings.integrity,i.crossOrigin=t.settings.crossorigin||"anonymous",!1!==t.settings.async&&(i.async=!0),t.settings.defer&&(i.defer=!0)):i.async=!0,document.head.appendChild(i)}loadPixel(t){const e=new Image;e.src=t.content,e.style.display="none",e.dataset.datalyrPixel=t.id,document.body.appendChild(e)}initializePixels(){var t,e,i;this.pixels&&((null===(t=this.pixels.meta)||void 0===t?void 0:t.enabled)&&this.pixels.meta.pixel_id&&this.initializeMetaPixel(this.pixels.meta),(null===(e=this.pixels.google)||void 0===e?void 0:e.enabled)&&this.pixels.google.tag_id&&this.initializeGoogleTag(this.pixels.google),(null===(i=this.pixels.tiktok)||void 0===i?void 0:i.enabled)&&this.pixels.tiktok.pixel_id&&this.initializeTikTokPixel(this.pixels.tiktok))}initializeMetaPixel(t){try{e=window,i=document,s="script",e.fbq||(n=e.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)},e._fbq||(e._fbq=n),n.push=n,n.loaded=!0,n.version="2.0",n.queue=[],(o=i.createElement(s)).async=!0,o.src="https://connect.facebook.net/en_US/fbevents.js",(r=i.getElementsByTagName(s)[0]).parentNode.insertBefore(o,r)),window.fbq("init",t.pixel_id),window.fbq("track","PageView"),this.log("Meta Pixel initialized:",t.pixel_id)}catch(t){this.log("Error initializing Meta Pixel:",t)}var e,i,s,n,o,r}initializeGoogleTag(t){try{const e=document.createElement("script");function i(...t){window.dataLayer.push(t)}e.async=!0,e.src=`https://www.googletagmanager.com/gtag/js?id=${t.tag_id}`,document.head.appendChild(e),window.dataLayer=window.dataLayer||[],window.gtag=i,i("js",new Date),i("config",t.tag_id,{allow_enhanced_conversions:!1!==t.enhanced_conversions}),this.log("Google Tag initialized:",t.tag_id)}catch(s){this.log("Error initializing Google Tag:",s)}}initializeTikTokPixel(t){try{!function(t,e,i){t.TiktokAnalyticsObject=i;var s=t[i]=t[i]||[];s.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"],s.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var n=0;n<s.methods.length;n++)s.setAndDefer(s,s.methods[n]);s.instance=function(t){for(var e=s._i[t]||[],i=0;i<s.methods.length;i++)s.setAndDefer(e,s.methods[i]);return e},s.load=function(t,e){var n;s._i=s._i||{},s._i[t]=[],s._o=s._o||{},s._o[t]=e||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src="https://analytics.tiktok.com/i18n/pixel/events.js?sdkid="+t+"&lib="+i;var r=document.getElementsByTagName("script")[0];null===(n=r.parentNode)||void 0===n||n.insertBefore(o,r)}}(window,document,"ttq"),window.ttq.load(t.pixel_id),window.ttq.page(),this.log("TikTok Pixel initialized:",t.pixel_id)}catch(t){this.log("Error initializing TikTok Pixel:",t)}}trackToPixels(t,e={}){var i,s,n,o,r,a;const c=this.sanitizeEventName(t),l=this.sanitizeProperties(e);if((null===(s=null===(i=this.pixels)||void 0===i?void 0:i.meta)||void 0===s?void 0:s.enabled)&&window.fbq)try{window.fbq("track",c,l)}catch(t){this.log("Error tracking Meta Pixel event:",t)}if((null===(o=null===(n=this.pixels)||void 0===n?void 0:n.google)||void 0===o?void 0:o.enabled)&&window.gtag)try{window.gtag("event",c,l)}catch(t){this.log("Error tracking Google Tag event:",t)}if((null===(a=null===(r=this.pixels)||void 0===r?void 0:r.tiktok)||void 0===a?void 0:a.enabled)&&window.ttq)try{const t={Purchase:"CompletePayment",AddToCart:"AddToCart",InitiateCheckout:"InitiateCheckout",ViewContent:"ViewContent",Search:"Search",Lead:"SubmitForm"}[c]||c;window.ttq.track(t,l)}catch(t){this.log("Error tracking TikTok Pixel event:",t)}}triggerCustomScript(t){const e=this.scripts.find(e=>e.id===t&&"custom"===e.trigger);e&&this.shouldLoadScript(e)&&this.loadScript(e)}getLoadedScripts(){return Array.from(this.loadedScripts)}isValidScriptUrl(t){try{const e=new URL(t);return!("https:"!==e.protocol&&!e.hostname.includes("localhost"))&&!["data:","javascript:","file:"].includes(e.protocol)}catch(t){return!1}}sanitizeEventName(t){return"string"!=typeof t?"unknown_event":t.replace(/[^a-zA-Z0-9_$ ]/g,"").substring(0,100)}sanitizeProperties(t){if(null==t)return{};if("object"!=typeof t)return this.sanitizeValue(t);if(Array.isArray(t))return t.map(t=>this.sanitizeValue(t));const e={};for(const[i,s]of Object.entries(t)){const t=i.replace(/[^a-zA-Z0-9_]/g,"").substring(0,100);t&&(e[t]=this.sanitizeValue(s))}return e}sanitizeValue(t){return null==t?t:"string"==typeof t?t.replace(/<script[^>]*>.*?<\/script>/gi,"").replace(/<[^>]+>/g,"").replace(/javascript:/gi,"").replace(/on\w+\s*=/gi,"").substring(0,1e3):"number"==typeof t||"boolean"==typeof t?t:"object"==typeof t?this.sanitizeProperties(t):String(t).substring(0,1e3)}log(...t){this.debug&&console.log("[Datalyr Container]",...t)}}class w{constructor(t={}){this.formListeners=[],this.lastIdentifyTime=0,this.RATE_LIMIT_MS=5e3,this.config={enabled:!1!==t.enabled,captureFromForms:!1!==t.captureFromForms,captureFromAPI:!1!==t.captureFromAPI,captureFromShopify:!1!==t.captureFromShopify,trustedDomains:t.trustedDomains||[],debug:t.debug||!1}}initialize(t){if(!this.config.enabled)return void this.log("Auto-identify disabled");this.identifyCallback=t;const e=n.get("dl_auto_identified_email");e?this.log("User already auto-identified:",e):(this.config.captureFromForms&&this.setupFormMonitoring(),this.config.captureFromAPI&&(this.setupFetchInterception(),this.setupXHRInterception()),this.config.captureFromShopify&&this.setupShopifyMonitoring(),this.log("Auto-identify initialized"))}setupFormMonitoring(){this.scanForEmailForms();new MutationObserver(()=>{this.scanForEmailForms()}).observe(document.body,{childList:!0,subtree:!0}),this.log("Form monitoring active")}scanForEmailForms(){document.querySelectorAll("form").forEach(t=>{if(this.formListeners.some(e=>e.element===t))return;if(t.querySelector('input[type="email"], input[name*="email" i], input[id*="email" i]')){const e=e=>this.handleFormSubmit(e,t);t.addEventListener("submit",e),this.formListeners.push({element:t,handler:e}),this.log("Monitoring form:",t)}})}handleFormSubmit(t,e){try{const t=e.querySelector('input[type="email"], input[name*="email" i], input[id*="email" i]');if(!t)return;const i=t.value.trim();this.isValidEmail(i)&&(this.log("Email captured from form:",i),this.triggerIdentify(i,"form"))}catch(t){this.log("Error handling form submit:",t)}}setupFetchInterception(){if("function"!=typeof window.fetch)return;this.originalFetch=window.fetch;const e=this;window.fetch=function(i,s){return t(this,void 0,void 0,function*(){const n="string"==typeof i?i:i instanceof URL?i.href:i.url;if(!e.isTrustedDomain(n))return e.originalFetch.call(window,i,s);try{(null==s?void 0:s.body)&&e.extractEmailFromData(s.body,"api-request");const n=e.originalFetch.call(window,i,s);return n.then(i=>t(this,void 0,void 0,function*(){var t;if(i.ok&&(null===(t=i.headers.get("content-type"))||void 0===t?void 0:t.includes("application/json")))try{const t=i.clone(),s=yield t.json();e.extractEmailFromData(s,"api-response")}catch(t){}})).catch(()=>{}),n}catch(t){return e.log("Error intercepting fetch:",t),e.originalFetch.call(window,i,s)}})},this.log("Fetch interception active")}setupXHRInterception(){if("undefined"==typeof XMLHttpRequest)return;const t=this;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.open=function(e,i,...s){return this._datalyrUrl="string"==typeof i?i:i.href,t.originalXHROpen.apply(this,[e,i,...s])},XMLHttpRequest.prototype.send=function(e){const i=this._datalyrUrl;return i&&t.isTrustedDomain(i)&&(e&&t.extractEmailFromData(e,"api-request"),this.addEventListener("load",function(){if(this.status>=200&&this.status<300)try{const e=this.getResponseHeader("content-type");if(null==e?void 0:e.includes("application/json")){const e=JSON.parse(this.responseText);t.extractEmailFromData(e,"api-response")}}catch(t){}})),t.originalXHRSend.call(this,e)},this.log("XHR interception active")}setupShopifyMonitoring(){this.isShopify()&&(this.log("Shopify detected, setting up monitoring"),this.checkShopifyCustomer(),this.shopifyCheckInterval=setInterval(()=>{this.checkShopifyCustomer()},1e4),this.log("Shopify monitoring active"))}isShopify(){return!!(window.Shopify||document.querySelector('meta[name="shopify-checkout-api-token"]')||window.location.hostname.includes(".myshopify.com"))}checkShopifyCustomer(){return t(this,void 0,void 0,function*(){var t;try{const e=yield fetch("/account.json",{credentials:"same-origin"});if(e.ok){const i=yield e.json();(null===(t=null==i?void 0:i.customer)||void 0===t?void 0:t.email)&&(this.log("Email captured from Shopify:",i.customer.email),this.triggerIdentify(i.customer.email,"shopify"),this.shopifyCheckInterval&&(clearInterval(this.shopifyCheckInterval),this.shopifyCheckInterval=void 0))}}catch(t){this.log("Shopify customer check failed:",t)}})}extractEmailFromData(t,e){try{let i=[];if("string"==typeof t)try{const e=JSON.parse(t);i=this.findEmailsInObject(e)}catch(e){const s=/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,n=t.match(s);n&&(i=n)}else t instanceof FormData?t.forEach(t=>{"string"==typeof t&&this.isValidEmail(t)&&i.push(t)}):"object"==typeof t&&null!==t&&(i=this.findEmailsInObject(t));if(i.length>0){const t=i[0];this.log(`Email found in ${e}:`,t),this.triggerIdentify(t,"api")}}catch(t){this.log("Error extracting email from data:",t)}}findEmailsInObject(t,e=0){if(e>5)return[];const i=[];for(const s in t){if(!t.hasOwnProperty(s))continue;const n=t[s];/email/i.test(s)&&"string"==typeof n&&this.isValidEmail(n)?i.push(n):"object"==typeof n&&null!==n&&i.push(...this.findEmailsInObject(n,e+1))}return i}isTrustedDomain(t){try{const e=new URL(t,window.location.origin);return e.origin===window.location.origin||0!==this.config.trustedDomains.length&&this.config.trustedDomains.some(t=>e.hostname===t||e.hostname.endsWith(`.${t}`))}catch(t){return!1}}isValidEmail(t){if(!t||"string"!=typeof t)return!1;if(!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(t))return!1;return![/test@/i,/example@/i,/demo@/i,/fake@/i,/@test\./i,/@example\./i].some(e=>e.test(t))}triggerIdentify(t,e){const i=Date.now();if(i-this.lastIdentifyTime<this.RATE_LIMIT_MS)return void this.log("Rate limited, skipping identify");n.get("dl_auto_identified_email")!==t?(n.set("dl_auto_identified_email",t),this.lastIdentifyTime=i,this.identifyCallback&&(this.log(`Auto-identifying user: ${t} (source: ${e})`),this.identifyCallback(t,e))):this.log("Already identified with this email")}destroy(){this.originalFetch&&(window.fetch=this.originalFetch,this.originalFetch=void 0),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen,this.originalXHROpen=void 0),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend,this.originalXHRSend=void 0),this.formListeners.forEach(({element:t,handler:e})=>{t.removeEventListener("submit",e)}),this.formListeners=[],this.shopifyCheckInterval&&(clearInterval(this.shopifyCheckInterval),this.shopifyCheckInterval=void 0),this.log("Auto-identify destroyed")}log(...t){this.config.debug&&console.log("[Datalyr Auto-Identify]",...t)}}const b=new class{constructor(){this.superProperties={},this.userProperties={},this.optedOut=!1,this.initialized=!1,this.errors=[],this.MAX_ERRORS=50,this.initializationPromise=null}init(t){if(this.initialized)return void console.warn("[Datalyr] SDK already initialized");if(!t.workspaceId)throw new Error("[Datalyr] workspaceId is required");this.config=Object.assign({endpoint:"https://ingest.datalyr.com",debug:!1,batchSize:10,flushInterval:5e3,flushAt:10,criticalEvents:void 0,highPriorityEvents:void 0,sessionTimeout:36e5,trackSessions:!0,attributionWindow:7776e6,trackedParams:[],respectDoNotTrack:!1,respectGlobalPrivacyControl:!0,privacyMode:"standard",cookieDomain:"auto",cookieExpires:365,secureCookie:"auto",sameSite:"Lax",cookiePrefix:"__dl_",enablePerformanceTracking:!0,enableFingerprinting:!0,maxRetries:5,retryDelay:1e3,maxOfflineQueueSize:100,trackSPA:!0,trackPageViews:!0,fallbackEndpoints:[],plugins:[]},t),this.cookies=new s({domain:this.config.cookieDomain,maxAge:this.config.cookieExpires,sameSite:this.config.sameSite,secure:this.config.secureCookie}),n.migrateFromLegacyPrefix(),this.optedOut="true"===this.cookies.get("__dl_opt_out"),this.identity=new u,this.session=new g(this.config.sessionTimeout),this.attribution=new p({attributionWindow:this.config.attributionWindow,trackedParams:this.config.trackedParams}),this.queue=new y(this.config),this.fingerprint=new v({privacyMode:this.config.privacyMode,enableFingerprinting:this.config.enableFingerprinting});const e=this.session.getSessionId();if(this.identity.setSessionId(e),this.initializeAsync(),this.setupUnloadHandler(),this.config.plugins)for(const t of this.config.plugins)try{t.initialize(this),this.log(`Plugin initialized: ${t.name}`)}catch(e){console.warn(`[Datalyr] Plugin '${t.name}' failed to initialize:`,e),this.trackError(e,{plugin:t.name})}this.initialized=!0,this.log("SDK initialized")}initializeAsync(){return t(this,void 0,void 0,function*(){return this.initializationPromise||(this.initializationPromise=(()=>t(this,void 0,void 0,function*(){try{const t=this.identity.getAnonymousId();yield e.initialize(this.config.workspaceId,t),this.userProperties=yield n.getEncrypted("dl_user_traits",{}),this.log("Encryption initialized, user properties loaded"),this.config.trackSPA&&this.setupSPATracking(),!1!==this.config.enableContainer&&(this.container=new _({workspaceId:this.config.workspaceId,endpoint:this.config.endpoint,debug:this.config.debug}),yield this.container.init().catch(t=>{this.log("Container initialization failed:",t)})),!0===this.config.autoIdentify&&(this.autoIdentify=new w({enabled:!0,captureFromForms:this.config.autoIdentifyForms,captureFromAPI:this.config.autoIdentifyAPI,captureFromShopify:this.config.autoIdentifyShopify,trustedDomains:this.config.autoIdentifyTrustedDomains,debug:this.config.debug}),this.autoIdentify.initialize((t,e)=>{this.log(`Auto-identified user: ${t} from ${e}`),this.track("$auto_identify",{email:t,source:e,timestamp:Date.now()}),this.identify(t,{email:t})})),this.config.trackPageViews&&this.page(),this.log("Async initialization complete")}catch(t){console.error("[Datalyr] Async initialization failed:",t),this.userProperties=n.get("dl_user_traits",{})}}))()),this.initializationPromise})}ready(){return t(this,void 0,void 0,function*(){if(!this.initialized)throw new Error("[Datalyr] SDK not initialized. Call init() first.");return this.initializationPromise||Promise.resolve()})}track(t,e={}){if(this.initialized){if(this.shouldTrack())try{this.session.updateActivity(t);const i=this.createEventPayload(t,e);if(this.queue.enqueue(i),this.container&&this.container.trackToPixels(t,e),this.config.plugins)for(const i of this.config.plugins)if(i.track)try{i.track(t,e)}catch(e){this.trackError(e,{plugin:i.name,event:t})}this.log("Event tracked:",t)}catch(e){this.trackError(e,{event:t})}}else console.warn("[Datalyr] SDK not initialized. Call init() first.")}identify(t,e={}){if(this.initialized){if(this.shouldTrack())if(t)try{this.session&&this.session.rotateSessionId();const i=this.identity.identify(t,e);if(this.userProperties=Object.assign(Object.assign({},this.userProperties),e),n.setEncrypted("dl_user_traits",this.userProperties).catch(t=>{console.error("[Datalyr] Failed to encrypt user traits - NOT storing unencrypted PII:",t),console.error("[Datalyr] User traits will only persist in memory until page reload")}),this.track("$identify",Object.assign(Object.assign({},i),{traits:e})),this.config.plugins)for(const i of this.config.plugins)if(i.identify)try{i.identify(t,e)}catch(t){this.trackError(t,{plugin:i.name})}this.log("User identified:",t)}catch(e){this.trackError(e,{userId:t})}else console.warn("[Datalyr] identify() called without userId")}else console.warn("[Datalyr] SDK not initialized. Call init() first.")}page(t={}){if(!this.initialized)return void console.warn("[Datalyr] SDK not initialized. Call init() first.");if(!this.shouldTrack())return;const e=Object.assign({title:document.title,url:window.location.href,path:window.location.pathname,search:window.location.search,referrer:document.referrer},t),i=function(){const t=document.referrer;if(!t)return{};try{const e=new URL(t);return{referrer:t,referrer_host:e.hostname,referrer_path:e.pathname,referrer_search:e.search,referrer_source:d(e.hostname)}}catch(e){return{referrer:t}}}();if(Object.assign(e,i),this.config.enablePerformanceTracking){const t=this.getPerformanceMetrics();t&&(e.performance=t)}if(this.track("pageview",e),this.config.plugins)for(const t of this.config.plugins)if(t.page)try{t.page(e)}catch(e){this.trackError(e,{plugin:t.name})}}screen(t,e={}){this.track("screen_view",Object.assign({screen_name:t},e))}group(t,e={}){this.initialized?this.track("$group",{group_id:t,traits:e}):console.warn("[Datalyr] SDK not initialized. Call init() first.")}alias(t,e){if(!this.initialized)return void console.warn("[Datalyr] SDK not initialized. Call init() first.");const i=this.identity.alias(t,e);this.track("$alias",i)}reset(){this.initialized?(this.identity.reset(),this.userProperties={},n.remove("dl_user_traits"),this.session.createNewSession(),this.log("User reset")):console.warn("[Datalyr] SDK not initialized. Call init() first.")}getAnonymousId(){return this.identity.getAnonymousId()}getUserId(){return this.identity.getUserId()}getDistinctId(){return this.identity.getDistinctId()}getSessionId(){return this.session.getSessionId()}startNewSession(){const t=this.session.createNewSession();return this.identity.setSessionId(t),t}getSessionData(){return this.session.getSessionData()}getAttribution(){return this.attribution.captureAttribution()}getJourney(){return this.attribution.getJourney()}setAttribution(t){const e=this.attribution.captureAttribution(),i=Object.assign(Object.assign({},e),t);this.session.storeAttribution(i)}optOut(){this.initialized?(this.optedOut=!0,this.cookies.set("__dl_opt_out","true",this.config.cookieExpires),this.queue.clear(),this.log("User opted out")):console.warn("[Datalyr] SDK not initialized. Call init() first.")}optIn(){this.initialized?(this.optedOut=!1,this.cookies.set("__dl_opt_out","false",this.config.cookieExpires),this.log("User opted in")):console.warn("[Datalyr] SDK not initialized. Call init() first.")}isOptedOut(){return this.optedOut}setConsent(t){n.set("dl_consent",t),this.log("Consent updated:",t)}flush(){return t(this,void 0,void 0,function*(){yield this.queue.flush()})}setSuperProperties(t){this.superProperties=Object.assign(Object.assign({},this.superProperties),t),this.log("Super properties set:",t)}unsetSuperProperty(t){delete this.superProperties[t],this.log("Super property unset:",t)}getSuperProperties(){return Object.assign({},this.superProperties)}createEventPayload(t,e){const i=c(e),s=l({},this.superProperties,i),n=this.attribution.getAttributionData();Object.assign(s,n);const o=this.session.getMetrics();if(Object.assign(s,o),this.config.enableFingerprinting){const t=this.fingerprint.collect();Object.assign(s,{device_fingerprint:t})}Object.assign(s,{url:window.location.href,path:window.location.pathname,referrer:document.referrer,title:document.title,screen_width:screen.width,screen_height:screen.height,viewport_width:window.innerWidth,viewport_height:window.innerHeight});const a=this.identity.getIdentityFields(),h=r(),d=a.distinct_id,u=a.anonymous_id,g=a.visitor_id||u,p=a.session_id;return{workspace_id:this.config.workspaceId,event_id:h,event_name:t,event_data:s,source:"web",timestamp:(new Date).toISOString(),distinct_id:d,anonymous_id:u,visitor_id:g,user_id:a.user_id,canonical_id:a.canonical_id,session_id:p,resolution_method:"browser_sdk",resolution_confidence:1,sdk_version:"1.2.1",sdk_name:"datalyr-web-sdk"}}shouldTrack(){return!this.optedOut&&((!this.config.respectDoNotTrack||"1"!==navigator.doNotTrack&&"1"!==window.doNotTrack&&"yes"!==navigator.doNotTrack)&&(!this.config.respectGlobalPrivacyControl||!0!==navigator.globalPrivacyControl&&!0!==window.globalPrivacyControl))}setupSPATracking(){this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;const t=this;history.pushState=function(...e){t.originalPushState.apply(history,e),setTimeout(()=>{t.attribution.clearCache(),t.page()},0)},history.replaceState=function(...e){t.originalReplaceState.apply(history,e),setTimeout(()=>{t.attribution.clearCache(),t.page()},0)},this.popstateHandler=()=>{setTimeout(()=>{t.attribution.clearCache(),t.page()},0)},window.addEventListener("popstate",this.popstateHandler),this.hashchangeHandler=()=>{t.attribution.clearCache(),t.page()},window.addEventListener("hashchange",this.hashchangeHandler)}setupUnloadHandler(){const t=()=>{this.queue.forceFlush()};window.addEventListener("beforeunload",t),window.addEventListener("pagehide",t),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&t()})}getPerformanceMetrics(){if(!this.config.enablePerformanceTracking)return null;const t={};try{if(performance&&"function"==typeof performance.getEntriesByType){const e=performance.getEntriesByType("navigation"),i=e&&e[0];i&&(t.pageLoadTime=Math.round(i.loadEventEnd),t.domReadyTime=Math.round(i.domContentLoadedEventEnd),t.firstByteTime=Math.round(i.responseStart),t.dnsTime=Math.round(i.domainLookupEnd-i.domainLookupStart),t.tcpTime=Math.round(i.connectEnd-i.connectStart),t.requestTime=Math.round(i.responseEnd-i.requestStart),t.timeOnPage=Math.round(performance.now()))}}catch(t){this.trackError(t,{context:"performance_metrics"})}return Object.keys(t).length>0?t:null}trackError(t,e){const i={message:t.message||String(t),stack:t.stack,context:e,timestamp:(new Date).toISOString(),url:window.location.href};this.errors.push(i),this.errors.length>this.MAX_ERRORS&&(this.errors=this.errors.slice(-this.MAX_ERRORS)),this.config.debug&&console.error("[Datalyr Error]",i)}getErrors(){return[...this.errors]}getNetworkStatus(){return this.queue.getNetworkStatus()}loadScript(t){this.container&&this.container.triggerCustomScript(t)}getLoadedScripts(){return this.container?this.container.getLoadedScripts():[]}log(...t){this.config.debug&&console.log("[Datalyr]",...t)}destroy(){this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.popstateHandler&&window.removeEventListener("popstate",this.popstateHandler),this.hashchangeHandler&&window.removeEventListener("hashchange",this.hashchangeHandler),this.queue&&this.queue.destroy(),this.session&&this.session.destroy(),this.container&&this.container.cleanupAllIframes(),this.autoIdentify&&this.autoIdentify.destroy(),e.destroy(),this.superProperties={},this.userProperties={},this.errors=[],this.initialized=!1,this.log("SDK destroyed")}};return"undefined"!=typeof window&&(window.datalyr=b),b}();
2
2
  //# sourceMappingURL=datalyr.min.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalyr/web",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Datalyr Web SDK - Modern attribution tracking for web applications",
5
5
  "main": "dist/datalyr.js",
6
6
  "module": "dist/datalyr.esm.js",