@grainql/analytics-web 2.7.1 → 2.9.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 +36 -3
- package/dist/cjs/consent.d.ts +38 -7
- package/dist/cjs/consent.d.ts.map +1 -1
- package/dist/cjs/consent.js +82 -23
- package/dist/cjs/consent.js.map +1 -1
- package/dist/cjs/debug-agent.d.ts +171 -0
- package/dist/cjs/debug-agent.d.ts.map +1 -0
- package/dist/cjs/debug-agent.js +1219 -0
- package/dist/cjs/debug-agent.js.map +1 -0
- package/dist/cjs/id-manager.d.ts +66 -0
- package/dist/cjs/id-manager.d.ts.map +1 -0
- package/dist/cjs/id-manager.js +212 -0
- package/dist/cjs/id-manager.js.map +1 -0
- package/dist/cjs/index.d.ts +26 -8
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interaction-tracking.d.ts +6 -0
- package/dist/cjs/interaction-tracking.d.ts.map +1 -1
- package/dist/cjs/interaction-tracking.js +55 -5
- package/dist/cjs/interaction-tracking.js.map +1 -1
- package/dist/cjs/page-tracking.d.ts +6 -0
- package/dist/cjs/page-tracking.d.ts.map +1 -1
- package/dist/cjs/page-tracking.js +23 -2
- package/dist/cjs/page-tracking.js.map +1 -1
- package/dist/cjs/react/hooks/useConsent.d.ts +18 -2
- package/dist/cjs/react/hooks/useConsent.d.ts.map +1 -1
- package/dist/cjs/react/hooks/useConsent.js +52 -1
- package/dist/cjs/react/hooks/useConsent.js.map +1 -1
- package/dist/consent.d.ts +38 -7
- package/dist/consent.d.ts.map +1 -1
- package/dist/consent.js +82 -23
- package/dist/debug-agent.d.ts +171 -0
- package/dist/debug-agent.d.ts.map +1 -0
- package/dist/debug-agent.js +1219 -0
- package/dist/esm/consent.d.ts +38 -7
- package/dist/esm/consent.d.ts.map +1 -1
- package/dist/esm/consent.js +82 -23
- package/dist/esm/consent.js.map +1 -1
- package/dist/esm/debug-agent.d.ts +171 -0
- package/dist/esm/debug-agent.d.ts.map +1 -0
- package/dist/esm/debug-agent.js +1215 -0
- package/dist/esm/debug-agent.js.map +1 -0
- package/dist/esm/id-manager.d.ts +66 -0
- package/dist/esm/id-manager.d.ts.map +1 -0
- package/dist/esm/id-manager.js +208 -0
- package/dist/esm/id-manager.js.map +1 -0
- package/dist/esm/index.d.ts +26 -8
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interaction-tracking.d.ts +6 -0
- package/dist/esm/interaction-tracking.d.ts.map +1 -1
- package/dist/esm/interaction-tracking.js +55 -5
- package/dist/esm/interaction-tracking.js.map +1 -1
- package/dist/esm/page-tracking.d.ts +6 -0
- package/dist/esm/page-tracking.d.ts.map +1 -1
- package/dist/esm/page-tracking.js +23 -2
- package/dist/esm/page-tracking.js.map +1 -1
- package/dist/esm/react/hooks/useConsent.d.ts +18 -2
- package/dist/esm/react/hooks/useConsent.d.ts.map +1 -1
- package/dist/esm/react/hooks/useConsent.js +49 -1
- package/dist/esm/react/hooks/useConsent.js.map +1 -1
- package/dist/id-manager.d.ts +66 -0
- package/dist/id-manager.d.ts.map +1 -0
- package/dist/id-manager.js +212 -0
- package/dist/index.d.ts +26 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +1635 -86
- package/dist/index.global.dev.js.map +4 -4
- package/dist/index.global.js +506 -2
- package/dist/index.global.js.map +4 -4
- package/dist/index.js +171 -44
- package/dist/index.mjs +172 -45
- package/dist/interaction-tracking.d.ts +6 -0
- package/dist/interaction-tracking.d.ts.map +1 -1
- package/dist/interaction-tracking.js +55 -5
- package/dist/page-tracking.d.ts +6 -0
- package/dist/page-tracking.d.ts.map +1 -1
- package/dist/page-tracking.js +23 -2
- package/dist/react/hooks/useConsent.d.ts +18 -2
- package/dist/react/hooks/useConsent.d.ts.map +1 -1
- package/dist/react/hooks/useConsent.js +52 -1
- package/dist/react/hooks/useConsent.mjs +49 -1
- package/package.json +1 -1
package/dist/index.global.js
CHANGED
|
@@ -1,3 +1,507 @@
|
|
|
1
|
-
/* Grain Analytics Web SDK v2.
|
|
2
|
-
"use strict";var Grain=(()=>{var _=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var A=(s,e)=>()=>(s&&(e=s(s=0)),e);var S=(s,e)=>{for(var t in e)_(s,t,{get:e[t],enumerable:!0})},ne=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ie(e))!re.call(s,r)&&r!==t&&_(s,r,{get:()=>e[r],enumerable:!(i=te(e,r))||i.enumerable});return s};var ae=s=>ne(_({},"__esModule",{value:!0}),s);var ge,m,x=A(()=>{"use strict";ge={maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4},m=class{constructor(e,t={}){this.isDestroyed=!1;this.isPageVisible=!0;this.visibilityChangeHandler=null;this.sectionStates=new Map;this.lastFilterReason=null;this.activityDetector=e,this.options={...ge,...t,debug:t.debug??!1},this.setupPageVisibilityTracking()}setupPageVisibilityTracking(){typeof document>"u"||(this.isPageVisible=document.visibilityState==="visible",this.visibilityChangeHandler=()=>{let e=this.isPageVisible;this.isPageVisible=document.visibilityState==="visible",!this.isPageVisible&&e?this.log("Page hidden - tracking paused"):this.isPageVisible&&!e&&(this.log("Page visible - tracking resumed"),this.resetAllSections())},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}shouldTrack(){return this.isPageVisible?this.activityDetector.isActive(this.options.idleThreshold)?(this.lastFilterReason=null,!0):(this.lastFilterReason="user_idle",!1):(this.lastFilterReason="page_hidden",!1)}shouldTrackSection(e,t){if(!this.shouldTrack())return{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"};let i=this.sectionStates.get(e);i||(i={sectionName:e,currentDuration:0,lastScrollPosition:t,lastResetTime:Date.now()},this.sectionStates.set(e,i));let r=Math.abs(t-i.lastScrollPosition);return r>=this.options.minScrollDistance?(this.log(`Section "${e}": Attention reset due to ${Math.round(r)}px scroll`),i.currentDuration=0,i.lastScrollPosition=t,i.lastResetTime=Date.now(),{shouldTrack:!0,resetAttention:!0}):i.currentDuration>=this.options.maxSectionDuration?{shouldTrack:!1,reason:"max_duration_reached"}:{shouldTrack:!0}}updateSectionDuration(e,t){let i=this.sectionStates.get(e);i&&(i.currentDuration+=t,i.currentDuration>=this.options.maxSectionDuration&&this.log(`Section "${e}": Max duration cap reached (${i.currentDuration}ms)`))}resetSection(e){let t=this.sectionStates.get(e);t&&(this.log(`Section "${e}": Attention reset (section exit)`),t.currentDuration=0,t.lastResetTime=Date.now())}resetAllSections(){this.log("Resetting all section attention states");for(let e of this.sectionStates.values())e.currentDuration=0,e.lastResetTime=Date.now()}getSectionState(e){return this.sectionStates.get(e)}getLastFilterReason(){return this.lastFilterReason}shouldTrackScroll(e,t){return this.shouldTrack()?Math.abs(t-e)<10?{shouldTrack:!1,reason:"scroll_too_small"}:{shouldTrack:!0}:{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"}}getPolicies(){return{maxSectionDuration:this.options.maxSectionDuration,minScrollDistance:this.options.minScrollDistance,idleThreshold:this.options.idleThreshold}}getTrackingState(){return{isPageVisible:this.isPageVisible,isUserActive:this.activityDetector.isActive(this.options.idleThreshold),timeSinceLastActivity:this.activityDetector.getTimeSinceLastActivity(),activeSections:this.sectionStates.size}}log(...e){this.options.debug&&console.log("[AttentionQuality]",...e)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.sectionStates.clear())}}});function me(s){if(s)return s.replace(/[\u{1F300}-\u{1F9FF}]/gu,"").replace(/[\u{1F600}-\u{1F64F}]/gu,"").replace(/[\u{1F680}-\u{1F6FF}]/gu,"").replace(/[\u{2600}-\u{26FF}]/gu,"").replace(/[\u{2700}-\u{27BF}]/gu,"").replace(/[\u{1F900}-\u{1F9FF}]/gu,"").replace(/[\u{1F1E0}-\u{1F1FF}]/gu,"").replace(/[\u{200D}]/gu,"").replace(/[\u{FE0F}]/gu,"").replace(/[\u{20E3}]/gu,"").trim()}function M(s,e=100){if(!s)return;let t=me(s);if(t)return t.substring(0,e)||void 0}var L=A(()=>{"use strict"});var J={};S(J,{HeatmapTrackingManager:()=>N});var fe,N,j=A(()=>{"use strict";x();L();fe={scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:!1},N=class{constructor(e,t={}){this.isDestroyed=!1;this.currentScrollState=null;this.pendingClicks=[];this.pendingScrolls=[];this.scrollDebounceTimer=null;this.batchTimer=null;this.scrollTrackingTimer=null;this.periodicScrollTimer=null;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.SPLIT_DURATION=3e3;this.tracker=e,this.options={...fe,...t},this.attentionQuality=new m(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing heatmap tracking"),this.setupClickTracking(),this.setupScrollTracking(),this.startScrollTracking(),this.setupUnloadHandler())}setupClickTracking(){if(typeof document>"u")return;let e=t=>{this.isDestroyed||this.tracker.hasConsent("analytics")&&this.handleClick(t)};document.addEventListener("click",e,{passive:!0,capture:!0})}setupScrollTracking(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.handleScroll(),this.scrollDebounceTimer=null},this.options.scrollDebounceDelay)};window.addEventListener("scroll",e,{passive:!0})}startScrollTracking(){typeof window>"u"||(this.updateScrollState(),this.scrollTrackingTimer=window.setInterval(()=>{this.isDestroyed||this.updateScrollState()},500),this.startPeriodicScrollTracking())}startPeriodicScrollTracking(){typeof window>"u"||(this.periodicScrollTimer=window.setInterval(()=>{if(this.isDestroyed||!this.currentScrollState||!this.tracker.hasConsent("analytics"))return;if(!this.attentionQuality.shouldTrack()){this.log("Scroll tracking paused:",this.attentionQuality.getLastFilterReason());return}let e=Date.now(),t=e-this.currentScrollState.entryTime;if(t>1e3){let i=window.scrollY||window.pageYOffset,r=window.innerHeight,a=document.documentElement.scrollHeight,n=`viewport_section_${this.currentScrollState.viewportSection}`,o=this.attentionQuality.shouldTrackSection(n,i);if(o.resetAttention){this.log(`Viewport section ${this.currentScrollState.viewportSection}: Attention reset`),this.currentScrollState.entryTime=e;return}if(!o.shouldTrack){this.log(`Viewport section ${this.currentScrollState.viewportSection}: ${o.reason}`);return}let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:i,durationMs:t,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:a,viewportHeight:r};this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:c.pageUrl,viewport_section:c.viewportSection,scroll_depth_px:c.scrollDepthPx,duration_ms:c.durationMs,entry_timestamp:c.entryTimestamp,exit_timestamp:c.exitTimestamp,page_height:c.pageHeight,viewport_height:c.viewportHeight,is_split:!0},{flush:!0}),this.attentionQuality.updateSectionDuration(n,t),this.currentScrollState.entryTime=e}},this.SPLIT_DURATION))}setupUnloadHandler(){if(typeof window>"u")return;let e=()=>{if(this.currentScrollState){let t=Date.now(),i=t-this.currentScrollState.entryTime;if(i>100){let r={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:i,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:t,pageHeight:document.documentElement.scrollHeight,viewportHeight:window.innerHeight};this.pendingScrolls.push(r)}}this.flushPendingEventsWithBeacon()};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e)}handleClick(e){if(!this.tracker.hasConsent("analytics"))return;let t=e.target;if(!t)return;let i=window.location.href,r=this.generateXPath(t),a=Math.round(e.clientX),n=Math.round(e.clientY),o=Math.round(e.pageX),c=Math.round(e.pageY),u=t.tagName?.toLowerCase()||"unknown",l=M(t.textContent),d={pageUrl:i,xpath:r,viewportX:a,viewportY:n,pageX:o,pageY:c,elementTag:u,elementText:l||void 0,timestamp:Date.now()};t instanceof HTMLAnchorElement&&t.href?this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:d.pageUrl,xpath:d.xpath,viewport_x:d.viewportX,viewport_y:d.viewportY,page_x:d.pageX,page_y:d.pageY,element_tag:d.elementTag,element_text:d.elementText,timestamp:d.timestamp},{flush:!0}):(this.pendingClicks.push(d),this.considerBatchFlush())}handleScroll(){this.tracker.hasConsent("analytics")&&this.updateScrollState()}updateScrollState(){if(typeof window>"u"||!this.tracker.hasConsent("analytics"))return;let e=Date.now(),t=window.scrollY||window.pageYOffset,i=window.innerHeight,r=document.documentElement.scrollHeight,a=Math.floor(t/i);if(this.currentScrollState&&this.currentScrollState.viewportSection!==a){let n=e-this.currentScrollState.entryTime;if(n>100){let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:n,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:r,viewportHeight:i};this.pendingScrolls.push(c)}let o=`viewport_section_${this.currentScrollState.viewportSection}`;this.attentionQuality.resetSection(o)}(!this.currentScrollState||this.currentScrollState.viewportSection!==a)&&(this.currentScrollState={viewportSection:a,entryTime:e,scrollDepthPx:t}),this.lastScrollPosition=t,this.lastScrollTime=e,this.considerBatchFlush()}generateXPath(e){if(!e)return"";if(e.id)return`//*[@id="${e.id}"]`;let t=[],i=e;for(;i&&i.nodeType===Node.ELEMENT_NODE;){let r=0,a=i;for(;a;)a=a.previousElementSibling,a&&a.nodeName===i.nodeName&&r++;let n=i.nodeName.toLowerCase(),o=r>0?`[${r+1}]`:"";t.unshift(`${n}${o}`),i=i.parentElement}return t.length?`/${t.join("/")}`:""}considerBatchFlush(){let e=this.pendingClicks.length+this.pendingScrolls.length;if(e>=this.options.maxBatchSize){this.flushPendingEvents();return}this.batchTimer===null&&e>0&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents(),this.batchTimer=null},this.options.batchDelay))}flushPendingEvents(){if(!this.isDestroyed){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight});this.pendingScrolls=[]}this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null)}}flushPendingEventsWithBeacon(){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp},{flush:!0});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight},{flush:!0});this.pendingScrolls=[]}}log(...e){this.options.debug&&this.tracker.log("[Heatmap Tracking]",...e)}destroy(){this.isDestroyed=!0,this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.scrollTrackingTimer!==null&&(clearInterval(this.scrollTrackingTimer),this.scrollTrackingTimer=null),this.periodicScrollTimer!==null&&(clearInterval(this.periodicScrollTimer),this.periodicScrollTimer=null),this.attentionQuality.destroy(),this.flushPendingEvents()}}});var Y={};S(Y,{InteractionTrackingManager:()=>O});var O,Z=A(()=>{"use strict";L();O=class{constructor(e,t,i={}){this.isDestroyed=!1;this.attachedListeners=new Map;this.xpathCache=new Map;this.mutationObserver=null;this.mutationDebounceTimer=null;this.tracker=e,this.interactions=t,this.config={debug:i.debug??!1,enableMutationObserver:i.enableMutationObserver??!0,mutationDebounceDelay:i.mutationDebounceDelay??500},typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.attachAllListeners()):setTimeout(()=>this.attachAllListeners(),0),this.config.enableMutationObserver&&this.setupMutationObserver())}attachAllListeners(){if(!this.isDestroyed){this.log("Attaching interaction listeners");for(let e of this.interactions)this.attachInteractionListener(e)}}attachInteractionListener(e){if(this.isDestroyed)return;let t=this.findElementByXPath(e.selector);if(!t){this.log("Element not found for interaction:",e.eventName,"selector:",e.selector);return}if(this.attachedListeners.has(t)){this.log("Listeners already attached for element:",t);return}let i=[],r=a=>this.handleInteractionClick(e,a);if(t.addEventListener("click",r,{passive:!0}),i.push({event:"click",handler:r}),t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){let a=n=>this.handleInteractionFocus(e,n);t.addEventListener("focus",a,{passive:!0}),i.push({event:"focus",handler:a})}this.attachedListeners.set(t,i)}handleInteractionClick(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target,r=i instanceof HTMLAnchorElement&&i.href,a={interaction_type:"click",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_text:M(i.textContent),element_id:i.id||void 0,element_class:i.className||void 0,...r&&{href:i.href},timestamp:Date.now()},n=this.tracker.track(e.eventName,a,{flush:!0});n instanceof Promise&&n.catch(o=>{this.log("Failed to track click:",o)})}handleInteractionFocus(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target;this.tracker.track(e.eventName,{interaction_type:"focus",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_id:i.id||void 0,element_class:i.className||void 0,timestamp:Date.now()})}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}setupMutationObserver(){if(typeof MutationObserver>"u"){this.log("MutationObserver not supported");return}this.mutationObserver=new MutationObserver(e=>{this.mutationDebounceTimer!==null&&clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=window.setTimeout(()=>{this.handleMutations(e),this.mutationDebounceTimer=null},this.config.mutationDebounceDelay)}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Mutation observer setup")}handleMutations(e){if(this.isDestroyed)return;this.xpathCache.clear();let t=new Set;for(let i of e)i.removedNodes.forEach(r=>{r instanceof Element&&(t.add(r),this.attachedListeners.forEach((a,n)=>{r.contains(n)&&t.add(n)}))});t.forEach(i=>{this.detachListeners(i)}),this.attachAllListeners()}detachListeners(e){let t=this.attachedListeners.get(e);t&&(t.forEach(({event:i,handler:r})=>{e.removeEventListener(i,r)}),this.attachedListeners.delete(e))}log(...e){this.config.debug&&console.log("[InteractionTracking]",...e)}updateInteractions(e){this.isDestroyed||(this.log("Updating interactions configuration"),this.attachedListeners.forEach((t,i)=>{this.detachListeners(i)}),this.xpathCache.clear(),this.interactions=e,this.attachAllListeners())}destroy(){this.isDestroyed||(this.log("Destroying interaction tracking manager"),this.isDestroyed=!0,this.mutationDebounceTimer!==null&&(clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.attachedListeners.forEach((e,t)=>{this.detachListeners(t)}),this.attachedListeners.clear(),this.xpathCache.clear())}}});var q={};S(q,{SectionTrackingManager:()=>H});var pe,H,X=A(()=>{"use strict";x();pe={minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:!1},H=class{constructor(e,t,i={}){this.isDestroyed=!1;this.sectionStates=new Map;this.intersectionObserver=null;this.xpathCache=new Map;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.scrollVelocity=0;this.scrollDebounceTimer=null;this.pendingEvents=[];this.batchTimer=null;this.sectionTimers=new Map;this.SPLIT_DURATION=3e3;this.tracker=e,this.sections=t,this.options={...pe,...i},this.attentionQuality=new m(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing section tracking"),this.setupIntersectionObserver(),this.setupScrollListener(),this.initializeSections())}setupIntersectionObserver(){if(typeof IntersectionObserver>"u"){this.log("IntersectionObserver not supported");return}this.intersectionObserver=new IntersectionObserver(e=>{e.forEach(t=>{this.handleIntersection(t)})},{threshold:[0,.1,.25,.5,.75,1],rootMargin:"0px"}),this.log("IntersectionObserver created")}setupScrollListener(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.updateScrollVelocity(),this.scrollDebounceTimer=null},this.options.debounceDelay)};window.addEventListener("scroll",e,{passive:!0}),this.log("Scroll listener attached")}initializeSections(){for(let e of this.sections){let t=this.findElementByXPath(e.selector);if(!t){this.log("Section element not found:",e.sectionName,"selector:",e.selector);continue}let i={element:t,config:e,entryTime:null,exitTime:null,isVisible:!1,lastScrollPosition:window.scrollY,lastScrollTime:Date.now(),entryScrollSpeed:0,exitScrollSpeed:0,maxVisibleArea:0};this.sectionStates.set(e.sectionName,i),this.intersectionObserver&&this.intersectionObserver.observe(t)}}handleIntersection(e){if(this.isDestroyed)return;let t=Array.from(this.sectionStates.values()).find(a=>a.element===e.target);if(!t)return;let i=e.isIntersecting&&e.intersectionRatio>=this.options.intersectionThreshold,r=e.intersectionRatio;r>t.maxVisibleArea&&(t.maxVisibleArea=r),i&&!t.isVisible?this.handleSectionEntry(t):!i&&t.isVisible&&this.handleSectionExit(t),t.isVisible=i}handleSectionEntry(e){e.entryTime=Date.now(),e.entryScrollSpeed=this.scrollVelocity,e.lastScrollPosition=window.scrollY,e.lastScrollTime=Date.now(),e.maxVisibleArea=0,this.startPeriodicTracking(e)}startPeriodicTracking(e){this.stopPeriodicTracking(e.config.sectionName);let t=window.setInterval(()=>{if(this.isDestroyed||!e.isVisible||e.entryTime===null){this.stopPeriodicTracking(e.config.sectionName);return}let i=Date.now(),r=i-e.entryTime;if(r>=this.options.minDwellTime){let a=window.scrollY,n=this.attentionQuality.shouldTrackSection(e.config.sectionName,a);if(n.resetAttention){this.log(`Section "${e.config.sectionName}": Attention reset, restarting timer`),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity;return}if(!n.shouldTrack){this.log(`Section "${e.config.sectionName}": Tracking paused - ${n.reason}`);return}let o={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:i,duration:r,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:this.scrollVelocity};this.shouldTrackSection(o)&&(this.tracker.trackSystemEvent("_grain_section_view",{section_name:o.sectionName,section_type:o.sectionType,duration_ms:o.duration,viewport_width:o.viewportWidth,viewport_height:o.viewportHeight,scroll_depth_percent:o.scrollDepth,visible_area_percent:o.visibleAreaPercentage,scroll_speed_entry:Math.round(o.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(o.scrollSpeedAtExit||0),entry_timestamp:o.entryTime,exit_timestamp:o.exitTime,is_split:!0}),this.attentionQuality.updateSectionDuration(e.config.sectionName,r),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity)}},this.SPLIT_DURATION);this.sectionTimers.set(e.config.sectionName,t)}stopPeriodicTracking(e){let t=this.sectionTimers.get(e);t!==void 0&&(clearInterval(t),this.sectionTimers.delete(e))}handleSectionExit(e){if(this.stopPeriodicTracking(e.config.sectionName),this.attentionQuality.resetSection(e.config.sectionName),e.entryTime===null)return;e.exitTime=Date.now(),e.exitScrollSpeed=this.scrollVelocity;let t=e.exitTime-e.entryTime,i={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:e.exitTime,duration:t,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:e.exitScrollSpeed};this.shouldTrackSection(i)?this.queueSectionView(i):this.log("Section view filtered out:",e.config.sectionName,"duration:",t),e.entryTime=null}updateScrollVelocity(){let e=Date.now(),t=window.scrollY,i=e-this.lastScrollTime,r=Math.abs(t-this.lastScrollPosition);i>0&&(this.scrollVelocity=r/i*1e3),this.lastScrollPosition=t,this.lastScrollTime=e}calculateScrollDepth(){if(typeof window>"u"||typeof document>"u")return 0;let e=window.innerHeight,t=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight),i=window.scrollY,r=t-e;return r<=0?100:Math.round(i/r*100)}shouldTrackSection(e){return!(e.duration<this.options.minDwellTime||(e.scrollSpeedAtEntry+e.scrollSpeedAtExit)/2>this.options.scrollVelocityThreshold*2||e.visibleAreaPercentage<10)}queueSectionView(e){this.pendingEvents.push(e),this.batchTimer===null&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents()},this.options.batchDelay))}flushPendingEvents(){if(!(this.isDestroyed||this.pendingEvents.length===0)){if(!this.tracker.hasConsent("analytics")){this.pendingEvents=[];return}for(let e of this.pendingEvents)this.tracker.trackSystemEvent("_grain_section_view",{section_name:e.sectionName,section_type:e.sectionType,duration_ms:e.duration,viewport_width:e.viewportWidth,viewport_height:e.viewportHeight,scroll_depth_percent:e.scrollDepth,visible_area_percent:e.visibleAreaPercentage,scroll_speed_entry:Math.round(e.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(e.scrollSpeedAtExit||0),entry_timestamp:e.entryTime,exit_timestamp:e.exitTime});this.pendingEvents=[],this.batchTimer=null}}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}log(...e){this.options.debug&&console.log("[SectionTracking]",...e)}updateSections(e){this.isDestroyed||(this.log("Updating sections configuration"),this.intersectionObserver&&this.intersectionObserver.disconnect(),this.sectionStates.clear(),this.xpathCache.clear(),this.sections=e,this.setupIntersectionObserver(),this.initializeSections())}destroy(){this.isDestroyed||(this.log("Destroying section tracking manager"),this.isDestroyed=!0,this.sectionTimers.forEach(e=>{clearInterval(e)}),this.sectionTimers.clear(),this.flushPendingEvents(),this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.intersectionObserver&&(this.intersectionObserver.disconnect(),this.intersectionObserver=null),this.attentionQuality.destroy(),this.sectionStates.clear(),this.xpathCache.clear(),this.pendingEvents=[])}}});var ve={};S(ve,{GrainAnalytics:()=>f,categorizeReferrer:()=>h,createGrainAnalytics:()=>ee,default:()=>Ae,getCountry:()=>$,getCountryCodeFromTimezone:()=>k,getState:()=>W,parseUTMParameters:()=>v});var B=["necessary","analytics","functional"],E="1.0.0",T=class{constructor(e,t="opt-out"){this.consentState=null;this.listeners=[];this.consentMode=t,this.storageKey=`grain_consent_${e}`,this.loadConsentState()}loadConsentState(){if(!(typeof window>"u"))try{let e=localStorage.getItem(this.storageKey);if(e){let t=JSON.parse(e);this.consentState={...t,timestamp:new Date(t.timestamp)}}else(this.consentMode==="opt-out"||this.consentMode==="disabled")&&(this.consentState={granted:!0,categories:B,timestamp:new Date,version:E},this.saveConsentState())}catch{}}saveConsentState(){if(!(typeof window>"u"||!this.consentState))try{localStorage.setItem(this.storageKey,JSON.stringify(this.consentState))}catch{}}grantConsent(e){let t=e||B;this.consentState={granted:!0,categories:t,timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}revokeConsent(e){this.consentState?e?this.consentState={...this.consentState,categories:this.consentState.categories.filter(t=>!e.includes(t)),granted:this.consentState.categories.length>0,timestamp:new Date}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}getConsentState(){return this.consentState?{...this.consentState}:null}hasConsent(e){return this.consentMode==="disabled"?!0:this.consentMode==="opt-in"&&!this.consentState||!this.consentState?.granted?!1:e?this.consentState.categories.includes(e):!0}shouldWaitForConsent(){return this.consentMode==="opt-in"&&!this.consentState?.granted}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){this.consentState&&this.listeners.forEach(e=>{try{e(this.consentState)}catch{}})}clearConsent(){if(!(typeof window>"u"))try{localStorage.removeItem(this.storageKey),this.consentState=null}catch{}}};function I(s,e,t){if(typeof document>"u")return;let i=[`${encodeURIComponent(s)}=${encodeURIComponent(e)}`];t?.maxAge!==void 0&&i.push(`max-age=${t.maxAge}`),t?.domain&&i.push(`domain=${t.domain}`),t?.path?i.push(`path=${t.path}`):i.push("path=/"),t?.sameSite&&i.push(`samesite=${t.sameSite}`),t?.secure&&i.push("secure"),document.cookie=i.join("; ")}function D(s){if(typeof document>"u")return null;let e=encodeURIComponent(s)+"=",t=document.cookie.split(";");for(let i=0;i<t.length;i++){let r=t[i];for(;r.charAt(0)===" ";)r=r.substring(1);if(r.indexOf(e)===0)return decodeURIComponent(r.substring(e.length))}return null}function oe(s,e){if(typeof document>"u")return;let t=[`${encodeURIComponent(s)}=`,"max-age=0"];e?.domain&&t.push(`domain=${e.domain}`),e?.path?t.push(`path=${e.path}`):t.push("path=/"),document.cookie=t.join("; ")}function F(){if(typeof document>"u")return!1;try{let s="_grain_cookie_test";I(s,"test",{maxAge:1});let e=D(s)==="test";return oe(s),e}catch{return!1}}var b=class{constructor(){this.activityThreshold=3e4;this.listeners=[];this.isDestroyed=!1;this.activityEvents=["mousemove","mousedown","keydown","scroll","touchstart","click"];this.lastActivityTime=Date.now(),this.boundActivityHandler=this.debounce(this.handleActivity.bind(this),500),this.setupListeners()}setupListeners(){if(!(typeof window>"u"))for(let e of this.activityEvents)window.addEventListener(e,this.boundActivityHandler,{passive:!0})}handleActivity(){this.isDestroyed||(this.lastActivityTime=Date.now(),this.notifyListeners())}debounce(e,t){let i=null;return()=>{i!==null&&clearTimeout(i),i=window.setTimeout(()=>{e(),i=null},t)}}isActive(e){let t=e??this.activityThreshold;return Date.now()-this.lastActivityTime<t}getTimeSinceLastActivity(){return Date.now()-this.lastActivityTime}getLastActivityTime(){return this.lastActivityTime}setActivityThreshold(e){this.activityThreshold=e}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){for(let e of this.listeners)try{e()}catch{}}destroy(){if(!this.isDestroyed){if(typeof window<"u")for(let e of this.activityEvents)window.removeEventListener(e,this.boundActivityHandler);this.listeners=[],this.isDestroyed=!0}}};var C=class{constructor(e,t,i){this.heartbeatTimer=null;this.isDestroyed=!1;this.hasSentPageLoadHeartbeat=!1;this.tracker=e,this.activityDetector=t,this.config=i,this.lastHeartbeatTime=Date.now(),this.currentInterval=i.activeInterval,this.sendPageLoadHeartbeat(),this.scheduleNextHeartbeat()}sendPageLoadHeartbeat(){if(!(this.isDestroyed||this.hasSentPageLoadHeartbeat))if(typeof window<"u"&&document.readyState!=="complete"){let e=()=>{this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0,window.removeEventListener("load",e)};window.addEventListener("load",e)}else this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0}scheduleNextHeartbeat(){if(this.isDestroyed)return;this.heartbeatTimer!==null&&clearTimeout(this.heartbeatTimer);let e=this.activityDetector.isActive(6e4);this.currentInterval=e?this.config.activeInterval:this.config.inactiveInterval,this.heartbeatTimer=window.setTimeout(()=>{this.sendHeartbeat("periodic"),this.scheduleNextHeartbeat()},this.currentInterval),this.config.debug&&console.log(`[Heartbeat] Scheduled next heartbeat in ${this.currentInterval/1e3}s (${e?"active":"inactive"})`)}sendHeartbeat(e="periodic"){if(this.isDestroyed)return;let t=Date.now(),i=this.activityDetector.isActive(6e4),r=this.tracker.hasConsent("analytics"),a={heartbeat_type:e,status:i?"active":"inactive",timestamp:t};if(r){let n=this.tracker.getCurrentPage();n&&(a.page=n),a.session_id=this.tracker.getSessionId(),e==="periodic"&&(a.duration=t-this.lastHeartbeatTime,a.event_count=this.tracker.getEventCountSinceLastHeartbeat(),this.tracker.resetEventCountSinceLastHeartbeat())}this.tracker.trackSystemEvent("_grain_heartbeat",a),this.lastHeartbeatTime=t}destroy(){this.isDestroyed||(this.heartbeatTimer!==null&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null),this.isDestroyed=!0)}};var se=["gclid","msclkid","fbclid","ttclid","li_fat_id","twclid","ScCid"],ce=["facebook.com","twitter.com","x.com","linkedin.com","instagram.com","pinterest.com","reddit.com","tiktok.com","youtube.com","snapchat.com","t.co","fb.me","lnkd.in"],ue=["google.","bing.com","yahoo.com","duckduckgo.com","baidu.com","yandex.com","ecosia.org","ask.com"],le=["mail.google.com","outlook.live.com","mail.yahoo.com","mail.aol.com"];function R(s){try{return new URL(s).hostname.toLowerCase()}catch{return""}}function K(s){try{let e=new URL(s);return se.some(t=>e.searchParams.has(t))}catch{return!1}}function h(s,e=""){if(!s||s.trim()==="")return"direct";let t=R(s);if(e){let i=R(e);if(t===i)return"direct"}return K(s)||K(e)?"paid":le.some(i=>t.includes(i))?"email":ce.some(i=>t.includes(i))?"social":ue.some(i=>t.includes(i))?"organic":"referral"}function v(s){try{let e=new URL(s),t={},i=e.searchParams.get("utm_source"),r=e.searchParams.get("utm_medium"),a=e.searchParams.get("utm_campaign"),n=e.searchParams.get("utm_term"),o=e.searchParams.get("utm_content");return i&&(t.utm_source=i),r&&(t.utm_medium=r),a&&(t.utm_campaign=a),n&&(t.utm_term=n),o&&(t.utm_content=o),t}catch{return{}}}function U(s){if(typeof window>"u"||typeof localStorage>"u")return null;try{let e=`_grain_first_touch_${s}`,t=localStorage.getItem(e);if(t)return JSON.parse(t)}catch(e){console.warn("[Grain Attribution] Failed to retrieve first-touch attribution:",e)}return null}function de(s,e){if(!(typeof window>"u"||typeof localStorage>"u"))try{let t=`_grain_first_touch_${s}`;localStorage.setItem(t,JSON.stringify(e))}catch(t){console.warn("[Grain Attribution] Failed to store first-touch attribution:",t)}}function w(s,e,t,i){let r=U(s);if(r)return r;let a=h(e,t),n=R(e),o={source:i.utm_source||n||"direct",medium:i.utm_medium||a,campaign:i.utm_campaign||"none",referrer:e||"direct",referrer_category:a,timestamp:Date.now()};return de(s,o),o}var V=null;function g(){return V}function z(s){V=s}var he={AD:"Andorra",AE:"United Arab Emirates",AF:"Afghanistan",AG:"Antigua and Barbuda",AI:"Anguilla",AL:"Albania",AM:"Armenia",AO:"Angola",AQ:"Antarctica",AR:"Argentina",AS:"American Samoa",AT:"Austria",AU:"Australia",AW:"Aruba",AX:"\xC5land Islands",AZ:"Azerbaijan",BA:"Bosnia and Herzegovina",BB:"Barbados",BD:"Bangladesh",BE:"Belgium",BF:"Burkina Faso",BG:"Bulgaria",BH:"Bahrain",BI:"Burundi",BJ:"Benin",BL:"Saint Barth\xE9lemy",BM:"Bermuda",BN:"Brunei",BO:"Bolivia",BQ:"Caribbean Netherlands",BR:"Brazil",BS:"Bahamas",BT:"Bhutan",BV:"Bouvet Island",BW:"Botswana",BY:"Belarus",BZ:"Belize",CA:"Canada",CC:"Cocos Islands",CD:"Democratic Republic of the Congo",CF:"Central African Republic",CG:"Republic of the Congo",CH:"Switzerland",CI:"Ivory Coast",CK:"Cook Islands",CL:"Chile",CM:"Cameroon",CN:"China",CO:"Colombia",CR:"Costa Rica",CU:"Cuba",CV:"Cabo Verde",CW:"Cura\xE7ao",CX:"Christmas Island",CY:"Cyprus",CZ:"Czechia",DE:"Germany",DJ:"Djibouti",DK:"Denmark",DM:"Dominica",DO:"Dominican Republic",DZ:"Algeria",EC:"Ecuador",EE:"Estonia",EG:"Egypt",EH:"Western Sahara",ER:"Eritrea",ES:"Spain",ET:"Ethiopia",FI:"Finland",FJ:"Fiji",FK:"Falkland Islands",FM:"Micronesia",FO:"Faroe Islands",FR:"France",GA:"Gabon",GB:"United Kingdom",GD:"Grenada",GE:"Georgia",GF:"French Guiana",GG:"Guernsey",GH:"Ghana",GI:"Gibraltar",GL:"Greenland",GM:"Gambia",GN:"Guinea",GP:"Guadeloupe",GQ:"Equatorial Guinea",GR:"Greece",GS:"South Georgia and the South Sandwich Islands",GT:"Guatemala",GU:"Guam",GW:"Guinea-Bissau",GY:"Guyana",HK:"Hong Kong",HM:"Heard Island and McDonald Islands",HN:"Honduras",HR:"Croatia",HT:"Haiti",HU:"Hungary",ID:"Indonesia",IE:"Ireland",IL:"Israel",IM:"Isle of Man",IN:"India",IO:"British Indian Ocean Territory",IQ:"Iraq",IR:"Iran",IS:"Iceland",IT:"Italy",JE:"Jersey",JM:"Jamaica",JO:"Jordan",JP:"Japan",KE:"Kenya",KG:"Kyrgyzstan",KH:"Cambodia",KI:"Kiribati",KM:"Comoros",KN:"Saint Kitts and Nevis",KP:"North Korea",KR:"South Korea",KW:"Kuwait",KY:"Cayman Islands",KZ:"Kazakhstan",LA:"Laos",LB:"Lebanon",LC:"Saint Lucia",LI:"Liechtenstein",LK:"Sri Lanka",LR:"Liberia",LS:"Lesotho",LT:"Lithuania",LU:"Luxembourg",LV:"Latvia",LY:"Libya",MA:"Morocco",MC:"Monaco",MD:"Moldova",ME:"Montenegro",MF:"Saint Martin",MG:"Madagascar",MH:"Marshall Islands",MK:"North Macedonia",ML:"Mali",MM:"Myanmar",MN:"Mongolia",MO:"Macao",MP:"Northern Mariana Islands",MQ:"Martinique",MR:"Mauritania",MS:"Montserrat",MT:"Malta",MU:"Mauritius",MV:"Maldives",MW:"Malawi",MX:"Mexico",MY:"Malaysia",MZ:"Mozambique",NA:"Namibia",NC:"New Caledonia",NE:"Niger",NF:"Norfolk Island",NG:"Nigeria",NI:"Nicaragua",NL:"Netherlands",NO:"Norway",NP:"Nepal",NR:"Nauru",NU:"Niue",NZ:"New Zealand",OM:"Oman",PA:"Panama",PE:"Peru",PF:"French Polynesia",PG:"Papua New Guinea",PH:"Philippines",PK:"Pakistan",PL:"Poland",PM:"Saint Pierre and Miquelon",PN:"Pitcairn",PR:"Puerto Rico",PS:"Palestine",PT:"Portugal",PW:"Palau",PY:"Paraguay",QA:"Qatar",RE:"R\xE9union",RO:"Romania",RS:"Serbia",RU:"Russia",RW:"Rwanda",SA:"Saudi Arabia",SB:"Solomon Islands",SC:"Seychelles",SD:"Sudan",SE:"Sweden",SG:"Singapore",SH:"Saint Helena, Ascension and Tristan da Cunha",SI:"Slovenia",SJ:"Svalbard and Jan Mayen",SK:"Slovakia",SL:"Sierra Leone",SM:"San Marino",SN:"Senegal",SO:"Somalia",SR:"Suriname",SS:"South Sudan",ST:"Sao Tome and Principe",SV:"El Salvador",SX:"Sint Maarten",SY:"Syria",SZ:"Eswatini",TC:"Turks and Caicos Islands",TD:"Chad",TF:"French Southern Territories",TG:"Togo",TH:"Thailand",TJ:"Tajikistan",TK:"Tokelau",TL:"Timor-Leste",TM:"Turkmenistan",TN:"Tunisia",TO:"Tonga",TR:"Turkey",TT:"Trinidad and Tobago",TV:"Tuvalu",TW:"Taiwan",TZ:"Tanzania",UA:"Ukraine",UG:"Uganda",UM:"United States Minor Outlying Islands",US:"United States of America",UY:"Uruguay",UZ:"Uzbekistan",VA:"Holy See",VC:"Saint Vincent and the Grenadines",VE:"Venezuela",VG:"Virgin Islands (UK)",VI:"Virgin Islands (US)",VN:"Vietnam",VU:"Vanuatu",WF:"Wallis and Futuna",WS:"Samoa",YE:"Yemen",YT:"Mayotte",ZA:"South Africa",ZM:"Zambia",ZW:"Zimbabwe"},Q={"Africa/Abidjan":{u:0,c:["CI","BF","GH","GM","GN","ML","MR","SH","SL","SN","TG"]},"Africa/Accra":{a:"Africa/Abidjan",c:["GH"],r:1},"Africa/Addis_Ababa":{a:"Africa/Nairobi",c:["ET"],r:1},"Africa/Algiers":{u:60,c:["DZ"]},"Africa/Asmara":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Asmera":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Bamako":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Bangui":{a:"Africa/Lagos",c:["CF"],r:1},"Africa/Banjul":{a:"Africa/Abidjan",c:["GM"],r:1},"Africa/Bissau":{u:0,c:["GW"]},"Africa/Blantyre":{a:"Africa/Maputo",c:["MW"],r:1},"Africa/Brazzaville":{a:"Africa/Lagos",c:["CG"],r:1},"Africa/Bujumbura":{a:"Africa/Maputo",c:["BI"],r:1},"Africa/Cairo":{u:120,c:["EG"]},"Africa/Casablanca":{u:60,d:0,c:["MA"]},"Africa/Ceuta":{u:60,d:120,c:["ES"]},"Africa/Conakry":{a:"Africa/Abidjan",c:["GN"],r:1},"Africa/Dakar":{a:"Africa/Abidjan",c:["SN"],r:1},"Africa/Dar_es_Salaam":{a:"Africa/Nairobi",c:["TZ"],r:1},"Africa/Djibouti":{a:"Africa/Nairobi",c:["DJ"],r:1},"Africa/Douala":{a:"Africa/Lagos",c:["CM"],r:1},"Africa/El_Aaiun":{u:60,d:0,c:["EH"]},"Africa/Freetown":{a:"Africa/Abidjan",c:["SL"],r:1},"Africa/Gaborone":{a:"Africa/Maputo",c:["BW"],r:1},"Africa/Harare":{a:"Africa/Maputo",c:["ZW"],r:1},"Africa/Johannesburg":{u:120,c:["ZA","LS","SZ"]},"Africa/Juba":{u:120,c:["SS"]},"Africa/Kampala":{a:"Africa/Nairobi",c:["UG"],r:1},"Africa/Khartoum":{u:120,c:["SD"]},"Africa/Kigali":{a:"Africa/Maputo",c:["RW"],r:1},"Africa/Kinshasa":{a:"Africa/Lagos",c:["CD"],r:1},"Africa/Lagos":{u:60,c:["NG","AO","BJ","CD","CF","CG","CM","GA","GQ","NE"]},"Africa/Libreville":{a:"Africa/Lagos",c:["GA"],r:1},"Africa/Lome":{a:"Africa/Abidjan",c:["TG"],r:1},"Africa/Luanda":{a:"Africa/Lagos",c:["AO"],r:1},"Africa/Lubumbashi":{a:"Africa/Maputo",c:["CD"],r:1},"Africa/Lusaka":{a:"Africa/Maputo",c:["ZM"],r:1},"Africa/Malabo":{a:"Africa/Lagos",c:["GQ"],r:1},"Africa/Maputo":{u:120,c:["MZ","BI","BW","CD","MW","RW","ZM","ZW"]},"Africa/Maseru":{a:"Africa/Johannesburg",c:["LS"],r:1},"Africa/Mbabane":{a:"Africa/Johannesburg",c:["SZ"],r:1},"Africa/Mogadishu":{a:"Africa/Nairobi",c:["SO"],r:1},"Africa/Monrovia":{u:0,c:["LR"]},"Africa/Nairobi":{u:180,c:["KE","DJ","ER","ET","KM","MG","SO","TZ","UG","YT"]},"Africa/Ndjamena":{u:60,c:["TD"]},"Africa/Niamey":{a:"Africa/Lagos",c:["NE"],r:1},"Africa/Nouakchott":{a:"Africa/Abidjan",c:["MR"],r:1},"Africa/Ouagadougou":{a:"Africa/Abidjan",c:["BF"],r:1},"Africa/Porto-Novo":{a:"Africa/Lagos",c:["BJ"],r:1},"Africa/Sao_Tome":{u:0,c:["ST"]},"Africa/Timbuktu":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Tripoli":{u:120,c:["LY"]},"Africa/Tunis":{u:60,c:["TN"]},"Africa/Windhoek":{u:120,c:["NA"]},"America/Adak":{u:-600,d:-540,c:["US"]},"America/Anchorage":{u:-540,d:-480,c:["US"]},"America/Anguilla":{a:"America/Puerto_Rico",c:["AI"],r:1},"America/Antigua":{a:"America/Puerto_Rico",c:["AG"],r:1},"America/Araguaina":{u:-180,c:["BR"]},"America/Argentina/Buenos_Aires":{u:-180,c:["AR"]},"America/Argentina/Catamarca":{u:-180,c:["AR"]},"America/Argentina/ComodRivadavia":{a:"America/Argentina/Catamarca",r:1},"America/Argentina/Cordoba":{u:-180,c:["AR"]},"America/Argentina/Jujuy":{u:-180,c:["AR"]},"America/Argentina/La_Rioja":{u:-180,c:["AR"]},"America/Argentina/Mendoza":{u:-180,c:["AR"]},"America/Argentina/Rio_Gallegos":{u:-180,c:["AR"]},"America/Argentina/Salta":{u:-180,c:["AR"]},"America/Argentina/San_Juan":{u:-180,c:["AR"]},"America/Argentina/San_Luis":{u:-180,c:["AR"]},"America/Argentina/Tucuman":{u:-180,c:["AR"]},"America/Argentina/Ushuaia":{u:-180,c:["AR"]},"America/Aruba":{a:"America/Puerto_Rico",c:["AW"],r:1},"America/Asuncion":{u:-240,d:-180,c:["PY"]},"America/Atikokan":{a:"America/Panama",c:["CA"],r:1},"America/Atka":{a:"America/Adak",r:1},"America/Bahia":{u:-180,c:["BR"]},"America/Bahia_Banderas":{u:-360,d:-300,c:["MX"]},"America/Barbados":{u:-240,c:["BB"]},"America/Belem":{u:-180,c:["BR"]},"America/Belize":{u:-360,c:["BZ"]},"America/Blanc-Sablon":{a:"America/Puerto_Rico",c:["CA"],r:1},"America/Boa_Vista":{u:-240,c:["BR"]},"America/Bogota":{u:-300,c:["CO"]},"America/Boise":{u:-420,d:-360,c:["US"]},"America/Buenos_Aires":{a:"America/Argentina/Buenos_Aires",r:1},"America/Cambridge_Bay":{u:-420,d:-360,c:["CA"]},"America/Campo_Grande":{u:-240,c:["BR"]},"America/Cancun":{u:-300,c:["MX"]},"America/Caracas":{u:-240,c:["VE"]},"America/Catamarca":{a:"America/Argentina/Catamarca",r:1},"America/Cayenne":{u:-180,c:["GF"]},"America/Cayman":{a:"America/Panama",c:["KY"],r:1},"America/Chicago":{u:-360,d:-300,c:["US"]},"America/Chihuahua":{u:-420,d:-360,c:["MX"]},"America/Coral_Harbour":{a:"America/Panama",c:["CA"],r:1},"America/Cordoba":{a:"America/Argentina/Cordoba",r:1},"America/Costa_Rica":{u:-360,c:["CR"]},"America/Creston":{a:"America/Phoenix",c:["CA"],r:1},"America/Cuiaba":{u:-240,c:["BR"]},"America/Curacao":{a:"America/Puerto_Rico",c:["CW"],r:1},"America/Danmarkshavn":{u:0,c:["GL"]},"America/Dawson":{u:-420,c:["CA"]},"America/Dawson_Creek":{u:-420,c:["CA"]},"America/Denver":{u:-420,d:-360,c:["US"]},"America/Detroit":{u:-300,d:-240,c:["US"]},"America/Dominica":{a:"America/Puerto_Rico",c:["DM"],r:1},"America/Edmonton":{u:-420,d:-360,c:["CA"]},"America/Eirunepe":{u:-300,c:["BR"]},"America/El_Salvador":{u:-360,c:["SV"]},"America/Ensenada":{a:"America/Tijuana",r:1},"America/Fort_Nelson":{u:-420,c:["CA"]},"America/Fort_Wayne":{a:"America/Indiana/Indianapolis",r:1},"America/Fortaleza":{u:-180,c:["BR"]},"America/Glace_Bay":{u:-240,d:-180,c:["CA"]},"America/Godthab":{a:"America/Nuuk",r:1},"America/Goose_Bay":{u:-240,d:-180,c:["CA"]},"America/Grand_Turk":{u:-300,d:-240,c:["TC"]},"America/Grenada":{a:"America/Puerto_Rico",c:["GD"],r:1},"America/Guadeloupe":{a:"America/Puerto_Rico",c:["GP"],r:1},"America/Guatemala":{u:-360,c:["GT"]},"America/Guayaquil":{u:-300,c:["EC"]},"America/Guyana":{u:-240,c:["GY"]},"America/Halifax":{u:-240,d:-180,c:["CA"]},"America/Havana":{u:-300,d:-240,c:["CU"]},"America/Hermosillo":{u:-420,c:["MX"]},"America/Indiana/Indianapolis":{u:-300,d:-240,c:["US"]},"America/Indiana/Knox":{u:-360,d:-300,c:["US"]},"America/Indiana/Marengo":{u:-300,d:-240,c:["US"]},"America/Indiana/Petersburg":{u:-300,d:-240,c:["US"]},"America/Indiana/Tell_City":{u:-360,d:-300,c:["US"]},"America/Indiana/Vevay":{u:-300,d:-240,c:["US"]},"America/Indiana/Vincennes":{u:-300,d:-240,c:["US"]},"America/Indiana/Winamac":{u:-300,d:-240,c:["US"]},"America/Indianapolis":{a:"America/Indiana/Indianapolis",r:1},"America/Inuvik":{u:-420,d:-360,c:["CA"]},"America/Iqaluit":{u:-300,d:-240,c:["CA"]},"America/Jamaica":{u:-300,c:["JM"]},"America/Jujuy":{a:"America/Argentina/Jujuy",r:1},"America/Juneau":{u:-540,d:-480,c:["US"]},"America/Kentucky/Louisville":{u:-300,d:-240,c:["US"]},"America/Kentucky/Monticello":{u:-300,d:-240,c:["US"]},"America/Knox_IN":{a:"America/Indiana/Knox",r:1},"America/Kralendijk":{a:"America/Puerto_Rico",c:["BQ"],r:1},"America/La_Paz":{u:-240,c:["BO"]},"America/Lima":{u:-300,c:["PE"]},"America/Los_Angeles":{u:-480,d:-420,c:["US"]},"America/Louisville":{a:"America/Kentucky/Louisville",r:1},"America/Lower_Princes":{a:"America/Puerto_Rico",c:["SX"],r:1},"America/Maceio":{u:-180,c:["BR"]},"America/Managua":{u:-360,c:["NI"]},"America/Manaus":{u:-240,c:["BR"]},"America/Marigot":{a:"America/Puerto_Rico",c:["MF"],r:1},"America/Martinique":{u:-240,c:["MQ"]},"America/Matamoros":{u:-360,d:-300,c:["MX"]},"America/Mazatlan":{u:-420,d:-360,c:["MX"]},"America/Mendoza":{a:"America/Argentina/Mendoza",r:1},"America/Menominee":{u:-360,d:-300,c:["US"]},"America/Merida":{u:-360,d:-300,c:["MX"]},"America/Metlakatla":{u:-540,d:-480,c:["US"]},"America/Mexico_City":{u:-360,d:-300,c:["MX"]},"America/Miquelon":{u:-180,d:-120,c:["PM"]},"America/Moncton":{u:-240,d:-180,c:["CA"]},"America/Monterrey":{u:-360,d:-300,c:["MX"]},"America/Montevideo":{u:-180,c:["UY"]},"America/Montreal":{a:"America/Toronto",c:["CA"],r:1},"America/Montserrat":{a:"America/Puerto_Rico",c:["MS"],r:1},"America/Nassau":{a:"America/Toronto",c:["BS"],r:1},"America/New_York":{u:-300,d:-240,c:["US"]},"America/Nipigon":{u:-300,d:-240,c:["CA"]},"America/Nome":{u:-540,d:-480,c:["US"]},"America/Noronha":{u:-120,c:["BR"]},"America/North_Dakota/Beulah":{u:-360,d:-300,c:["US"]},"America/North_Dakota/Center":{u:-360,d:-300,c:["US"]},"America/North_Dakota/New_Salem":{u:-360,d:-300,c:["US"]},"America/Nuuk":{u:-180,d:-120,c:["GL"]},"America/Ojinaga":{u:-420,d:-360,c:["MX"]},"America/Panama":{u:-300,c:["PA","CA","KY"]},"America/Pangnirtung":{u:-300,d:-240,c:["CA"]},"America/Paramaribo":{u:-180,c:["SR"]},"America/Phoenix":{u:-420,c:["US","CA"]},"America/Port-au-Prince":{u:-300,d:-240,c:["HT"]},"America/Port_of_Spain":{a:"America/Puerto_Rico",c:["TT"],r:1},"America/Porto_Acre":{a:"America/Rio_Branco",r:1},"America/Porto_Velho":{u:-240,c:["BR"]},"America/Puerto_Rico":{u:-240,c:["PR","AG","CA","AI","AW","BL","BQ","CW","DM","GD","GP","KN","LC","MF","MS","SX","TT","VC","VG","VI"]},"America/Punta_Arenas":{u:-180,c:["CL"]},"America/Rainy_River":{u:-360,d:-300,c:["CA"]},"America/Rankin_Inlet":{u:-360,d:-300,c:["CA"]},"America/Recife":{u:-180,c:["BR"]},"America/Regina":{u:-360,c:["CA"]},"America/Resolute":{u:-360,d:-300,c:["CA"]},"America/Rio_Branco":{u:-300,c:["BR"]},"America/Rosario":{a:"America/Argentina/Cordoba",r:1},"America/Santa_Isabel":{a:"America/Tijuana",r:1},"America/Santarem":{u:-180,c:["BR"]},"America/Santiago":{u:-240,d:-180,c:["CL"]},"America/Santo_Domingo":{u:-240,c:["DO"]},"America/Sao_Paulo":{u:-180,c:["BR"]},"America/Scoresbysund":{u:-60,d:0,c:["GL"]},"America/Shiprock":{a:"America/Denver",r:1},"America/Sitka":{u:-540,d:-480,c:["US"]},"America/St_Barthelemy":{a:"America/Puerto_Rico",c:["BL"],r:1},"America/St_Johns":{u:-150,d:-90,c:["CA"]},"America/St_Kitts":{a:"America/Puerto_Rico",c:["KN"],r:1},"America/St_Lucia":{a:"America/Puerto_Rico",c:["LC"],r:1},"America/St_Thomas":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/St_Vincent":{a:"America/Puerto_Rico",c:["VC"],r:1},"America/Swift_Current":{u:-360,c:["CA"]},"America/Tegucigalpa":{u:-360,c:["HN"]},"America/Thule":{u:-240,d:-180,c:["GL"]},"America/Thunder_Bay":{u:-300,d:-240,c:["CA"]},"America/Tijuana":{u:-480,d:-420,c:["MX"]},"America/Toronto":{u:-300,d:-240,c:["CA","BS"]},"America/Tortola":{a:"America/Puerto_Rico",c:["VG"],r:1},"America/Vancouver":{u:-480,d:-420,c:["CA"]},"America/Virgin":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/Whitehorse":{u:-420,c:["CA"]},"America/Winnipeg":{u:-360,d:-300,c:["CA"]},"America/Yakutat":{u:-540,d:-480,c:["US"]},"America/Yellowknife":{u:-420,d:-360,c:["CA"]},"Antarctica/Casey":{u:660,c:["AQ"]},"Antarctica/Davis":{u:420,c:["AQ"]},"Antarctica/DumontDUrville":{a:"Pacific/Port_Moresby",c:["AQ"],r:1},"Antarctica/Macquarie":{u:600,d:660,c:["AU"]},"Antarctica/Mawson":{u:300,c:["AQ"]},"Antarctica/McMurdo":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Palmer":{u:-180,c:["AQ"]},"Antarctica/Rothera":{u:-180,c:["AQ"]},"Antarctica/South_Pole":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Syowa":{a:"Asia/Riyadh",c:["AQ"],r:1},"Antarctica/Troll":{u:0,d:120,c:["AQ"]},"Antarctica/Vostok":{u:360,c:["AQ"]},"Arctic/Longyearbyen":{a:"Europe/Oslo",c:["SJ"],r:1},"Asia/Aden":{a:"Asia/Riyadh",c:["YE"],r:1},"Asia/Almaty":{u:360,c:["KZ"]},"Asia/Amman":{u:120,d:180,c:["JO"]},"Asia/Anadyr":{u:720,c:["RU"]},"Asia/Aqtau":{u:300,c:["KZ"]},"Asia/Aqtobe":{u:300,c:["KZ"]},"Asia/Ashgabat":{u:300,c:["TM"]},"Asia/Ashkhabad":{a:"Asia/Ashgabat",r:1},"Asia/Atyrau":{u:300,c:["KZ"]},"Asia/Baghdad":{u:180,c:["IQ"]},"Asia/Bahrain":{a:"Asia/Qatar",c:["BH"],r:1},"Asia/Baku":{u:240,c:["AZ"]},"Asia/Bangkok":{u:420,c:["TH","KH","LA","VN"]},"Asia/Barnaul":{u:420,c:["RU"]},"Asia/Beirut":{u:120,d:180,c:["LB"]},"Asia/Bishkek":{u:360,c:["KG"]},"Asia/Brunei":{u:480,c:["BN"]},"Asia/Calcutta":{a:"Asia/Kolkata",r:1},"Asia/Chita":{u:540,c:["RU"]},"Asia/Choibalsan":{u:480,c:["MN"]},"Asia/Chongqing":{a:"Asia/Shanghai",r:1},"Asia/Chungking":{a:"Asia/Shanghai",r:1},"Asia/Colombo":{u:330,c:["LK"]},"Asia/Dacca":{a:"Asia/Dhaka",r:1},"Asia/Damascus":{u:120,d:180,c:["SY"]},"Asia/Dhaka":{u:360,c:["BD"]},"Asia/Dili":{u:540,c:["TL"]},"Asia/Dubai":{u:240,c:["AE","OM"]},"Asia/Dushanbe":{u:300,c:["TJ"]},"Asia/Famagusta":{u:120,d:180,c:["CY"]},"Asia/Gaza":{u:120,d:180,c:["PS"]},"Asia/Harbin":{a:"Asia/Shanghai",r:1},"Asia/Hebron":{u:120,d:180,c:["PS"]},"Asia/Ho_Chi_Minh":{u:420,c:["VN"]},"Asia/Hong_Kong":{u:480,c:["HK"]},"Asia/Hovd":{u:420,c:["MN"]},"Asia/Irkutsk":{u:480,c:["RU"]},"Asia/Istanbul":{a:"Europe/Istanbul",r:1},"Asia/Jakarta":{u:420,c:["ID"]},"Asia/Jayapura":{u:540,c:["ID"]},"Asia/Jerusalem":{u:120,d:180,c:["IL"]},"Asia/Kabul":{u:270,c:["AF"]},"Asia/Kamchatka":{u:720,c:["RU"]},"Asia/Karachi":{u:300,c:["PK"]},"Asia/Kashgar":{a:"Asia/Urumqi",r:1},"Asia/Kathmandu":{u:345,c:["NP"]},"Asia/Katmandu":{a:"Asia/Kathmandu",r:1},"Asia/Khandyga":{u:540,c:["RU"]},"Asia/Kolkata":{u:330,c:["IN"]},"Asia/Krasnoyarsk":{u:420,c:["RU"]},"Asia/Kuala_Lumpur":{u:480,c:["MY"]},"Asia/Kuching":{u:480,c:["MY"]},"Asia/Kuwait":{a:"Asia/Riyadh",c:["KW"],r:1},"Asia/Macao":{a:"Asia/Macau",r:1},"Asia/Macau":{u:480,c:["MO"]},"Asia/Magadan":{u:660,c:["RU"]},"Asia/Makassar":{u:480,c:["ID"]},"Asia/Manila":{u:480,c:["PH"]},"Asia/Muscat":{a:"Asia/Dubai",c:["OM"],r:1},"Asia/Nicosia":{u:120,d:180,c:["CY"]},"Asia/Novokuznetsk":{u:420,c:["RU"]},"Asia/Novosibirsk":{u:420,c:["RU"]},"Asia/Omsk":{u:360,c:["RU"]},"Asia/Oral":{u:300,c:["KZ"]},"Asia/Phnom_Penh":{a:"Asia/Bangkok",c:["KH"],r:1},"Asia/Pontianak":{u:420,c:["ID"]},"Asia/Pyongyang":{u:540,c:["KP"]},"Asia/Qatar":{u:180,c:["QA","BH"]},"Asia/Qostanay":{u:360,c:["KZ"]},"Asia/Qyzylorda":{u:300,c:["KZ"]},"Asia/Rangoon":{a:"Asia/Yangon",r:1},"Asia/Riyadh":{u:180,c:["SA","AQ","KW","YE"]},"Asia/Saigon":{a:"Asia/Ho_Chi_Minh",r:1},"Asia/Sakhalin":{u:660,c:["RU"]},"Asia/Samarkand":{u:300,c:["UZ"]},"Asia/Seoul":{u:540,c:["KR"]},"Asia/Shanghai":{u:480,c:["CN"]},"Asia/Singapore":{u:480,c:["SG","MY"]},"Asia/Srednekolymsk":{u:660,c:["RU"]},"Asia/Taipei":{u:480,c:["TW"]},"Asia/Tashkent":{u:300,c:["UZ"]},"Asia/Tbilisi":{u:240,c:["GE"]},"Asia/Tehran":{u:210,d:270,c:["IR"]},"Asia/Tel_Aviv":{a:"Asia/Jerusalem",r:1},"Asia/Thimbu":{a:"Asia/Thimphu",r:1},"Asia/Thimphu":{u:360,c:["BT"]},"Asia/Tokyo":{u:540,c:["JP"]},"Asia/Tomsk":{u:420,c:["RU"]},"Asia/Ujung_Pandang":{a:"Asia/Makassar",r:1},"Asia/Ulaanbaatar":{u:480,c:["MN"]},"Asia/Ulan_Bator":{a:"Asia/Ulaanbaatar",r:1},"Asia/Urumqi":{u:360,c:["CN"]},"Asia/Ust-Nera":{u:600,c:["RU"]},"Asia/Vientiane":{a:"Asia/Bangkok",c:["LA"],r:1},"Asia/Vladivostok":{u:600,c:["RU"]},"Asia/Yakutsk":{u:540,c:["RU"]},"Asia/Yangon":{u:390,c:["MM"]},"Asia/Yekaterinburg":{u:300,c:["RU"]},"Asia/Yerevan":{u:240,c:["AM"]},"Atlantic/Azores":{u:-60,d:0,c:["PT"]},"Atlantic/Bermuda":{u:-240,d:-180,c:["BM"]},"Atlantic/Canary":{u:0,d:60,c:["ES"]},"Atlantic/Cape_Verde":{u:-60,c:["CV"]},"Atlantic/Faeroe":{a:"Atlantic/Faroe",r:1},"Atlantic/Faroe":{u:0,d:60,c:["FO"]},"Atlantic/Jan_Mayen":{a:"Europe/Oslo",c:["SJ"],r:1},"Atlantic/Madeira":{u:0,d:60,c:["PT"]},"Atlantic/Reykjavik":{u:0,c:["IS"]},"Atlantic/South_Georgia":{u:-120,c:["GS"]},"Atlantic/St_Helena":{a:"Africa/Abidjan",c:["SH"],r:1},"Atlantic/Stanley":{u:-180,c:["FK"]},"Australia/ACT":{a:"Australia/Sydney",r:1},"Australia/Adelaide":{u:570,d:630,c:["AU"]},"Australia/Brisbane":{u:600,c:["AU"]},"Australia/Broken_Hill":{u:570,d:630,c:["AU"]},"Australia/Canberra":{a:"Australia/Sydney",r:1},"Australia/Currie":{a:"Australia/Hobart",r:1},"Australia/Darwin":{u:570,c:["AU"]},"Australia/Eucla":{u:525,c:["AU"]},"Australia/Hobart":{u:600,d:660,c:["AU"]},"Australia/LHI":{a:"Australia/Lord_Howe",r:1},"Australia/Lindeman":{u:600,c:["AU"]},"Australia/Lord_Howe":{u:630,d:660,c:["AU"]},"Australia/Melbourne":{u:600,d:660,c:["AU"]},"Australia/NSW":{a:"Australia/Sydney",r:1},"Australia/North":{a:"Australia/Darwin",r:1},"Australia/Perth":{u:480,c:["AU"]},"Australia/Queensland":{a:"Australia/Brisbane",r:1},"Australia/South":{a:"Australia/Adelaide",r:1},"Australia/Sydney":{u:600,d:660,c:["AU"]},"Australia/Tasmania":{a:"Australia/Hobart",r:1},"Australia/Victoria":{a:"Australia/Melbourne",r:1},"Australia/West":{a:"Australia/Perth",r:1},"Australia/Yancowinna":{a:"Australia/Broken_Hill",r:1},"Brazil/Acre":{a:"America/Rio_Branco",r:1},"Brazil/DeNoronha":{a:"America/Noronha",r:1},"Brazil/East":{a:"America/Sao_Paulo",r:1},"Brazil/West":{a:"America/Manaus",r:1},CET:{u:60,d:120},CST6CDT:{u:-360,d:-300},"Canada/Atlantic":{a:"America/Halifax",r:1},"Canada/Central":{a:"America/Winnipeg",r:1},"Canada/Eastern":{a:"America/Toronto",c:["CA"],r:1},"Canada/Mountain":{a:"America/Edmonton",r:1},"Canada/Newfoundland":{a:"America/St_Johns",r:1},"Canada/Pacific":{a:"America/Vancouver",r:1},"Canada/Saskatchewan":{a:"America/Regina",r:1},"Canada/Yukon":{a:"America/Whitehorse",r:1},"Chile/Continental":{a:"America/Santiago",r:1},"Chile/EasterIsland":{a:"Pacific/Easter",r:1},Cuba:{a:"America/Havana",r:1},EET:{u:120,d:180},EST:{u:-300},EST5EDT:{u:-300,d:-240},Egypt:{a:"Africa/Cairo",r:1},Eire:{a:"Europe/Dublin",r:1},"Etc/GMT":{u:0},"Etc/GMT+0":{a:"Etc/GMT",r:1},"Etc/GMT+1":{u:-60},"Etc/GMT+10":{u:-600},"Etc/GMT+11":{u:-660},"Etc/GMT+12":{u:-720},"Etc/GMT+2":{u:-120},"Etc/GMT+3":{u:-180},"Etc/GMT+4":{u:-240},"Etc/GMT+5":{u:-300},"Etc/GMT+6":{u:-360},"Etc/GMT+7":{u:-420},"Etc/GMT+8":{u:-480},"Etc/GMT+9":{u:-540},"Etc/GMT-0":{a:"Etc/GMT",r:1},"Etc/GMT-1":{u:60},"Etc/GMT-10":{u:600},"Etc/GMT-11":{u:660},"Etc/GMT-12":{u:720},"Etc/GMT-13":{u:780},"Etc/GMT-14":{u:840},"Etc/GMT-2":{u:120},"Etc/GMT-3":{u:180},"Etc/GMT-4":{u:240},"Etc/GMT-5":{u:300},"Etc/GMT-6":{u:360},"Etc/GMT-7":{u:420},"Etc/GMT-8":{u:480},"Etc/GMT-9":{u:540},"Etc/GMT0":{a:"Etc/GMT",r:1},"Etc/Greenwich":{a:"Etc/GMT",r:1},"Etc/UCT":{a:"Etc/UTC",r:1},"Etc/UTC":{u:0},"Etc/Universal":{a:"Etc/UTC",r:1},"Etc/Zulu":{a:"Etc/UTC",r:1},"Europe/Amsterdam":{u:60,d:120,c:["NL"]},"Europe/Andorra":{u:60,d:120,c:["AD"]},"Europe/Astrakhan":{u:240,c:["RU"]},"Europe/Athens":{u:120,d:180,c:["GR"]},"Europe/Belfast":{a:"Europe/London",c:["GB"],r:1},"Europe/Belgrade":{u:60,d:120,c:["RS","BA","HR","ME","MK","SI"]},"Europe/Berlin":{u:60,d:120,c:["DE"]},"Europe/Bratislava":{a:"Europe/Prague",c:["SK"],r:1},"Europe/Brussels":{u:60,d:120,c:["BE"]},"Europe/Bucharest":{u:120,d:180,c:["RO"]},"Europe/Budapest":{u:60,d:120,c:["HU"]},"Europe/Busingen":{a:"Europe/Zurich",c:["DE"],r:1},"Europe/Chisinau":{u:120,d:180,c:["MD"]},"Europe/Copenhagen":{u:60,d:120,c:["DK"]},"Europe/Dublin":{u:60,d:0,c:["IE"]},"Europe/Gibraltar":{u:60,d:120,c:["GI"]},"Europe/Guernsey":{a:"Europe/London",c:["GG"],r:1},"Europe/Helsinki":{u:120,d:180,c:["FI","AX"]},"Europe/Isle_of_Man":{a:"Europe/London",c:["IM"],r:1},"Europe/Istanbul":{u:180,c:["TR"]},"Europe/Jersey":{a:"Europe/London",c:["JE"],r:1},"Europe/Kaliningrad":{u:120,c:["RU"]},"Europe/Kiev":{u:120,d:180,c:["UA"]},"Europe/Kirov":{u:180,c:["RU"]},"Europe/Lisbon":{u:0,d:60,c:["PT"]},"Europe/Ljubljana":{a:"Europe/Belgrade",c:["SI"],r:1},"Europe/London":{u:0,d:60,c:["GB","GG","IM","JE"]},"Europe/Luxembourg":{u:60,d:120,c:["LU"]},"Europe/Madrid":{u:60,d:120,c:["ES"]},"Europe/Malta":{u:60,d:120,c:["MT"]},"Europe/Mariehamn":{a:"Europe/Helsinki",c:["AX"],r:1},"Europe/Minsk":{u:180,c:["BY"]},"Europe/Monaco":{u:60,d:120,c:["MC"]},"Europe/Moscow":{u:180,c:["RU"]},"Europe/Nicosia":{a:"Asia/Nicosia",r:1},"Europe/Oslo":{u:60,d:120,c:["NO","SJ","BV"]},"Europe/Paris":{u:60,d:120,c:["FR"]},"Europe/Podgorica":{a:"Europe/Belgrade",c:["ME"],r:1},"Europe/Prague":{u:60,d:120,c:["CZ","SK"]},"Europe/Riga":{u:120,d:180,c:["LV"]},"Europe/Rome":{u:60,d:120,c:["IT","SM","VA"]},"Europe/Samara":{u:240,c:["RU"]},"Europe/San_Marino":{a:"Europe/Rome",c:["SM"],r:1},"Europe/Sarajevo":{a:"Europe/Belgrade",c:["BA"],r:1},"Europe/Saratov":{u:240,c:["RU"]},"Europe/Simferopol":{u:180,c:["RU","UA"]},"Europe/Skopje":{a:"Europe/Belgrade",c:["MK"],r:1},"Europe/Sofia":{u:120,d:180,c:["BG"]},"Europe/Stockholm":{u:60,d:120,c:["SE"]},"Europe/Tallinn":{u:120,d:180,c:["EE"]},"Europe/Tirane":{u:60,d:120,c:["AL"]},"Europe/Tiraspol":{a:"Europe/Chisinau",r:1},"Europe/Ulyanovsk":{u:240,c:["RU"]},"Europe/Uzhgorod":{u:120,d:180,c:["UA"]},"Europe/Vaduz":{a:"Europe/Zurich",c:["LI"],r:1},"Europe/Vatican":{a:"Europe/Rome",c:["VA"],r:1},"Europe/Vienna":{u:60,d:120,c:["AT"]},"Europe/Vilnius":{u:120,d:180,c:["LT"]},"Europe/Volgograd":{u:180,c:["RU"]},"Europe/Warsaw":{u:60,d:120,c:["PL"]},"Europe/Zagreb":{a:"Europe/Belgrade",c:["HR"],r:1},"Europe/Zaporozhye":{u:120,d:180,c:["UA"]},"Europe/Zurich":{u:60,d:120,c:["CH","DE","LI"]},Factory:{u:0},GB:{a:"Europe/London",c:["GB"],r:1},"GB-Eire":{a:"Europe/London",c:["GB"],r:1},GMT:{a:"Etc/GMT",r:1},"GMT+0":{a:"Etc/GMT",r:1},"GMT-0":{a:"Etc/GMT",r:1},GMT0:{a:"Etc/GMT",r:1},Greenwich:{a:"Etc/GMT",r:1},HST:{u:-600},Hongkong:{a:"Asia/Hong_Kong",r:1},Iceland:{a:"Atlantic/Reykjavik",r:1},"Indian/Antananarivo":{a:"Africa/Nairobi",c:["MG"],r:1},"Indian/Chagos":{u:360,c:["IO"]},"Indian/Christmas":{u:420,c:["CX"]},"Indian/Cocos":{u:390,c:["CC"]},"Indian/Comoro":{a:"Africa/Nairobi",c:["KM"],r:1},"Indian/Kerguelen":{u:300,c:["TF","HM"]},"Indian/Mahe":{u:240,c:["SC"]},"Indian/Maldives":{u:300,c:["MV"]},"Indian/Mauritius":{u:240,c:["MU"]},"Indian/Mayotte":{a:"Africa/Nairobi",c:["YT"],r:1},"Indian/Reunion":{u:240,c:["RE","TF"]},Iran:{a:"Asia/Tehran",r:1},Israel:{a:"Asia/Jerusalem",r:1},Jamaica:{a:"America/Jamaica",r:1},Japan:{a:"Asia/Tokyo",r:1},Kwajalein:{a:"Pacific/Kwajalein",r:1},Libya:{a:"Africa/Tripoli",r:1},MET:{u:60,d:120},MST:{u:-420},MST7MDT:{u:-420,d:-360},"Mexico/BajaNorte":{a:"America/Tijuana",r:1},"Mexico/BajaSur":{a:"America/Mazatlan",r:1},"Mexico/General":{a:"America/Mexico_City",r:1},NZ:{a:"Pacific/Auckland",c:["NZ"],r:1},"NZ-CHAT":{a:"Pacific/Chatham",r:1},Navajo:{a:"America/Denver",r:1},PRC:{a:"Asia/Shanghai",r:1},PST8PDT:{u:-480,d:-420},"Pacific/Apia":{u:780,c:["WS"]},"Pacific/Auckland":{u:720,d:780,c:["NZ","AQ"]},"Pacific/Bougainville":{u:660,c:["PG"]},"Pacific/Chatham":{u:765,d:825,c:["NZ"]},"Pacific/Chuuk":{u:600,c:["FM"]},"Pacific/Easter":{u:-360,d:-300,c:["CL"]},"Pacific/Efate":{u:660,c:["VU"]},"Pacific/Enderbury":{a:"Pacific/Kanton",r:1},"Pacific/Fakaofo":{u:780,c:["TK"]},"Pacific/Fiji":{u:720,d:780,c:["FJ"]},"Pacific/Funafuti":{u:720,c:["TV"]},"Pacific/Galapagos":{u:-360,c:["EC"]},"Pacific/Gambier":{u:-540,c:["PF"]},"Pacific/Guadalcanal":{u:660,c:["SB"]},"Pacific/Guam":{u:600,c:["GU","MP"]},"Pacific/Honolulu":{u:-600,c:["US","UM"]},"Pacific/Johnston":{a:"Pacific/Honolulu",c:["UM"],r:1},"Pacific/Kanton":{u:780,c:["KI"]},"Pacific/Kiritimati":{u:840,c:["KI"]},"Pacific/Kosrae":{u:660,c:["FM"]},"Pacific/Kwajalein":{u:720,c:["MH"]},"Pacific/Majuro":{u:720,c:["MH"]},"Pacific/Marquesas":{u:-510,c:["PF"]},"Pacific/Midway":{a:"Pacific/Pago_Pago",c:["UM"],r:1},"Pacific/Nauru":{u:720,c:["NR"]},"Pacific/Niue":{u:-660,c:["NU"]},"Pacific/Norfolk":{u:660,d:720,c:["NF"]},"Pacific/Noumea":{u:660,c:["NC"]},"Pacific/Pago_Pago":{u:-660,c:["AS","UM"]},"Pacific/Palau":{u:540,c:["PW"]},"Pacific/Pitcairn":{u:-480,c:["PN"]},"Pacific/Pohnpei":{u:660,c:["FM"]},"Pacific/Ponape":{a:"Pacific/Pohnpei",r:1},"Pacific/Port_Moresby":{u:600,c:["PG","AQ"]},"Pacific/Rarotonga":{u:-600,c:["CK"]},"Pacific/Saipan":{a:"Pacific/Guam",c:["MP"],r:1},"Pacific/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},"Pacific/Tahiti":{u:-600,c:["PF"]},"Pacific/Tarawa":{u:720,c:["KI"]},"Pacific/Tongatapu":{u:780,c:["TO"]},"Pacific/Truk":{a:"Pacific/Chuuk",r:1},"Pacific/Wake":{u:720,c:["UM"]},"Pacific/Wallis":{u:720,c:["WF"]},"Pacific/Yap":{a:"Pacific/Chuuk",r:1},Poland:{a:"Europe/Warsaw",r:1},Portugal:{a:"Europe/Lisbon",r:1},ROC:{a:"Asia/Taipei",r:1},ROK:{a:"Asia/Seoul",r:1},Singapore:{a:"Asia/Singapore",c:["SG"],r:1},Turkey:{a:"Europe/Istanbul",r:1},UCT:{a:"Etc/UTC",r:1},"US/Alaska":{a:"America/Anchorage",r:1},"US/Aleutian":{a:"America/Adak",r:1},"US/Arizona":{a:"America/Phoenix",c:["US"],r:1},"US/Central":{a:"America/Chicago",r:1},"US/East-Indiana":{a:"America/Indiana/Indianapolis",r:1},"US/Eastern":{a:"America/New_York",r:1},"US/Hawaii":{a:"Pacific/Honolulu",c:["US"],r:1},"US/Indiana-Starke":{a:"America/Indiana/Knox",r:1},"US/Michigan":{a:"America/Detroit",r:1},"US/Mountain":{a:"America/Denver",r:1},"US/Pacific":{a:"America/Los_Angeles",r:1},"US/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},UTC:{a:"Etc/UTC",r:1},Universal:{a:"Etc/UTC",r:1},"W-SU":{a:"Europe/Moscow",r:1},WET:{u:0,d:60},Zulu:{a:"Etc/UTC",r:1}};function $(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return null;try{let e=Q[s]?.c?.[0];return e&&he[e]||null}catch{return null}}function k(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return"Unknown";try{return Q[s]?.c?.[0]||"Unknown"}catch{return"Unknown"}}function W(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;return s===""||!s?null:s.split("/")[1]?.replace("_"," ")||null}var P=class{constructor(e,t){this.isDestroyed=!1;this.currentPath=null;this.originalPushState=null;this.originalReplaceState=null;this.previousPage=null;this.landingPage=null;this.pageViewCount=0;this.handlePopState=()=>{this.isDestroyed||this.trackCurrentPage()};this.handleHashChange=()=>{this.isDestroyed||this.trackCurrentPage()};this.tracker=e,this.config=t,this.trackCurrentPage(!0),this.setupHistoryListeners(),this.setupHashChangeListener()}setupHistoryListeners(){typeof window>"u"||typeof history>"u"||(this.originalPushState=history.pushState,history.pushState=(e,t,i)=>{this.originalPushState?.call(history,e,t,i),this.trackCurrentPage()},this.originalReplaceState=history.replaceState,history.replaceState=(e,t,i)=>{this.originalReplaceState?.call(history,e,t,i),this.trackCurrentPage()},window.addEventListener("popstate",this.handlePopState))}setupHashChangeListener(){typeof window>"u"||window.addEventListener("hashchange",this.handleHashChange)}trackCurrentPage(e=!1){if(this.isDestroyed||typeof window>"u")return;let t=this.extractPath(window.location.href);if(!e&&t===this.currentPath)return;this.currentPath&&(this.previousPage=this.currentPath),this.currentPath=t,this.pageViewCount++,e&&(this.landingPage=t);let i=this.tracker.hasConsent("analytics"),r=window.location.href,a=document.referrer||"",n=v(r);Object.keys(n).length>0&&(!g()||e)&&z(n);let o=g()||{},c=w(this.config.tenantId,a,r,o),u={page:t,timestamp:Date.now()};if(i){u.title=document.title||"",u.full_url=r,u.session_id=this.tracker.getSessionId(),a&&(u.referrer=a,u.referrer_domain=this.extractDomain(a),u.referrer_category=h(a,r)),this.landingPage&&!e&&(u.landing_page=this.landingPage),this.previousPage&&(u.previous_page=this.previousPage),o.utm_source&&(u.utm_source=o.utm_source),o.utm_medium&&(u.utm_medium=o.utm_medium),o.utm_campaign&&(u.utm_campaign=o.utm_campaign),o.utm_term&&(u.utm_term=o.utm_term),o.utm_content&&(u.utm_content=o.utm_content),u.first_touch_source=c.source,u.first_touch_medium=c.medium,u.first_touch_campaign=c.campaign,u.first_touch_referrer_category=c.referrer_category,u.device=this.getDeviceType(),u.browser=this.getBrowser(),u.os=this.getOS(),u.language=navigator.language||"";let l=Intl.DateTimeFormat().resolvedOptions().timeZone;u.timezone=l,u.country=k(),u.screen_resolution=`${screen.width}x${screen.height}`,u.viewport=`${window.innerWidth}x${window.innerHeight}`}this.tracker.trackSystemEvent("page_view",u)}extractDomain(e){try{return new URL(e).hostname}catch{return""}}getBrowser(){let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}extractPath(e){try{let t=new URL(e),i=t.pathname+t.hash;return!this.config.stripQueryParams&&t.search&&(i+=t.search),i}catch(t){return this.config.debug&&console.warn("[Page Tracking] Failed to parse URL:",e,t),e}}getCurrentPage(){return this.currentPath}trackPage(e,t){if(this.isDestroyed)return;let i=this.tracker.hasConsent("analytics"),r={page:e,timestamp:Date.now(),...t};i&&typeof document<"u"&&typeof window<"u"&&(r.referrer||(r.referrer=document.referrer||""),r.title||(r.title=document.title||""),r.full_url||(r.full_url=window.location.href),r.session_id||(r.session_id=this.tracker.getSessionId()),r.browser||(r.browser=this.getBrowser()),r.os||(r.os=this.getOS())),this.tracker.trackSystemEvent("page_view",r)}getPageViewCount(){return this.pageViewCount}destroy(){this.isDestroyed||(typeof history<"u"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState)),typeof window<"u"&&(window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)),this.isDestroyed=!0)}};var f=class{constructor(e){this.eventQueue=[];this.waitingForConsentQueue=[];this.flushTimer=null;this.isDestroyed=!1;this.globalUserId=null;this.persistentAnonymousUserId=null;this.configCache=null;this.configRefreshTimer=null;this.configChangeListeners=[];this.configFetchPromise=null;this.cookiesEnabled=!1;this.activityDetector=null;this.heartbeatManager=null;this.pageTrackingManager=null;this.ephemeralSessionId=null;this.eventCountSinceLastHeartbeat=0;this.interactionTrackingManager=null;this.sectionTrackingManager=null;this.heatmapTrackingManager=null;this.sessionStartTime=Date.now();this.sessionEventCount=0;this.config={apiUrl:"https://api.grainql.com",authStrategy:"NONE",batchSize:50,flushInterval:5e3,retryAttempts:3,retryDelay:1e3,maxEventsPerRequest:160,debug:!1,defaultConfigurations:{},configCacheKey:"grain_config",configRefreshInterval:3e5,enableConfigCache:!0,consentMode:"opt-out",waitForConsent:!1,enableCookies:!1,anonymizeIP:!1,disableAutoProperties:!1,enableHeartbeat:!0,heartbeatActiveInterval:12e4,heartbeatInactiveInterval:3e5,enableAutoPageView:!0,stripQueryParams:!0,enableHeatmapTracking:!0,...e,tenantId:e.tenantId},this.consentManager=new T(this.config.tenantId,this.config.consentMode),this.config.enableCookies&&(this.cookiesEnabled=F(),!this.cookiesEnabled&&this.config.debug&&console.warn("[Grain Analytics] Cookies are not available, falling back to localStorage")),e.userId&&(this.globalUserId=e.userId),this.validateConfig(),this.initializePersistentAnonymousUserId(),this.setupBeforeUnload(),this.startFlushTimer(),this.initializeConfigCache(),this.ephemeralSessionId=this.generateUUID(),typeof window<"u"&&(this.initializeAutomaticTracking(),this.trackSessionStart(),this.config.enableHeatmapTracking&&this.initializeHeatmapTracking()),this.consentManager.addListener(t=>{t.granted&&this.handleConsentGranted()})}validateConfig(){if(!this.config.tenantId)throw new Error("Grain Analytics: tenantId is required");if(this.config.authStrategy==="SERVER_SIDE"&&!this.config.secretKey)throw new Error("Grain Analytics: secretKey is required for SERVER_SIDE auth strategy");if(this.config.authStrategy==="JWT"&&!this.config.authProvider)throw new Error("Grain Analytics: authProvider is required for JWT auth strategy")}generateUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}shouldAllowPersistentStorage(){let e=this.consentManager.hasConsent("analytics"),t=this.config.consentMode==="opt-in",i=!!this.globalUserId,r=this.config.authStrategy==="JWT";return e||!t||i||r}generateAnonymousUserId(){return this.generateUUID()}initializePersistentAnonymousUserId(){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID initialization (GDPR compliance)");return}let e=`grain_anonymous_user_id_${this.config.tenantId}`,t="_grain_uid";try{if(this.cookiesEnabled){let r=D(t);if(r){this.persistentAnonymousUserId=r,this.log("Loaded persistent anonymous user ID from cookie:",this.persistentAnonymousUserId);return}}let i=localStorage.getItem(e);i?(this.persistentAnonymousUserId=i,this.log("Loaded persistent anonymous user ID from localStorage:",this.persistentAnonymousUserId),this.cookiesEnabled&&this.savePersistentAnonymousUserId(i)):(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId),this.log("Generated new persistent anonymous user ID:",this.persistentAnonymousUserId))}catch(i){this.log("Failed to initialize persistent anonymous user ID:",i),this.persistentAnonymousUserId=this.generateAnonymousUserId()}}savePersistentAnonymousUserId(e){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID save (GDPR compliance)");return}let t=`grain_anonymous_user_id_${this.config.tenantId}`,i="_grain_uid";try{if(this.cookiesEnabled){let r={maxAge:31536e3,sameSite:"lax",secure:typeof window<"u"&&window.location.protocol==="https:",...this.config.cookieOptions};I(i,e,r)}localStorage.setItem(t,e)}catch(r){this.log("Failed to save persistent anonymous user ID:",r)}}getEffectiveUserIdInternal(){return this.globalUserId?this.globalUserId:this.persistentAnonymousUserId?this.persistentAnonymousUserId:(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId),this.persistentAnonymousUserId)}log(...e){this.config.debug&&console.log("[Grain Analytics]",...e)}createErrorDigest(e){let t=[...new Set(e.map(n=>n.eventName))],i=[...new Set(e.map(n=>n.userId))],r=0,a=0;return e.forEach(n=>{let o=n.properties||{};r+=Object.keys(o).length,a+=JSON.stringify(n).length}),{eventCount:e.length,totalProperties:r,totalSize:a,eventNames:t,userIds:i}}formatError(e,t,i){let r=i?this.createErrorDigest(i):{eventCount:0,totalProperties:0,totalSize:0,eventNames:[],userIds:[]},a="UNKNOWN_ERROR",n="An unknown error occurred";if(e instanceof Error)n=e.message,n.includes("fetch failed")||n.includes("network error")?a="NETWORK_ERROR":n.includes("timeout")?a="TIMEOUT_ERROR":n.includes("HTTP 4")?a="CLIENT_ERROR":n.includes("HTTP 5")?a="SERVER_ERROR":n.includes("JSON")?a="PARSE_ERROR":n.includes("auth")||n.includes("unauthorized")?a="AUTH_ERROR":n.includes("rate limit")||n.includes("429")?a="RATE_LIMIT_ERROR":a="GENERAL_ERROR";else if(typeof e=="string")n=e,a="STRING_ERROR";else if(e&&typeof e=="object"&&"status"in e){let o=e.status;a=`HTTP_${o}`,n=`HTTP ${o} error`}return{code:a,message:n,digest:r,timestamp:new Date().toISOString(),context:t,originalError:e}}logError(e){if(!this.config.debug)return;let{code:t,message:i,digest:r,timestamp:a,context:n}=e,o={"\u{1F6A8} Grain Analytics Error":{"Error Code":t,Message:i,Context:n,Timestamp:a,"Event Digest":{Events:r.eventCount,Properties:r.totalProperties,"Size (bytes)":r.totalSize,"Event Names":r.eventNames.length>0?r.eventNames.join(", "):"None","User IDs":r.userIds.length>0?r.userIds.slice(0,3).join(", ")+(r.userIds.length>3?"...":""):"None"}}};console.error("\u{1F6A8} Grain Analytics Error:",o),console.error(`[Grain Analytics] ${t}: ${i} (${n}) - Events: ${r.eventCount}, Props: ${r.totalProperties}, Size: ${r.totalSize}B`)}async safeExecute(e,t,i){try{return await e()}catch(r){let a=this.formatError(r,t,i);return this.logError(a),null}}formatEvent(e){let t=e.properties||{};if(!this.config.disableAutoProperties&&typeof window<"u"){let i=this.consentManager.hasConsent("analytics");if(!e.eventName.startsWith("_grain_")&&i){let a=g();a&&(a.utm_source&&(t.utm_source=a.utm_source),a.utm_medium&&(t.utm_medium=a.utm_medium),a.utm_campaign&&(t.utm_campaign=a.utm_campaign),a.utm_term&&(t.utm_term=a.utm_term),a.utm_content&&(t.utm_content=a.utm_content));let n=U(this.config.tenantId);n&&(t.first_touch_source=n.source,t.first_touch_medium=n.medium,t.first_touch_campaign=n.campaign,t.first_touch_referrer_category=n.referrer_category),t.session_id||(t.session_id=this.getSessionId())}}return{eventName:e.eventName,userId:e.userId||this.getEffectiveUserIdInternal(),properties:t}}async getAuthHeaders(){let e={"Content-Type":"application/json"};switch(this.config.authStrategy){case"NONE":break;case"SERVER_SIDE":e.Authorization=`Chase ${this.config.secretKey}`;break;case"JWT":if(this.config.authProvider){let t=await this.config.authProvider.getToken();e.Authorization=`Bearer ${t}`}break}return e}async delay(e){return new Promise(t=>setTimeout(t,e))}isRetriableError(e){if(e instanceof Error){let t=e.message.toLowerCase();if(t.includes("fetch failed")||t==="network error"||t.includes("timeout")||t.includes("connection"))return!0}if(typeof e=="object"&&e!==null&&"status"in e){let t=e.status;return t>=500||t===429}return!1}async sendEvents(e){if(e.length===0)return;let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(e)});if(!n.ok){let o=`HTTP ${n.status}`;try{let u=await n.json();u?.message&&(o=u.message)}catch{let u=await n.text();u&&(o=u)}let c=new Error(`Failed to send events: ${o}`);throw c.status=n.status,c}this.log(`Successfully sent ${e.length} events`);return}catch(r){if(t=r,i===this.config.retryAttempts){let n=this.formatError(r,`sendEvents (attempt ${i+1}/${this.config.retryAttempts+1})`,e);this.logError(n);return}if(!this.isRetriableError(r)){let n=this.formatError(r,"sendEvents (non-retriable error)",e);this.logError(n);return}let a=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${a}ms after error:`,r),await this.delay(a)}}async sendEventsWithBeacon(e){if(e.length!==0)try{let t=await this.getAuthHeaders(),i=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,r=JSON.stringify(e);if(!(this.config.authStrategy!=="NONE")&&typeof navigator<"u"&&"sendBeacon"in navigator){let n=new Blob([r],{type:"application/json"});if(navigator.sendBeacon(i,n)){this.log(`Successfully sent ${e.length} events via beacon`);return}}await fetch(i,{method:"POST",headers:t,body:r,keepalive:!0})}catch(t){let i=this.formatError(t,"sendEventsWithBeacon",e);this.logError(i)}}startFlushTimer(){typeof window>"u"||(this.flushTimer&&clearInterval(this.flushTimer),this.flushTimer=window.setInterval(()=>{this.eventQueue.length>0&&this.flush().catch(e=>{let t=this.formatError(e,"auto-flush");this.logError(t)})},this.config.flushInterval))}setupBeforeUnload(){if(typeof window>"u")return;let e=()=>{if(this.trackSessionEnd(),this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden"&&this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}})}initializeAutomaticTracking(){if(this.config.enableHeartbeat)try{this.activityDetector=new b,this.heartbeatManager=new C(this,this.activityDetector,{activeInterval:this.config.heartbeatActiveInterval,inactiveInterval:this.config.heartbeatInactiveInterval,debug:this.config.debug})}catch(e){this.log("Failed to initialize heartbeat tracking:",e)}if(this.config.enableAutoPageView)try{this.pageTrackingManager=new P(this,{stripQueryParams:this.config.stripQueryParams,debug:this.config.debug,tenantId:this.config.tenantId})}catch(e){this.log("Failed to initialize page view tracking:",e)}this.initializeAutoTracking()}initializeHeatmapTracking(){if(!(typeof window>"u"))try{this.log("Initializing heatmap tracking"),Promise.resolve().then(()=>(j(),J)).then(({HeatmapTrackingManager:e})=>{try{this.heatmapTrackingManager=new e(this,{scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:this.config.debug}),this.log("Heatmap tracking initialized")}catch(t){this.log("Failed to initialize heatmap tracking:",t)}}).catch(e=>{this.log("Failed to load heatmap tracking module:",e)})}catch(e){this.log("Failed to initialize heatmap tracking:",e)}}async initializeAutoTracking(){try{this.log("Initializing auto-tracking");let e=this.globalUserId||this.persistentAnonymousUserId||this.generateUUID(),t=typeof window<"u"?window.location.href:"",i={userId:e,immediateKeys:[],properties:{},currentUrl:t},r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(i)});if(!n.ok){this.log("Failed to fetch auto-tracking config:",n.status);return}let o=await n.json();o.autoTrackingConfig&&(this.log("Auto-tracking config loaded"),this.setupAutoTrackingManagers(o.autoTrackingConfig))}catch(e){this.log("Failed to initialize auto-tracking:",e)}}setupAutoTrackingManagers(e){this.log("Setting up auto-tracking managers"),e.interactions&&e.interactions.length>0&&(this.log("Loading interaction tracking:",e.interactions.length,"interactions"),Promise.resolve().then(()=>(Z(),Y)).then(({InteractionTrackingManager:t})=>{try{this.interactionTrackingManager=new t(this,e.interactions,{debug:this.config.debug,enableMutationObserver:!0,mutationDebounceDelay:500}),this.log("Interaction tracking initialized")}catch(i){this.log("Failed to initialize interaction tracking:",i)}}).catch(t=>{this.log("Failed to load interaction tracking module:",t)})),e.sections&&e.sections.length>0&&(this.log("Loading section tracking:",e.sections.length,"sections"),Promise.resolve().then(()=>(X(),q)).then(({SectionTrackingManager:t})=>{try{this.sectionTrackingManager=new t(this,e.sections,{minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:this.config.debug}),this.log("Section tracking initialized")}catch(i){this.log("Failed to initialize section tracking:",i)}}).catch(t=>{this.log("Failed to load section tracking module:",t)}))}trackSessionStart(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t={session_id:this.getSessionId(),timestamp:this.sessionStartTime};if(e){let i=document.referrer||"",r=window.location.href,a=v(r),n=g()||a,o=w(this.config.tenantId,i,r,n);t.landing_page=window.location.pathname,i?(t.referrer=i,t.referrer_domain=new URL(i).hostname,t.referrer_category=h(i,r)):t.referrer_category="direct",n.utm_source&&(t.utm_source=n.utm_source),n.utm_medium&&(t.utm_medium=n.utm_medium),n.utm_campaign&&(t.utm_campaign=n.utm_campaign),n.utm_term&&(t.utm_term=n.utm_term),n.utm_content&&(t.utm_content=n.utm_content),t.first_touch_source=o.source,t.first_touch_medium=o.medium,t.first_touch_campaign=o.campaign,t.first_touch_referrer_category=o.referrer_category,t.device=this.getDeviceType(),t.screen_resolution=`${screen.width}x${screen.height}`,t.viewport=`${window.innerWidth}x${window.innerHeight}`,t.browser=this.getBrowser(),t.os=this.getOS(),t.language=navigator.language||"",t.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}this.trackSystemEvent("_grain_session_start",t),this.log("Session started")}trackSessionEnd(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t=Date.now()-this.sessionStartTime,i={session_id:this.getSessionId(),session_duration:Math.floor(t/1e3),duration:t,event_count:this.sessionEventCount,timestamp:Date.now()};if(e&&this.pageTrackingManager){let r=this.pageTrackingManager.getPageViewCount();i.pages_per_session=r,i.page_count=r}this.trackSystemEvent("_grain_session_end",i),this.log("Session ended")}getBrowser(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){if(typeof window>"u"||typeof navigator>"u")return"Unknown";let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}handleConsentGranted(){this.flushWaitingForConsentQueue(),this.persistentAnonymousUserId||(this.initializePersistentAnonymousUserId(),this.log("Initialized persistent ID after consent grant")),this.ephemeralSessionId&&this.trackSystemEvent("_grain_consent_granted",{previous_session_id:this.ephemeralSessionId,new_user_id:this.getEffectiveUserId(),timestamp:Date.now()})}trackSystemEvent(e,t){if(this.isDestroyed)return;let i=this.consentManager.hasConsent("analytics"),r={eventName:e,userId:i?this.getEffectiveUserId():this.getEphemeralSessionId(),properties:{...t,_minimal:!i,_consent_status:i?"granted":"pending"}};this.eventQueue.push(r),this.eventCountSinceLastHeartbeat++,this.log(`Queued system event: ${e}`),this.eventQueue.length>=this.config.batchSize&&this.flush().catch(a=>{let n=this.formatError(a,"flush system event");this.logError(n)})}getEphemeralSessionId(){return this.ephemeralSessionId||(this.ephemeralSessionId=this.generateUUID()),this.ephemeralSessionId}getCurrentPage(){return this.pageTrackingManager?.getCurrentPage()||null}getEventCountSinceLastHeartbeat(){return this.eventCountSinceLastHeartbeat}resetEventCountSinceLastHeartbeat(){this.eventCountSinceLastHeartbeat=0}getActivityDetector(){if(!this.activityDetector)throw new Error("Activity detector not initialized");return this.activityDetector}getEffectiveUserId(){return this.getEffectiveUserIdInternal()}getSessionId(){return this.consentManager.hasConsent("analytics")?this.getEffectiveUserId():this.getEphemeralSessionId()}async track(e,t,i){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"track (client destroyed)");this.logError(c);return}let r,a={};if(typeof e=="string"?(r={eventName:e,properties:t},a=i||{}):(r=e,a=t||{}),this.config.allowedProperties&&r.properties){let o={};for(let c of this.config.allowedProperties)c in r.properties&&(o[c]=r.properties[c]);r.properties=o}let n=this.formatEvent(r);if(this.consentManager.shouldWaitForConsent()&&this.config.waitForConsent){this.waitingForConsentQueue.push(n),this.log(`Event waiting for consent: ${r.eventName}`,r.properties);return}if(!this.consentManager.hasConsent("analytics")){this.log(`Event blocked by consent: ${r.eventName}`);return}this.eventQueue.push(n),this.eventCountSinceLastHeartbeat++,this.sessionEventCount++,this.log(`Queued event: ${r.eventName}`),(a.flush||this.eventQueue.length>=this.config.batchSize)&&await this.flush()}catch(r){let a=this.formatError(r,"track");this.logError(a)}}flushWaitingForConsentQueue(){this.waitingForConsentQueue.length!==0&&(this.log(`Flushing ${this.waitingForConsentQueue.length} events waiting for consent`),this.eventQueue.push(...this.waitingForConsentQueue),this.waitingForConsentQueue=[],this.flush().catch(e=>{let t=this.formatError(e,"flush waiting for consent queue");this.logError(t)}))}identify(e){this.log(`Identified user: ${e}`),this.globalUserId=e,this.persistentAnonymousUserId=null}setUserId(e){this.log(`Set global user ID: ${e}`),this.globalUserId=e,e?this.persistentAnonymousUserId=null:this.persistentAnonymousUserId||(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId))}getUserId(){return this.globalUserId}getEffectiveUserIdPublic(){return this.getEffectiveUserIdInternal()}login(e){try{if(this.isDestroyed){let t=new Error("Grain Analytics: Client has been destroyed"),i=this.formatError(t,"login (client destroyed)");this.logError(i);return}e.userId&&(this.log(`Login: Setting user ID to ${e.userId}`),this.globalUserId=e.userId,this.persistentAnonymousUserId=null),e.authToken&&(this.log("Login: Setting auth token"),this.config.authStrategy==="NONE"&&(this.config.authStrategy="JWT"),this.config.authProvider={getToken:()=>e.authToken}),e.authStrategy&&(this.log(`Login: Setting auth strategy to ${e.authStrategy}`),this.config.authStrategy=e.authStrategy),this.log(`Login successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(t){let i=this.formatError(t,"login");this.logError(i)}}logout(){try{if(this.isDestroyed){let e=new Error("Grain Analytics: Client has been destroyed"),t=this.formatError(e,"logout (client destroyed)");this.logError(t);return}if(this.log("Logout: Clearing user session"),this.globalUserId=null,this.config.authStrategy="NONE",this.config.authProvider=void 0,!this.persistentAnonymousUserId&&(this.persistentAnonymousUserId=this.generateAnonymousUserId(),typeof window<"u"))try{let e=`grain_anonymous_user_id_${this.config.tenantId}`;localStorage.setItem(e,this.persistentAnonymousUserId)}catch(e){this.log("Failed to persist new anonymous user ID after logout:",e)}this.log(`Logout successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(e){let t=this.formatError(e,"logout");this.logError(t)}}async setProperty(e,t){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"setProperty (client destroyed)");this.logError(c);return}let i=t?.userId||this.getEffectiveUserIdInternal(),r=Object.keys(e);if(r.length>4){let o=new Error("Grain Analytics: Maximum 4 properties allowed per request"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}if(r.length===0){let o=new Error("Grain Analytics: At least one property is required"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}let a={};for(let[o,c]of Object.entries(e))c==null?a[o]="":typeof c=="string"?a[o]=c:a[o]=JSON.stringify(c);let n={userId:i,...a};await this.sendProperties(n)}catch(i){let r=this.formatError(i,"setProperty");this.logError(r)}}async sendProperties(e){let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(e)});if(!n.ok){let o=`HTTP ${n.status}`;try{let u=await n.json();u?.message&&(o=u.message)}catch{let u=await n.text();u&&(o=u)}let c=new Error(`Failed to set properties: ${o}`);throw c.status=n.status,c}this.log(`Successfully set properties for user ${e.userId}`);return}catch(r){if(t=r,i===this.config.retryAttempts){let n=this.formatError(r,`sendProperties (attempt ${i+1}/${this.config.retryAttempts+1})`);this.logError(n);return}if(!this.isRetriableError(r)){let n=this.formatError(r,"sendProperties (non-retriable error)");this.logError(n);return}let a=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${a}ms after error:`,r),await this.delay(a)}}async trackLogin(e,t){try{return await this.track("login",e,t)}catch(i){let r=this.formatError(i,"trackLogin");this.logError(r)}}async trackSignup(e,t){try{return await this.track("signup",e,t)}catch(i){let r=this.formatError(i,"trackSignup");this.logError(r)}}async trackCheckout(e,t){try{return await this.track("checkout",e,t)}catch(i){let r=this.formatError(i,"trackCheckout");this.logError(r)}}async trackPageView(e,t){try{return await this.track("page_view",e,t)}catch(i){let r=this.formatError(i,"trackPageView");this.logError(r)}}async trackPurchase(e,t){try{return await this.track("purchase",e,t)}catch(i){let r=this.formatError(i,"trackPurchase");this.logError(r)}}async trackSearch(e,t){try{return await this.track("search",e,t)}catch(i){let r=this.formatError(i,"trackSearch");this.logError(r)}}async trackAddToCart(e,t){try{return await this.track("add_to_cart",e,t)}catch(i){let r=this.formatError(i,"trackAddToCart");this.logError(r)}}async trackRemoveFromCart(e,t){try{return await this.track("remove_from_cart",e,t)}catch(i){let r=this.formatError(i,"trackRemoveFromCart");this.logError(r)}}async flush(){try{if(this.eventQueue.length===0)return;let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);for(let i of t)await this.sendEvents(i)}catch(e){let t=this.formatError(e,"flush");this.logError(t)}}initializeConfigCache(){if(!(!this.config.enableConfigCache||typeof window>"u"))try{let e=localStorage.getItem(this.config.configCacheKey);e&&(this.configCache=JSON.parse(e),this.log("Loaded configuration from cache:",this.configCache))}catch(e){this.log("Failed to load configuration cache:",e)}}saveConfigCache(e){if(!(!this.config.enableConfigCache||typeof window>"u"))try{localStorage.setItem(this.config.configCacheKey,JSON.stringify(e)),this.log("Saved configuration to cache:",e)}catch(t){this.log("Failed to save configuration cache:",t)}}getConfig(e){if(this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e]}getAllConfigs(){let e={...this.config.defaultConfigurations};return this.configCache?.configurations&&Object.assign(e,this.configCache.configurations),e}async fetchConfig(e={}){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"fetchConfig (client destroyed)");return this.logError(c),null}let t=e.userId||this.getEffectiveUserIdInternal(),i=e.immediateKeys||[],r=e.properties||{},a={userId:t,immediateKeys:i,properties:r},n;for(let o=0;o<=this.config.retryAttempts;o++)try{let c=await this.getAuthHeaders(),u=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,l=await fetch(u,{method:"POST",headers:c,body:JSON.stringify(a)});if(!l.ok){let y=`HTTP ${l.status}`;try{let p=await l.json();p?.message&&(y=p.message)}catch{let p=await l.text();p&&(y=p)}let G=new Error(`Failed to fetch configurations: ${y}`);throw G.status=l.status,G}let d=await l.json();return d.configurations&&this.updateConfigCache(d,t),this.log("Successfully fetched configurations"),d}catch(c){if(n=c,o===this.config.retryAttempts){let l=this.formatError(c,`fetchConfig (attempt ${o+1}/${this.config.retryAttempts+1})`);return this.logError(l),null}if(!this.isRetriableError(c)){let l=this.formatError(c,"fetchConfig (non-retriable error)");return this.logError(l),null}let u=this.config.retryDelay*Math.pow(2,o);this.log(`Retrying config fetch in ${u}ms after error:`,c),await this.delay(u)}return null}catch(t){let i=this.formatError(t,"fetchConfig");return this.logError(i),null}}async getConfigAsync(e,t={}){try{if(!t.forceRefresh&&this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(!t.forceRefresh&&this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e];let i=await this.fetchConfig(t);return i?i.configurations[e]:this.config.defaultConfigurations?.[e]}catch(i){let r=this.formatError(i,"getConfigAsync");return this.logError(r),this.config.defaultConfigurations?.[e]}}async getAllConfigsAsync(e={}){try{if(!e.forceRefresh&&this.configCache?.configurations)return{...this.config.defaultConfigurations,...this.configCache.configurations};let t=await this.fetchConfig(e);return t?{...this.config.defaultConfigurations,...t.configurations}:{...this.config.defaultConfigurations}}catch(t){let i=this.formatError(t,"getAllConfigsAsync");return this.logError(i),{...this.config.defaultConfigurations}}}updateConfigCache(e,t){let i={configurations:e.configurations,snapshotId:e.snapshotId,timestamp:e.timestamp,userId:t},r=this.configCache?.configurations||{};this.configCache=i,this.saveConfigCache(i),JSON.stringify(r)!==JSON.stringify(e.configurations)&&this.notifyConfigChangeListeners(e.configurations)}addConfigChangeListener(e){this.configChangeListeners.push(e)}removeConfigChangeListener(e){let t=this.configChangeListeners.indexOf(e);t>-1&&this.configChangeListeners.splice(t,1)}notifyConfigChangeListeners(e){this.configChangeListeners.forEach(t=>{try{t(e)}catch(i){console.error("[Grain Analytics] Config change listener error:",i)}})}startConfigRefreshTimer(){typeof window>"u"||(this.configRefreshTimer&&clearInterval(this.configRefreshTimer),this.configRefreshTimer=window.setInterval(()=>{this.isDestroyed||this.fetchConfig().catch(e=>{let t=this.formatError(e,"auto-config refresh");this.logError(t)})},this.config.configRefreshInterval))}stopConfigRefreshTimer(){this.configRefreshTimer&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null)}async preloadConfig(e=[],t){try{let i=this.getEffectiveUserIdInternal();this.log(`Preloading config for user: ${i}`),await this.fetchConfig({immediateKeys:e,properties:t})&&this.startConfigRefreshTimer()}catch(i){let r=this.formatError(i,"preloadConfig");this.logError(r)}}chunkEvents(e,t){let i=[];for(let r=0;r<e.length;r+=t)i.push(e.slice(r,r+t));return i}grantConsent(e){try{this.consentManager.grantConsent(e),this.log("Consent granted",e)}catch(t){let i=this.formatError(t,"grantConsent");this.logError(i)}}revokeConsent(e){try{this.consentManager.revokeConsent(e),this.log("Consent revoked",e),this.eventQueue=[],this.waitingForConsentQueue=[]}catch(t){let i=this.formatError(t,"revokeConsent");this.logError(i)}}getConsentState(){return this.consentManager.getConsentState()}hasConsent(e){return this.consentManager.hasConsent(e)}onConsentChange(e){this.consentManager.addListener(e)}offConsentChange(e){this.consentManager.removeListener(e)}destroy(){if(this.isDestroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.stopConfigRefreshTimer(),this.configChangeListeners=[],this.heartbeatManager&&(this.heartbeatManager.destroy(),this.heartbeatManager=null),this.pageTrackingManager&&(this.pageTrackingManager.destroy(),this.pageTrackingManager=null),this.activityDetector&&(this.activityDetector.destroy(),this.activityDetector=null),this.interactionTrackingManager&&(this.interactionTrackingManager.destroy(),this.interactionTrackingManager=null),this.sectionTrackingManager&&(this.sectionTrackingManager.destroy(),this.sectionTrackingManager=null),this.heatmapTrackingManager&&(this.heatmapTrackingManager.destroy(),this.heatmapTrackingManager=null),this.eventQueue.length>0){let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);if(t.length>0){this.sendEventsWithBeacon(t[0]).catch(()=>{});for(let i=1;i<t.length;i++)this.sendEventsWithBeacon(t[i]).catch(()=>{})}}}};function ee(s){return new f(s)}var Ae=f;typeof window<"u"&&(window.Grain={GrainAnalytics:f,createGrainAnalytics:ee});return ae(ve);})();
|
|
1
|
+
/* Grain Analytics Web SDK v2.9.0 | MIT License */
|
|
2
|
+
"use strict";var Grain=(()=>{var _=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var se=Object.prototype.hasOwnProperty;var g=(s,e)=>()=>(s&&(e=s(s=0)),e);var b=(s,e)=>{for(var t in e)_(s,t,{get:e[t],enumerable:!0})},ce=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of oe(e))!se.call(s,r)&&r!==t&&_(s,r,{get:()=>e[r],enumerable:!(i=ae(e,r))||i.enumerable});return s};var le=s=>ce(_({},"__esModule",{value:!0}),s);var be,f,U=g(()=>{"use strict";be={maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4},f=class{constructor(e,t={}){this.isDestroyed=!1;this.isPageVisible=!0;this.visibilityChangeHandler=null;this.sectionStates=new Map;this.lastFilterReason=null;this.activityDetector=e,this.options={...be,...t,debug:t.debug??!1},this.setupPageVisibilityTracking()}setupPageVisibilityTracking(){typeof document>"u"||(this.isPageVisible=document.visibilityState==="visible",this.visibilityChangeHandler=()=>{let e=this.isPageVisible;this.isPageVisible=document.visibilityState==="visible",!this.isPageVisible&&e?this.log("Page hidden - tracking paused"):this.isPageVisible&&!e&&(this.log("Page visible - tracking resumed"),this.resetAllSections())},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}shouldTrack(){return this.isPageVisible?this.activityDetector.isActive(this.options.idleThreshold)?(this.lastFilterReason=null,!0):(this.lastFilterReason="user_idle",!1):(this.lastFilterReason="page_hidden",!1)}shouldTrackSection(e,t){if(!this.shouldTrack())return{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"};let i=this.sectionStates.get(e);i||(i={sectionName:e,currentDuration:0,lastScrollPosition:t,lastResetTime:Date.now()},this.sectionStates.set(e,i));let r=Math.abs(t-i.lastScrollPosition);return r>=this.options.minScrollDistance?(this.log(`Section "${e}": Attention reset due to ${Math.round(r)}px scroll`),i.currentDuration=0,i.lastScrollPosition=t,i.lastResetTime=Date.now(),{shouldTrack:!0,resetAttention:!0}):i.currentDuration>=this.options.maxSectionDuration?{shouldTrack:!1,reason:"max_duration_reached"}:{shouldTrack:!0}}updateSectionDuration(e,t){let i=this.sectionStates.get(e);i&&(i.currentDuration+=t,i.currentDuration>=this.options.maxSectionDuration&&this.log(`Section "${e}": Max duration cap reached (${i.currentDuration}ms)`))}resetSection(e){let t=this.sectionStates.get(e);t&&(this.log(`Section "${e}": Attention reset (section exit)`),t.currentDuration=0,t.lastResetTime=Date.now())}resetAllSections(){this.log("Resetting all section attention states");for(let e of this.sectionStates.values())e.currentDuration=0,e.lastResetTime=Date.now()}getSectionState(e){return this.sectionStates.get(e)}getLastFilterReason(){return this.lastFilterReason}shouldTrackScroll(e,t){return this.shouldTrack()?Math.abs(t-e)<10?{shouldTrack:!1,reason:"scroll_too_small"}:{shouldTrack:!0}:{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"}}getPolicies(){return{maxSectionDuration:this.options.maxSectionDuration,minScrollDistance:this.options.minScrollDistance,idleThreshold:this.options.idleThreshold}}getTrackingState(){return{isPageVisible:this.isPageVisible,isUserActive:this.activityDetector.isActive(this.options.idleThreshold),timeSinceLastActivity:this.activityDetector.getTimeSinceLastActivity(),activeSections:this.sectionStates.size}}log(...e){this.options.debug&&console.log("[AttentionQuality]",...e)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.sectionStates.clear())}}});function Ae(s){if(s)return s.replace(/[\u{1F300}-\u{1F9FF}]/gu,"").replace(/[\u{1F600}-\u{1F64F}]/gu,"").replace(/[\u{1F680}-\u{1F6FF}]/gu,"").replace(/[\u{2600}-\u{26FF}]/gu,"").replace(/[\u{2700}-\u{27BF}]/gu,"").replace(/[\u{1F900}-\u{1F9FF}]/gu,"").replace(/[\u{1F1E0}-\u{1F1FF}]/gu,"").replace(/[\u{200D}]/gu,"").replace(/[\u{FE0F}]/gu,"").replace(/[\u{20E3}]/gu,"").trim()}function x(s,e=100){if(!s)return;let t=Ae(s);if(t)return t.substring(0,e)||void 0}var N=g(()=>{"use strict"});var J={};b(J,{HeatmapTrackingManager:()=>H});var Se,H,q=g(()=>{"use strict";U();N();Se={scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:!1},H=class{constructor(e,t={}){this.isDestroyed=!1;this.currentScrollState=null;this.pendingClicks=[];this.pendingScrolls=[];this.scrollDebounceTimer=null;this.batchTimer=null;this.scrollTrackingTimer=null;this.periodicScrollTimer=null;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.SPLIT_DURATION=3e3;this.tracker=e,this.options={...Se,...t},this.attentionQuality=new f(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing heatmap tracking"),this.setupClickTracking(),this.setupScrollTracking(),this.startScrollTracking(),this.setupUnloadHandler())}setupClickTracking(){if(typeof document>"u")return;let e=t=>{this.isDestroyed||this.tracker.hasConsent("analytics")&&this.handleClick(t)};document.addEventListener("click",e,{passive:!0,capture:!0})}setupScrollTracking(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.handleScroll(),this.scrollDebounceTimer=null},this.options.scrollDebounceDelay)};window.addEventListener("scroll",e,{passive:!0})}startScrollTracking(){typeof window>"u"||(this.updateScrollState(),this.scrollTrackingTimer=window.setInterval(()=>{this.isDestroyed||this.updateScrollState()},500),this.startPeriodicScrollTracking())}startPeriodicScrollTracking(){typeof window>"u"||(this.periodicScrollTimer=window.setInterval(()=>{if(this.isDestroyed||!this.currentScrollState||!this.tracker.hasConsent("analytics"))return;if(!this.attentionQuality.shouldTrack()){this.log("Scroll tracking paused:",this.attentionQuality.getLastFilterReason());return}let e=Date.now(),t=e-this.currentScrollState.entryTime;if(t>1e3){let i=window.scrollY||window.pageYOffset,r=window.innerHeight,a=document.documentElement.scrollHeight,n=`viewport_section_${this.currentScrollState.viewportSection}`,o=this.attentionQuality.shouldTrackSection(n,i);if(o.resetAttention){this.log(`Viewport section ${this.currentScrollState.viewportSection}: Attention reset`),this.currentScrollState.entryTime=e;return}if(!o.shouldTrack){this.log(`Viewport section ${this.currentScrollState.viewportSection}: ${o.reason}`);return}let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:i,durationMs:t,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:a,viewportHeight:r};this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:c.pageUrl,viewport_section:c.viewportSection,scroll_depth_px:c.scrollDepthPx,duration_ms:c.durationMs,entry_timestamp:c.entryTimestamp,exit_timestamp:c.exitTimestamp,page_height:c.pageHeight,viewport_height:c.viewportHeight,is_split:!0},{flush:!0}),this.attentionQuality.updateSectionDuration(n,t),this.currentScrollState.entryTime=e}},this.SPLIT_DURATION))}setupUnloadHandler(){if(typeof window>"u")return;let e=()=>{if(this.currentScrollState){let t=Date.now(),i=t-this.currentScrollState.entryTime;if(i>100){let r={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:i,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:t,pageHeight:document.documentElement.scrollHeight,viewportHeight:window.innerHeight};this.pendingScrolls.push(r)}}this.flushPendingEventsWithBeacon()};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e)}handleClick(e){if(!this.tracker.hasConsent("analytics"))return;let t=e.target;if(!t)return;let i=window.location.href,r=this.generateXPath(t),a=Math.round(e.clientX),n=Math.round(e.clientY),o=Math.round(e.pageX),c=Math.round(e.pageY),l=t.tagName?.toLowerCase()||"unknown",u=x(t.textContent),d={pageUrl:i,xpath:r,viewportX:a,viewportY:n,pageX:o,pageY:c,elementTag:l,elementText:u||void 0,timestamp:Date.now()};t instanceof HTMLAnchorElement&&t.href?this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:d.pageUrl,xpath:d.xpath,viewport_x:d.viewportX,viewport_y:d.viewportY,page_x:d.pageX,page_y:d.pageY,element_tag:d.elementTag,element_text:d.elementText,timestamp:d.timestamp},{flush:!0}):(this.pendingClicks.push(d),this.considerBatchFlush())}handleScroll(){this.tracker.hasConsent("analytics")&&this.updateScrollState()}updateScrollState(){if(typeof window>"u"||!this.tracker.hasConsent("analytics"))return;let e=Date.now(),t=window.scrollY||window.pageYOffset,i=window.innerHeight,r=document.documentElement.scrollHeight,a=Math.floor(t/i);if(this.currentScrollState&&this.currentScrollState.viewportSection!==a){let n=e-this.currentScrollState.entryTime;if(n>100){let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:n,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:r,viewportHeight:i};this.pendingScrolls.push(c)}let o=`viewport_section_${this.currentScrollState.viewportSection}`;this.attentionQuality.resetSection(o)}(!this.currentScrollState||this.currentScrollState.viewportSection!==a)&&(this.currentScrollState={viewportSection:a,entryTime:e,scrollDepthPx:t}),this.lastScrollPosition=t,this.lastScrollTime=e,this.considerBatchFlush()}generateXPath(e){if(!e)return"";if(e.id)return`//*[@id="${e.id}"]`;let t=[],i=e;for(;i&&i.nodeType===Node.ELEMENT_NODE;){let r=0,a=i;for(;a;)a=a.previousElementSibling,a&&a.nodeName===i.nodeName&&r++;let n=i.nodeName.toLowerCase(),o=r>0?`[${r+1}]`:"";t.unshift(`${n}${o}`),i=i.parentElement}return t.length?`/${t.join("/")}`:""}considerBatchFlush(){let e=this.pendingClicks.length+this.pendingScrolls.length;if(e>=this.options.maxBatchSize){this.flushPendingEvents();return}this.batchTimer===null&&e>0&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents(),this.batchTimer=null},this.options.batchDelay))}flushPendingEvents(){if(!this.isDestroyed){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight});this.pendingScrolls=[]}this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null)}}flushPendingEventsWithBeacon(){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp},{flush:!0});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight},{flush:!0});this.pendingScrolls=[]}}log(...e){this.options.debug&&this.tracker.log("[Heatmap Tracking]",...e)}destroy(){this.isDestroyed=!0,this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.scrollTrackingTimer!==null&&(clearInterval(this.scrollTrackingTimer),this.scrollTrackingTimer=null),this.periodicScrollTimer!==null&&(clearInterval(this.periodicScrollTimer),this.periodicScrollTimer=null),this.attentionQuality.destroy(),this.flushPendingEvents()}}});var X={};b(X,{InteractionTrackingManager:()=>O});var O,Z=g(()=>{"use strict";N();O=class{constructor(e,t,i={}){this.isDestroyed=!1;this.attachedListeners=new Map;this.xpathCache=new Map;this.mutationObserver=null;this.mutationDebounceTimer=null;this.tracker=e,this.interactions=t,this.config={debug:i.debug??!1,enableMutationObserver:i.enableMutationObserver??!0,mutationDebounceDelay:i.mutationDebounceDelay??500,tenantId:i.tenantId,apiUrl:i.apiUrl},typeof window<"u"&&typeof document<"u"&&(this.config.tenantId&&this.config.apiUrl?this.fetchAndMergeTrackers().then(()=>{this.attachAllListeners()}):document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.attachAllListeners()):setTimeout(()=>this.attachAllListeners(),0),this.config.enableMutationObserver&&this.setupMutationObserver())}async fetchAndMergeTrackers(){if(!(!this.config.tenantId||!this.config.apiUrl))try{let e=typeof window<"u"?window.location.href:"",t=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/trackers?url=${encodeURIComponent(e)}`;this.log("Fetching trackers from:",t);let i=await fetch(t,{method:"GET",headers:{"Content-Type":"application/json"}});if(!i.ok){this.log("Failed to fetch trackers:",i.status);return}let r=await i.json();if(r.trackers&&Array.isArray(r.trackers)){this.log("Fetched",r.trackers.length,"trackers");let a=r.trackers.map(n=>({eventName:n.eventName,selector:n.selector,priority:5,label:n.eventName,description:`Tracker: ${n.eventName}`}));this.interactions=[...a,...this.interactions],this.log("Merged trackers, total interactions:",this.interactions.length)}}catch(e){this.log("Error fetching trackers:",e)}}attachAllListeners(){if(!this.isDestroyed){this.log("Attaching interaction listeners");for(let e of this.interactions)this.attachInteractionListener(e)}}attachInteractionListener(e){if(this.isDestroyed)return;let t=this.findElementByXPath(e.selector);if(!t){this.log("Element not found for interaction:",e.eventName,"selector:",e.selector);return}if(this.attachedListeners.has(t)){this.log("Listeners already attached for element:",t);return}let i=[],r=a=>this.handleInteractionClick(e,a);if(t.addEventListener("click",r,{passive:!0}),i.push({event:"click",handler:r}),t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){let a=n=>this.handleInteractionFocus(e,n);t.addEventListener("focus",a,{passive:!0}),i.push({event:"focus",handler:a})}this.attachedListeners.set(t,i)}handleInteractionClick(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target,r=i instanceof HTMLAnchorElement&&i.href,a={interaction_type:"click",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_text:x(i.textContent),element_id:i.id||void 0,element_class:i.className||void 0,...r&&{href:i.href},timestamp:Date.now()},n=this.tracker.track(e.eventName,a,{flush:!0});n instanceof Promise&&n.catch(o=>{this.log("Failed to track click:",o)})}handleInteractionFocus(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target;this.tracker.track(e.eventName,{interaction_type:"focus",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_id:i.id||void 0,element_class:i.className||void 0,timestamp:Date.now()})}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}setupMutationObserver(){if(typeof MutationObserver>"u"){this.log("MutationObserver not supported");return}this.mutationObserver=new MutationObserver(e=>{this.mutationDebounceTimer!==null&&clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=window.setTimeout(()=>{this.handleMutations(e),this.mutationDebounceTimer=null},this.config.mutationDebounceDelay)}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Mutation observer setup")}handleMutations(e){if(this.isDestroyed)return;this.xpathCache.clear();let t=new Set;for(let i of e)i.removedNodes.forEach(r=>{r instanceof Element&&(t.add(r),this.attachedListeners.forEach((a,n)=>{r.contains(n)&&t.add(n)}))});t.forEach(i=>{this.detachListeners(i)}),this.attachAllListeners()}detachListeners(e){let t=this.attachedListeners.get(e);t&&(t.forEach(({event:i,handler:r})=>{e.removeEventListener(i,r)}),this.attachedListeners.delete(e))}log(...e){this.config.debug&&console.log("[InteractionTracking]",...e)}updateInteractions(e){this.isDestroyed||(this.log("Updating interactions configuration"),this.attachedListeners.forEach((t,i)=>{this.detachListeners(i)}),this.xpathCache.clear(),this.interactions=e,this.attachAllListeners())}destroy(){this.isDestroyed||(this.log("Destroying interaction tracking manager"),this.isDestroyed=!0,this.mutationDebounceTimer!==null&&(clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.attachedListeners.forEach((e,t)=>{this.detachListeners(t)}),this.attachedListeners.clear(),this.xpathCache.clear())}}});var ee={};b(ee,{SectionTrackingManager:()=>B});var Ee,B,te=g(()=>{"use strict";U();Ee={minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:!1},B=class{constructor(e,t,i={}){this.isDestroyed=!1;this.sectionStates=new Map;this.intersectionObserver=null;this.xpathCache=new Map;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.scrollVelocity=0;this.scrollDebounceTimer=null;this.pendingEvents=[];this.batchTimer=null;this.sectionTimers=new Map;this.SPLIT_DURATION=3e3;this.tracker=e,this.sections=t,this.options={...Ee,...i},this.attentionQuality=new f(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing section tracking"),this.setupIntersectionObserver(),this.setupScrollListener(),this.initializeSections())}setupIntersectionObserver(){if(typeof IntersectionObserver>"u"){this.log("IntersectionObserver not supported");return}this.intersectionObserver=new IntersectionObserver(e=>{e.forEach(t=>{this.handleIntersection(t)})},{threshold:[0,.1,.25,.5,.75,1],rootMargin:"0px"}),this.log("IntersectionObserver created")}setupScrollListener(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.updateScrollVelocity(),this.scrollDebounceTimer=null},this.options.debounceDelay)};window.addEventListener("scroll",e,{passive:!0}),this.log("Scroll listener attached")}initializeSections(){for(let e of this.sections){let t=this.findElementByXPath(e.selector);if(!t){this.log("Section element not found:",e.sectionName,"selector:",e.selector);continue}let i={element:t,config:e,entryTime:null,exitTime:null,isVisible:!1,lastScrollPosition:window.scrollY,lastScrollTime:Date.now(),entryScrollSpeed:0,exitScrollSpeed:0,maxVisibleArea:0};this.sectionStates.set(e.sectionName,i),this.intersectionObserver&&this.intersectionObserver.observe(t)}}handleIntersection(e){if(this.isDestroyed)return;let t=Array.from(this.sectionStates.values()).find(a=>a.element===e.target);if(!t)return;let i=e.isIntersecting&&e.intersectionRatio>=this.options.intersectionThreshold,r=e.intersectionRatio;r>t.maxVisibleArea&&(t.maxVisibleArea=r),i&&!t.isVisible?this.handleSectionEntry(t):!i&&t.isVisible&&this.handleSectionExit(t),t.isVisible=i}handleSectionEntry(e){e.entryTime=Date.now(),e.entryScrollSpeed=this.scrollVelocity,e.lastScrollPosition=window.scrollY,e.lastScrollTime=Date.now(),e.maxVisibleArea=0,this.startPeriodicTracking(e)}startPeriodicTracking(e){this.stopPeriodicTracking(e.config.sectionName);let t=window.setInterval(()=>{if(this.isDestroyed||!e.isVisible||e.entryTime===null){this.stopPeriodicTracking(e.config.sectionName);return}let i=Date.now(),r=i-e.entryTime;if(r>=this.options.minDwellTime){let a=window.scrollY,n=this.attentionQuality.shouldTrackSection(e.config.sectionName,a);if(n.resetAttention){this.log(`Section "${e.config.sectionName}": Attention reset, restarting timer`),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity;return}if(!n.shouldTrack){this.log(`Section "${e.config.sectionName}": Tracking paused - ${n.reason}`);return}let o={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:i,duration:r,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:this.scrollVelocity};this.shouldTrackSection(o)&&(this.tracker.trackSystemEvent("_grain_section_view",{section_name:o.sectionName,section_type:o.sectionType,duration_ms:o.duration,viewport_width:o.viewportWidth,viewport_height:o.viewportHeight,scroll_depth_percent:o.scrollDepth,visible_area_percent:o.visibleAreaPercentage,scroll_speed_entry:Math.round(o.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(o.scrollSpeedAtExit||0),entry_timestamp:o.entryTime,exit_timestamp:o.exitTime,is_split:!0}),this.attentionQuality.updateSectionDuration(e.config.sectionName,r),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity)}},this.SPLIT_DURATION);this.sectionTimers.set(e.config.sectionName,t)}stopPeriodicTracking(e){let t=this.sectionTimers.get(e);t!==void 0&&(clearInterval(t),this.sectionTimers.delete(e))}handleSectionExit(e){if(this.stopPeriodicTracking(e.config.sectionName),this.attentionQuality.resetSection(e.config.sectionName),e.entryTime===null)return;e.exitTime=Date.now(),e.exitScrollSpeed=this.scrollVelocity;let t=e.exitTime-e.entryTime,i={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:e.exitTime,duration:t,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:e.exitScrollSpeed};this.shouldTrackSection(i)?this.queueSectionView(i):this.log("Section view filtered out:",e.config.sectionName,"duration:",t),e.entryTime=null}updateScrollVelocity(){let e=Date.now(),t=window.scrollY,i=e-this.lastScrollTime,r=Math.abs(t-this.lastScrollPosition);i>0&&(this.scrollVelocity=r/i*1e3),this.lastScrollPosition=t,this.lastScrollTime=e}calculateScrollDepth(){if(typeof window>"u"||typeof document>"u")return 0;let e=window.innerHeight,t=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight),i=window.scrollY,r=t-e;return r<=0?100:Math.round(i/r*100)}shouldTrackSection(e){return!(e.duration<this.options.minDwellTime||(e.scrollSpeedAtEntry+e.scrollSpeedAtExit)/2>this.options.scrollVelocityThreshold*2||e.visibleAreaPercentage<10)}queueSectionView(e){this.pendingEvents.push(e),this.batchTimer===null&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents()},this.options.batchDelay))}flushPendingEvents(){if(!(this.isDestroyed||this.pendingEvents.length===0)){if(!this.tracker.hasConsent("analytics")){this.pendingEvents=[];return}for(let e of this.pendingEvents)this.tracker.trackSystemEvent("_grain_section_view",{section_name:e.sectionName,section_type:e.sectionType,duration_ms:e.duration,viewport_width:e.viewportWidth,viewport_height:e.viewportHeight,scroll_depth_percent:e.scrollDepth,visible_area_percent:e.visibleAreaPercentage,scroll_speed_entry:Math.round(e.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(e.scrollSpeedAtExit||0),entry_timestamp:e.entryTime,exit_timestamp:e.exitTime});this.pendingEvents=[],this.batchTimer=null}}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}log(...e){this.options.debug&&console.log("[SectionTracking]",...e)}updateSections(e){this.isDestroyed||(this.log("Updating sections configuration"),this.intersectionObserver&&this.intersectionObserver.disconnect(),this.sectionStates.clear(),this.xpathCache.clear(),this.sections=e,this.setupIntersectionObserver(),this.initializeSections())}destroy(){this.isDestroyed||(this.log("Destroying section tracking manager"),this.isDestroyed=!0,this.sectionTimers.forEach(e=>{clearInterval(e)}),this.sectionTimers.clear(),this.flushPendingEvents(),this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.intersectionObserver&&(this.intersectionObserver.disconnect(),this.intersectionObserver=null),this.attentionQuality.destroy(),this.sectionStates.clear(),this.xpathCache.clear(),this.pendingEvents=[])}}});var ie={};b(ie,{DebugAgent:()=>G});var G,re=g(()=>{"use strict";G=class{constructor(e,t,i,r,a={}){this.isDestroyed=!1;this.isInspectMode=!1;this.showTrackers=!1;this.selectedElement=null;this.toolbarElement=null;this.panelElement=null;this.highlightElement=null;this.existingTrackers=[];this.trackerHighlights=[];this.isDragging=!1;this.dragStartX=0;this.dragStartY=0;this.toolbarStartX=0;this.toolbarStartY=0;this.mouseMoveListener=null;this.clickListener=null;this.dragMoveListener=null;this.dragEndListener=null;this.handleEscapeKey=e=>{e.key==="Escape"&&this.isInspectMode&&this.disableInspectMode()};this.tracker=e,this.sessionId=t,this.tenantId=i,this.apiUrl=r,this.config={debug:a.debug??!1},typeof window<"u"&&typeof document<"u"&&this.initialize()}async initialize(){this.log("Initializing debug agent"),await this.loadExistingTrackers(),this.showToolbar(),this.createHighlightElement(),this.showTrackers=!0,this.showTrackerHighlights(),this.showTrackersList()}async loadExistingTrackers(){try{let e=`${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/trackers`,t=await fetch(e);t.ok&&(this.existingTrackers=await t.json(),this.log("Loaded trackers:",this.existingTrackers))}catch(e){this.log("Failed to load trackers:",e),this.existingTrackers=[]}}showToolbar(){if(this.toolbarElement)return;let e=document.createElement("div");e.id="grain-debug-toolbar",e.innerHTML=`
|
|
3
|
+
<style>
|
|
4
|
+
#grain-debug-toolbar {
|
|
5
|
+
position: fixed;
|
|
6
|
+
bottom: 20px;
|
|
7
|
+
right: 20px;
|
|
8
|
+
background: repeating-linear-gradient(
|
|
9
|
+
45deg,
|
|
10
|
+
#fbbf24,
|
|
11
|
+
#fbbf24 10px,
|
|
12
|
+
#1e293b 10px,
|
|
13
|
+
#1e293b 20px
|
|
14
|
+
);
|
|
15
|
+
border: 2px solid #1e293b;
|
|
16
|
+
border-radius: 12px;
|
|
17
|
+
padding: 6px;
|
|
18
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
19
|
+
z-index: 999999;
|
|
20
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
21
|
+
font-size: 13px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.grain-toolbar-inner {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: 12px;
|
|
28
|
+
background: white;
|
|
29
|
+
border-radius: 6px;
|
|
30
|
+
padding: 8px 12px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#grain-debug-toolbar.dragging {
|
|
34
|
+
cursor: move;
|
|
35
|
+
user-select: none;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.grain-toolbar-header {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
cursor: move;
|
|
42
|
+
user-select: none;
|
|
43
|
+
padding: 6px 10px;
|
|
44
|
+
background: #1e293b;
|
|
45
|
+
border-radius: 4px;
|
|
46
|
+
margin-right: 4px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.grain-toolbar-title {
|
|
50
|
+
font-size: 11px;
|
|
51
|
+
font-weight: 700;
|
|
52
|
+
letter-spacing: 1.2px;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
color: #fbbf24;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.grain-toolbar-body {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 10px;
|
|
61
|
+
flex: 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.grain-toolbar-stats {
|
|
65
|
+
display: flex;
|
|
66
|
+
gap: 12px;
|
|
67
|
+
padding: 6px 10px;
|
|
68
|
+
background: #f8fafc;
|
|
69
|
+
border-radius: 4px;
|
|
70
|
+
margin-right: 4px;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.grain-stat {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: baseline;
|
|
76
|
+
gap: 6px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.grain-stat-value {
|
|
80
|
+
font-size: 18px;
|
|
81
|
+
font-weight: 700;
|
|
82
|
+
color: #1e293b;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.grain-stat-label {
|
|
86
|
+
font-size: 11px;
|
|
87
|
+
color: #64748b;
|
|
88
|
+
font-weight: 500;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.grain-toolbar-actions {
|
|
92
|
+
display: flex;
|
|
93
|
+
gap: 8px;
|
|
94
|
+
align-items: center;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#grain-debug-toolbar button {
|
|
98
|
+
background: white;
|
|
99
|
+
border: 1.5px solid #e2e8f0;
|
|
100
|
+
color: #475569;
|
|
101
|
+
padding: 8px 14px;
|
|
102
|
+
border-radius: 8px;
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
font-size: 12px;
|
|
105
|
+
font-weight: 600;
|
|
106
|
+
transition: all 0.2s;
|
|
107
|
+
display: flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
justify-content: center;
|
|
110
|
+
gap: 6px;
|
|
111
|
+
white-space: nowrap;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
#grain-debug-toolbar button:hover {
|
|
115
|
+
background: #f8fafc;
|
|
116
|
+
border-color: #cbd5e1;
|
|
117
|
+
transform: translateY(-1px);
|
|
118
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
#grain-debug-toolbar button.active {
|
|
122
|
+
background: #fbbf24;
|
|
123
|
+
color: #1e293b;
|
|
124
|
+
border-color: #fbbf24;
|
|
125
|
+
box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#grain-debug-toolbar button.danger {
|
|
129
|
+
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
|
|
130
|
+
border-color: #ef4444;
|
|
131
|
+
color: white;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#grain-debug-toolbar button.danger:hover {
|
|
135
|
+
transform: translateY(-1px);
|
|
136
|
+
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.25);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.grain-debug-highlight {
|
|
140
|
+
position: absolute;
|
|
141
|
+
pointer-events: none;
|
|
142
|
+
border: 2px solid #10b981;
|
|
143
|
+
background: rgba(16, 185, 129, 0.1);
|
|
144
|
+
z-index: 999998;
|
|
145
|
+
transition: all 0.1s;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.grain-tracker-highlight {
|
|
149
|
+
position: absolute;
|
|
150
|
+
pointer-events: none;
|
|
151
|
+
border: 2px solid #6366f1;
|
|
152
|
+
background: rgba(99, 102, 241, 0.08);
|
|
153
|
+
z-index: 999997;
|
|
154
|
+
transition: opacity 0.2s;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.grain-tracker-label {
|
|
158
|
+
position: absolute;
|
|
159
|
+
top: -28px;
|
|
160
|
+
left: 0;
|
|
161
|
+
background: #6366f1;
|
|
162
|
+
color: white;
|
|
163
|
+
padding: 4px 10px;
|
|
164
|
+
border-radius: 6px;
|
|
165
|
+
font-size: 11px;
|
|
166
|
+
font-weight: 600;
|
|
167
|
+
white-space: nowrap;
|
|
168
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
169
|
+
pointer-events: none;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.grain-tracker-label::after {
|
|
173
|
+
content: '';
|
|
174
|
+
position: absolute;
|
|
175
|
+
bottom: -4px;
|
|
176
|
+
left: 10px;
|
|
177
|
+
width: 0;
|
|
178
|
+
height: 0;
|
|
179
|
+
border-left: 4px solid transparent;
|
|
180
|
+
border-right: 4px solid transparent;
|
|
181
|
+
border-top: 4px solid #6366f1;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.grain-trackers-list {
|
|
185
|
+
position: fixed;
|
|
186
|
+
bottom: 80px;
|
|
187
|
+
right: 20px;
|
|
188
|
+
background: white;
|
|
189
|
+
border: 1.5px solid #e2e8f0;
|
|
190
|
+
border-radius: 10px;
|
|
191
|
+
padding: 12px;
|
|
192
|
+
max-height: 400px;
|
|
193
|
+
width: 320px;
|
|
194
|
+
overflow-y: auto;
|
|
195
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
196
|
+
z-index: 999998;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.grain-tracker-item {
|
|
200
|
+
padding: 10px;
|
|
201
|
+
background: #f8fafc;
|
|
202
|
+
border-radius: 8px;
|
|
203
|
+
margin-bottom: 8px;
|
|
204
|
+
cursor: pointer;
|
|
205
|
+
transition: all 0.2s;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.grain-tracker-item:hover {
|
|
209
|
+
background: #f1f5f9;
|
|
210
|
+
transform: translateX(4px);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.grain-tracker-item:last-child {
|
|
214
|
+
margin-bottom: 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.grain-tracker-name {
|
|
218
|
+
font-weight: 600;
|
|
219
|
+
color: #1e293b;
|
|
220
|
+
font-size: 13px;
|
|
221
|
+
margin-bottom: 4px;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.grain-tracker-details {
|
|
225
|
+
font-size: 11px;
|
|
226
|
+
color: #64748b;
|
|
227
|
+
display: flex;
|
|
228
|
+
gap: 8px;
|
|
229
|
+
align-items: center;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.grain-tracker-type {
|
|
233
|
+
background: #dbeafe;
|
|
234
|
+
color: #1e40af;
|
|
235
|
+
padding: 2px 6px;
|
|
236
|
+
border-radius: 4px;
|
|
237
|
+
font-weight: 600;
|
|
238
|
+
text-transform: uppercase;
|
|
239
|
+
font-size: 9px;
|
|
240
|
+
letter-spacing: 0.5px;
|
|
241
|
+
}
|
|
242
|
+
</style>
|
|
243
|
+
<div class="grain-toolbar-inner">
|
|
244
|
+
<div class="grain-toolbar-header" id="grain-toolbar-handle">
|
|
245
|
+
<div class="grain-toolbar-title">Grain Debug</div>
|
|
246
|
+
</div>
|
|
247
|
+
<div class="grain-toolbar-body">
|
|
248
|
+
<div class="grain-toolbar-stats">
|
|
249
|
+
<div class="grain-stat">
|
|
250
|
+
<div class="grain-stat-value">${this.existingTrackers.length}</div>
|
|
251
|
+
<div class="grain-stat-label">trackers</div>
|
|
252
|
+
</div>
|
|
253
|
+
<div class="grain-stat">
|
|
254
|
+
<div class="grain-stat-value">${this.existingTrackers.filter(n=>n.isEnabled).length}</div>
|
|
255
|
+
<div class="grain-stat-label">active</div>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
<div class="grain-toolbar-actions">
|
|
259
|
+
<button id="grain-debug-inspect" type="button">
|
|
260
|
+
+ New
|
|
261
|
+
</button>
|
|
262
|
+
<button id="grain-debug-trackers" class="active" type="button">
|
|
263
|
+
Hide
|
|
264
|
+
</button>
|
|
265
|
+
<button id="grain-debug-end" class="danger" type="button">
|
|
266
|
+
End Session
|
|
267
|
+
</button>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
<div id="grain-trackers-list-container"></div>
|
|
272
|
+
`,document.body.appendChild(e),this.toolbarElement=e;let t=e.querySelector("#grain-toolbar-handle");t&&t.addEventListener("mousedown",n=>this.startDrag(n));let i=e.querySelector("#grain-debug-inspect"),r=e.querySelector("#grain-debug-trackers"),a=e.querySelector("#grain-debug-end");i&&i.addEventListener("click",()=>this.toggleInspectMode()),r&&r.addEventListener("click",()=>this.toggleTrackerView()),a&&a.addEventListener("click",()=>this.endDebug()),this.log("Toolbar shown")}createHighlightElement(){if(this.highlightElement)return;let e=document.createElement("div");e.className="grain-debug-highlight",e.style.display="none",document.body.appendChild(e),this.highlightElement=e}startDrag(e){if(!this.toolbarElement)return;this.isDragging=!0,this.dragStartX=e.clientX,this.dragStartY=e.clientY;let t=this.toolbarElement.getBoundingClientRect();this.toolbarStartX=t.left,this.toolbarStartY=t.top,this.toolbarElement.classList.add("dragging"),this.dragMoveListener=i=>this.onDrag(i),this.dragEndListener=()=>this.endDrag(),document.addEventListener("mousemove",this.dragMoveListener),document.addEventListener("mouseup",this.dragEndListener)}onDrag(e){if(!this.isDragging||!this.toolbarElement)return;let t=e.clientX-this.dragStartX,i=e.clientY-this.dragStartY,r=this.toolbarStartX+t,a=this.toolbarStartY+i,n=window.innerWidth-this.toolbarElement.offsetWidth,o=window.innerHeight-this.toolbarElement.offsetHeight,c=Math.max(0,Math.min(r,n)),l=Math.max(0,Math.min(a,o));this.toolbarElement.style.left=`${c}px`,this.toolbarElement.style.top=`${l}px`,this.toolbarElement.style.right="auto",this.toolbarElement.style.bottom="auto"}endDrag(){this.isDragging&&(this.isDragging=!1,this.toolbarElement&&this.toolbarElement.classList.remove("dragging"),this.dragMoveListener&&(document.removeEventListener("mousemove",this.dragMoveListener),this.dragMoveListener=null),this.dragEndListener&&(document.removeEventListener("mouseup",this.dragEndListener),this.dragEndListener=null))}toggleTrackerView(){this.showTrackers=!this.showTrackers;let e=document.querySelector("#grain-debug-trackers");e&&(e.textContent=this.showTrackers?"Hide":"View",e.classList.toggle("active",this.showTrackers)),this.showTrackers?(this.showTrackerHighlights(),this.showTrackersList()):(this.hideTrackerHighlights(),this.hideTrackersList())}showTrackerHighlights(){this.hideTrackerHighlights();for(let e of this.existingTrackers)if(e.isEnabled)try{let t=this.findElementBySelector(e.selector);if(!t)continue;let i=t.getBoundingClientRect(),r=document.createElement("div");r.className="grain-tracker-highlight";let a=document.createElement("div");a.className="grain-tracker-label",a.textContent=e.name,r.style.top=`${i.top+window.scrollY}px`,r.style.left=`${i.left+window.scrollX}px`,r.style.width=`${i.width}px`,r.style.height=`${i.height}px`,r.appendChild(a),document.body.appendChild(r),this.trackerHighlights.push(r)}catch(t){this.log("Failed to highlight tracker:",e.name,t)}}hideTrackerHighlights(){for(let e of this.trackerHighlights)e.remove();this.trackerHighlights=[]}showTrackersList(){let e=document.querySelector(".grain-trackers-list");if(this.existingTrackers.length===0){e&&e.remove();return}e||(e=document.createElement("div"),e.className="grain-trackers-list",document.body.appendChild(e)),e.innerHTML=`
|
|
273
|
+
${this.existingTrackers.map(t=>`
|
|
274
|
+
<div class="grain-tracker-item" data-tracker-id="${t.trackerId}">
|
|
275
|
+
<div class="grain-tracker-name">${t.name}</div>
|
|
276
|
+
<div class="grain-tracker-details">
|
|
277
|
+
<span class="grain-tracker-type">${t.type}</span>
|
|
278
|
+
<span>${t.urlScope}</span>
|
|
279
|
+
${t.isEnabled?"":'<span style="color: #ef4444;">\u2022 Disabled</span>'}
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
`).join("")}
|
|
283
|
+
`,e.querySelectorAll(".grain-tracker-item").forEach(t=>{t.addEventListener("click",()=>{let i=t.getAttribute("data-tracker-id"),r=this.existingTrackers.find(a=>a.trackerId===i);r&&this.scrollToTracker(r)})})}hideTrackersList(){let e=document.querySelector(".grain-trackers-list");e&&e.remove()}scrollToTracker(e){try{let t=this.findElementBySelector(e.selector);if(t){t.scrollIntoView({behavior:"smooth",block:"center"});let i=this.trackerHighlights.find(r=>{let a=t.getBoundingClientRect(),n=r.getBoundingClientRect();return Math.abs(n.top-a.top)<5});i&&(i.style.opacity="0",setTimeout(()=>{i.style.opacity="1"},100),setTimeout(()=>{i.style.opacity="0"},300),setTimeout(()=>{i.style.opacity="1"},500))}}catch(t){this.log("Failed to scroll to tracker:",t)}}findElementBySelector(e){try{return document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}catch(t){return this.log("Failed to find element:",t),null}}toggleInspectMode(){this.isInspectMode?this.disableInspectMode():this.enableInspectMode()}enableInspectMode(){if(this.isInspectMode)return;this.log("Enabling inspect mode"),this.isInspectMode=!0;let e=document.querySelector("#grain-debug-inspect");e&&(e.classList.add("active"),e.textContent="Click Element"),this.mouseMoveListener=t=>this.handleMouseMove(t),this.clickListener=t=>this.handleElementClick(t),document.addEventListener("mousemove",this.mouseMoveListener,!0),document.addEventListener("click",this.clickListener,!0),document.addEventListener("keydown",this.handleEscapeKey)}disableInspectMode(){if(!this.isInspectMode)return;this.log("Disabling inspect mode"),this.isInspectMode=!1;let e=document.querySelector("#grain-debug-inspect");e&&(e.classList.remove("active"),e.textContent="+ New"),this.mouseMoveListener&&(document.removeEventListener("mousemove",this.mouseMoveListener,!0),this.mouseMoveListener=null),this.clickListener&&(document.removeEventListener("click",this.clickListener,!0),this.clickListener=null),document.removeEventListener("keydown",this.handleEscapeKey),this.highlightElement&&(this.highlightElement.style.display="none")}handleMouseMove(e){if(!this.isInspectMode||!this.highlightElement)return;let t=e.target;if(t.closest("#grain-debug-toolbar")||t.closest("#grain-debug-panel")||t.closest(".grain-trackers-list")){this.highlightElement.style.display="none";return}let r=e.target.getBoundingClientRect();this.highlightElement.style.display="block",this.highlightElement.style.top=`${r.top+window.scrollY}px`,this.highlightElement.style.left=`${r.left+window.scrollX}px`,this.highlightElement.style.width=`${r.width}px`,this.highlightElement.style.height=`${r.height}px`}handleElementClick(e){if(!this.isInspectMode)return;let t=e.target;if(t.closest("#grain-debug-toolbar")||t.closest(".grain-trackers-list")){this.disableInspectMode();return}if(t.closest("#grain-debug-panel")){e.preventDefault(),e.stopPropagation();return}e.preventDefault(),e.stopPropagation(),this.selectedElement=t,this.disableInspectMode(),this.showCreationPanel(t)}showCreationPanel(e){this.panelElement&&this.panelElement.remove();let t=document.createElement("div");t.id="grain-debug-panel";let i=e.tagName.toLowerCase(),r=e.id,a=e.textContent?.trim().substring(0,50)||"",n=this.getXPathForElement(e);t.innerHTML=`
|
|
284
|
+
<style>
|
|
285
|
+
#grain-debug-panel {
|
|
286
|
+
position: fixed;
|
|
287
|
+
top: 50%;
|
|
288
|
+
left: 50%;
|
|
289
|
+
transform: translate(-50%, -50%);
|
|
290
|
+
background: repeating-linear-gradient(
|
|
291
|
+
45deg,
|
|
292
|
+
#fbbf24,
|
|
293
|
+
#fbbf24 10px,
|
|
294
|
+
#1e293b 10px,
|
|
295
|
+
#1e293b 20px
|
|
296
|
+
);
|
|
297
|
+
border: 2px solid #1e293b;
|
|
298
|
+
border-radius: 16px;
|
|
299
|
+
padding: 6px;
|
|
300
|
+
width: 420px;
|
|
301
|
+
max-width: 90vw;
|
|
302
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25), 0 8px 24px rgba(0, 0, 0, 0.15);
|
|
303
|
+
z-index: 1000000;
|
|
304
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.grain-panel-inner {
|
|
308
|
+
background: white;
|
|
309
|
+
border-radius: 10px;
|
|
310
|
+
overflow: hidden;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.grain-panel-header {
|
|
314
|
+
background: #1e293b;
|
|
315
|
+
padding: 14px 18px;
|
|
316
|
+
color: white;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.grain-panel-header h3 {
|
|
320
|
+
margin: 0 0 4px 0;
|
|
321
|
+
font-size: 16px;
|
|
322
|
+
font-weight: 700;
|
|
323
|
+
letter-spacing: 0.5px;
|
|
324
|
+
color: #fbbf24;
|
|
325
|
+
text-transform: uppercase;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.grain-panel-header p {
|
|
329
|
+
margin: 0;
|
|
330
|
+
font-size: 12px;
|
|
331
|
+
opacity: 0.85;
|
|
332
|
+
color: white;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.grain-panel-body {
|
|
336
|
+
padding: 18px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
#grain-debug-panel .element-preview {
|
|
340
|
+
background: #f8fafc;
|
|
341
|
+
border: 1.5px solid #e2e8f0;
|
|
342
|
+
border-radius: 8px;
|
|
343
|
+
padding: 10px 12px;
|
|
344
|
+
margin-bottom: 16px;
|
|
345
|
+
font-size: 11px;
|
|
346
|
+
color: #475569;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
#grain-debug-panel .element-preview div {
|
|
350
|
+
margin-bottom: 4px;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
#grain-debug-panel .element-preview div:last-child {
|
|
354
|
+
margin-bottom: 0;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
#grain-debug-panel .element-preview strong {
|
|
358
|
+
color: #1e293b;
|
|
359
|
+
font-weight: 600;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
#grain-debug-panel label {
|
|
363
|
+
display: block;
|
|
364
|
+
color: #1e293b;
|
|
365
|
+
font-size: 12px;
|
|
366
|
+
font-weight: 600;
|
|
367
|
+
margin-bottom: 6px;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
#grain-debug-panel input,
|
|
371
|
+
#grain-debug-panel select {
|
|
372
|
+
width: 100%;
|
|
373
|
+
background: white;
|
|
374
|
+
border: 1.5px solid #e2e8f0;
|
|
375
|
+
border-radius: 8px;
|
|
376
|
+
padding: 9px 12px;
|
|
377
|
+
color: #1e293b;
|
|
378
|
+
font-size: 13px;
|
|
379
|
+
margin-bottom: 14px;
|
|
380
|
+
box-sizing: border-box;
|
|
381
|
+
transition: all 0.2s;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
#grain-debug-panel input:focus,
|
|
385
|
+
#grain-debug-panel select:focus {
|
|
386
|
+
outline: none;
|
|
387
|
+
border-color: #fbbf24;
|
|
388
|
+
box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.1);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
#grain-debug-panel .button-group {
|
|
392
|
+
display: flex;
|
|
393
|
+
gap: 8px;
|
|
394
|
+
margin-top: 18px;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
#grain-debug-panel button {
|
|
398
|
+
flex: 1;
|
|
399
|
+
padding: 10px 16px;
|
|
400
|
+
border: none;
|
|
401
|
+
border-radius: 8px;
|
|
402
|
+
font-size: 13px;
|
|
403
|
+
font-weight: 600;
|
|
404
|
+
cursor: pointer;
|
|
405
|
+
transition: all 0.2s;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
#grain-debug-panel button.primary {
|
|
409
|
+
background: #fbbf24;
|
|
410
|
+
color: #1e293b;
|
|
411
|
+
box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
#grain-debug-panel button.primary:hover {
|
|
415
|
+
background: #f59e0b;
|
|
416
|
+
transform: translateY(-1px);
|
|
417
|
+
box-shadow: 0 4px 12px rgba(251, 191, 36, 0.4);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
#grain-debug-panel button.secondary {
|
|
421
|
+
background: white;
|
|
422
|
+
border: 1.5px solid #e2e8f0;
|
|
423
|
+
color: #475569;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
#grain-debug-panel button.secondary:hover {
|
|
427
|
+
background: #f8fafc;
|
|
428
|
+
border-color: #cbd5e1;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
#grain-debug-panel .url-pattern-input {
|
|
432
|
+
display: none;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
#grain-debug-panel .url-pattern-input.visible {
|
|
436
|
+
display: block;
|
|
437
|
+
}
|
|
438
|
+
</style>
|
|
439
|
+
<div class="grain-panel-inner">
|
|
440
|
+
<div class="grain-panel-header">
|
|
441
|
+
<h3>Create Tracker</h3>
|
|
442
|
+
<p>Set up automatic tracking for this element</p>
|
|
443
|
+
</div>
|
|
444
|
+
<div class="grain-panel-body">
|
|
445
|
+
<div class="element-preview">
|
|
446
|
+
<div><strong>Element:</strong> ${i}${r?`#${r}`:""}</div>
|
|
447
|
+
${a?`<div><strong>Text:</strong> ${a}</div>`:""}
|
|
448
|
+
</div>
|
|
449
|
+
<div>
|
|
450
|
+
<label>Event Name</label>
|
|
451
|
+
<input type="text" id="grain-event-name" placeholder="e.g., signup_button_click" value="" />
|
|
452
|
+
</div>
|
|
453
|
+
<div>
|
|
454
|
+
<label>Type</label>
|
|
455
|
+
<select id="grain-event-type">
|
|
456
|
+
<option value="metric">Metric</option>
|
|
457
|
+
<option value="conversion">Conversion</option>
|
|
458
|
+
</select>
|
|
459
|
+
</div>
|
|
460
|
+
<div>
|
|
461
|
+
<label>URL Scope</label>
|
|
462
|
+
<select id="grain-url-scope">
|
|
463
|
+
<option value="all">All Pages</option>
|
|
464
|
+
<option value="contains" selected>This Page</option>
|
|
465
|
+
<option value="equals">Exact URL</option>
|
|
466
|
+
</select>
|
|
467
|
+
</div>
|
|
468
|
+
<div class="url-pattern-input visible" id="grain-url-pattern-container">
|
|
469
|
+
<label>URL Pattern</label>
|
|
470
|
+
<input type="text" id="grain-url-pattern" placeholder="e.g., /pricing" value="${window.location.pathname}" />
|
|
471
|
+
</div>
|
|
472
|
+
<div class="button-group">
|
|
473
|
+
<button type="button" class="secondary" id="grain-cancel">Cancel</button>
|
|
474
|
+
<button type="button" class="primary" id="grain-create">\u2713 Create</button>
|
|
475
|
+
</div>
|
|
476
|
+
</div>
|
|
477
|
+
</div>
|
|
478
|
+
`,document.body.appendChild(t),this.panelElement=t;let o=t.querySelector("#grain-event-name");if(o){let S=this.generateEventName(e);o.value=S,o.select()}let c=t.querySelector("#grain-url-scope"),l=t.querySelector("#grain-url-pattern-container"),u=t.querySelector("#grain-url-pattern");c&&l&&c.addEventListener("change",()=>{c.value==="all"?l.classList.remove("visible"):(l.classList.add("visible"),u&&!u.value&&(u.value=window.location.pathname))});let d=t.querySelector("#grain-cancel"),h=t.querySelector("#grain-create");d&&d.addEventListener("click",()=>this.hideCreationPanel()),h&&h.addEventListener("click",()=>this.handleCreateTracker(n))}generateEventName(e){let t=e.tagName.toLowerCase(),i=e.id,r=e.textContent?.trim().toLowerCase().replace(/\s+/g,"_").substring(0,30)||"";return i?`${i}_click`:r?`${r}_click`:t==="button"?"button_click":t==="a"?"link_click":`${t}_click`}async handleCreateTracker(e){if(!this.panelElement)return;let t=this.panelElement.querySelector("#grain-event-name"),i=this.panelElement.querySelector("#grain-event-type"),r=this.panelElement.querySelector("#grain-url-scope"),a=this.panelElement.querySelector("#grain-url-pattern");if(!t||!i||!r)return;let n=t.value.trim(),o=i.value,c=r.value,l=a?.value.trim()||void 0;if(!n){alert("Please enter an event name");return}if(!n.match(/^[a-zA-Z0-9_-]+$/)){alert("Event name can only contain letters, numbers, underscores, and hyphens");return}if((c==="contains"||c==="equals")&&!l){alert("Please enter a URL pattern");return}try{let u=this.panelElement.querySelector("#grain-create");u&&(u.textContent="Creating...",u.disabled=!0),await this.createTracker(n,o,e,c,l),this.hideCreationPanel(),this.showSuccessMessage(`Tracker "${n}" created successfully!`),await this.loadExistingTrackers(),this.updateToolbarStats(),this.showTrackers&&(this.showTrackerHighlights(),this.showTrackersList()),this.log("Tracker created:",n)}catch(u){alert("Failed to create tracker. Please try again."),this.log("Failed to create tracker:",u);let d=this.panelElement.querySelector("#grain-create");d&&(d.textContent="Create Tracker",d.disabled=!1)}}async createTracker(e,t,i,r,a){let n=`${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/trackers`,o=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,type:t,selector:i,urlScope:r,urlPattern:a})});if(!o.ok)throw new Error(`Failed to create tracker: ${o.status}`)}hideCreationPanel(){this.panelElement&&(this.panelElement.remove(),this.panelElement=null),this.selectedElement=null}showSuccessMessage(e){let t=document.createElement("div");t.style.cssText=`
|
|
479
|
+
position: fixed;
|
|
480
|
+
top: 20px;
|
|
481
|
+
left: 50%;
|
|
482
|
+
transform: translateX(-50%) translateY(-20px);
|
|
483
|
+
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
|
484
|
+
color: white;
|
|
485
|
+
padding: 14px 24px;
|
|
486
|
+
border-radius: 12px;
|
|
487
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
488
|
+
font-size: 14px;
|
|
489
|
+
font-weight: 600;
|
|
490
|
+
box-shadow: 0 12px 32px rgba(16, 185, 129, 0.3), 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
491
|
+
z-index: 1000000;
|
|
492
|
+
display: flex;
|
|
493
|
+
align-items: center;
|
|
494
|
+
gap: 10px;
|
|
495
|
+
animation: slideDown 0.3s ease-out forwards;
|
|
496
|
+
`,t.innerHTML=`
|
|
497
|
+
<style>
|
|
498
|
+
@keyframes slideDown {
|
|
499
|
+
to {
|
|
500
|
+
transform: translateX(-50%) translateY(0);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
</style>
|
|
504
|
+
<span style="font-size: 18px;">\u2713</span>
|
|
505
|
+
<span>${e}</span>
|
|
506
|
+
`,document.body.appendChild(t),setTimeout(()=>{t.style.animation="slideDown 0.3s ease-in reverse",setTimeout(()=>{t.remove()},300)},2700)}async endDebug(){try{let t=`${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/end`;await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"}})}catch(t){this.log("Failed to end debug session:",t)}this.destroy();let e=new URL(window.location.href);e.searchParams.delete("grain_debug"),e.searchParams.delete("grain_session"),window.location.href=e.toString()}getXPathForElement(e){if(e.id)return`//*[@id="${e.id}"]`;let t=[],i=e;for(;i&&i.nodeType===Node.ELEMENT_NODE;){let r=0,a=i;for(;a;)a.nodeType===Node.ELEMENT_NODE&&a.tagName===i.tagName&&r++,a=a.previousElementSibling;let n=i.tagName.toLowerCase(),o=r>1?`[${r}]`:"";t.unshift(`${n}${o}`),i=i.parentElement}return t.length?`/${t.join("/")}`:""}log(...e){this.config.debug&&console.log("[DebugAgent]",...e)}updateToolbarStats(){if(!this.toolbarElement)return;let e=this.toolbarElement.querySelector(".grain-stat:nth-child(1) .grain-stat-value"),t=this.toolbarElement.querySelector(".grain-stat:nth-child(2) .grain-stat-value");e&&(e.textContent=String(this.existingTrackers.length)),t&&(t.textContent=String(this.existingTrackers.filter(i=>i.isEnabled).length))}destroy(){this.isDestroyed||(this.log("Destroying debug agent"),this.isDestroyed=!0,this.disableInspectMode(),this.hideTrackerHighlights(),this.endDrag(),this.toolbarElement&&(this.toolbarElement.remove(),this.toolbarElement=null),this.panelElement&&(this.panelElement.remove(),this.panelElement=null),this.highlightElement&&(this.highlightElement.remove(),this.highlightElement=null))}}});var we={};b(we,{GrainAnalytics:()=>v,categorizeReferrer:()=>m,createGrainAnalytics:()=>ne,default:()=>Te,getCountry:()=>j,getCountryCodeFromTimezone:()=>M,getState:()=>Y,parseUTMParameters:()=>A});var F=["necessary","analytics","functional"],E="1.0.0",T=class{constructor(e,t="cookieless"){this.consentState=null;this.listeners=[];this.consentMode=t,this.storageKey=`grain_consent_${e}`,this.loadConsentState()}loadConsentState(){if(!(typeof window>"u"))try{let e=localStorage.getItem(this.storageKey);if(e){let t=JSON.parse(e);this.consentState={...t,timestamp:new Date(t.timestamp)}}else this.consentMode==="gdpr-opt-out"&&(this.consentState={granted:!0,categories:F,timestamp:new Date,version:E},this.saveConsentState())}catch{}}saveConsentState(){if(!(typeof window>"u"||!this.consentState))try{localStorage.setItem(this.storageKey,JSON.stringify(this.consentState))}catch{}}grantConsent(e){let t=e||F;this.consentState={granted:!0,categories:t,timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}revokeConsent(e){this.consentState?e?this.consentState={...this.consentState,categories:this.consentState.categories.filter(t=>!e.includes(t)),granted:this.consentState.categories.length>0,timestamp:new Date}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}getConsentState(){return this.consentState?{...this.consentState}:null}hasConsent(e){if(this.consentMode==="cookieless"||this.consentMode==="gdpr-strict"&&!this.consentState?.granted)return!1;if(this.consentMode==="gdpr-opt-out"){if(!this.consentState)return!0;if(!this.consentState.granted)return!1}return e&&this.consentState?this.consentState.categories.includes(e):this.consentState?.granted??this.consentMode==="gdpr-opt-out"}shouldUsePermanentId(){return this.hasConsent()}shouldStripQueryParams(){return this.consentMode==="cookieless"?!0:this.consentMode==="gdpr-strict"?!this.hasConsent():this.consentMode!=="gdpr-opt-out"}canTrack(){return!0}shouldWaitForConsent(){return this.consentMode==="gdpr-strict"&&!this.consentState?.granted}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){this.consentState&&this.listeners.forEach(e=>{try{e(this.consentState)}catch{}})}clearConsent(){if(!(typeof window>"u"))try{localStorage.removeItem(this.storageKey),this.consentState=null}catch{}}getConsentMode(){return this.consentMode}getIdMode(){return this.shouldUsePermanentId()?"permanent":"cookieless"}};function $(s,e,t){if(typeof document>"u")return;let i=[`${encodeURIComponent(s)}=${encodeURIComponent(e)}`];t?.maxAge!==void 0&&i.push(`max-age=${t.maxAge}`),t?.domain&&i.push(`domain=${t.domain}`),t?.path?i.push(`path=${t.path}`):i.push("path=/"),t?.sameSite&&i.push(`samesite=${t.sameSite}`),t?.secure&&i.push("secure"),document.cookie=i.join("; ")}function K(s){if(typeof document>"u")return null;let e=encodeURIComponent(s)+"=",t=document.cookie.split(";");for(let i=0;i<t.length;i++){let r=t[i];for(;r.charAt(0)===" ";)r=r.substring(1);if(r.indexOf(e)===0)return decodeURIComponent(r.substring(e.length))}return null}var w=class{constructor(){this.activityThreshold=3e4;this.listeners=[];this.isDestroyed=!1;this.activityEvents=["mousemove","mousedown","keydown","scroll","touchstart","click"];this.lastActivityTime=Date.now(),this.boundActivityHandler=this.debounce(this.handleActivity.bind(this),500),this.setupListeners()}setupListeners(){if(!(typeof window>"u"))for(let e of this.activityEvents)window.addEventListener(e,this.boundActivityHandler,{passive:!0})}handleActivity(){this.isDestroyed||(this.lastActivityTime=Date.now(),this.notifyListeners())}debounce(e,t){let i=null;return()=>{i!==null&&clearTimeout(i),i=window.setTimeout(()=>{e(),i=null},t)}}isActive(e){let t=e??this.activityThreshold;return Date.now()-this.lastActivityTime<t}getTimeSinceLastActivity(){return Date.now()-this.lastActivityTime}getLastActivityTime(){return this.lastActivityTime}setActivityThreshold(e){this.activityThreshold=e}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){for(let e of this.listeners)try{e()}catch{}}destroy(){if(!this.isDestroyed){if(typeof window<"u")for(let e of this.activityEvents)window.removeEventListener(e,this.boundActivityHandler);this.listeners=[],this.isDestroyed=!0}}};var k=class{constructor(e,t,i){this.heartbeatTimer=null;this.isDestroyed=!1;this.hasSentPageLoadHeartbeat=!1;this.tracker=e,this.activityDetector=t,this.config=i,this.lastHeartbeatTime=Date.now(),this.currentInterval=i.activeInterval,this.sendPageLoadHeartbeat(),this.scheduleNextHeartbeat()}sendPageLoadHeartbeat(){if(!(this.isDestroyed||this.hasSentPageLoadHeartbeat))if(typeof window<"u"&&document.readyState!=="complete"){let e=()=>{this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0,window.removeEventListener("load",e)};window.addEventListener("load",e)}else this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0}scheduleNextHeartbeat(){if(this.isDestroyed)return;this.heartbeatTimer!==null&&clearTimeout(this.heartbeatTimer);let e=this.activityDetector.isActive(6e4);this.currentInterval=e?this.config.activeInterval:this.config.inactiveInterval,this.heartbeatTimer=window.setTimeout(()=>{this.sendHeartbeat("periodic"),this.scheduleNextHeartbeat()},this.currentInterval),this.config.debug&&console.log(`[Heartbeat] Scheduled next heartbeat in ${this.currentInterval/1e3}s (${e?"active":"inactive"})`)}sendHeartbeat(e="periodic"){if(this.isDestroyed)return;let t=Date.now(),i=this.activityDetector.isActive(6e4),r=this.tracker.hasConsent("analytics"),a={heartbeat_type:e,status:i?"active":"inactive",timestamp:t};if(r){let n=this.tracker.getCurrentPage();n&&(a.page=n),a.session_id=this.tracker.getSessionId(),e==="periodic"&&(a.duration=t-this.lastHeartbeatTime,a.event_count=this.tracker.getEventCountSinceLastHeartbeat(),this.tracker.resetEventCountSinceLastHeartbeat())}this.tracker.trackSystemEvent("_grain_heartbeat",a),this.lastHeartbeatTime=t}destroy(){this.isDestroyed||(this.heartbeatTimer!==null&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null),this.isDestroyed=!0)}};var ue=["gclid","msclkid","fbclid","ttclid","li_fat_id","twclid","ScCid"],de=["facebook.com","twitter.com","x.com","linkedin.com","instagram.com","pinterest.com","reddit.com","tiktok.com","youtube.com","snapchat.com","t.co","fb.me","lnkd.in"],he=["google.","bing.com","yahoo.com","duckduckgo.com","baidu.com","yandex.com","ecosia.org","ask.com"],ge=["mail.google.com","outlook.live.com","mail.yahoo.com","mail.aol.com"];function D(s){try{return new URL(s).hostname.toLowerCase()}catch{return""}}function z(s){try{let e=new URL(s);return ue.some(t=>e.searchParams.has(t))}catch{return!1}}function m(s,e=""){if(!s||s.trim()==="")return"direct";let t=D(s);if(e){let i=D(e);if(t===i)return"direct"}return z(s)||z(e)?"paid":ge.some(i=>t.includes(i))?"email":de.some(i=>t.includes(i))?"social":he.some(i=>t.includes(i))?"organic":"referral"}function A(s){try{let e=new URL(s),t={},i=e.searchParams.get("utm_source"),r=e.searchParams.get("utm_medium"),a=e.searchParams.get("utm_campaign"),n=e.searchParams.get("utm_term"),o=e.searchParams.get("utm_content");return i&&(t.utm_source=i),r&&(t.utm_medium=r),a&&(t.utm_campaign=a),n&&(t.utm_term=n),o&&(t.utm_content=o),t}catch{return{}}}function R(s){if(typeof window>"u"||typeof localStorage>"u")return null;try{let e=`_grain_first_touch_${s}`,t=localStorage.getItem(e);if(t)return JSON.parse(t)}catch(e){console.warn("[Grain Attribution] Failed to retrieve first-touch attribution:",e)}return null}function me(s,e){if(!(typeof window>"u"||typeof localStorage>"u"))try{let t=`_grain_first_touch_${s}`;localStorage.setItem(t,JSON.stringify(e))}catch(t){console.warn("[Grain Attribution] Failed to store first-touch attribution:",t)}}function C(s,e,t,i){let r=R(s);if(r)return r;let a=m(e,t),n=D(e),o={source:i.utm_source||n||"direct",medium:i.utm_medium||a,campaign:i.utm_campaign||"none",referrer:e||"direct",referrer_category:a,timestamp:Date.now()};return me(s,o),o}var V=null;function p(){return V}function Q(s){V=s}var pe={AD:"Andorra",AE:"United Arab Emirates",AF:"Afghanistan",AG:"Antigua and Barbuda",AI:"Anguilla",AL:"Albania",AM:"Armenia",AO:"Angola",AQ:"Antarctica",AR:"Argentina",AS:"American Samoa",AT:"Austria",AU:"Australia",AW:"Aruba",AX:"\xC5land Islands",AZ:"Azerbaijan",BA:"Bosnia and Herzegovina",BB:"Barbados",BD:"Bangladesh",BE:"Belgium",BF:"Burkina Faso",BG:"Bulgaria",BH:"Bahrain",BI:"Burundi",BJ:"Benin",BL:"Saint Barth\xE9lemy",BM:"Bermuda",BN:"Brunei",BO:"Bolivia",BQ:"Caribbean Netherlands",BR:"Brazil",BS:"Bahamas",BT:"Bhutan",BV:"Bouvet Island",BW:"Botswana",BY:"Belarus",BZ:"Belize",CA:"Canada",CC:"Cocos Islands",CD:"Democratic Republic of the Congo",CF:"Central African Republic",CG:"Republic of the Congo",CH:"Switzerland",CI:"Ivory Coast",CK:"Cook Islands",CL:"Chile",CM:"Cameroon",CN:"China",CO:"Colombia",CR:"Costa Rica",CU:"Cuba",CV:"Cabo Verde",CW:"Cura\xE7ao",CX:"Christmas Island",CY:"Cyprus",CZ:"Czechia",DE:"Germany",DJ:"Djibouti",DK:"Denmark",DM:"Dominica",DO:"Dominican Republic",DZ:"Algeria",EC:"Ecuador",EE:"Estonia",EG:"Egypt",EH:"Western Sahara",ER:"Eritrea",ES:"Spain",ET:"Ethiopia",FI:"Finland",FJ:"Fiji",FK:"Falkland Islands",FM:"Micronesia",FO:"Faroe Islands",FR:"France",GA:"Gabon",GB:"United Kingdom",GD:"Grenada",GE:"Georgia",GF:"French Guiana",GG:"Guernsey",GH:"Ghana",GI:"Gibraltar",GL:"Greenland",GM:"Gambia",GN:"Guinea",GP:"Guadeloupe",GQ:"Equatorial Guinea",GR:"Greece",GS:"South Georgia and the South Sandwich Islands",GT:"Guatemala",GU:"Guam",GW:"Guinea-Bissau",GY:"Guyana",HK:"Hong Kong",HM:"Heard Island and McDonald Islands",HN:"Honduras",HR:"Croatia",HT:"Haiti",HU:"Hungary",ID:"Indonesia",IE:"Ireland",IL:"Israel",IM:"Isle of Man",IN:"India",IO:"British Indian Ocean Territory",IQ:"Iraq",IR:"Iran",IS:"Iceland",IT:"Italy",JE:"Jersey",JM:"Jamaica",JO:"Jordan",JP:"Japan",KE:"Kenya",KG:"Kyrgyzstan",KH:"Cambodia",KI:"Kiribati",KM:"Comoros",KN:"Saint Kitts and Nevis",KP:"North Korea",KR:"South Korea",KW:"Kuwait",KY:"Cayman Islands",KZ:"Kazakhstan",LA:"Laos",LB:"Lebanon",LC:"Saint Lucia",LI:"Liechtenstein",LK:"Sri Lanka",LR:"Liberia",LS:"Lesotho",LT:"Lithuania",LU:"Luxembourg",LV:"Latvia",LY:"Libya",MA:"Morocco",MC:"Monaco",MD:"Moldova",ME:"Montenegro",MF:"Saint Martin",MG:"Madagascar",MH:"Marshall Islands",MK:"North Macedonia",ML:"Mali",MM:"Myanmar",MN:"Mongolia",MO:"Macao",MP:"Northern Mariana Islands",MQ:"Martinique",MR:"Mauritania",MS:"Montserrat",MT:"Malta",MU:"Mauritius",MV:"Maldives",MW:"Malawi",MX:"Mexico",MY:"Malaysia",MZ:"Mozambique",NA:"Namibia",NC:"New Caledonia",NE:"Niger",NF:"Norfolk Island",NG:"Nigeria",NI:"Nicaragua",NL:"Netherlands",NO:"Norway",NP:"Nepal",NR:"Nauru",NU:"Niue",NZ:"New Zealand",OM:"Oman",PA:"Panama",PE:"Peru",PF:"French Polynesia",PG:"Papua New Guinea",PH:"Philippines",PK:"Pakistan",PL:"Poland",PM:"Saint Pierre and Miquelon",PN:"Pitcairn",PR:"Puerto Rico",PS:"Palestine",PT:"Portugal",PW:"Palau",PY:"Paraguay",QA:"Qatar",RE:"R\xE9union",RO:"Romania",RS:"Serbia",RU:"Russia",RW:"Rwanda",SA:"Saudi Arabia",SB:"Solomon Islands",SC:"Seychelles",SD:"Sudan",SE:"Sweden",SG:"Singapore",SH:"Saint Helena, Ascension and Tristan da Cunha",SI:"Slovenia",SJ:"Svalbard and Jan Mayen",SK:"Slovakia",SL:"Sierra Leone",SM:"San Marino",SN:"Senegal",SO:"Somalia",SR:"Suriname",SS:"South Sudan",ST:"Sao Tome and Principe",SV:"El Salvador",SX:"Sint Maarten",SY:"Syria",SZ:"Eswatini",TC:"Turks and Caicos Islands",TD:"Chad",TF:"French Southern Territories",TG:"Togo",TH:"Thailand",TJ:"Tajikistan",TK:"Tokelau",TL:"Timor-Leste",TM:"Turkmenistan",TN:"Tunisia",TO:"Tonga",TR:"Turkey",TT:"Trinidad and Tobago",TV:"Tuvalu",TW:"Taiwan",TZ:"Tanzania",UA:"Ukraine",UG:"Uganda",UM:"United States Minor Outlying Islands",US:"United States of America",UY:"Uruguay",UZ:"Uzbekistan",VA:"Holy See",VC:"Saint Vincent and the Grenadines",VE:"Venezuela",VG:"Virgin Islands (UK)",VI:"Virgin Islands (US)",VN:"Vietnam",VU:"Vanuatu",WF:"Wallis and Futuna",WS:"Samoa",YE:"Yemen",YT:"Mayotte",ZA:"South Africa",ZM:"Zambia",ZW:"Zimbabwe"},W={"Africa/Abidjan":{u:0,c:["CI","BF","GH","GM","GN","ML","MR","SH","SL","SN","TG"]},"Africa/Accra":{a:"Africa/Abidjan",c:["GH"],r:1},"Africa/Addis_Ababa":{a:"Africa/Nairobi",c:["ET"],r:1},"Africa/Algiers":{u:60,c:["DZ"]},"Africa/Asmara":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Asmera":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Bamako":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Bangui":{a:"Africa/Lagos",c:["CF"],r:1},"Africa/Banjul":{a:"Africa/Abidjan",c:["GM"],r:1},"Africa/Bissau":{u:0,c:["GW"]},"Africa/Blantyre":{a:"Africa/Maputo",c:["MW"],r:1},"Africa/Brazzaville":{a:"Africa/Lagos",c:["CG"],r:1},"Africa/Bujumbura":{a:"Africa/Maputo",c:["BI"],r:1},"Africa/Cairo":{u:120,c:["EG"]},"Africa/Casablanca":{u:60,d:0,c:["MA"]},"Africa/Ceuta":{u:60,d:120,c:["ES"]},"Africa/Conakry":{a:"Africa/Abidjan",c:["GN"],r:1},"Africa/Dakar":{a:"Africa/Abidjan",c:["SN"],r:1},"Africa/Dar_es_Salaam":{a:"Africa/Nairobi",c:["TZ"],r:1},"Africa/Djibouti":{a:"Africa/Nairobi",c:["DJ"],r:1},"Africa/Douala":{a:"Africa/Lagos",c:["CM"],r:1},"Africa/El_Aaiun":{u:60,d:0,c:["EH"]},"Africa/Freetown":{a:"Africa/Abidjan",c:["SL"],r:1},"Africa/Gaborone":{a:"Africa/Maputo",c:["BW"],r:1},"Africa/Harare":{a:"Africa/Maputo",c:["ZW"],r:1},"Africa/Johannesburg":{u:120,c:["ZA","LS","SZ"]},"Africa/Juba":{u:120,c:["SS"]},"Africa/Kampala":{a:"Africa/Nairobi",c:["UG"],r:1},"Africa/Khartoum":{u:120,c:["SD"]},"Africa/Kigali":{a:"Africa/Maputo",c:["RW"],r:1},"Africa/Kinshasa":{a:"Africa/Lagos",c:["CD"],r:1},"Africa/Lagos":{u:60,c:["NG","AO","BJ","CD","CF","CG","CM","GA","GQ","NE"]},"Africa/Libreville":{a:"Africa/Lagos",c:["GA"],r:1},"Africa/Lome":{a:"Africa/Abidjan",c:["TG"],r:1},"Africa/Luanda":{a:"Africa/Lagos",c:["AO"],r:1},"Africa/Lubumbashi":{a:"Africa/Maputo",c:["CD"],r:1},"Africa/Lusaka":{a:"Africa/Maputo",c:["ZM"],r:1},"Africa/Malabo":{a:"Africa/Lagos",c:["GQ"],r:1},"Africa/Maputo":{u:120,c:["MZ","BI","BW","CD","MW","RW","ZM","ZW"]},"Africa/Maseru":{a:"Africa/Johannesburg",c:["LS"],r:1},"Africa/Mbabane":{a:"Africa/Johannesburg",c:["SZ"],r:1},"Africa/Mogadishu":{a:"Africa/Nairobi",c:["SO"],r:1},"Africa/Monrovia":{u:0,c:["LR"]},"Africa/Nairobi":{u:180,c:["KE","DJ","ER","ET","KM","MG","SO","TZ","UG","YT"]},"Africa/Ndjamena":{u:60,c:["TD"]},"Africa/Niamey":{a:"Africa/Lagos",c:["NE"],r:1},"Africa/Nouakchott":{a:"Africa/Abidjan",c:["MR"],r:1},"Africa/Ouagadougou":{a:"Africa/Abidjan",c:["BF"],r:1},"Africa/Porto-Novo":{a:"Africa/Lagos",c:["BJ"],r:1},"Africa/Sao_Tome":{u:0,c:["ST"]},"Africa/Timbuktu":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Tripoli":{u:120,c:["LY"]},"Africa/Tunis":{u:60,c:["TN"]},"Africa/Windhoek":{u:120,c:["NA"]},"America/Adak":{u:-600,d:-540,c:["US"]},"America/Anchorage":{u:-540,d:-480,c:["US"]},"America/Anguilla":{a:"America/Puerto_Rico",c:["AI"],r:1},"America/Antigua":{a:"America/Puerto_Rico",c:["AG"],r:1},"America/Araguaina":{u:-180,c:["BR"]},"America/Argentina/Buenos_Aires":{u:-180,c:["AR"]},"America/Argentina/Catamarca":{u:-180,c:["AR"]},"America/Argentina/ComodRivadavia":{a:"America/Argentina/Catamarca",r:1},"America/Argentina/Cordoba":{u:-180,c:["AR"]},"America/Argentina/Jujuy":{u:-180,c:["AR"]},"America/Argentina/La_Rioja":{u:-180,c:["AR"]},"America/Argentina/Mendoza":{u:-180,c:["AR"]},"America/Argentina/Rio_Gallegos":{u:-180,c:["AR"]},"America/Argentina/Salta":{u:-180,c:["AR"]},"America/Argentina/San_Juan":{u:-180,c:["AR"]},"America/Argentina/San_Luis":{u:-180,c:["AR"]},"America/Argentina/Tucuman":{u:-180,c:["AR"]},"America/Argentina/Ushuaia":{u:-180,c:["AR"]},"America/Aruba":{a:"America/Puerto_Rico",c:["AW"],r:1},"America/Asuncion":{u:-240,d:-180,c:["PY"]},"America/Atikokan":{a:"America/Panama",c:["CA"],r:1},"America/Atka":{a:"America/Adak",r:1},"America/Bahia":{u:-180,c:["BR"]},"America/Bahia_Banderas":{u:-360,d:-300,c:["MX"]},"America/Barbados":{u:-240,c:["BB"]},"America/Belem":{u:-180,c:["BR"]},"America/Belize":{u:-360,c:["BZ"]},"America/Blanc-Sablon":{a:"America/Puerto_Rico",c:["CA"],r:1},"America/Boa_Vista":{u:-240,c:["BR"]},"America/Bogota":{u:-300,c:["CO"]},"America/Boise":{u:-420,d:-360,c:["US"]},"America/Buenos_Aires":{a:"America/Argentina/Buenos_Aires",r:1},"America/Cambridge_Bay":{u:-420,d:-360,c:["CA"]},"America/Campo_Grande":{u:-240,c:["BR"]},"America/Cancun":{u:-300,c:["MX"]},"America/Caracas":{u:-240,c:["VE"]},"America/Catamarca":{a:"America/Argentina/Catamarca",r:1},"America/Cayenne":{u:-180,c:["GF"]},"America/Cayman":{a:"America/Panama",c:["KY"],r:1},"America/Chicago":{u:-360,d:-300,c:["US"]},"America/Chihuahua":{u:-420,d:-360,c:["MX"]},"America/Coral_Harbour":{a:"America/Panama",c:["CA"],r:1},"America/Cordoba":{a:"America/Argentina/Cordoba",r:1},"America/Costa_Rica":{u:-360,c:["CR"]},"America/Creston":{a:"America/Phoenix",c:["CA"],r:1},"America/Cuiaba":{u:-240,c:["BR"]},"America/Curacao":{a:"America/Puerto_Rico",c:["CW"],r:1},"America/Danmarkshavn":{u:0,c:["GL"]},"America/Dawson":{u:-420,c:["CA"]},"America/Dawson_Creek":{u:-420,c:["CA"]},"America/Denver":{u:-420,d:-360,c:["US"]},"America/Detroit":{u:-300,d:-240,c:["US"]},"America/Dominica":{a:"America/Puerto_Rico",c:["DM"],r:1},"America/Edmonton":{u:-420,d:-360,c:["CA"]},"America/Eirunepe":{u:-300,c:["BR"]},"America/El_Salvador":{u:-360,c:["SV"]},"America/Ensenada":{a:"America/Tijuana",r:1},"America/Fort_Nelson":{u:-420,c:["CA"]},"America/Fort_Wayne":{a:"America/Indiana/Indianapolis",r:1},"America/Fortaleza":{u:-180,c:["BR"]},"America/Glace_Bay":{u:-240,d:-180,c:["CA"]},"America/Godthab":{a:"America/Nuuk",r:1},"America/Goose_Bay":{u:-240,d:-180,c:["CA"]},"America/Grand_Turk":{u:-300,d:-240,c:["TC"]},"America/Grenada":{a:"America/Puerto_Rico",c:["GD"],r:1},"America/Guadeloupe":{a:"America/Puerto_Rico",c:["GP"],r:1},"America/Guatemala":{u:-360,c:["GT"]},"America/Guayaquil":{u:-300,c:["EC"]},"America/Guyana":{u:-240,c:["GY"]},"America/Halifax":{u:-240,d:-180,c:["CA"]},"America/Havana":{u:-300,d:-240,c:["CU"]},"America/Hermosillo":{u:-420,c:["MX"]},"America/Indiana/Indianapolis":{u:-300,d:-240,c:["US"]},"America/Indiana/Knox":{u:-360,d:-300,c:["US"]},"America/Indiana/Marengo":{u:-300,d:-240,c:["US"]},"America/Indiana/Petersburg":{u:-300,d:-240,c:["US"]},"America/Indiana/Tell_City":{u:-360,d:-300,c:["US"]},"America/Indiana/Vevay":{u:-300,d:-240,c:["US"]},"America/Indiana/Vincennes":{u:-300,d:-240,c:["US"]},"America/Indiana/Winamac":{u:-300,d:-240,c:["US"]},"America/Indianapolis":{a:"America/Indiana/Indianapolis",r:1},"America/Inuvik":{u:-420,d:-360,c:["CA"]},"America/Iqaluit":{u:-300,d:-240,c:["CA"]},"America/Jamaica":{u:-300,c:["JM"]},"America/Jujuy":{a:"America/Argentina/Jujuy",r:1},"America/Juneau":{u:-540,d:-480,c:["US"]},"America/Kentucky/Louisville":{u:-300,d:-240,c:["US"]},"America/Kentucky/Monticello":{u:-300,d:-240,c:["US"]},"America/Knox_IN":{a:"America/Indiana/Knox",r:1},"America/Kralendijk":{a:"America/Puerto_Rico",c:["BQ"],r:1},"America/La_Paz":{u:-240,c:["BO"]},"America/Lima":{u:-300,c:["PE"]},"America/Los_Angeles":{u:-480,d:-420,c:["US"]},"America/Louisville":{a:"America/Kentucky/Louisville",r:1},"America/Lower_Princes":{a:"America/Puerto_Rico",c:["SX"],r:1},"America/Maceio":{u:-180,c:["BR"]},"America/Managua":{u:-360,c:["NI"]},"America/Manaus":{u:-240,c:["BR"]},"America/Marigot":{a:"America/Puerto_Rico",c:["MF"],r:1},"America/Martinique":{u:-240,c:["MQ"]},"America/Matamoros":{u:-360,d:-300,c:["MX"]},"America/Mazatlan":{u:-420,d:-360,c:["MX"]},"America/Mendoza":{a:"America/Argentina/Mendoza",r:1},"America/Menominee":{u:-360,d:-300,c:["US"]},"America/Merida":{u:-360,d:-300,c:["MX"]},"America/Metlakatla":{u:-540,d:-480,c:["US"]},"America/Mexico_City":{u:-360,d:-300,c:["MX"]},"America/Miquelon":{u:-180,d:-120,c:["PM"]},"America/Moncton":{u:-240,d:-180,c:["CA"]},"America/Monterrey":{u:-360,d:-300,c:["MX"]},"America/Montevideo":{u:-180,c:["UY"]},"America/Montreal":{a:"America/Toronto",c:["CA"],r:1},"America/Montserrat":{a:"America/Puerto_Rico",c:["MS"],r:1},"America/Nassau":{a:"America/Toronto",c:["BS"],r:1},"America/New_York":{u:-300,d:-240,c:["US"]},"America/Nipigon":{u:-300,d:-240,c:["CA"]},"America/Nome":{u:-540,d:-480,c:["US"]},"America/Noronha":{u:-120,c:["BR"]},"America/North_Dakota/Beulah":{u:-360,d:-300,c:["US"]},"America/North_Dakota/Center":{u:-360,d:-300,c:["US"]},"America/North_Dakota/New_Salem":{u:-360,d:-300,c:["US"]},"America/Nuuk":{u:-180,d:-120,c:["GL"]},"America/Ojinaga":{u:-420,d:-360,c:["MX"]},"America/Panama":{u:-300,c:["PA","CA","KY"]},"America/Pangnirtung":{u:-300,d:-240,c:["CA"]},"America/Paramaribo":{u:-180,c:["SR"]},"America/Phoenix":{u:-420,c:["US","CA"]},"America/Port-au-Prince":{u:-300,d:-240,c:["HT"]},"America/Port_of_Spain":{a:"America/Puerto_Rico",c:["TT"],r:1},"America/Porto_Acre":{a:"America/Rio_Branco",r:1},"America/Porto_Velho":{u:-240,c:["BR"]},"America/Puerto_Rico":{u:-240,c:["PR","AG","CA","AI","AW","BL","BQ","CW","DM","GD","GP","KN","LC","MF","MS","SX","TT","VC","VG","VI"]},"America/Punta_Arenas":{u:-180,c:["CL"]},"America/Rainy_River":{u:-360,d:-300,c:["CA"]},"America/Rankin_Inlet":{u:-360,d:-300,c:["CA"]},"America/Recife":{u:-180,c:["BR"]},"America/Regina":{u:-360,c:["CA"]},"America/Resolute":{u:-360,d:-300,c:["CA"]},"America/Rio_Branco":{u:-300,c:["BR"]},"America/Rosario":{a:"America/Argentina/Cordoba",r:1},"America/Santa_Isabel":{a:"America/Tijuana",r:1},"America/Santarem":{u:-180,c:["BR"]},"America/Santiago":{u:-240,d:-180,c:["CL"]},"America/Santo_Domingo":{u:-240,c:["DO"]},"America/Sao_Paulo":{u:-180,c:["BR"]},"America/Scoresbysund":{u:-60,d:0,c:["GL"]},"America/Shiprock":{a:"America/Denver",r:1},"America/Sitka":{u:-540,d:-480,c:["US"]},"America/St_Barthelemy":{a:"America/Puerto_Rico",c:["BL"],r:1},"America/St_Johns":{u:-150,d:-90,c:["CA"]},"America/St_Kitts":{a:"America/Puerto_Rico",c:["KN"],r:1},"America/St_Lucia":{a:"America/Puerto_Rico",c:["LC"],r:1},"America/St_Thomas":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/St_Vincent":{a:"America/Puerto_Rico",c:["VC"],r:1},"America/Swift_Current":{u:-360,c:["CA"]},"America/Tegucigalpa":{u:-360,c:["HN"]},"America/Thule":{u:-240,d:-180,c:["GL"]},"America/Thunder_Bay":{u:-300,d:-240,c:["CA"]},"America/Tijuana":{u:-480,d:-420,c:["MX"]},"America/Toronto":{u:-300,d:-240,c:["CA","BS"]},"America/Tortola":{a:"America/Puerto_Rico",c:["VG"],r:1},"America/Vancouver":{u:-480,d:-420,c:["CA"]},"America/Virgin":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/Whitehorse":{u:-420,c:["CA"]},"America/Winnipeg":{u:-360,d:-300,c:["CA"]},"America/Yakutat":{u:-540,d:-480,c:["US"]},"America/Yellowknife":{u:-420,d:-360,c:["CA"]},"Antarctica/Casey":{u:660,c:["AQ"]},"Antarctica/Davis":{u:420,c:["AQ"]},"Antarctica/DumontDUrville":{a:"Pacific/Port_Moresby",c:["AQ"],r:1},"Antarctica/Macquarie":{u:600,d:660,c:["AU"]},"Antarctica/Mawson":{u:300,c:["AQ"]},"Antarctica/McMurdo":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Palmer":{u:-180,c:["AQ"]},"Antarctica/Rothera":{u:-180,c:["AQ"]},"Antarctica/South_Pole":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Syowa":{a:"Asia/Riyadh",c:["AQ"],r:1},"Antarctica/Troll":{u:0,d:120,c:["AQ"]},"Antarctica/Vostok":{u:360,c:["AQ"]},"Arctic/Longyearbyen":{a:"Europe/Oslo",c:["SJ"],r:1},"Asia/Aden":{a:"Asia/Riyadh",c:["YE"],r:1},"Asia/Almaty":{u:360,c:["KZ"]},"Asia/Amman":{u:120,d:180,c:["JO"]},"Asia/Anadyr":{u:720,c:["RU"]},"Asia/Aqtau":{u:300,c:["KZ"]},"Asia/Aqtobe":{u:300,c:["KZ"]},"Asia/Ashgabat":{u:300,c:["TM"]},"Asia/Ashkhabad":{a:"Asia/Ashgabat",r:1},"Asia/Atyrau":{u:300,c:["KZ"]},"Asia/Baghdad":{u:180,c:["IQ"]},"Asia/Bahrain":{a:"Asia/Qatar",c:["BH"],r:1},"Asia/Baku":{u:240,c:["AZ"]},"Asia/Bangkok":{u:420,c:["TH","KH","LA","VN"]},"Asia/Barnaul":{u:420,c:["RU"]},"Asia/Beirut":{u:120,d:180,c:["LB"]},"Asia/Bishkek":{u:360,c:["KG"]},"Asia/Brunei":{u:480,c:["BN"]},"Asia/Calcutta":{a:"Asia/Kolkata",r:1},"Asia/Chita":{u:540,c:["RU"]},"Asia/Choibalsan":{u:480,c:["MN"]},"Asia/Chongqing":{a:"Asia/Shanghai",r:1},"Asia/Chungking":{a:"Asia/Shanghai",r:1},"Asia/Colombo":{u:330,c:["LK"]},"Asia/Dacca":{a:"Asia/Dhaka",r:1},"Asia/Damascus":{u:120,d:180,c:["SY"]},"Asia/Dhaka":{u:360,c:["BD"]},"Asia/Dili":{u:540,c:["TL"]},"Asia/Dubai":{u:240,c:["AE","OM"]},"Asia/Dushanbe":{u:300,c:["TJ"]},"Asia/Famagusta":{u:120,d:180,c:["CY"]},"Asia/Gaza":{u:120,d:180,c:["PS"]},"Asia/Harbin":{a:"Asia/Shanghai",r:1},"Asia/Hebron":{u:120,d:180,c:["PS"]},"Asia/Ho_Chi_Minh":{u:420,c:["VN"]},"Asia/Hong_Kong":{u:480,c:["HK"]},"Asia/Hovd":{u:420,c:["MN"]},"Asia/Irkutsk":{u:480,c:["RU"]},"Asia/Istanbul":{a:"Europe/Istanbul",r:1},"Asia/Jakarta":{u:420,c:["ID"]},"Asia/Jayapura":{u:540,c:["ID"]},"Asia/Jerusalem":{u:120,d:180,c:["IL"]},"Asia/Kabul":{u:270,c:["AF"]},"Asia/Kamchatka":{u:720,c:["RU"]},"Asia/Karachi":{u:300,c:["PK"]},"Asia/Kashgar":{a:"Asia/Urumqi",r:1},"Asia/Kathmandu":{u:345,c:["NP"]},"Asia/Katmandu":{a:"Asia/Kathmandu",r:1},"Asia/Khandyga":{u:540,c:["RU"]},"Asia/Kolkata":{u:330,c:["IN"]},"Asia/Krasnoyarsk":{u:420,c:["RU"]},"Asia/Kuala_Lumpur":{u:480,c:["MY"]},"Asia/Kuching":{u:480,c:["MY"]},"Asia/Kuwait":{a:"Asia/Riyadh",c:["KW"],r:1},"Asia/Macao":{a:"Asia/Macau",r:1},"Asia/Macau":{u:480,c:["MO"]},"Asia/Magadan":{u:660,c:["RU"]},"Asia/Makassar":{u:480,c:["ID"]},"Asia/Manila":{u:480,c:["PH"]},"Asia/Muscat":{a:"Asia/Dubai",c:["OM"],r:1},"Asia/Nicosia":{u:120,d:180,c:["CY"]},"Asia/Novokuznetsk":{u:420,c:["RU"]},"Asia/Novosibirsk":{u:420,c:["RU"]},"Asia/Omsk":{u:360,c:["RU"]},"Asia/Oral":{u:300,c:["KZ"]},"Asia/Phnom_Penh":{a:"Asia/Bangkok",c:["KH"],r:1},"Asia/Pontianak":{u:420,c:["ID"]},"Asia/Pyongyang":{u:540,c:["KP"]},"Asia/Qatar":{u:180,c:["QA","BH"]},"Asia/Qostanay":{u:360,c:["KZ"]},"Asia/Qyzylorda":{u:300,c:["KZ"]},"Asia/Rangoon":{a:"Asia/Yangon",r:1},"Asia/Riyadh":{u:180,c:["SA","AQ","KW","YE"]},"Asia/Saigon":{a:"Asia/Ho_Chi_Minh",r:1},"Asia/Sakhalin":{u:660,c:["RU"]},"Asia/Samarkand":{u:300,c:["UZ"]},"Asia/Seoul":{u:540,c:["KR"]},"Asia/Shanghai":{u:480,c:["CN"]},"Asia/Singapore":{u:480,c:["SG","MY"]},"Asia/Srednekolymsk":{u:660,c:["RU"]},"Asia/Taipei":{u:480,c:["TW"]},"Asia/Tashkent":{u:300,c:["UZ"]},"Asia/Tbilisi":{u:240,c:["GE"]},"Asia/Tehran":{u:210,d:270,c:["IR"]},"Asia/Tel_Aviv":{a:"Asia/Jerusalem",r:1},"Asia/Thimbu":{a:"Asia/Thimphu",r:1},"Asia/Thimphu":{u:360,c:["BT"]},"Asia/Tokyo":{u:540,c:["JP"]},"Asia/Tomsk":{u:420,c:["RU"]},"Asia/Ujung_Pandang":{a:"Asia/Makassar",r:1},"Asia/Ulaanbaatar":{u:480,c:["MN"]},"Asia/Ulan_Bator":{a:"Asia/Ulaanbaatar",r:1},"Asia/Urumqi":{u:360,c:["CN"]},"Asia/Ust-Nera":{u:600,c:["RU"]},"Asia/Vientiane":{a:"Asia/Bangkok",c:["LA"],r:1},"Asia/Vladivostok":{u:600,c:["RU"]},"Asia/Yakutsk":{u:540,c:["RU"]},"Asia/Yangon":{u:390,c:["MM"]},"Asia/Yekaterinburg":{u:300,c:["RU"]},"Asia/Yerevan":{u:240,c:["AM"]},"Atlantic/Azores":{u:-60,d:0,c:["PT"]},"Atlantic/Bermuda":{u:-240,d:-180,c:["BM"]},"Atlantic/Canary":{u:0,d:60,c:["ES"]},"Atlantic/Cape_Verde":{u:-60,c:["CV"]},"Atlantic/Faeroe":{a:"Atlantic/Faroe",r:1},"Atlantic/Faroe":{u:0,d:60,c:["FO"]},"Atlantic/Jan_Mayen":{a:"Europe/Oslo",c:["SJ"],r:1},"Atlantic/Madeira":{u:0,d:60,c:["PT"]},"Atlantic/Reykjavik":{u:0,c:["IS"]},"Atlantic/South_Georgia":{u:-120,c:["GS"]},"Atlantic/St_Helena":{a:"Africa/Abidjan",c:["SH"],r:1},"Atlantic/Stanley":{u:-180,c:["FK"]},"Australia/ACT":{a:"Australia/Sydney",r:1},"Australia/Adelaide":{u:570,d:630,c:["AU"]},"Australia/Brisbane":{u:600,c:["AU"]},"Australia/Broken_Hill":{u:570,d:630,c:["AU"]},"Australia/Canberra":{a:"Australia/Sydney",r:1},"Australia/Currie":{a:"Australia/Hobart",r:1},"Australia/Darwin":{u:570,c:["AU"]},"Australia/Eucla":{u:525,c:["AU"]},"Australia/Hobart":{u:600,d:660,c:["AU"]},"Australia/LHI":{a:"Australia/Lord_Howe",r:1},"Australia/Lindeman":{u:600,c:["AU"]},"Australia/Lord_Howe":{u:630,d:660,c:["AU"]},"Australia/Melbourne":{u:600,d:660,c:["AU"]},"Australia/NSW":{a:"Australia/Sydney",r:1},"Australia/North":{a:"Australia/Darwin",r:1},"Australia/Perth":{u:480,c:["AU"]},"Australia/Queensland":{a:"Australia/Brisbane",r:1},"Australia/South":{a:"Australia/Adelaide",r:1},"Australia/Sydney":{u:600,d:660,c:["AU"]},"Australia/Tasmania":{a:"Australia/Hobart",r:1},"Australia/Victoria":{a:"Australia/Melbourne",r:1},"Australia/West":{a:"Australia/Perth",r:1},"Australia/Yancowinna":{a:"Australia/Broken_Hill",r:1},"Brazil/Acre":{a:"America/Rio_Branco",r:1},"Brazil/DeNoronha":{a:"America/Noronha",r:1},"Brazil/East":{a:"America/Sao_Paulo",r:1},"Brazil/West":{a:"America/Manaus",r:1},CET:{u:60,d:120},CST6CDT:{u:-360,d:-300},"Canada/Atlantic":{a:"America/Halifax",r:1},"Canada/Central":{a:"America/Winnipeg",r:1},"Canada/Eastern":{a:"America/Toronto",c:["CA"],r:1},"Canada/Mountain":{a:"America/Edmonton",r:1},"Canada/Newfoundland":{a:"America/St_Johns",r:1},"Canada/Pacific":{a:"America/Vancouver",r:1},"Canada/Saskatchewan":{a:"America/Regina",r:1},"Canada/Yukon":{a:"America/Whitehorse",r:1},"Chile/Continental":{a:"America/Santiago",r:1},"Chile/EasterIsland":{a:"Pacific/Easter",r:1},Cuba:{a:"America/Havana",r:1},EET:{u:120,d:180},EST:{u:-300},EST5EDT:{u:-300,d:-240},Egypt:{a:"Africa/Cairo",r:1},Eire:{a:"Europe/Dublin",r:1},"Etc/GMT":{u:0},"Etc/GMT+0":{a:"Etc/GMT",r:1},"Etc/GMT+1":{u:-60},"Etc/GMT+10":{u:-600},"Etc/GMT+11":{u:-660},"Etc/GMT+12":{u:-720},"Etc/GMT+2":{u:-120},"Etc/GMT+3":{u:-180},"Etc/GMT+4":{u:-240},"Etc/GMT+5":{u:-300},"Etc/GMT+6":{u:-360},"Etc/GMT+7":{u:-420},"Etc/GMT+8":{u:-480},"Etc/GMT+9":{u:-540},"Etc/GMT-0":{a:"Etc/GMT",r:1},"Etc/GMT-1":{u:60},"Etc/GMT-10":{u:600},"Etc/GMT-11":{u:660},"Etc/GMT-12":{u:720},"Etc/GMT-13":{u:780},"Etc/GMT-14":{u:840},"Etc/GMT-2":{u:120},"Etc/GMT-3":{u:180},"Etc/GMT-4":{u:240},"Etc/GMT-5":{u:300},"Etc/GMT-6":{u:360},"Etc/GMT-7":{u:420},"Etc/GMT-8":{u:480},"Etc/GMT-9":{u:540},"Etc/GMT0":{a:"Etc/GMT",r:1},"Etc/Greenwich":{a:"Etc/GMT",r:1},"Etc/UCT":{a:"Etc/UTC",r:1},"Etc/UTC":{u:0},"Etc/Universal":{a:"Etc/UTC",r:1},"Etc/Zulu":{a:"Etc/UTC",r:1},"Europe/Amsterdam":{u:60,d:120,c:["NL"]},"Europe/Andorra":{u:60,d:120,c:["AD"]},"Europe/Astrakhan":{u:240,c:["RU"]},"Europe/Athens":{u:120,d:180,c:["GR"]},"Europe/Belfast":{a:"Europe/London",c:["GB"],r:1},"Europe/Belgrade":{u:60,d:120,c:["RS","BA","HR","ME","MK","SI"]},"Europe/Berlin":{u:60,d:120,c:["DE"]},"Europe/Bratislava":{a:"Europe/Prague",c:["SK"],r:1},"Europe/Brussels":{u:60,d:120,c:["BE"]},"Europe/Bucharest":{u:120,d:180,c:["RO"]},"Europe/Budapest":{u:60,d:120,c:["HU"]},"Europe/Busingen":{a:"Europe/Zurich",c:["DE"],r:1},"Europe/Chisinau":{u:120,d:180,c:["MD"]},"Europe/Copenhagen":{u:60,d:120,c:["DK"]},"Europe/Dublin":{u:60,d:0,c:["IE"]},"Europe/Gibraltar":{u:60,d:120,c:["GI"]},"Europe/Guernsey":{a:"Europe/London",c:["GG"],r:1},"Europe/Helsinki":{u:120,d:180,c:["FI","AX"]},"Europe/Isle_of_Man":{a:"Europe/London",c:["IM"],r:1},"Europe/Istanbul":{u:180,c:["TR"]},"Europe/Jersey":{a:"Europe/London",c:["JE"],r:1},"Europe/Kaliningrad":{u:120,c:["RU"]},"Europe/Kiev":{u:120,d:180,c:["UA"]},"Europe/Kirov":{u:180,c:["RU"]},"Europe/Lisbon":{u:0,d:60,c:["PT"]},"Europe/Ljubljana":{a:"Europe/Belgrade",c:["SI"],r:1},"Europe/London":{u:0,d:60,c:["GB","GG","IM","JE"]},"Europe/Luxembourg":{u:60,d:120,c:["LU"]},"Europe/Madrid":{u:60,d:120,c:["ES"]},"Europe/Malta":{u:60,d:120,c:["MT"]},"Europe/Mariehamn":{a:"Europe/Helsinki",c:["AX"],r:1},"Europe/Minsk":{u:180,c:["BY"]},"Europe/Monaco":{u:60,d:120,c:["MC"]},"Europe/Moscow":{u:180,c:["RU"]},"Europe/Nicosia":{a:"Asia/Nicosia",r:1},"Europe/Oslo":{u:60,d:120,c:["NO","SJ","BV"]},"Europe/Paris":{u:60,d:120,c:["FR"]},"Europe/Podgorica":{a:"Europe/Belgrade",c:["ME"],r:1},"Europe/Prague":{u:60,d:120,c:["CZ","SK"]},"Europe/Riga":{u:120,d:180,c:["LV"]},"Europe/Rome":{u:60,d:120,c:["IT","SM","VA"]},"Europe/Samara":{u:240,c:["RU"]},"Europe/San_Marino":{a:"Europe/Rome",c:["SM"],r:1},"Europe/Sarajevo":{a:"Europe/Belgrade",c:["BA"],r:1},"Europe/Saratov":{u:240,c:["RU"]},"Europe/Simferopol":{u:180,c:["RU","UA"]},"Europe/Skopje":{a:"Europe/Belgrade",c:["MK"],r:1},"Europe/Sofia":{u:120,d:180,c:["BG"]},"Europe/Stockholm":{u:60,d:120,c:["SE"]},"Europe/Tallinn":{u:120,d:180,c:["EE"]},"Europe/Tirane":{u:60,d:120,c:["AL"]},"Europe/Tiraspol":{a:"Europe/Chisinau",r:1},"Europe/Ulyanovsk":{u:240,c:["RU"]},"Europe/Uzhgorod":{u:120,d:180,c:["UA"]},"Europe/Vaduz":{a:"Europe/Zurich",c:["LI"],r:1},"Europe/Vatican":{a:"Europe/Rome",c:["VA"],r:1},"Europe/Vienna":{u:60,d:120,c:["AT"]},"Europe/Vilnius":{u:120,d:180,c:["LT"]},"Europe/Volgograd":{u:180,c:["RU"]},"Europe/Warsaw":{u:60,d:120,c:["PL"]},"Europe/Zagreb":{a:"Europe/Belgrade",c:["HR"],r:1},"Europe/Zaporozhye":{u:120,d:180,c:["UA"]},"Europe/Zurich":{u:60,d:120,c:["CH","DE","LI"]},Factory:{u:0},GB:{a:"Europe/London",c:["GB"],r:1},"GB-Eire":{a:"Europe/London",c:["GB"],r:1},GMT:{a:"Etc/GMT",r:1},"GMT+0":{a:"Etc/GMT",r:1},"GMT-0":{a:"Etc/GMT",r:1},GMT0:{a:"Etc/GMT",r:1},Greenwich:{a:"Etc/GMT",r:1},HST:{u:-600},Hongkong:{a:"Asia/Hong_Kong",r:1},Iceland:{a:"Atlantic/Reykjavik",r:1},"Indian/Antananarivo":{a:"Africa/Nairobi",c:["MG"],r:1},"Indian/Chagos":{u:360,c:["IO"]},"Indian/Christmas":{u:420,c:["CX"]},"Indian/Cocos":{u:390,c:["CC"]},"Indian/Comoro":{a:"Africa/Nairobi",c:["KM"],r:1},"Indian/Kerguelen":{u:300,c:["TF","HM"]},"Indian/Mahe":{u:240,c:["SC"]},"Indian/Maldives":{u:300,c:["MV"]},"Indian/Mauritius":{u:240,c:["MU"]},"Indian/Mayotte":{a:"Africa/Nairobi",c:["YT"],r:1},"Indian/Reunion":{u:240,c:["RE","TF"]},Iran:{a:"Asia/Tehran",r:1},Israel:{a:"Asia/Jerusalem",r:1},Jamaica:{a:"America/Jamaica",r:1},Japan:{a:"Asia/Tokyo",r:1},Kwajalein:{a:"Pacific/Kwajalein",r:1},Libya:{a:"Africa/Tripoli",r:1},MET:{u:60,d:120},MST:{u:-420},MST7MDT:{u:-420,d:-360},"Mexico/BajaNorte":{a:"America/Tijuana",r:1},"Mexico/BajaSur":{a:"America/Mazatlan",r:1},"Mexico/General":{a:"America/Mexico_City",r:1},NZ:{a:"Pacific/Auckland",c:["NZ"],r:1},"NZ-CHAT":{a:"Pacific/Chatham",r:1},Navajo:{a:"America/Denver",r:1},PRC:{a:"Asia/Shanghai",r:1},PST8PDT:{u:-480,d:-420},"Pacific/Apia":{u:780,c:["WS"]},"Pacific/Auckland":{u:720,d:780,c:["NZ","AQ"]},"Pacific/Bougainville":{u:660,c:["PG"]},"Pacific/Chatham":{u:765,d:825,c:["NZ"]},"Pacific/Chuuk":{u:600,c:["FM"]},"Pacific/Easter":{u:-360,d:-300,c:["CL"]},"Pacific/Efate":{u:660,c:["VU"]},"Pacific/Enderbury":{a:"Pacific/Kanton",r:1},"Pacific/Fakaofo":{u:780,c:["TK"]},"Pacific/Fiji":{u:720,d:780,c:["FJ"]},"Pacific/Funafuti":{u:720,c:["TV"]},"Pacific/Galapagos":{u:-360,c:["EC"]},"Pacific/Gambier":{u:-540,c:["PF"]},"Pacific/Guadalcanal":{u:660,c:["SB"]},"Pacific/Guam":{u:600,c:["GU","MP"]},"Pacific/Honolulu":{u:-600,c:["US","UM"]},"Pacific/Johnston":{a:"Pacific/Honolulu",c:["UM"],r:1},"Pacific/Kanton":{u:780,c:["KI"]},"Pacific/Kiritimati":{u:840,c:["KI"]},"Pacific/Kosrae":{u:660,c:["FM"]},"Pacific/Kwajalein":{u:720,c:["MH"]},"Pacific/Majuro":{u:720,c:["MH"]},"Pacific/Marquesas":{u:-510,c:["PF"]},"Pacific/Midway":{a:"Pacific/Pago_Pago",c:["UM"],r:1},"Pacific/Nauru":{u:720,c:["NR"]},"Pacific/Niue":{u:-660,c:["NU"]},"Pacific/Norfolk":{u:660,d:720,c:["NF"]},"Pacific/Noumea":{u:660,c:["NC"]},"Pacific/Pago_Pago":{u:-660,c:["AS","UM"]},"Pacific/Palau":{u:540,c:["PW"]},"Pacific/Pitcairn":{u:-480,c:["PN"]},"Pacific/Pohnpei":{u:660,c:["FM"]},"Pacific/Ponape":{a:"Pacific/Pohnpei",r:1},"Pacific/Port_Moresby":{u:600,c:["PG","AQ"]},"Pacific/Rarotonga":{u:-600,c:["CK"]},"Pacific/Saipan":{a:"Pacific/Guam",c:["MP"],r:1},"Pacific/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},"Pacific/Tahiti":{u:-600,c:["PF"]},"Pacific/Tarawa":{u:720,c:["KI"]},"Pacific/Tongatapu":{u:780,c:["TO"]},"Pacific/Truk":{a:"Pacific/Chuuk",r:1},"Pacific/Wake":{u:720,c:["UM"]},"Pacific/Wallis":{u:720,c:["WF"]},"Pacific/Yap":{a:"Pacific/Chuuk",r:1},Poland:{a:"Europe/Warsaw",r:1},Portugal:{a:"Europe/Lisbon",r:1},ROC:{a:"Asia/Taipei",r:1},ROK:{a:"Asia/Seoul",r:1},Singapore:{a:"Asia/Singapore",c:["SG"],r:1},Turkey:{a:"Europe/Istanbul",r:1},UCT:{a:"Etc/UTC",r:1},"US/Alaska":{a:"America/Anchorage",r:1},"US/Aleutian":{a:"America/Adak",r:1},"US/Arizona":{a:"America/Phoenix",c:["US"],r:1},"US/Central":{a:"America/Chicago",r:1},"US/East-Indiana":{a:"America/Indiana/Indianapolis",r:1},"US/Eastern":{a:"America/New_York",r:1},"US/Hawaii":{a:"Pacific/Honolulu",c:["US"],r:1},"US/Indiana-Starke":{a:"America/Indiana/Knox",r:1},"US/Michigan":{a:"America/Detroit",r:1},"US/Mountain":{a:"America/Denver",r:1},"US/Pacific":{a:"America/Los_Angeles",r:1},"US/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},UTC:{a:"Etc/UTC",r:1},Universal:{a:"Etc/UTC",r:1},"W-SU":{a:"Europe/Moscow",r:1},WET:{u:0,d:60},Zulu:{a:"Etc/UTC",r:1}};function j(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return null;try{let e=W[s]?.c?.[0];return e&&pe[e]||null}catch{return null}}function M(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return"Unknown";try{return W[s]?.c?.[0]||"Unknown"}catch{return"Unknown"}}function Y(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;return s===""||!s?null:s.split("/")[1]?.replace("_"," ")||null}var P=class{constructor(e,t){this.isDestroyed=!1;this.currentPath=null;this.originalPushState=null;this.originalReplaceState=null;this.previousPage=null;this.landingPage=null;this.pageViewCount=0;this.handlePopState=()=>{this.isDestroyed||this.trackCurrentPage()};this.handleHashChange=()=>{this.isDestroyed||this.trackCurrentPage()};this.tracker=e,this.config=t,this.trackCurrentPage(!0),this.setupHistoryListeners(),this.setupHashChangeListener()}setupHistoryListeners(){typeof window>"u"||typeof history>"u"||(this.originalPushState=history.pushState,history.pushState=(e,t,i)=>{this.originalPushState?.call(history,e,t,i),this.trackCurrentPage()},this.originalReplaceState=history.replaceState,history.replaceState=(e,t,i)=>{this.originalReplaceState?.call(history,e,t,i),this.trackCurrentPage()},window.addEventListener("popstate",this.handlePopState))}setupHashChangeListener(){typeof window>"u"||window.addEventListener("hashchange",this.handleHashChange)}trackCurrentPage(e=!1){if(this.isDestroyed||typeof window>"u")return;let t=this.extractPath(window.location.href);if(!e&&t===this.currentPath)return;this.currentPath&&(this.previousPage=this.currentPath),this.currentPath=t,this.pageViewCount++,e&&(this.landingPage=t);let i=this.tracker.hasConsent("analytics"),r=window.location.href,a=document.referrer||"",n=A(r);Object.keys(n).length>0&&(!p()||e)&&Q(n);let o=p()||{},c=C(this.config.tenantId,a,r,o),l={page:t,timestamp:Date.now()};if(i){l.title=document.title||"",l.full_url=this.cleanUrl(r),l.session_id=this.tracker.getSessionId(),a&&(l.referrer=a,l.referrer_domain=this.extractDomain(a),l.referrer_category=m(a,r)),this.landingPage&&!e&&(l.landing_page=this.landingPage),this.previousPage&&(l.previous_page=this.previousPage),o.utm_source&&(l.utm_source=o.utm_source),o.utm_medium&&(l.utm_medium=o.utm_medium),o.utm_campaign&&(l.utm_campaign=o.utm_campaign),o.utm_term&&(l.utm_term=o.utm_term),o.utm_content&&(l.utm_content=o.utm_content),l.first_touch_source=c.source,l.first_touch_medium=c.medium,l.first_touch_campaign=c.campaign,l.first_touch_referrer_category=c.referrer_category,l.device=this.getDeviceType(),l.browser=this.getBrowser(),l.os=this.getOS(),l.language=navigator.language||"";let u=Intl.DateTimeFormat().resolvedOptions().timeZone;l.timezone=u,l.country=M(),l.screen_resolution=`${screen.width}x${screen.height}`,l.viewport=`${window.innerWidth}x${window.innerHeight}`}this.tracker.trackSystemEvent("page_view",l)}extractDomain(e){try{return new URL(e).hostname}catch{return""}}getBrowser(){let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}extractPath(e){try{let t=new URL(e),i=t.pathname;return!this.config.stripQueryParams&&t.search&&(i+=t.search),!this.config.stripHash&&t.hash&&(i+=t.hash),i}catch(t){return this.config.debug&&console.warn("[Page Tracking] Failed to parse URL:",e,t),e}}cleanUrl(e){if(!this.config.stripQueryParams)return e;try{let t=new URL(e);return`${t.origin}${t.pathname}${this.config.stripHash?"":t.hash}`}catch{return e}}getCurrentPage(){return this.currentPath}trackPage(e,t){if(this.isDestroyed)return;let i=this.tracker.hasConsent("analytics"),r={page:e,timestamp:Date.now(),...t};i&&typeof document<"u"&&typeof window<"u"&&(r.referrer||(r.referrer=document.referrer||""),r.title||(r.title=document.title||""),r.full_url||(r.full_url=window.location.href),r.session_id||(r.session_id=this.tracker.getSessionId()),r.browser||(r.browser=this.getBrowser()),r.os||(r.os=this.getOS())),this.tracker.trackSystemEvent("page_view",r)}getPageViewCount(){return this.pageViewCount}destroy(){this.isDestroyed||(typeof history<"u"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState)),typeof window<"u"&&(window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)),this.isDestroyed=!0)}};function L(s){let e=0;for(let t=0;t<s.length;t++){let i=s.charCodeAt(t);e=(e<<5)-e+i,e=e&e}return Math.abs(e).toString(36)}function fe(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,s=>{let e=Math.random()*16|0;return(s==="x"?e:e&3|8).toString(16)})}function ve(){if(typeof window>"u")return"server";let s=[screen.width?.toString()||"",screen.height?.toString()||"",navigator.language||"",Intl.DateTimeFormat().resolvedOptions().timeZone||""];return L(s.join("|"))}function ye(){let s=new Date,e=s.getFullYear(),t=String(s.getMonth()+1).padStart(2,"0"),i=String(s.getDate()).padStart(2,"0");return`${e}-${t}-${i}`}var I=class{constructor(e){this.cachedDailyId=null;this.dailyIdDate=null;this.permanentId=null;this.config=e,e.mode==="permanent"&&e.useLocalStorage&&this.loadPermanentId()}generateDailyRotatingId(){let e=ye();if(this.cachedDailyId&&this.dailyIdDate===e)return this.cachedDailyId;let t=ve(),i=`${this.config.tenantId}|${e}|${t}`,r=`daily_${L(i)}_${L(Date.now().toString())}`;return this.cachedDailyId=r,this.dailyIdDate=e,r}generatePermanentId(){if(this.permanentId)return this.permanentId;if(this.config.useLocalStorage){let t=this.loadPermanentId();if(t)return t}let e=fe();return this.permanentId=e,this.config.useLocalStorage&&this.savePermanentId(e),e}getCurrentUserId(){return this.config.mode==="cookieless"?this.generateDailyRotatingId():this.generatePermanentId()}setMode(e){this.config.mode=e,e==="permanent"&&(this.cachedDailyId=null,this.dailyIdDate=null),e==="cookieless"&&(this.permanentId=null,this.config.useLocalStorage&&this.clearPermanentId())}loadPermanentId(){if(typeof window>"u")return null;try{let e=`grain_anonymous_user_id_${this.config.tenantId}`,t=localStorage.getItem(e);if(t)return this.permanentId=t,t}catch{}return null}savePermanentId(e){if(!(typeof window>"u"))try{let t=`grain_anonymous_user_id_${this.config.tenantId}`;localStorage.setItem(t,e)}catch{}}clearPermanentId(){if(!(typeof window>"u"))try{let e=`grain_anonymous_user_id_${this.config.tenantId}`;localStorage.removeItem(e)}catch{}}getIdInfo(){let e=this.getCurrentUserId();return{mode:this.config.mode,id:e,isDailyRotating:e.startsWith("daily_")}}};var v=class{constructor(e){this.eventQueue=[];this.waitingForConsentQueue=[];this.flushTimer=null;this.isDestroyed=!1;this.globalUserId=null;this.persistentAnonymousUserId=null;this.configCache=null;this.configRefreshTimer=null;this.configChangeListeners=[];this.configFetchPromise=null;this.cookiesEnabled=!1;this.activityDetector=null;this.heartbeatManager=null;this.pageTrackingManager=null;this.ephemeralSessionId=null;this.eventCountSinceLastHeartbeat=0;this.interactionTrackingManager=null;this.sectionTrackingManager=null;this.heatmapTrackingManager=null;this.sessionStartTime=Date.now();this.sessionEventCount=0;this.debugAgent=null;this.isDebugMode=!1;this.config={apiUrl:"https://api.grainql.com",authStrategy:"NONE",batchSize:50,flushInterval:5e3,retryAttempts:3,retryDelay:1e3,maxEventsPerRequest:160,debug:!1,defaultConfigurations:{},configCacheKey:"grain_config",configRefreshInterval:3e5,enableConfigCache:!0,consentMode:"cookieless",waitForConsent:!1,disableAutoProperties:!1,enableHeartbeat:!0,heartbeatActiveInterval:12e4,heartbeatInactiveInterval:3e5,enableAutoPageView:!0,stripQueryParams:!0,stripHash:!1,enableHeatmapTracking:!0,...e,tenantId:e.tenantId},this.consentManager=new T(this.config.tenantId,this.config.consentMode);let t=this.consentManager.getIdMode();this.idManager=new I({mode:t,tenantId:this.config.tenantId,useLocalStorage:!0}),e.userId&&(this.globalUserId=e.userId),this.validateConfig(),this.setupBeforeUnload(),this.startFlushTimer(),this.initializeConfigCache(),this.ephemeralSessionId=this.generateUUID(),typeof window<"u"&&(this.checkAndInitializeDebugMode(),this.initializeAutomaticTracking(),this.trackSessionStart(),this.config.enableHeatmapTracking&&this.initializeHeatmapTracking()),this.consentManager.addListener(i=>{let r=this.consentManager.getIdMode();this.idManager.setMode(r),i.granted&&this.handleConsentGranted()})}validateConfig(){if(!this.config.tenantId)throw new Error("Grain Analytics: tenantId is required");if(this.config.authStrategy==="SERVER_SIDE"&&!this.config.secretKey)throw new Error("Grain Analytics: secretKey is required for SERVER_SIDE auth strategy");if(this.config.authStrategy==="JWT"&&!this.config.authProvider)throw new Error("Grain Analytics: authProvider is required for JWT auth strategy")}generateUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}shouldAllowPersistentStorage(){let e=this.consentManager.hasConsent("analytics"),t=this.config.consentMode==="cookieless",i=!!this.globalUserId,r=this.config.authStrategy==="JWT";return t?!1:e||i||r}generateAnonymousUserId(){return this.generateUUID()}initializePersistentAnonymousUserId(){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID initialization (GDPR compliance)");return}let e=`grain_anonymous_user_id_${this.config.tenantId}`,t="_grain_uid";try{if(this.cookiesEnabled){let r=K(t);if(r){this.persistentAnonymousUserId=r,this.log("Loaded persistent anonymous user ID from cookie:",this.persistentAnonymousUserId);return}}let i=localStorage.getItem(e);i?(this.persistentAnonymousUserId=i,this.log("Loaded persistent anonymous user ID from localStorage:",this.persistentAnonymousUserId),this.cookiesEnabled&&this.savePersistentAnonymousUserId(i)):(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId),this.log("Generated new persistent anonymous user ID:",this.persistentAnonymousUserId))}catch(i){this.log("Failed to initialize persistent anonymous user ID:",i),this.persistentAnonymousUserId=this.generateAnonymousUserId()}}savePersistentAnonymousUserId(e){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID save (GDPR compliance)");return}let t=`grain_anonymous_user_id_${this.config.tenantId}`,i="_grain_uid";try{if(this.cookiesEnabled){let r={maxAge:31536e3,sameSite:"lax",secure:typeof window<"u"&&window.location.protocol==="https:",...this.config.cookieOptions};$(i,e,r)}localStorage.setItem(t,e)}catch(r){this.log("Failed to save persistent anonymous user ID:",r)}}getEffectiveUserIdInternal(){return this.globalUserId?this.globalUserId:this.idManager.getCurrentUserId()}log(...e){this.config.debug&&console.log("[Grain Analytics]",...e)}createErrorDigest(e){let t=[...new Set(e.map(n=>n.eventName))],i=[...new Set(e.map(n=>n.userId))],r=0,a=0;return e.forEach(n=>{let o=n.properties||{};r+=Object.keys(o).length,a+=JSON.stringify(n).length}),{eventCount:e.length,totalProperties:r,totalSize:a,eventNames:t,userIds:i}}formatError(e,t,i){let r=i?this.createErrorDigest(i):{eventCount:0,totalProperties:0,totalSize:0,eventNames:[],userIds:[]},a="UNKNOWN_ERROR",n="An unknown error occurred";if(e instanceof Error)n=e.message,n.includes("fetch failed")||n.includes("network error")?a="NETWORK_ERROR":n.includes("timeout")?a="TIMEOUT_ERROR":n.includes("HTTP 4")?a="CLIENT_ERROR":n.includes("HTTP 5")?a="SERVER_ERROR":n.includes("JSON")?a="PARSE_ERROR":n.includes("auth")||n.includes("unauthorized")?a="AUTH_ERROR":n.includes("rate limit")||n.includes("429")?a="RATE_LIMIT_ERROR":a="GENERAL_ERROR";else if(typeof e=="string")n=e,a="STRING_ERROR";else if(e&&typeof e=="object"&&"status"in e){let o=e.status;a=`HTTP_${o}`,n=`HTTP ${o} error`}return{code:a,message:n,digest:r,timestamp:new Date().toISOString(),context:t,originalError:e}}logError(e){if(!this.config.debug)return;let{code:t,message:i,digest:r,timestamp:a,context:n}=e,o={"\u{1F6A8} Grain Analytics Error":{"Error Code":t,Message:i,Context:n,Timestamp:a,"Event Digest":{Events:r.eventCount,Properties:r.totalProperties,"Size (bytes)":r.totalSize,"Event Names":r.eventNames.length>0?r.eventNames.join(", "):"None","User IDs":r.userIds.length>0?r.userIds.slice(0,3).join(", ")+(r.userIds.length>3?"...":""):"None"}}};console.error("\u{1F6A8} Grain Analytics Error:",o),console.error(`[Grain Analytics] ${t}: ${i} (${n}) - Events: ${r.eventCount}, Props: ${r.totalProperties}, Size: ${r.totalSize}B`)}async safeExecute(e,t,i){try{return await e()}catch(r){let a=this.formatError(r,t,i);return this.logError(a),null}}formatEvent(e){let t=e.properties||{};if(!this.config.disableAutoProperties&&typeof window<"u"){let i=this.consentManager.hasConsent("analytics");if(!e.eventName.startsWith("_grain_")&&i){let a=p();a&&(a.utm_source&&(t.utm_source=a.utm_source),a.utm_medium&&(t.utm_medium=a.utm_medium),a.utm_campaign&&(t.utm_campaign=a.utm_campaign),a.utm_term&&(t.utm_term=a.utm_term),a.utm_content&&(t.utm_content=a.utm_content));let n=R(this.config.tenantId);n&&(t.first_touch_source=n.source,t.first_touch_medium=n.medium,t.first_touch_campaign=n.campaign,t.first_touch_referrer_category=n.referrer_category),t.session_id||(t.session_id=this.getSessionId())}}return{eventName:e.eventName,userId:e.userId||this.getEffectiveUserIdInternal(),properties:t}}async getAuthHeaders(){let e={"Content-Type":"application/json"};switch(this.config.authStrategy){case"NONE":break;case"SERVER_SIDE":e.Authorization=`Chase ${this.config.secretKey}`;break;case"JWT":if(this.config.authProvider){let t=await this.config.authProvider.getToken();e.Authorization=`Bearer ${t}`}break}return e}async delay(e){return new Promise(t=>setTimeout(t,e))}isRetriableError(e){if(e instanceof Error){let t=e.message.toLowerCase();if(t.includes("fetch failed")||t==="network error"||t.includes("timeout")||t.includes("connection"))return!0}if(typeof e=="object"&&e!==null&&"status"in e){let t=e.status;return t>=500||t===429}return!1}async sendEvents(e){if(e.length===0)return;let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(e)});if(!n.ok){let o=`HTTP ${n.status}`;try{let l=await n.json();l?.message&&(o=l.message)}catch{let l=await n.text();l&&(o=l)}let c=new Error(`Failed to send events: ${o}`);throw c.status=n.status,c}this.log(`Successfully sent ${e.length} events`);return}catch(r){if(t=r,i===this.config.retryAttempts){let n=this.formatError(r,`sendEvents (attempt ${i+1}/${this.config.retryAttempts+1})`,e);this.logError(n);return}if(!this.isRetriableError(r)){let n=this.formatError(r,"sendEvents (non-retriable error)",e);this.logError(n);return}let a=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${a}ms after error:`,r),await this.delay(a)}}async sendEventsWithBeacon(e){if(e.length!==0)try{let t=await this.getAuthHeaders(),i=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,r=JSON.stringify(e);if(!(this.config.authStrategy!=="NONE")&&typeof navigator<"u"&&"sendBeacon"in navigator){let n=new Blob([r],{type:"application/json"});if(navigator.sendBeacon(i,n)){this.log(`Successfully sent ${e.length} events via beacon`);return}}await fetch(i,{method:"POST",headers:t,body:r,keepalive:!0})}catch(t){let i=this.formatError(t,"sendEventsWithBeacon",e);this.logError(i)}}startFlushTimer(){typeof window>"u"||(this.flushTimer&&clearInterval(this.flushTimer),this.flushTimer=window.setInterval(()=>{this.eventQueue.length>0&&this.flush().catch(e=>{let t=this.formatError(e,"auto-flush");this.logError(t)})},this.config.flushInterval))}setupBeforeUnload(){if(typeof window>"u")return;let e=()=>{if(this.trackSessionEnd(),this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden"&&this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}})}initializeAutomaticTracking(){if(this.config.enableHeartbeat)try{this.activityDetector=new w,this.heartbeatManager=new k(this,this.activityDetector,{activeInterval:this.config.heartbeatActiveInterval,inactiveInterval:this.config.heartbeatInactiveInterval,debug:this.config.debug})}catch(e){this.log("Failed to initialize heartbeat tracking:",e)}if(this.config.enableAutoPageView)try{this.pageTrackingManager=new P(this,{stripQueryParams:this.config.stripQueryParams,stripHash:this.config.stripHash,debug:this.config.debug,tenantId:this.config.tenantId})}catch(e){this.log("Failed to initialize page view tracking:",e)}this.initializeAutoTracking()}initializeHeatmapTracking(){if(!(typeof window>"u"))try{this.log("Initializing heatmap tracking"),Promise.resolve().then(()=>(q(),J)).then(({HeatmapTrackingManager:e})=>{try{this.heatmapTrackingManager=new e(this,{scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:this.config.debug}),this.log("Heatmap tracking initialized")}catch(t){this.log("Failed to initialize heatmap tracking:",t)}}).catch(e=>{this.log("Failed to load heatmap tracking module:",e)})}catch(e){this.log("Failed to initialize heatmap tracking:",e)}}async initializeAutoTracking(){try{this.log("Initializing auto-tracking");let e=this.globalUserId||this.persistentAnonymousUserId||this.generateUUID(),t=typeof window<"u"?window.location.href:"",i={userId:e,immediateKeys:[],properties:{},currentUrl:t},r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(i)});if(!n.ok){this.log("Failed to fetch auto-tracking config:",n.status);return}let o=await n.json();o.autoTrackingConfig&&(this.log("Auto-tracking config loaded"),this.setupAutoTrackingManagers(o.autoTrackingConfig))}catch(e){this.log("Failed to initialize auto-tracking:",e)}}setupAutoTrackingManagers(e){this.log("Setting up auto-tracking managers"),e.interactions&&e.interactions.length>0&&(this.log("Loading interaction tracking:",e.interactions.length,"interactions"),Promise.resolve().then(()=>(Z(),X)).then(({InteractionTrackingManager:t})=>{try{this.interactionTrackingManager=new t(this,e.interactions,{debug:this.config.debug,enableMutationObserver:!0,mutationDebounceDelay:500,tenantId:this.config.tenantId,apiUrl:this.config.apiUrl}),this.log("Interaction tracking initialized")}catch(i){this.log("Failed to initialize interaction tracking:",i)}}).catch(t=>{this.log("Failed to load interaction tracking module:",t)})),e.sections&&e.sections.length>0&&(this.log("Loading section tracking:",e.sections.length,"sections"),Promise.resolve().then(()=>(te(),ee)).then(({SectionTrackingManager:t})=>{try{this.sectionTrackingManager=new t(this,e.sections,{minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:this.config.debug}),this.log("Section tracking initialized")}catch(i){this.log("Failed to initialize section tracking:",i)}}).catch(t=>{this.log("Failed to load section tracking module:",t)}))}trackSessionStart(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t={session_id:this.getSessionId(),timestamp:this.sessionStartTime};if(e){let i=document.referrer||"",r=window.location.href,a=A(r),n=p()||a,o=C(this.config.tenantId,i,r,n);t.landing_page=window.location.pathname,i?(t.referrer=i,t.referrer_domain=new URL(i).hostname,t.referrer_category=m(i,r)):t.referrer_category="direct",n.utm_source&&(t.utm_source=n.utm_source),n.utm_medium&&(t.utm_medium=n.utm_medium),n.utm_campaign&&(t.utm_campaign=n.utm_campaign),n.utm_term&&(t.utm_term=n.utm_term),n.utm_content&&(t.utm_content=n.utm_content),t.first_touch_source=o.source,t.first_touch_medium=o.medium,t.first_touch_campaign=o.campaign,t.first_touch_referrer_category=o.referrer_category,t.device=this.getDeviceType(),t.screen_resolution=`${screen.width}x${screen.height}`,t.viewport=`${window.innerWidth}x${window.innerHeight}`,t.browser=this.getBrowser(),t.os=this.getOS(),t.language=navigator.language||"",t.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}this.trackSystemEvent("_grain_session_start",t),this.log("Session started")}trackSessionEnd(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t=Date.now()-this.sessionStartTime,i={session_id:this.getSessionId(),session_duration:Math.floor(t/1e3),duration:t,event_count:this.sessionEventCount,timestamp:Date.now()};if(e&&this.pageTrackingManager){let r=this.pageTrackingManager.getPageViewCount();i.pages_per_session=r,i.page_count=r}this.trackSystemEvent("_grain_session_end",i),this.log("Session ended")}getBrowser(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){if(typeof window>"u"||typeof navigator>"u")return"Unknown";let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}handleConsentGranted(){this.flushWaitingForConsentQueue(),this.persistentAnonymousUserId||(this.initializePersistentAnonymousUserId(),this.log("Initialized persistent ID after consent grant")),this.ephemeralSessionId&&this.trackSystemEvent("_grain_consent_granted",{previous_session_id:this.ephemeralSessionId,new_user_id:this.getEffectiveUserId(),timestamp:Date.now()})}trackSystemEvent(e,t){if(this.isDestroyed)return;let i=this.consentManager.hasConsent("analytics"),r={eventName:e,userId:this.getEffectiveUserId(),properties:{...t,_minimal:!i,_consent_status:i?"granted":"pending"}};this.eventQueue.push(r),this.eventCountSinceLastHeartbeat++,this.log(`Queued system event: ${e}`),this.eventQueue.length>=this.config.batchSize&&this.flush().catch(a=>{let n=this.formatError(a,"flush system event");this.logError(n)})}getEphemeralSessionId(){return this.ephemeralSessionId||(this.ephemeralSessionId=this.generateUUID()),this.ephemeralSessionId}getCurrentPage(){return this.pageTrackingManager?.getCurrentPage()||null}getEventCountSinceLastHeartbeat(){return this.eventCountSinceLastHeartbeat}resetEventCountSinceLastHeartbeat(){this.eventCountSinceLastHeartbeat=0}getActivityDetector(){if(!this.activityDetector)throw new Error("Activity detector not initialized");return this.activityDetector}getEffectiveUserId(){return this.getEffectiveUserIdInternal()}getSessionId(){return this.consentManager.hasConsent("analytics")?this.getEffectiveUserId():this.getEphemeralSessionId()}async track(e,t,i){try{if(this.isDestroyed){let c=new Error("Grain Analytics: Client has been destroyed"),l=this.formatError(c,"track (client destroyed)");this.logError(l);return}let r,a={};if(typeof e=="string"?(r={eventName:e,properties:t},a=i||{}):(r=e,a=t||{}),this.config.allowedProperties&&r.properties){let c={};for(let l of this.config.allowedProperties)l in r.properties&&(c[l]=r.properties[l]);r.properties=c}let n=this.formatEvent(r);if(this.consentManager.shouldWaitForConsent()&&this.config.waitForConsent){this.waitingForConsentQueue.push(n),this.log(`Event waiting for consent: ${r.eventName}`,r.properties);return}let o=this.consentManager.hasConsent("analytics");n.properties={...n.properties,_minimal:!o,_consent_status:o?"granted":"pending"},this.eventQueue.push(n),this.eventCountSinceLastHeartbeat++,this.sessionEventCount++,this.log(`Queued event: ${r.eventName}`),(a.flush||this.eventQueue.length>=this.config.batchSize)&&await this.flush()}catch(r){let a=this.formatError(r,"track");this.logError(a)}}flushWaitingForConsentQueue(){this.waitingForConsentQueue.length!==0&&(this.log(`Flushing ${this.waitingForConsentQueue.length} events waiting for consent`),this.eventQueue.push(...this.waitingForConsentQueue),this.waitingForConsentQueue=[],this.flush().catch(e=>{let t=this.formatError(e,"flush waiting for consent queue");this.logError(t)}))}identify(e){this.log(`Identified user: ${e}`),this.globalUserId=e,this.persistentAnonymousUserId=null}setUserId(e){this.log(`Set global user ID: ${e}`),this.globalUserId=e,e?this.persistentAnonymousUserId=null:this.persistentAnonymousUserId||(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId))}getUserId(){return this.globalUserId}getEffectiveUserIdPublic(){return this.getEffectiveUserIdInternal()}login(e){try{if(this.isDestroyed){let t=new Error("Grain Analytics: Client has been destroyed"),i=this.formatError(t,"login (client destroyed)");this.logError(i);return}e.userId&&(this.log(`Login: Setting user ID to ${e.userId}`),this.globalUserId=e.userId,this.persistentAnonymousUserId=null),e.authToken&&(this.log("Login: Setting auth token"),this.config.authStrategy==="NONE"&&(this.config.authStrategy="JWT"),this.config.authProvider={getToken:()=>e.authToken}),e.authStrategy&&(this.log(`Login: Setting auth strategy to ${e.authStrategy}`),this.config.authStrategy=e.authStrategy),this.log(`Login successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(t){let i=this.formatError(t,"login");this.logError(i)}}logout(){try{if(this.isDestroyed){let e=new Error("Grain Analytics: Client has been destroyed"),t=this.formatError(e,"logout (client destroyed)");this.logError(t);return}if(this.log("Logout: Clearing user session"),this.globalUserId=null,this.config.authStrategy="NONE",this.config.authProvider=void 0,!this.persistentAnonymousUserId&&(this.persistentAnonymousUserId=this.generateAnonymousUserId(),typeof window<"u"))try{let e=`grain_anonymous_user_id_${this.config.tenantId}`;localStorage.setItem(e,this.persistentAnonymousUserId)}catch(e){this.log("Failed to persist new anonymous user ID after logout:",e)}this.log(`Logout successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(e){let t=this.formatError(e,"logout");this.logError(t)}}async setProperty(e,t){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"setProperty (client destroyed)");this.logError(c);return}let i=t?.userId||this.getEffectiveUserIdInternal(),r=Object.keys(e);if(r.length>4){let o=new Error("Grain Analytics: Maximum 4 properties allowed per request"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}if(r.length===0){let o=new Error("Grain Analytics: At least one property is required"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}let a={};for(let[o,c]of Object.entries(e))c==null?a[o]="":typeof c=="string"?a[o]=c:a[o]=JSON.stringify(c);let n={userId:i,...a};await this.sendProperties(n)}catch(i){let r=this.formatError(i,"setProperty");this.logError(r)}}async sendProperties(e){let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(e)});if(!n.ok){let o=`HTTP ${n.status}`;try{let l=await n.json();l?.message&&(o=l.message)}catch{let l=await n.text();l&&(o=l)}let c=new Error(`Failed to set properties: ${o}`);throw c.status=n.status,c}this.log(`Successfully set properties for user ${e.userId}`);return}catch(r){if(t=r,i===this.config.retryAttempts){let n=this.formatError(r,`sendProperties (attempt ${i+1}/${this.config.retryAttempts+1})`);this.logError(n);return}if(!this.isRetriableError(r)){let n=this.formatError(r,"sendProperties (non-retriable error)");this.logError(n);return}let a=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${a}ms after error:`,r),await this.delay(a)}}async trackLogin(e,t){try{return await this.track("login",e,t)}catch(i){let r=this.formatError(i,"trackLogin");this.logError(r)}}async trackSignup(e,t){try{return await this.track("signup",e,t)}catch(i){let r=this.formatError(i,"trackSignup");this.logError(r)}}async trackCheckout(e,t){try{return await this.track("checkout",e,t)}catch(i){let r=this.formatError(i,"trackCheckout");this.logError(r)}}async trackPageView(e,t){try{return await this.track("page_view",e,t)}catch(i){let r=this.formatError(i,"trackPageView");this.logError(r)}}async trackPurchase(e,t){try{return await this.track("purchase",e,t)}catch(i){let r=this.formatError(i,"trackPurchase");this.logError(r)}}async trackSearch(e,t){try{return await this.track("search",e,t)}catch(i){let r=this.formatError(i,"trackSearch");this.logError(r)}}async trackAddToCart(e,t){try{return await this.track("add_to_cart",e,t)}catch(i){let r=this.formatError(i,"trackAddToCart");this.logError(r)}}async trackRemoveFromCart(e,t){try{return await this.track("remove_from_cart",e,t)}catch(i){let r=this.formatError(i,"trackRemoveFromCart");this.logError(r)}}async flush(){try{if(this.eventQueue.length===0)return;let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);for(let i of t)await this.sendEvents(i)}catch(e){let t=this.formatError(e,"flush");this.logError(t)}}initializeConfigCache(){if(!(!this.config.enableConfigCache||typeof window>"u"))try{let e=localStorage.getItem(this.config.configCacheKey);e&&(this.configCache=JSON.parse(e),this.log("Loaded configuration from cache:",this.configCache))}catch(e){this.log("Failed to load configuration cache:",e)}}saveConfigCache(e){if(!(!this.config.enableConfigCache||typeof window>"u"))try{localStorage.setItem(this.config.configCacheKey,JSON.stringify(e)),this.log("Saved configuration to cache:",e)}catch(t){this.log("Failed to save configuration cache:",t)}}getConfig(e){if(this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e]}getAllConfigs(){let e={...this.config.defaultConfigurations};return this.configCache?.configurations&&Object.assign(e,this.configCache.configurations),e}async fetchConfig(e={}){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"fetchConfig (client destroyed)");return this.logError(c),null}let t=e.userId||this.getEffectiveUserIdInternal(),i=e.immediateKeys||[],r=e.properties||{},a={userId:t,immediateKeys:i,properties:r},n;for(let o=0;o<=this.config.retryAttempts;o++)try{let c=await this.getAuthHeaders(),l=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,u=await fetch(l,{method:"POST",headers:c,body:JSON.stringify(a)});if(!u.ok){let h=`HTTP ${u.status}`;try{let y=await u.json();y?.message&&(h=y.message)}catch{let y=await u.text();y&&(h=y)}let S=new Error(`Failed to fetch configurations: ${h}`);throw S.status=u.status,S}let d=await u.json();return d.configurations&&this.updateConfigCache(d,t),this.log("Successfully fetched configurations"),d}catch(c){if(n=c,o===this.config.retryAttempts){let u=this.formatError(c,`fetchConfig (attempt ${o+1}/${this.config.retryAttempts+1})`);return this.logError(u),null}if(!this.isRetriableError(c)){let u=this.formatError(c,"fetchConfig (non-retriable error)");return this.logError(u),null}let l=this.config.retryDelay*Math.pow(2,o);this.log(`Retrying config fetch in ${l}ms after error:`,c),await this.delay(l)}return null}catch(t){let i=this.formatError(t,"fetchConfig");return this.logError(i),null}}async getConfigAsync(e,t={}){try{if(!t.forceRefresh&&this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(!t.forceRefresh&&this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e];let i=await this.fetchConfig(t);return i?i.configurations[e]:this.config.defaultConfigurations?.[e]}catch(i){let r=this.formatError(i,"getConfigAsync");return this.logError(r),this.config.defaultConfigurations?.[e]}}async getAllConfigsAsync(e={}){try{if(!e.forceRefresh&&this.configCache?.configurations)return{...this.config.defaultConfigurations,...this.configCache.configurations};let t=await this.fetchConfig(e);return t?{...this.config.defaultConfigurations,...t.configurations}:{...this.config.defaultConfigurations}}catch(t){let i=this.formatError(t,"getAllConfigsAsync");return this.logError(i),{...this.config.defaultConfigurations}}}updateConfigCache(e,t){let i={configurations:e.configurations,snapshotId:e.snapshotId,timestamp:e.timestamp,userId:t},r=this.configCache?.configurations||{};this.configCache=i,this.saveConfigCache(i),JSON.stringify(r)!==JSON.stringify(e.configurations)&&this.notifyConfigChangeListeners(e.configurations)}addConfigChangeListener(e){this.configChangeListeners.push(e)}removeConfigChangeListener(e){let t=this.configChangeListeners.indexOf(e);t>-1&&this.configChangeListeners.splice(t,1)}notifyConfigChangeListeners(e){this.configChangeListeners.forEach(t=>{try{t(e)}catch(i){console.error("[Grain Analytics] Config change listener error:",i)}})}startConfigRefreshTimer(){typeof window>"u"||(this.configRefreshTimer&&clearInterval(this.configRefreshTimer),this.configRefreshTimer=window.setInterval(()=>{this.isDestroyed||this.fetchConfig().catch(e=>{let t=this.formatError(e,"auto-config refresh");this.logError(t)})},this.config.configRefreshInterval))}stopConfigRefreshTimer(){this.configRefreshTimer&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null)}async preloadConfig(e=[],t){try{let i=this.getEffectiveUserIdInternal();this.log(`Preloading config for user: ${i}`),await this.fetchConfig({immediateKeys:e,properties:t})&&this.startConfigRefreshTimer()}catch(i){let r=this.formatError(i,"preloadConfig");this.logError(r)}}chunkEvents(e,t){let i=[];for(let r=0;r<e.length;r+=t)i.push(e.slice(r,r+t));return i}grantConsent(e){try{this.consentManager.grantConsent(e);let t=this.consentManager.getIdMode();this.idManager.setMode(t),this.log("Consent granted, switched to permanent IDs",e),this.waitingForConsentQueue.length>0&&(this.log(`Processing ${this.waitingForConsentQueue.length} queued events`),this.eventQueue.push(...this.waitingForConsentQueue),this.waitingForConsentQueue=[],this.flush())}catch(t){let i=this.formatError(t,"grantConsent");this.logError(i)}}revokeConsent(e){try{this.consentManager.revokeConsent(e);let t=this.consentManager.getIdMode();this.idManager.setMode(t),this.log("Consent revoked, switched to cookie-less mode",e),this.consentManager.hasConsent()||(this.eventQueue=[],this.waitingForConsentQueue=[])}catch(t){let i=this.formatError(t,"revokeConsent");this.logError(i)}}getConsentState(){return this.consentManager.getConsentState()}hasConsent(e){return this.consentManager.hasConsent(e)}onConsentChange(e){this.consentManager.addListener(e)}offConsentChange(e){this.consentManager.removeListener(e)}checkAndInitializeDebugMode(){if(!(typeof window>"u"))try{let e=new URLSearchParams(window.location.search),t=e.get("grain_debug")==="1",i=e.get("grain_session");if(!t||!i)return;this.log("Debug mode detected, verifying session:",i),this.verifyDebugSession(i,window.location.hostname).then(r=>{r?(this.log("Debug session verified, initializing debug agent"),this.isDebugMode=!0,this.initializeDebugAgent(i)):this.log("Debug session verification failed")}).catch(r=>{this.log("Failed to verify debug session:",r)})}catch(e){this.log("Error checking debug mode:",e)}}async verifyDebugSession(e,t){try{let i=`${this.config.apiUrl}/v1/tenant/${encodeURIComponent(this.config.tenantId)}/debug-sessions/verify`,r=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:e,domain:t})});return r.ok?(await r.json()).valid===!0:!1}catch(i){return this.log("Debug session verification error:",i),!1}}initializeDebugAgent(e){if(!(typeof window>"u"))try{this.log("Loading debug agent module"),Promise.resolve().then(()=>(re(),ie)).then(({DebugAgent:t})=>{try{this.debugAgent=new t(this,e,this.config.tenantId,this.config.apiUrl,{debug:this.config.debug}),this.log("Debug agent initialized")}catch(i){this.log("Failed to initialize debug agent:",i)}}).catch(t=>{this.log("Failed to load debug agent module:",t)})}catch(t){this.log("Error initializing debug agent:",t)}}destroy(){if(this.isDestroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.stopConfigRefreshTimer(),this.configChangeListeners=[],this.heartbeatManager&&(this.heartbeatManager.destroy(),this.heartbeatManager=null),this.pageTrackingManager&&(this.pageTrackingManager.destroy(),this.pageTrackingManager=null),this.activityDetector&&(this.activityDetector.destroy(),this.activityDetector=null),this.interactionTrackingManager&&(this.interactionTrackingManager.destroy(),this.interactionTrackingManager=null),this.sectionTrackingManager&&(this.sectionTrackingManager.destroy(),this.sectionTrackingManager=null),this.heatmapTrackingManager&&(this.heatmapTrackingManager.destroy(),this.heatmapTrackingManager=null),this.debugAgent&&(this.debugAgent.destroy(),this.debugAgent=null),this.eventQueue.length>0){let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);if(t.length>0){this.sendEventsWithBeacon(t[0]).catch(()=>{});for(let i=1;i<t.length;i++)this.sendEventsWithBeacon(t[i]).catch(()=>{})}}}};function ne(s){return new v(s)}var Te=v;typeof window<"u"&&(window.Grain={GrainAnalytics:v,createGrainAnalytics:ne});return le(we);})();
|
|
3
507
|
//# sourceMappingURL=index.global.js.map
|