@datalyr/web 1.1.1 → 1.2.0

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.
package/README.md CHANGED
@@ -9,17 +9,17 @@ The official Datalyr Web SDK for browser-based analytics. Track user behavior, m
9
9
 
10
10
  ## Features
11
11
 
12
- - 🚀 **Zero Configuration** - Start tracking with just your workspace ID
13
- - 📦 **Lightweight** - ~15KB minified + gzipped with zero dependencies
14
- - 🔒 **Privacy First** - GDPR compliant with built-in consent management
15
- - 🎯 **Smart Batching** - Optimized network usage with intelligent event queuing
16
- - 📱 **Cross-Platform** - Works on all modern browsers including mobile
17
- - 🔄 **Offline Support** - Events are queued and sent when connection restored
18
- - 🏷️ **Attribution Tracking** - Automatic UTM and click ID capture
19
- - 🔍 **Session Management** - Automatic session tracking with configurable timeout
20
- - 🎨 **TypeScript Support** - Full type definitions included
21
- - 🔌 **Extensible** - Plugin system for custom functionality
22
- - 📦 **Container Scripts** - Securely manage third-party pixels and tracking scripts
12
+ - **Zero Configuration** - Start tracking with just your workspace ID
13
+ - **Lightweight** - ~15KB minified + gzipped with zero dependencies
14
+ - **Privacy First** - GDPR compliant with built-in consent management
15
+ - **Smart Batching** - Optimized network usage with intelligent event queuing
16
+ - **Cross-Platform** - Works on all modern browsers including mobile
17
+ - **Offline Support** - Events are queued and sent when connection restored
18
+ - **Attribution Tracking** - Automatic UTM and click ID capture
19
+ - **Session Management** - Automatic session tracking with configurable timeout
20
+ - **TypeScript Support** - Full type definitions included
21
+ - **Extensible** - Plugin system for custom functionality
22
+ - **Container Scripts** - Securely manage third-party pixels and tracking scripts
23
23
 
24
24
  ## Choosing the Right Installation Method
25
25
 
@@ -35,11 +35,11 @@ Datalyr offers two installation methods. Choose based on your needs:
35
35
  ```
36
36
 
37
37
  **Pros:**
38
- - Zero bundle size (external script)
39
- - No npm install needed
40
- - Works in any HTML page
41
- - Automatic initialization
42
- - Perfect for Next.js, React, Vue
38
+ - Zero bundle size (external script)
39
+ - No npm install needed
40
+ - Works in any HTML page
41
+ - Automatic initialization
42
+ - Perfect for Next.js, React, Vue
43
43
 
44
44
  **API Usage:**
45
45
  ```javascript
@@ -62,10 +62,10 @@ npm install @datalyr/web
62
62
  ```
63
63
 
64
64
  **Pros:**
65
- - Full TypeScript definitions
66
- - ES module imports
67
- - Tree-shaking support
68
- - Better IDE autocomplete
65
+ - Full TypeScript definitions
66
+ - ES module imports
67
+ - Tree-shaking support
68
+ - Better IDE autocomplete
69
69
 
70
70
  **API Usage:**
71
71
  ```javascript
@@ -78,12 +78,12 @@ datalyr.identify('user_123', { email: 'user@example.com' })
78
78
 
79
79
  ---
80
80
 
81
- ### ⚠️ Important: Don't Mix Both Methods
81
+ ### Important: Don't Mix Both Methods
82
82
 
83
83
  Choose **one** installation method. Using both can cause conflicts:
84
84
 
85
85
  ```html
86
- <!-- DON'T DO THIS -->
86
+ <!-- DON'T DO THIS -->
87
87
  <script src="https://track.datalyr.com/container.js"></script>
88
88
  <script>
89
89
  import datalyr from '@datalyr/web' // Both methods at once!
@@ -417,11 +417,11 @@ The container manager supports:
417
417
  - **Frequency control**: Once per session, once per page, or always
418
418
 
419
419
  **Security Features:**
420
- - HTTPS-only script loading (except localhost)
421
- - XSS protection with pattern detection
422
- - URL validation and protocol blocking
423
- - CSP nonce support for inline scripts
424
- - Automatic async loading for better performance
420
+ - HTTPS-only script loading (except localhost)
421
+ - XSS protection with pattern detection
422
+ - URL validation and protocol blocking
423
+ - CSP nonce support for inline scripts
424
+ - Automatic async loading for better performance
425
425
 
426
426
  ### Plugins
427
427
 
@@ -554,7 +554,7 @@ export function AnalyticsProvider({ children }) {
554
554
  });
555
555
 
556
556
  // Verify initialization
557
- console.log('Datalyr initialized');
557
+ console.log('Datalyr initialized');
558
558
  console.log('Session ID:', datalyr.getSessionId());
559
559
  console.log('Anonymous ID:', datalyr.getAnonymousId());
560
560
 
@@ -583,7 +583,7 @@ export default function RootLayout({ children }) {
583
583
 
584
584
  ## Authentication & Attribution Tracking
585
585
 
586
- ### ⚠️ Critical: Client-Side Identification for Attribution
586
+ ### Critical: Client-Side Identification for Attribution
587
587
 
588
588
  When implementing authentication flows (login, signup, OAuth), you **MUST** call identify on the client-side (browser) to preserve attribution data. Server-side identification creates new sessions and loses all attribution context.
589
589
 
@@ -1095,4 +1095,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
1095
1095
 
1096
1096
  ---
1097
1097
 
1098
- Built with ❤️ by the Datalyr team
1098
+ Built by the Datalyr team
@@ -1,7 +1,7 @@
1
1
  /**
2
- * @datalyr/web v1.1.1
2
+ * @datalyr/web v1.2.0
3
3
  * Datalyr Web SDK - Modern attribution tracking for web applications
4
- * (c) 2025 Datalyr Inc.
4
+ * (c) 2026 Datalyr Inc.
5
5
  * Released under the MIT License
6
6
  */
7
7
  'use strict';
@@ -3829,7 +3829,7 @@ class Datalyr {
3829
3829
  resolution_method: 'browser_sdk',
3830
3830
  resolution_confidence: 1.0,
3831
3831
  // SDK metadata
3832
- sdk_version: '1.1.1',
3832
+ sdk_version: '1.2.0',
3833
3833
  sdk_name: 'datalyr-web-sdk'
3834
3834
  };
3835
3835
  return payload;
@@ -1,7 +1,7 @@
1
1
  /**
2
- * @datalyr/web v1.1.1
2
+ * @datalyr/web v1.2.0
3
3
  * Datalyr Web SDK - Modern attribution tracking for web applications
4
- * (c) 2025 Datalyr Inc.
4
+ * (c) 2026 Datalyr Inc.
5
5
  * Released under the MIT License
6
6
  */
7
7
  /******************************************************************************
@@ -3827,7 +3827,7 @@ class Datalyr {
3827
3827
  resolution_method: 'browser_sdk',
3828
3828
  resolution_confidence: 1.0,
3829
3829
  // SDK metadata
3830
- sdk_version: '1.1.1',
3830
+ sdk_version: '1.2.0',
3831
3831
  sdk_name: 'datalyr-web-sdk'
3832
3832
  };
3833
3833
  return payload;
@@ -1,2 +1,2 @@
1
- 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.1.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")}};"undefined"!=typeof window&&(window.datalyr=b);export{b as default};
1
+ 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")}};"undefined"!=typeof window&&(window.datalyr=b);export{b as default};
2
2
  //# sourceMappingURL=datalyr.esm.min.js.map
package/dist/datalyr.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * @datalyr/web v1.1.1
2
+ * @datalyr/web v1.2.0
3
3
  * Datalyr Web SDK - Modern attribution tracking for web applications
4
- * (c) 2025 Datalyr Inc.
4
+ * (c) 2026 Datalyr Inc.
5
5
  * Released under the MIT License
6
6
  */
7
7
  var Datalyr = (function () {
@@ -3830,7 +3830,7 @@ var Datalyr = (function () {
3830
3830
  resolution_method: 'browser_sdk',
3831
3831
  resolution_confidence: 1.0,
3832
3832
  // SDK metadata
3833
- sdk_version: '1.1.1',
3833
+ sdk_version: '1.2.0',
3834
3834
  sdk_name: 'datalyr-web-sdk'
3835
3835
  };
3836
3836
  return payload;
@@ -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.1.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}();
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}();
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.1.1",
3
+ "version": "1.2.0",
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",