@tracelog/lib 0.11.3 → 0.11.4
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/dist/browser/tracelog.esm.js +3040 -0
- package/dist/browser/tracelog.esm.js.map +1 -0
- package/dist/browser/tracelog.js +8 -0
- package/dist/browser/tracelog.js.map +1 -0
- package/dist/public-api.cjs +51 -11
- package/dist/public-api.cjs.map +1 -1
- package/dist/public-api.d.mts +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.js +51 -11
- package/dist/public-api.js.map +1 -1
- package/package.json +2 -3
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
(function(h){"use strict";const A="data-tlog",He=["button","a",'input[type="button"]','input[type="submit"]','input[type="reset"]','input[type="checkbox"]','input[type="radio"]',"select","textarea",'[role="button"]','[role="link"]','[role="tab"]','[role="menuitem"]','[role="option"]','[role="checkbox"]','[role="radio"]','[role="switch"]',"[routerLink]","[ng-click]","[data-action]","[data-click]","[data-navigate]","[data-toggle]","[onclick]",".btn",".button",".clickable",".nav-link",".menu-item","[data-testid]",'[tabindex="0"]'],Ue=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],Fe=["token","auth","key","session","reset","password","api_key","apikey","secret","access_token","refresh_token","verification","code","otp"],E={INVALID_SESSION_TIMEOUT:"Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",INVALID_SAMPLING_RATE:"Sampling rate must be between 0 and 1",INVALID_ERROR_SAMPLING_RATE:"Error sampling must be between 0 and 1",INVALID_TRACELOG_PROJECT_ID:"TraceLog project ID is required when integration is enabled",INVALID_CUSTOM_API_URL:"Custom API URL is required when integration is enabled",INVALID_GOOGLE_ANALYTICS_ID:"Google Analytics measurement ID is required when integration is enabled",INVALID_GLOBAL_METADATA:"Global metadata must be an object",INVALID_SENSITIVE_QUERY_PARAMS:"Sensitive query params must be an array of strings",INVALID_PRIMARY_SCROLL_SELECTOR:"Primary scroll selector must be a non-empty string",INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX:"Invalid CSS selector syntax for primaryScrollSelector",INVALID_PAGE_VIEW_THROTTLE:"Page view throttle must be a non-negative number",INVALID_CLICK_THROTTLE:"Click throttle must be a non-negative number",INVALID_MAX_SAME_EVENT_PER_MINUTE:"Max same event per minute must be a positive number",INVALID_VIEWPORT_CONFIG:"Viewport config must be an object",INVALID_VIEWPORT_ELEMENTS:"Viewport elements must be a non-empty array",INVALID_VIEWPORT_ELEMENT:"Each viewport element must have a valid selector string",INVALID_VIEWPORT_ELEMENT_ID:"Viewport element id must be a non-empty string",INVALID_VIEWPORT_ELEMENT_NAME:"Viewport element name must be a non-empty string",INVALID_VIEWPORT_THRESHOLD:"Viewport threshold must be a number between 0 and 1",INVALID_VIEWPORT_MIN_DWELL_TIME:"Viewport minDwellTime must be a non-negative number",INVALID_VIEWPORT_COOLDOWN_PERIOD:"Viewport cooldownPeriod must be a non-negative number",INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS:"Viewport maxTrackedElements must be a positive number"},Ge=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,/<embed\b[^>]*>/gi,/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi];var F=(n=>(n.Localhost="localhost:8080",n.Fail="localhost:9999",n))(F||{}),w=(n=>(n.Mobile="mobile",n.Tablet="tablet",n.Desktop="desktop",n.Unknown="unknown",n))(w||{}),G=(n=>(n.EVENT="event",n.QUEUE="queue",n))(G||{});class R extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="PermanentError",Error.captureStackTrace&&Error.captureStackTrace(this,R)}}var u=(n=>(n.PAGE_VIEW="page_view",n.CLICK="click",n.SCROLL="scroll",n.SESSION_START="session_start",n.SESSION_END="session_end",n.CUSTOM="custom",n.WEB_VITALS="web_vitals",n.ERROR="error",n.VIEWPORT_VISIBLE="viewport_visible",n))(u||{}),H=(n=>(n.UP="up",n.DOWN="down",n))(H||{}),C=(n=>(n.JS_ERROR="js_error",n.PROMISE_REJECTION="promise_rejection",n))(C||{}),b=(n=>(n.QA="qa",n))(b||{});function xe(n){return n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!0}function We(n){return n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!1}class P extends Error{constructor(e,t,r){super(e),this.errorCode=t,this.layer=r,this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class f extends P{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class fe extends P{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class j extends P{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class N extends P{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class Xe extends P{constructor(e,t,r="runtime"){super(e,"INITIALIZATION_TIMEOUT",r),this.timeoutMs=t}}const Be=(n,e)=>{if(e){if(e instanceof Error){const t=e.message.replace(/\s+at\s+.*$/gm,"").replace(/\(.*?:\d+:\d+\)/g,"");return`[TraceLog] ${n}: ${t}`}return`[TraceLog] ${n}: ${e instanceof Error?e.message:"Unknown error"}`}return`[TraceLog] ${n}`},a=(n,e,t)=>{const{error:r,data:s,showToClient:i=!1}=t??{},o=r?Be(e,r):`[TraceLog] ${e}`,l=n==="error"?"error":n==="warn"?"warn":"log";if(!(n==="debug"||n==="info"&&!i))if(s!==void 0){const c=$e(s);console[l](o,c)}else s!==void 0?console[l](o,s):console[l](o)},$e=n=>{const e={},t=["token","password","secret","key","apikey","api_key","sessionid","session_id"];for(const[r,s]of Object.entries(n)){const i=r.toLowerCase();t.some(o=>i.includes(o))?e[r]="[REDACTED]":e[r]=s}return e};let K,ge;const ze=()=>{typeof window<"u"&&!K&&(K=window.matchMedia("(pointer: coarse)"),ge=window.matchMedia("(hover: none)"))},Ye=()=>{try{const n=navigator;if(n.userAgentData&&typeof n.userAgentData.mobile=="boolean")return n.userAgentData.platform&&/ipad|tablet/i.test(n.userAgentData.platform)?w.Tablet:n.userAgentData.mobile?w.Mobile:w.Desktop;ze();const e=window.innerWidth,t=K?.matches??!1,r=ge?.matches??!1,s="ontouchstart"in window||navigator.maxTouchPoints>0,i=navigator.userAgent.toLowerCase(),o=/mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i),l=/tablet|ipad|android(?!.*mobile)/.test(i);return e<=767||o&&s?w.Mobile:e>=768&&e<=1024||l||t&&r&&s?w.Tablet:w.Desktop}catch(n){return a("warn","Device detection failed, defaulting to desktop",{error:n}),w.Desktop}},M="tlog",me=`${M}:qa_mode`,Qe=`${M}:uid`,je=n=>n?`${M}:${n}:queue`:`${M}:queue`,Ke=n=>n?`${M}:${n}:session`:`${M}:session`,qe=n=>n?`${M}:${n}:broadcast`:`${M}:broadcast`,Se={LCP:4e3,FCP:1800,CLS:.25,INP:200,TTFB:800,LONG_TASK:50},Ze=1e3,Je=50,q=[/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,/\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,/\b[A-Z]{2}\d{2}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/gi,/\b[sp]k_(test|live)_[a-zA-Z0-9]{10,}\b/gi,/Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,/:\/\/[^:/]+:([^@]+)@/gi],Te=500,_e=5e3,x=50,et=x*2,Ie=1,tt=1e3,rt=10,pe=5e3,nt=6e4,ve="tlog_mode",st="qa",it=()=>{if(sessionStorage.getItem(me)==="true")return!0;const e=new URLSearchParams(window.location.search),r=e.get(ve)===st;if(r){sessionStorage.setItem(me,"true"),e.delete(ve);const s=e.toString(),i=`${window.location.pathname}${s?"?"+s:""}${window.location.hash}`;try{window.history.replaceState({},"",i)}catch(o){a("warn","History API not available, cannot replace URL",{error:o})}console.log("%c[TraceLog] QA Mode ACTIVE","background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;")}return r},Ae=()=>{const n=new URLSearchParams(window.location.search),e={};return Ue.forEach(r=>{const s=n.get(r);if(s){const i=r.split("utm_")[1];e[i]=s}}),Object.keys(e).length?e:void 0},ot=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)}),at=()=>{const n=Date.now();let e="";try{if(typeof crypto<"u"&&crypto.getRandomValues){const t=crypto.getRandomValues(new Uint8Array(4));t&&(e=Array.from(t,r=>r.toString(16).padStart(2,"0")).join(""))}}catch{}return e||(e=Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0")),`${n}-${e}`},we=(n,e=!1)=>{try{const t=new URL(n),r=t.protocol==="https:",s=t.protocol==="http:";return r||e&&s}catch{return!1}},lt=n=>{if(n.integrations?.tracelog?.projectId)try{const r=new URL(window.location.href).hostname;if(!r||typeof r!="string")throw new Error("Invalid hostname");const s=r.split(".");if(!s||!Array.isArray(s)||s.length===0||s.length===1&&s[0]==="")throw new Error("Invalid hostname structure");const i=n.integrations.tracelog.projectId,o=s.slice(-2).join(".");if(!o)throw new Error("Invalid domain");const l=`https://${i}.${o}/collect`;if(!we(l))throw new Error("Invalid URL");return l}catch(t){throw new Error(`Invalid URL configuration: ${t instanceof Error?t.message:String(t)}`)}const e=n.integrations?.custom?.collectApiUrl;if(e){const t=n.integrations?.custom?.allowHttp??!1;if(!we(e,t))throw new Error("Invalid URL");return e}return""},Z=(n,e=[])=>{if(!n||typeof n!="string")return a("warn","Invalid URL provided to normalizeUrl",{data:{url:String(n)}}),n||"";try{const t=new URL(n),r=t.searchParams,s=[...new Set([...Fe,...e])];let i=!1;const o=[];return s.forEach(c=>{r.has(c)&&(r.delete(c),i=!0,o.push(c))}),!i&&n.includes("?")?n:(t.search=r.toString(),t.toString())}catch(t){const r=n&&typeof n=="string"?n.slice(0,100):String(n);return a("warn","URL normalization failed, returning original",{error:t,data:{url:r}}),n}},ye=n=>{if(!n||typeof n!="string"||n.trim().length===0)return"";let e=n;n.length>1e3&&(e=n.slice(0,Math.max(0,1e3)));let t=0;for(const s of Ge){const i=e;e=e.replace(s,""),i!==e&&t++}return t>0&&a("warn","XSS patterns detected and removed",{data:{patternMatches:t,originalValue:n.slice(0,100)}}),e=e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'").replaceAll("/","/"),e.trim()},J=(n,e=0)=>{if(e>3||n==null)return null;if(typeof n=="string")return ye(n);if(typeof n=="number")return!Number.isFinite(n)||n<-Number.MAX_SAFE_INTEGER||n>Number.MAX_SAFE_INTEGER?0:n;if(typeof n=="boolean")return n;if(Array.isArray(n))return n.slice(0,100).map(s=>J(s,e+1)).filter(s=>s!==null);if(typeof n=="object"){const t={},s=Object.entries(n).slice(0,20);for(const[i,o]of s){const l=ye(i);if(l){const c=J(o,e+1);c!==null&&(t[l]=c)}}return t}return null},ct=n=>{if(typeof n!="object"||n===null)return{};try{const e=J(n);return typeof e=="object"&&e!==null?e:{}}catch(e){const t=e instanceof Error?e.message:String(e);throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`)}},ut=n=>{if(n!==void 0&&(n===null||typeof n!="object"))throw new f("Configuration must be an object","config");if(n){if(n.sessionTimeout!==void 0&&(typeof n.sessionTimeout!="number"||n.sessionTimeout<3e4||n.sessionTimeout>864e5))throw new fe(E.INVALID_SESSION_TIMEOUT,"config");if(n.globalMetadata!==void 0&&(typeof n.globalMetadata!="object"||n.globalMetadata===null))throw new f(E.INVALID_GLOBAL_METADATA,"config");if(n.integrations&&ht(n.integrations),n.sensitiveQueryParams!==void 0){if(!Array.isArray(n.sensitiveQueryParams))throw new f(E.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of n.sensitiveQueryParams)if(typeof e!="string")throw new f("All sensitive query params must be strings","config")}if(n.errorSampling!==void 0&&(typeof n.errorSampling!="number"||n.errorSampling<0||n.errorSampling>1))throw new j(E.INVALID_ERROR_SAMPLING_RATE,"config");if(n.samplingRate!==void 0&&(typeof n.samplingRate!="number"||n.samplingRate<0||n.samplingRate>1))throw new j(E.INVALID_SAMPLING_RATE,"config");if(n.primaryScrollSelector!==void 0){if(typeof n.primaryScrollSelector!="string"||!n.primaryScrollSelector.trim())throw new f(E.INVALID_PRIMARY_SCROLL_SELECTOR,"config");if(n.primaryScrollSelector!=="window")try{document.querySelector(n.primaryScrollSelector)}catch{throw new f(`${E.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${n.primaryScrollSelector}"`,"config")}}if(n.pageViewThrottleMs!==void 0&&(typeof n.pageViewThrottleMs!="number"||n.pageViewThrottleMs<0))throw new f(E.INVALID_PAGE_VIEW_THROTTLE,"config");if(n.clickThrottleMs!==void 0&&(typeof n.clickThrottleMs!="number"||n.clickThrottleMs<0))throw new f(E.INVALID_CLICK_THROTTLE,"config");if(n.maxSameEventPerMinute!==void 0&&(typeof n.maxSameEventPerMinute!="number"||n.maxSameEventPerMinute<=0))throw new f(E.INVALID_MAX_SAME_EVENT_PER_MINUTE,"config");n.viewport!==void 0&&dt(n.viewport)}},dt=n=>{if(typeof n!="object"||n===null)throw new f(E.INVALID_VIEWPORT_CONFIG,"config");if(!n.elements||!Array.isArray(n.elements))throw new f(E.INVALID_VIEWPORT_ELEMENTS,"config");if(n.elements.length===0)throw new f(E.INVALID_VIEWPORT_ELEMENTS,"config");const e=new Set;for(const t of n.elements){if(!t.selector||typeof t.selector!="string"||!t.selector.trim())throw new f(E.INVALID_VIEWPORT_ELEMENT,"config");const r=t.selector.trim();if(e.has(r))throw new f(`Duplicate viewport selector found: "${r}". Each selector should appear only once.`,"config");if(e.add(r),t.id!==void 0&&(typeof t.id!="string"||!t.id.trim()))throw new f(E.INVALID_VIEWPORT_ELEMENT_ID,"config");if(t.name!==void 0&&(typeof t.name!="string"||!t.name.trim()))throw new f(E.INVALID_VIEWPORT_ELEMENT_NAME,"config")}if(n.threshold!==void 0&&(typeof n.threshold!="number"||n.threshold<0||n.threshold>1))throw new f(E.INVALID_VIEWPORT_THRESHOLD,"config");if(n.minDwellTime!==void 0&&(typeof n.minDwellTime!="number"||n.minDwellTime<0))throw new f(E.INVALID_VIEWPORT_MIN_DWELL_TIME,"config");if(n.cooldownPeriod!==void 0&&(typeof n.cooldownPeriod!="number"||n.cooldownPeriod<0))throw new f(E.INVALID_VIEWPORT_COOLDOWN_PERIOD,"config");if(n.maxTrackedElements!==void 0&&(typeof n.maxTrackedElements!="number"||n.maxTrackedElements<=0))throw new f(E.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS,"config")},ht=n=>{if(n){if(n.tracelog&&(!n.tracelog.projectId||typeof n.tracelog.projectId!="string"||n.tracelog.projectId.trim()===""))throw new N(E.INVALID_TRACELOG_PROJECT_ID,"config");if(n.custom){if(!n.custom.collectApiUrl||typeof n.custom.collectApiUrl!="string"||n.custom.collectApiUrl.trim()==="")throw new N(E.INVALID_CUSTOM_API_URL,"config");if(n.custom.allowHttp!==void 0&&typeof n.custom.allowHttp!="boolean")throw new N("allowHttp must be a boolean","config");const e=n.custom.collectApiUrl.trim();if(!e.startsWith("http://")&&!e.startsWith("https://"))throw new N('Custom API URL must start with "http://" or "https://"',"config");if(!(n.custom.allowHttp??!1)&&e.startsWith("http://"))throw new N("Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)","config")}if(n.googleAnalytics){if(!n.googleAnalytics.measurementId||typeof n.googleAnalytics.measurementId!="string"||n.googleAnalytics.measurementId.trim()==="")throw new N(E.INVALID_GOOGLE_ANALYTICS_ID,"config");if(!n.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))throw new N('Google Analytics measurement ID must start with "G-" or "UA-"',"config")}}},Et=n=>{ut(n);const e={...n??{},sessionTimeout:n?.sessionTimeout??9e5,globalMetadata:n?.globalMetadata??{},sensitiveQueryParams:n?.sensitiveQueryParams??[],errorSampling:n?.errorSampling??Ie,samplingRate:n?.samplingRate??1,pageViewThrottleMs:n?.pageViewThrottleMs??1e3,clickThrottleMs:n?.clickThrottleMs??300,maxSameEventPerMinute:n?.maxSameEventPerMinute??60};return e.integrations?.custom&&(e.integrations.custom={...e.integrations.custom,allowHttp:e.integrations.custom.allowHttp??!1}),e.viewport&&(e.viewport={...e.viewport,threshold:e.viewport.threshold??.5,minDwellTime:e.viewport.minDwellTime??2e3,cooldownPeriod:e.viewport.cooldownPeriod??6e4,maxTrackedElements:e.viewport.maxTrackedElements??100}),e},ft=n=>{if(typeof n=="string")return!0;if(typeof n=="object"&&n!==null&&!Array.isArray(n)){const e=Object.entries(n);if(e.length>20)return!1;for(const[,t]of e){if(t==null)continue;const r=typeof t;if(r!=="string"&&r!=="number"&&r!=="boolean")return!1}return!0}return!1},Ne=(n,e=0)=>{if(typeof n!="object"||n===null||e>1)return!1;for(const t of Object.values(n)){if(t==null)continue;const r=typeof t;if(!(r==="string"||r==="number"||r==="boolean")){if(Array.isArray(t)){if(t.length===0)continue;if(typeof t[0]=="string"){if(!t.every(o=>typeof o=="string"))return!1}else if(!t.every(o=>ft(o)))return!1;continue}if(r==="object"&&e===0){if(!Ne(t,e+1))return!1;continue}return!1}}return!0},gt=n=>typeof n!="string"?{valid:!1,error:"Event name must be a string"}:n.length===0?{valid:!1,error:"Event name cannot be empty"}:n.length>120?{valid:!1,error:"Event name is too long (max 120 characters)"}:n.includes("<")||n.includes(">")||n.includes("&")?{valid:!1,error:"Event name contains invalid characters"}:["constructor","prototype","__proto__","eval","function","var","let","const"].includes(n.toLowerCase())?{valid:!1,error:"Event name cannot be a reserved word"}:{valid:!0},Me=(n,e,t)=>{const r=ct(e),s=`${t} "${n}" metadata error`;if(!Ne(r))return{valid:!1,error:`${s}: object has invalid types. Valid types are string, number, boolean or string arrays.`};let i;try{i=JSON.stringify(r)}catch{return{valid:!1,error:`${s}: object contains circular references or cannot be serialized.`}}if(i.length>8192)return{valid:!1,error:`${s}: object is too large (max ${8192/1024} KB).`};if(Object.keys(r).length>10)return{valid:!1,error:`${s}: object has too many keys (max 10 keys).`};for(const[l,c]of Object.entries(r)){if(Array.isArray(c)){if(c.length>10)return{valid:!1,error:`${s}: array property "${l}" is too large (max 10 items).`};for(const d of c)if(typeof d=="string"&&d.length>500)return{valid:!1,error:`${s}: array property "${l}" contains strings that are too long (max 500 characters).`}}if(typeof c=="string"&&c.length>1e3)return{valid:!1,error:`${s}: property "${l}" is too long (max 1000 characters).`}}return{valid:!0,sanitizedMetadata:r}},mt=(n,e,t)=>{if(Array.isArray(e)){const r=[],s=`${t} "${n}" metadata error`;for(let i=0;i<e.length;i++){const o=e[i];if(typeof o!="object"||o===null||Array.isArray(o))return{valid:!1,error:`${s}: array item at index ${i} must be an object.`};const l=Me(n,o,t);if(!l.valid)return{valid:!1,error:`${s}: array item at index ${i} is invalid: ${l.error}`};l.sanitizedMetadata&&r.push(l.sanitizedMetadata)}return{valid:!0,sanitizedMetadata:r}}return Me(n,e,t)},St=(n,e)=>{const t=gt(n);if(!t.valid)return a("error","Event name validation failed",{showToClient:!0,data:{eventName:n,error:t.error}}),t;if(!e)return{valid:!0};const r=mt(n,e,"customEvent");return r.valid||a("error","Event metadata validation failed",{showToClient:!0,data:{eventName:n,error:r.error}}),r};class Tt{listeners=new Map;on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){const r=this.listeners.get(e);if(r){const s=r.indexOf(t);s>-1&&r.splice(s,1)}}emit(e,t){const r=this.listeners.get(e);r&&r.forEach(s=>{s(t)})}removeAllListeners(){this.listeners.clear()}}const ee={};class S{get(e){return ee[e]}set(e,t){ee[e]=t}getState(){return{...ee}}}class _t extends S{storeManager;lastPermanentErrorLog=null;recoveryInProgress=!1;constructor(e){super(),this.storeManager=e}getQueueStorageKey(){const e=this.get("userId")||"anonymous";return je(e)}sendEventsQueueSync(e){return this.shouldSkipSend()?!0:this.get("config")?.integrations?.custom?.collectApiUrl===F.Fail?(a("warn","Fail mode: simulating network failure (sync)",{data:{events:e.events.length}}),!1):this.sendQueueSyncInternal(e)}async sendEventsQueue(e,t){try{const r=await this.send(e);return r?(this.clearPersistedEvents(),t?.onSuccess?.(e.events.length,e.events,e)):(this.persistEvents(e),t?.onFailure?.()),r}catch(r){return r instanceof R?(this.logPermanentError("Permanent error, not retrying",r),this.clearPersistedEvents(),t?.onFailure?.(),!1):(this.persistEvents(e),t?.onFailure?.(),!1)}}async recoverPersistedEvents(e){if(this.recoveryInProgress){a("debug","Recovery already in progress, skipping duplicate attempt");return}this.recoveryInProgress=!0;try{const t=this.getPersistedData();if(!t||!this.isDataRecent(t)||t.events.length===0){this.clearPersistedEvents();return}const r=this.createRecoveryBody(t);await this.send(r)?(this.clearPersistedEvents(),e?.onSuccess?.(t.events.length,t.events,r)):e?.onFailure?.()}catch(t){if(t instanceof R){this.logPermanentError("Permanent error during recovery, clearing persisted events",t),this.clearPersistedEvents(),e?.onFailure?.();return}a("error","Failed to recover persisted events",{error:t})}finally{this.recoveryInProgress=!1}}stop(){}async send(e){if(this.shouldSkipSend())return this.simulateSuccessfulSend();if(this.get("config")?.integrations?.custom?.collectApiUrl===F.Fail)return a("warn","Fail mode: simulating network failure",{data:{events:e.events.length}}),!1;const{url:r,payload:s}=this.prepareRequest(e);try{return(await this.sendWithTimeout(r,s)).ok}catch(i){if(i instanceof R)throw i;return a("error","Send request failed",{error:i,data:{events:e.events.length,url:r.replace(/\/\/[^/]+/,"//[DOMAIN]")}}),!1}}async sendWithTimeout(e,t){const r=new AbortController,s=setTimeout(()=>{r.abort()},1e4);try{const i=await fetch(e,{method:"POST",body:t,keepalive:!0,credentials:"include",signal:r.signal,headers:{"Content-Type":"application/json"}});if(!i.ok)throw i.status>=400&&i.status<500?new R(`HTTP ${i.status}: ${i.statusText}`,i.status):new Error(`HTTP ${i.status}: ${i.statusText}`);return i}finally{clearTimeout(s)}}sendQueueSyncInternal(e){const{url:t,payload:r}=this.prepareRequest(e);if(r.length>65536)return a("warn","Payload exceeds sendBeacon limit, persisting for recovery",{data:{size:r.length,limit:65536,events:e.events.length}}),this.persistEvents(e),!1;const s=new Blob([r],{type:"application/json"});if(!this.isSendBeaconAvailable())return a("warn","sendBeacon not available, persisting events for recovery"),this.persistEvents(e),!1;const i=navigator.sendBeacon(t,s);return i||(a("warn","sendBeacon rejected request, persisting events for recovery"),this.persistEvents(e)),i}prepareRequest(e){const t={...e,_metadata:{referer:typeof window<"u"?window.location.href:void 0,timestamp:Date.now()}};return{url:this.get("collectApiUrl"),payload:JSON.stringify(t)}}getPersistedData(){try{const e=this.getQueueStorageKey(),t=this.storeManager.getItem(e);if(t)return JSON.parse(t)}catch(e){a("warn","Failed to parse persisted data",{error:e}),this.clearPersistedEvents()}return null}isDataRecent(e){return!e.timestamp||typeof e.timestamp!="number"?!1:(Date.now()-e.timestamp)/(1e3*60*60)<2}createRecoveryBody(e){const{timestamp:t,...r}=e;return r}persistEvents(e){try{const t=this.getPersistedData();if(t&&t.timestamp){const i=Date.now()-t.timestamp;if(i<1e3)return a("debug","Skipping persistence, another tab recently persisted events",{data:{timeSinceExisting:i}}),!0}const r={...e,timestamp:Date.now()},s=this.getQueueStorageKey();return this.storeManager.setItem(s,JSON.stringify(r)),!!this.storeManager.getItem(s)}catch(t){return a("warn","Failed to persist events",{error:t}),!1}}clearPersistedEvents(){try{const e=this.getQueueStorageKey();this.storeManager.removeItem(e)}catch(e){a("warn","Failed to clear persisted events",{error:e})}}shouldSkipSend(){return!this.get("collectApiUrl")}async simulateSuccessfulSend(){const e=Math.random()*400+100;return await new Promise(t=>setTimeout(t,e)),!0}isSendBeaconAvailable(){return typeof navigator<"u"&&typeof navigator.sendBeacon=="function"}logPermanentError(e,t){const r=Date.now();(!this.lastPermanentErrorLog||this.lastPermanentErrorLog.statusCode!==t.statusCode||r-this.lastPermanentErrorLog.timestamp>=nt)&&(a("error",e,{data:{status:t.statusCode,message:t.message}}),this.lastPermanentErrorLog={statusCode:t.statusCode,timestamp:r})}}class It extends S{googleAnalytics;dataSender;emitter;eventsQueue=[];pendingEventsBuffer=[];recentEventFingerprints=new Map;sendIntervalId=null;rateLimitCounter=0;rateLimitWindowStart=0;perEventRateLimits=new Map;sessionEventCounts={total:0,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.SCROLL]:0};lastSessionId=null;constructor(e,t=null,r=null){super(),this.googleAnalytics=t,this.dataSender=new _t(e),this.emitter=r}async recoverPersistedEvents(){await this.dataSender.recoverPersistedEvents({onSuccess:(e,t,r)=>{if(t&&t.length>0){const s=t.map(i=>i.id);this.removeProcessedEvents(s),r&&this.emitEventsQueue(r)}},onFailure:()=>{a("warn","Failed to recover persisted events")}})}track({type:e,page_url:t,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,session_end_reason:d,viewport_data:_}){if(!e){a("error","Event type is required - event will be ignored");return}const m=this.get("sessionId");if(!m){this.pendingEventsBuffer.length>=100&&(this.pendingEventsBuffer.shift(),a("warn","Pending events buffer full - dropping oldest event",{data:{maxBufferSize:100}})),this.pendingEventsBuffer.push({type:e,page_url:t,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,session_end_reason:d,viewport_data:_});return}this.lastSessionId!==m&&(this.lastSessionId=m,this.sessionEventCounts={total:0,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.SCROLL]:0});const y=e===u.SESSION_START||e===u.SESSION_END;if(!y&&!this.checkRateLimit())return;const T=e;if(!y){if(this.sessionEventCounts.total>=1e3){a("warn","Session event limit reached",{data:{type:T,total:this.sessionEventCounts.total,limit:1e3}});return}const L=this.getTypeLimitForEvent(T);if(L){const Ee=this.sessionEventCounts[T];if(Ee!==void 0&&Ee>=L){a("warn","Session event type limit reached",{data:{type:T,count:Ee,limit:L}});return}}}if(T===u.CUSTOM&&o?.name){const L=this.get("config")?.maxSameEventPerMinute??60;if(!this.checkPerEventRateLimit(o.name,L))return}const ur=T===u.SESSION_START,dr=t||this.get("pageUrl"),he=this.buildEventPayload({type:T,page_url:dr,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,session_end_reason:d,viewport_data:_});if(!(!y&&!this.shouldSample())){if(ur){const L=this.get("sessionId");if(!L){a("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){a("warn","Duplicate session_start detected",{data:{sessionId:L}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(he)){if(this.get("mode")===b.QA&&T===u.CUSTOM&&o){console.log("[TraceLog] Event",{name:o.name,...o.metadata&&{metadata:o.metadata}}),this.emitEvent(he);return}this.addToQueue(he),y||(this.sessionEventCounts.total++,this.sessionEventCounts[T]!==void 0&&this.sessionEventCounts[T]++)}}}stop(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null),this.eventsQueue=[],this.pendingEventsBuffer=[],this.recentEventFingerprints.clear(),this.rateLimitCounter=0,this.rateLimitWindowStart=0,this.perEventRateLimits.clear(),this.sessionEventCounts={total:0,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.SCROLL]:0},this.lastSessionId=null,this.dataSender.stop()}async flushImmediately(){return this.flushEvents(!1)}flushImmediatelySync(){return this.flushEvents(!0)}getQueueLength(){return this.eventsQueue.length}flushPendingEvents(){if(this.pendingEventsBuffer.length===0)return;if(!this.get("sessionId")){a("warn","Cannot flush pending events: session not initialized - keeping in buffer",{data:{bufferedEventCount:this.pendingEventsBuffer.length}});return}const t=[...this.pendingEventsBuffer];this.pendingEventsBuffer=[],t.forEach(r=>{this.track(r)})}clearSendInterval(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null)}flushEvents(e){if(this.eventsQueue.length===0)return e?!0:Promise.resolve(!0);const t=this.buildEventsPayload(),r=[...this.eventsQueue],s=r.map(i=>i.id);if(e){const i=this.dataSender.sendEventsQueueSync(t);return i?(this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t)):(this.removeProcessedEvents(s),this.clearSendInterval()),i}else return this.dataSender.sendEventsQueue(t,{onSuccess:()=>{this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t)},onFailure:()=>{this.removeProcessedEvents(s),this.eventsQueue.length===0&&this.clearSendInterval(),a("warn","Async flush failed, removed from queue and persisted for recovery on next page load",{data:{eventCount:r.length}})}})}async sendEventsQueue(){if(!this.get("sessionId")||this.eventsQueue.length===0)return;const e=this.buildEventsPayload(),t=[...this.eventsQueue],r=t.map(s=>s.id);await this.dataSender.sendEventsQueue(e,{onSuccess:()=>{this.removeProcessedEvents(r),this.emitEventsQueue(e)},onFailure:()=>{this.removeProcessedEvents(r),this.eventsQueue.length===0&&this.clearSendInterval(),a("warn","Events send failed, removed from queue and persisted for recovery on next page load",{data:{eventCount:t.length}})}})}buildEventsPayload(){const e=new Map,t=[];for(const s of this.eventsQueue){const i=this.createEventSignature(s);e.has(i)||t.push(i),e.set(i,s)}const r=t.map(s=>e.get(s)).filter(s=>!!s).sort((s,i)=>s.timestamp-i.timestamp);return{user_id:this.get("userId"),session_id:this.get("sessionId"),device:this.get("device"),events:r,...this.get("config")?.globalMetadata&&{global_metadata:this.get("config")?.globalMetadata}}}buildEventPayload(e){const t=e.type===u.SESSION_START,r=e.page_url??this.get("pageUrl");return{id:at(),type:e.type,page_url:r,timestamp:Date.now(),...t&&{referrer:document.referrer||"Direct"},...e.from_page_url&&{from_page_url:e.from_page_url},...e.scroll_data&&{scroll_data:e.scroll_data},...e.click_data&&{click_data:e.click_data},...e.custom_event&&{custom_event:e.custom_event},...e.web_vitals&&{web_vitals:e.web_vitals},...e.error_data&&{error_data:e.error_data},...e.session_end_reason&&{session_end_reason:e.session_end_reason},...e.viewport_data&&{viewport_data:e.viewport_data},...t&&Ae()&&{utm:Ae()}}}isDuplicateEvent(e){const t=Date.now(),r=this.createEventFingerprint(e),s=this.recentEventFingerprints.get(r);return s&&t-s<500?(this.recentEventFingerprints.set(r,t),!0):(this.recentEventFingerprints.set(r,t),this.recentEventFingerprints.size>1e3&&this.pruneOldFingerprints(),this.recentEventFingerprints.size>2e3&&(this.recentEventFingerprints.clear(),this.recentEventFingerprints.set(r,t),a("warn","Event fingerprint cache exceeded hard limit, cleared",{data:{hardLimit:2e3}})),!1)}pruneOldFingerprints(){const e=Date.now(),t=500*10;for(const[r,s]of this.recentEventFingerprints.entries())e-s>t&&this.recentEventFingerprints.delete(r);a("debug","Pruned old event fingerprints",{data:{remaining:this.recentEventFingerprints.size,cutoffMs:t}})}createEventFingerprint(e){let t=`${e.type}_${e.page_url}`;if(e.click_data){const r=Math.round((e.click_data.x||0)/10)*10,s=Math.round((e.click_data.y||0)/10)*10;t+=`_click_${r}_${s}`}return e.scroll_data&&(t+=`_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`),e.custom_event&&(t+=`_custom_${e.custom_event.name}`),e.web_vitals&&(t+=`_vitals_${e.web_vitals.type}`),e.error_data&&(t+=`_error_${e.error_data.type}_${e.error_data.message}`),t}createEventSignature(e){return this.createEventFingerprint(e)}addToQueue(e){if(this.eventsQueue.push(e),this.emitEvent(e),this.eventsQueue.length>100){const t=this.eventsQueue.findIndex(s=>s.type!==u.SESSION_START&&s.type!==u.SESSION_END),r=t>=0?this.eventsQueue.splice(t,1)[0]:this.eventsQueue.shift();a("warn","Event queue overflow, oldest non-critical event removed",{data:{maxLength:100,currentLength:this.eventsQueue.length,removedEventType:r?.type,wasCritical:r?.type===u.SESSION_START||r?.type===u.SESSION_END}})}this.sendIntervalId||this.startSendInterval(),this.eventsQueue.length>=50&&this.sendEventsQueue(),this.handleGoogleAnalyticsIntegration(e)}startSendInterval(){this.sendIntervalId=window.setInterval(()=>{this.eventsQueue.length>0&&this.sendEventsQueue()},1e4)}handleGoogleAnalyticsIntegration(e){if(this.googleAnalytics&&e.type===u.CUSTOM&&e.custom_event){if(this.get("mode")===b.QA)return;this.googleAnalytics.trackEvent(e.custom_event.name,e.custom_event.metadata??{})}}shouldSample(){const e=this.get("config")?.samplingRate??1;return Math.random()<e}checkRateLimit(){const e=Date.now();return e-this.rateLimitWindowStart>1e3&&(this.rateLimitCounter=0,this.rateLimitWindowStart=e),this.rateLimitCounter>=50?!1:(this.rateLimitCounter++,!0)}checkPerEventRateLimit(e,t){const r=Date.now(),i=(this.perEventRateLimits.get(e)??[]).filter(o=>r-o<6e4);return i.length>=t?(a("warn","Per-event rate limit exceeded for custom event",{data:{eventName:e,limit:t,window:`${6e4/1e3}s`}}),!1):(i.push(r),this.perEventRateLimits.set(e,i),!0)}getTypeLimitForEvent(e){return{[u.CLICK]:500,[u.PAGE_VIEW]:100,[u.CUSTOM]:500,[u.VIEWPORT_VISIBLE]:200,[u.SCROLL]:120}[e]??null}removeProcessedEvents(e){const t=new Set(e);this.eventsQueue=this.eventsQueue.filter(r=>!t.has(r.id))}emitEvent(e){this.emitter&&this.emitter.emit(G.EVENT,e)}emitEventsQueue(e){this.emitter&&this.emitter.emit(G.QUEUE,e)}}class pt{static getId(e){const t=Qe,r=e.getItem(t);if(r)return r;const s=ot();return e.setItem(t,s),s}}class vt extends S{storageManager;eventManager;projectId;sessionTimeoutId=null;broadcastChannel=null;activityHandler=null;visibilityChangeHandler=null;beforeUnloadHandler=null;isTracking=!1;constructor(e,t,r){super(),this.storageManager=e,this.eventManager=t,this.projectId=r}initCrossTabSync(){if(typeof BroadcastChannel>"u"){a("warn","BroadcastChannel not supported");return}const e=this.getProjectId();this.broadcastChannel=new BroadcastChannel(qe(e)),this.broadcastChannel.onmessage=t=>{const{action:r,sessionId:s,timestamp:i,projectId:o}=t.data??{};if(o===e){if(r==="session_end"){this.resetSessionState();return}s&&typeof i=="number"&&i>Date.now()-5e3&&(this.set("sessionId",s),this.set("hasStartSession",!0),this.persistSession(s,i),this.isTracking&&this.setupSessionTimeout())}}}shareSession(e){this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function"&&this.broadcastChannel.postMessage({action:"session_start",projectId:this.getProjectId(),sessionId:e,timestamp:Date.now()})}broadcastSessionEnd(e,t){if(e&&this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function")try{this.broadcastChannel.postMessage({action:"session_end",projectId:this.getProjectId(),sessionId:e,reason:t,timestamp:Date.now()})}catch(r){a("warn","Failed to broadcast session end",{error:r,data:{sessionId:e,reason:t}})}}cleanupCrossTabSync(){this.broadcastChannel&&(typeof this.broadcastChannel.close=="function"&&this.broadcastChannel.close(),this.broadcastChannel=null)}recoverSession(){const e=this.loadStoredSession();if(!e)return null;const t=this.get("config")?.sessionTimeout??9e5;return Date.now()-e.lastActivity>t?(this.clearStoredSession(),null):e.id}persistSession(e,t=Date.now()){this.saveStoredSession({id:e,lastActivity:t})}clearStoredSession(){const e=this.getSessionStorageKey();this.storageManager.removeItem(e)}loadStoredSession(){const e=this.getSessionStorageKey(),t=this.storageManager.getItem(e);if(!t)return null;try{const r=JSON.parse(t);return!r.id||typeof r.lastActivity!="number"?null:r}catch{return this.storageManager.removeItem(e),null}}saveStoredSession(e){const t=this.getSessionStorageKey();this.storageManager.setItem(t,JSON.stringify(e))}getSessionStorageKey(){return Ke(this.getProjectId())}getProjectId(){return this.projectId}startTracking(){if(this.isTracking){a("warn","Session tracking already active");return}const e=this.recoverSession(),t=e??this.generateSessionId(),r=!!e;this.isTracking=!0;try{this.set("sessionId",t),this.persistSession(t),r||this.eventManager.track({type:u.SESSION_START}),this.initCrossTabSync(),this.shareSession(t),this.setupSessionTimeout(),this.setupActivityListeners(),this.setupLifecycleListeners()}catch(s){throw this.isTracking=!1,this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.set("sessionId",null),s}}generateSessionId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}setupSessionTimeout(){this.clearSessionTimeout();const e=this.get("config")?.sessionTimeout??9e5;this.sessionTimeoutId=setTimeout(()=>{this.endSession("inactivity")},e)}resetSessionTimeout(){this.setupSessionTimeout();const e=this.get("sessionId");e&&this.persistSession(e)}clearSessionTimeout(){this.sessionTimeoutId&&(clearTimeout(this.sessionTimeoutId),this.sessionTimeoutId=null)}setupActivityListeners(){this.activityHandler=()=>{this.resetSessionTimeout()},document.addEventListener("click",this.activityHandler,{passive:!0}),document.addEventListener("keydown",this.activityHandler,{passive:!0}),document.addEventListener("scroll",this.activityHandler,{passive:!0})}cleanupActivityListeners(){this.activityHandler&&(document.removeEventListener("click",this.activityHandler),document.removeEventListener("keydown",this.activityHandler),document.removeEventListener("scroll",this.activityHandler),this.activityHandler=null)}setupLifecycleListeners(){this.visibilityChangeHandler||this.beforeUnloadHandler||(this.visibilityChangeHandler=()=>{document.hidden?this.clearSessionTimeout():this.get("sessionId")&&this.setupSessionTimeout()},this.beforeUnloadHandler=()=>{this.endSession("page_unload")},document.addEventListener("visibilitychange",this.visibilityChangeHandler),window.addEventListener("beforeunload",this.beforeUnloadHandler))}cleanupLifecycleListeners(){this.visibilityChangeHandler&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)}endSession(e){const t=this.get("sessionId");if(!t){a("warn","endSession called without active session",{data:{reason:e}}),this.resetSessionState(e);return}this.eventManager.track({type:u.SESSION_END,session_end_reason:e}),this.eventManager.flushImmediatelySync()||a("warn","Sync flush failed during session end, events persisted for recovery",{data:{reason:e,sessionId:t}}),this.broadcastSessionEnd(t,e),this.resetSessionState(e)}resetSessionState(e){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),e!=="page_unload"&&this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.isTracking=!1}stopTracking(){this.endSession("manual_stop")}destroy(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupCrossTabSync(),this.cleanupLifecycleListeners(),this.isTracking=!1,this.set("hasStartSession",!1)}}class At extends S{eventManager;storageManager;sessionManager=null;destroyed=!1;constructor(e,t){super(),this.eventManager=t,this.storageManager=e}startTracking(){if(this.isActive())return;if(this.destroyed){a("warn","Cannot start tracking on destroyed handler");return}const e=this.get("config"),t=e?.integrations?.tracelog?.projectId??e?.integrations?.custom?.collectApiUrl??"default";if(!t)throw new Error("Cannot start session tracking: config not available");try{this.sessionManager=new vt(this.storageManager,this.eventManager,t),this.sessionManager.startTracking(),this.eventManager.flushPendingEvents()}catch(r){if(this.sessionManager){try{this.sessionManager.destroy()}catch{}this.sessionManager=null}throw a("error","Failed to start session tracking",{error:r}),r}}isActive(){return this.sessionManager!==null&&!this.destroyed}cleanupSessionManager(){this.sessionManager&&(this.sessionManager.stopTracking(),this.sessionManager.destroy(),this.sessionManager=null)}stopTracking(){this.cleanupSessionManager()}destroy(){this.destroyed||(this.sessionManager&&(this.sessionManager.destroy(),this.sessionManager=null),this.destroyed=!0,this.set("hasStartSession",!1))}}class wt extends S{eventManager;onTrack;originalPushState;originalReplaceState;lastPageViewTime=0;constructor(e,t){super(),this.eventManager=e,this.onTrack=t}startTracking(){this.trackInitialPageView(),window.addEventListener("popstate",this.trackCurrentPage,!0),window.addEventListener("hashchange",this.trackCurrentPage,!0),this.patchHistory("pushState"),this.patchHistory("replaceState")}stopTracking(){window.removeEventListener("popstate",this.trackCurrentPage,!0),window.removeEventListener("hashchange",this.trackCurrentPage,!0),this.originalPushState&&(window.history.pushState=this.originalPushState),this.originalReplaceState&&(window.history.replaceState=this.originalReplaceState),this.lastPageViewTime=0}patchHistory(e){const t=window.history[e];e==="pushState"&&!this.originalPushState?this.originalPushState=t:e==="replaceState"&&!this.originalReplaceState&&(this.originalReplaceState=t),window.history[e]=(...r)=>{t.apply(window.history,r),this.trackCurrentPage()}}trackCurrentPage=()=>{const e=window.location.href,t=Z(e,this.get("config").sensitiveQueryParams);if(this.get("pageUrl")===t)return;const r=Date.now(),s=this.get("config").pageViewThrottleMs??1e3;if(r-this.lastPageViewTime<s)return;this.lastPageViewTime=r,this.onTrack();const i=this.get("pageUrl");this.set("pageUrl",t);const o=this.extractPageViewData();this.eventManager.track({type:u.PAGE_VIEW,page_url:this.get("pageUrl"),from_page_url:i,...o&&{page_view:o}})};trackInitialPageView(){const e=Z(window.location.href,this.get("config").sensitiveQueryParams),t=this.extractPageViewData();this.lastPageViewTime=Date.now(),this.eventManager.track({type:u.PAGE_VIEW,page_url:e,...t&&{page_view:t}}),this.onTrack()}extractPageViewData(){const{pathname:e,search:t,hash:r}=window.location,{referrer:s}=document,{title:i}=document;return!s&&!i&&!e&&!t&&!r?void 0:{...s&&{referrer:s},...i&&{title:i},...e&&{pathname:e},...t&&{search:t},...r&&{hash:r}}}}class yt extends S{eventManager;lastClickTimes=new Map;clickHandler;lastPruneTime=0;constructor(e){super(),this.eventManager=e}startTracking(){this.clickHandler||(this.clickHandler=e=>{const t=e,r=t.target,s=typeof HTMLElement<"u"&&r instanceof HTMLElement?r:typeof HTMLElement<"u"&&r instanceof Node&&r.parentElement instanceof HTMLElement?r.parentElement:null;if(!s){a("warn","Click target not found or not an element");return}if(this.shouldIgnoreElement(s))return;const i=this.get("config")?.clickThrottleMs??300;if(i>0&&!this.checkClickThrottle(s,i))return;const o=this.findTrackingElement(s),l=this.getRelevantClickElement(s),c=this.calculateClickCoordinates(t,s);if(o){const _=this.extractTrackingData(o);if(_){const m=this.createCustomEventData(_);this.eventManager.track({type:u.CUSTOM,custom_event:{name:m.name,...m.value&&{metadata:{value:m.value}}}})}}const d=this.generateClickData(s,l,c);this.eventManager.track({type:u.CLICK,click_data:d})},window.addEventListener("click",this.clickHandler,!0))}stopTracking(){this.clickHandler&&(window.removeEventListener("click",this.clickHandler,!0),this.clickHandler=void 0),this.lastClickTimes.clear(),this.lastPruneTime=0}shouldIgnoreElement(e){return e.hasAttribute(`${A}-ignore`)?!0:e.closest(`[${A}-ignore]`)!==null}checkClickThrottle(e,t){const r=this.getElementSignature(e),s=Date.now();this.pruneThrottleCache(s);const i=this.lastClickTimes.get(r);return i!==void 0&&s-i<t?(a("debug","ClickHandler: Click suppressed by throttle",{data:{signature:r,throttleRemaining:t-(s-i)}}),!1):(this.lastClickTimes.set(r,s),!0)}pruneThrottleCache(e){if(e-this.lastPruneTime<3e4)return;this.lastPruneTime=e;const t=e-3e5;for(const[r,s]of this.lastClickTimes.entries())s<t&&this.lastClickTimes.delete(r);if(this.lastClickTimes.size>1e3){const r=Array.from(this.lastClickTimes.entries()).sort((o,l)=>o[1]-l[1]),s=this.lastClickTimes.size-1e3,i=r.slice(0,s);for(const[o]of i)this.lastClickTimes.delete(o);a("debug","ClickHandler: Pruned throttle cache",{data:{removed:i.length,remaining:this.lastClickTimes.size}})}}getElementSignature(e){if(e.id)return`#${e.id}`;const t=e.getAttribute("data-testid");if(t)return`[data-testid="${t}"]`;const r=e.getAttribute(`${A}-name`);return r?`[${A}-name="${r}"]`:this.getElementPath(e)}getElementPath(e){const t=[];let r=e;for(;r&&r!==document.body;){let s=r.tagName.toLowerCase();if(r.className){const i=r.className.split(" ")[0];i&&(s+=`.${i}`)}t.unshift(s),r=r.parentElement}return t.join(">")||"unknown"}findTrackingElement(e){return e.hasAttribute(`${A}-name`)?e:e.closest(`[${A}-name]`)}getRelevantClickElement(e){for(const t of He)try{if(e.matches(t))return e;const r=e.closest(t);if(r)return r}catch(r){a("warn","Invalid selector in element search",{error:r,data:{selector:t}});continue}return e}clamp(e){return Math.max(0,Math.min(1,Number(e.toFixed(3))))}calculateClickCoordinates(e,t){const r=t.getBoundingClientRect(),s=e.clientX,i=e.clientY,o=r.width>0?this.clamp((s-r.left)/r.width):0,l=r.height>0?this.clamp((i-r.top)/r.height):0;return{x:s,y:i,relativeX:o,relativeY:l}}extractTrackingData(e){const t=e.getAttribute(`${A}-name`),r=e.getAttribute(`${A}-value`);if(t)return{element:e,name:t,...r&&{value:r}}}generateClickData(e,t,r){const{x:s,y:i,relativeX:o,relativeY:l}=r,c=this.getRelevantText(e,t),d=this.extractElementAttributes(t);return{x:s,y:i,relativeX:o,relativeY:l,tag:t.tagName.toLowerCase(),...t.id&&{id:t.id},...t.className&&{class:t.className},...c&&{text:c},...d.href&&{href:d.href},...d.title&&{title:d.title},...d.alt&&{alt:d.alt},...d.role&&{role:d.role},...d["aria-label"]&&{ariaLabel:d["aria-label"]},...Object.keys(d).length>0&&{dataAttributes:d}}}sanitizeText(e){let t=e;for(const r of q){const s=new RegExp(r.source,r.flags);t=t.replace(s,"[REDACTED]")}return t}getRelevantText(e,t){const r=e.textContent?.trim()??"",s=t.textContent?.trim()??"";if(!r&&!s)return"";let i="";return r&&r.length<=255?i=r:s.length<=255?i=s:i=s.slice(0,252)+"...",this.sanitizeText(i)}extractElementAttributes(e){const t=["id","class","data-testid","aria-label","title","href","type","name","alt","role"],r={};for(const s of t){const i=e.getAttribute(s);i&&(r[s]=i)}return r}createCustomEventData(e){return{name:e.name,...e.value&&{value:e.value}}}}class Nt extends S{eventManager;containers=[];limitWarningLogged=!1;minDepthChange=5;minIntervalMs=500;maxEventsPerSession=120;containerDiscoveryTimeoutId=null;constructor(e){super(),this.eventManager=e}startTracking(){this.limitWarningLogged=!1,this.applyConfigOverrides(),this.set("scrollEventCount",0),this.tryDetectScrollContainers(0)}stopTracking(){this.containerDiscoveryTimeoutId!==null&&(clearTimeout(this.containerDiscoveryTimeoutId),this.containerDiscoveryTimeoutId=null);for(const e of this.containers)this.clearContainerTimer(e),e.element===window?window.removeEventListener("scroll",e.listener):e.element.removeEventListener("scroll",e.listener);this.containers.length=0,this.set("scrollEventCount",0),this.limitWarningLogged=!1}tryDetectScrollContainers(e){const t=this.findScrollableElements();if(this.isWindowScrollable()&&this.setupScrollContainer(window,"window"),t.length>0){for(const r of t){const s=this.getElementSelector(r);this.setupScrollContainer(r,s)}this.applyPrimaryScrollSelectorIfConfigured();return}if(e<5){this.containerDiscoveryTimeoutId=window.setTimeout(()=>{this.containerDiscoveryTimeoutId=null,this.tryDetectScrollContainers(e+1)},200);return}this.containers.length===0&&this.setupScrollContainer(window,"window"),this.applyPrimaryScrollSelectorIfConfigured()}applyPrimaryScrollSelectorIfConfigured(){const e=this.get("config");e?.primaryScrollSelector&&this.applyPrimaryScrollSelector(e.primaryScrollSelector)}findScrollableElements(){if(!document.body)return[];const e=[],t=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT,{acceptNode:s=>{const i=s;if(!i.isConnected||!i.offsetParent)return NodeFilter.FILTER_SKIP;const o=getComputedStyle(i);return o.overflowY==="auto"||o.overflowY==="scroll"||o.overflow==="auto"||o.overflow==="scroll"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});let r;for(;(r=t.nextNode())&&e.length<10;){const s=r;this.isElementScrollable(s)&&e.push(s)}return e}getElementSelector(e){if(e===window)return"window";const t=e;if(t.id)return`#${t.id}`;if(t.className&&typeof t.className=="string"){const r=t.className.split(" ").filter(s=>s.trim())[0];if(r)return`.${r}`}return t.tagName.toLowerCase()}determineIfPrimary(e){return this.isWindowScrollable()?e===window:this.containers.length===0}setupScrollContainer(e,t){if(this.containers.some(d=>d.element===e)||e!==window&&!this.isElementScrollable(e))return;const s=this.getScrollTop(e),i=this.calculateScrollDepth(s,this.getScrollHeight(e),this.getViewportHeight(e)),o=this.determineIfPrimary(e),l={element:e,selector:t,isPrimary:o,lastScrollPos:s,lastDepth:i,lastDirection:H.DOWN,lastEventTime:0,firstScrollEventTime:null,maxDepthReached:i,debounceTimer:null,listener:null},c=()=>{this.get("suppressNextScroll")||(l.firstScrollEventTime===null&&(l.firstScrollEventTime=Date.now()),this.clearContainerTimer(l),l.debounceTimer=window.setTimeout(()=>{const d=this.calculateScrollData(l);if(d){const _=Date.now();this.processScrollEvent(l,d,_)}l.debounceTimer=null},250))};l.listener=c,this.containers.push(l),e===window?window.addEventListener("scroll",c,{passive:!0}):e.addEventListener("scroll",c,{passive:!0})}processScrollEvent(e,t,r){if(!this.shouldEmitScrollEvent(e,t,r))return;e.lastEventTime=r,e.lastDepth=t.depth,e.lastDirection=t.direction;const s=this.get("scrollEventCount")??0;this.set("scrollEventCount",s+1),this.eventManager.track({type:u.SCROLL,scroll_data:{...t,container_selector:e.selector,is_primary:e.isPrimary}})}shouldEmitScrollEvent(e,t,r){return this.hasReachedSessionLimit()?(this.logLimitOnce(),!1):!(!this.hasElapsedMinimumInterval(e,r)||!this.hasSignificantDepthChange(e,t.depth))}hasReachedSessionLimit(){return(this.get("scrollEventCount")??0)>=this.maxEventsPerSession}hasElapsedMinimumInterval(e,t){return e.lastEventTime===0?!0:t-e.lastEventTime>=this.minIntervalMs}hasSignificantDepthChange(e,t){return Math.abs(t-e.lastDepth)>=this.minDepthChange}logLimitOnce(){this.limitWarningLogged||(this.limitWarningLogged=!0,a("warn","Max scroll events per session reached",{data:{limit:this.maxEventsPerSession}}))}applyConfigOverrides(){this.minDepthChange=5,this.minIntervalMs=500,this.maxEventsPerSession=120}isWindowScrollable(){return document.documentElement.scrollHeight>window.innerHeight}clearContainerTimer(e){e.debounceTimer!==null&&(clearTimeout(e.debounceTimer),e.debounceTimer=null)}getScrollDirection(e,t){return e>t?H.DOWN:H.UP}calculateScrollDepth(e,t,r){if(t<=r)return 0;const s=t-r;return Math.min(100,Math.max(0,Math.floor(e/s*100)))}calculateScrollData(e){const{element:t,lastScrollPos:r,lastEventTime:s}=e,i=this.getScrollTop(t),o=Date.now(),l=Math.abs(i-r);if(l<10||t===window&&!this.isWindowScrollable())return null;const c=this.getViewportHeight(t),d=this.getScrollHeight(t),_=this.getScrollDirection(i,r),m=this.calculateScrollDepth(i,d,c);let y;s>0?y=o-s:e.firstScrollEventTime!==null?y=o-e.firstScrollEventTime:y=250;const T=Math.round(l/y*1e3);return m>e.maxDepthReached&&(e.maxDepthReached=m),e.lastScrollPos=i,{depth:m,direction:_,velocity:T,max_depth_reached:e.maxDepthReached}}getScrollTop(e){return e===window?window.scrollY:e.scrollTop}getViewportHeight(e){return e===window?window.innerHeight:e.clientHeight}getScrollHeight(e){return e===window?document.documentElement.scrollHeight:e.scrollHeight}isElementScrollable(e){const t=getComputedStyle(e),r=t.overflowY==="auto"||t.overflowY==="scroll"||t.overflow==="auto"||t.overflow==="scroll",s=e.scrollHeight>e.clientHeight;return r&&s}applyPrimaryScrollSelector(e){let t;if(e==="window")t=window;else{const s=document.querySelector(e);if(!(s instanceof HTMLElement)){a("warn",`Selector "${e}" did not match an HTMLElement`);return}t=s}this.containers.forEach(s=>{this.updateContainerPrimary(s,s.element===t)}),!this.containers.some(s=>s.element===t)&&t instanceof HTMLElement&&this.isElementScrollable(t)&&this.setupScrollContainer(t,e)}updateContainerPrimary(e,t){e.isPrimary=t}}class Mt extends S{eventManager;trackedElements=new Map;observer=null;mutationObserver=null;mutationDebounceTimer=null;config=null;constructor(e){super(),this.eventManager=e}startTracking(){const e=this.get("config");if(this.config=e.viewport??null,!this.config?.elements||this.config.elements.length===0)return;const t=this.config.threshold??.5,r=this.config.minDwellTime??1e3;if(t<0||t>1){a("warn","ViewportHandler: Invalid threshold, must be between 0 and 1");return}if(r<0){a("warn","ViewportHandler: Invalid minDwellTime, must be non-negative");return}if(typeof IntersectionObserver>"u"){a("warn","ViewportHandler: IntersectionObserver not supported in this browser");return}this.observer=new IntersectionObserver(this.handleIntersection,{threshold:t}),this.observeElements(),this.setupMutationObserver()}stopTracking(){this.observer&&(this.observer.disconnect(),this.observer=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.mutationDebounceTimer!==null&&(window.clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=null);for(const e of this.trackedElements.values())e.timeoutId!==null&&window.clearTimeout(e.timeoutId);this.trackedElements.clear()}observeElements(){if(!this.config||!this.observer)return;const e=this.config.maxTrackedElements??100;let t=this.trackedElements.size;for(const r of this.config.elements)try{const s=document.querySelectorAll(r.selector);for(const i of Array.from(s)){if(t>=e){a("warn","ViewportHandler: Maximum tracked elements reached",{data:{limit:e,selector:r.selector,message:"Some elements will not be tracked. Consider more specific selectors."}});return}i.hasAttribute(`${A}-ignore`)||this.trackedElements.has(i)||(this.trackedElements.set(i,{element:i,selector:r.selector,id:r.id,name:r.name,startTime:null,timeoutId:null,lastFiredTime:null}),this.observer?.observe(i),t++)}}catch(s){a("warn",`ViewportHandler: Invalid selector "${r.selector}"`,{error:s})}a("debug","ViewportHandler: Elements tracked",{data:{count:t,limit:e}})}handleIntersection=e=>{if(!this.config)return;const t=this.config.minDwellTime??1e3;for(const r of e){const s=this.trackedElements.get(r.target);s&&(r.isIntersecting?s.startTime===null&&(s.startTime=performance.now(),s.timeoutId=window.setTimeout(()=>{const i=Math.round(r.intersectionRatio*100)/100;this.fireViewportEvent(s,i)},t)):s.startTime!==null&&(s.timeoutId!==null&&(window.clearTimeout(s.timeoutId),s.timeoutId=null),s.startTime=null))}};fireViewportEvent(e,t){if(e.startTime===null)return;const r=Math.round(performance.now()-e.startTime);if(e.element.hasAttribute("data-tlog-ignore"))return;const s=this.config?.cooldownPeriod??6e4,i=Date.now();if(e.lastFiredTime!==null&&i-e.lastFiredTime<s){a("debug","ViewportHandler: Event suppressed by cooldown period",{data:{selector:e.selector,cooldownRemaining:s-(i-e.lastFiredTime)}}),e.startTime=null,e.timeoutId=null;return}const o={selector:e.selector,dwellTime:r,visibilityRatio:t,...e.id!==void 0&&{id:e.id},...e.name!==void 0&&{name:e.name}};this.eventManager.track({type:u.VIEWPORT_VISIBLE,viewport_data:o}),e.startTime=null,e.timeoutId=null,e.lastFiredTime=i}setupMutationObserver(){if(!(!this.config||typeof MutationObserver>"u")){if(!document.body){a("warn","ViewportHandler: document.body not available, skipping MutationObserver setup");return}this.mutationObserver=new MutationObserver(e=>{let t=!1;for(const r of e)r.type==="childList"&&(r.addedNodes.length>0&&(t=!0),r.removedNodes.length>0&&this.cleanupRemovedNodes(r.removedNodes));t&&(this.mutationDebounceTimer!==null&&window.clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=window.setTimeout(()=>{this.observeElements(),this.mutationDebounceTimer=null},100))}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}}cleanupRemovedNodes(e){e.forEach(t=>{if(t.nodeType!==1)return;const r=t,s=this.trackedElements.get(r);s&&(s.timeoutId!==null&&window.clearTimeout(s.timeoutId),this.observer?.unobserve(r),this.trackedElements.delete(r)),Array.from(this.trackedElements.keys()).filter(o=>r.contains(o)).forEach(o=>{const l=this.trackedElements.get(o);l&&l.timeoutId!==null&&window.clearTimeout(l.timeoutId),this.observer?.unobserve(o),this.trackedElements.delete(o)})})}}class Lt extends S{isInitialized=!1;async initialize(){if(this.isInitialized)return;const e=this.get("config").integrations?.googleAnalytics?.measurementId,t=this.get("userId");if(!(!e?.trim()||!t?.trim()))try{if(this.isScriptAlreadyLoaded()){this.isInitialized=!0;return}await this.loadScript(e),this.configureGtag(e,t),this.isInitialized=!0}catch(r){a("error","Google Analytics initialization failed",{error:r})}}trackEvent(e,t){if(!(!e?.trim()||!this.isInitialized||typeof window.gtag!="function"))try{const r=Array.isArray(t)?{items:t}:t;window.gtag("event",e,r)}catch(r){a("error","Google Analytics event tracking failed",{error:r})}}cleanup(){this.isInitialized=!1;const e=document.getElementById("tracelog-ga-script");e&&e.remove()}isScriptAlreadyLoaded(){return document.getElementById("tracelog-ga-script")?!0:!!document.querySelector('script[src*="googletagmanager.com/gtag/js"]')}async loadScript(e){return new Promise((t,r)=>{const s=document.createElement("script");s.id="tracelog-ga-script",s.async=!0,s.src=`https://www.googletagmanager.com/gtag/js?id=${e}`,s.onload=()=>{t()},s.onerror=()=>{r(new Error("Failed to load Google Analytics script"))},document.head.appendChild(s)})}configureGtag(e,t){const r=document.createElement("script");r.innerHTML=`
|
|
2
|
+
window.dataLayer = window.dataLayer || [];
|
|
3
|
+
function gtag(){dataLayer.push(arguments);}
|
|
4
|
+
gtag('js', new Date());
|
|
5
|
+
gtag('config', '${e}', {
|
|
6
|
+
'user_id': '${t}'
|
|
7
|
+
});
|
|
8
|
+
`,document.head.appendChild(r)}}class Rt{storage;sessionStorageRef;fallbackStorage=new Map;fallbackSessionStorage=new Map;hasQuotaExceededError=!1;constructor(){this.storage=this.initializeStorage("localStorage"),this.sessionStorageRef=this.initializeStorage("sessionStorage"),this.storage||a("warn","localStorage not available, using memory fallback"),this.sessionStorageRef||a("warn","sessionStorage not available, using memory fallback")}getItem(e){try{return this.storage?this.storage.getItem(e):this.fallbackStorage.get(e)??null}catch{return this.fallbackStorage.get(e)??null}}setItem(e,t){this.fallbackStorage.set(e,t);try{if(this.storage){this.storage.setItem(e,t);return}}catch(r){if(r instanceof DOMException&&r.name==="QuotaExceededError")if(this.hasQuotaExceededError=!0,a("warn","localStorage quota exceeded, attempting cleanup",{data:{key:e,valueSize:t.length}}),this.cleanupOldData())try{if(this.storage){this.storage.setItem(e,t);return}}catch(i){a("error","localStorage quota exceeded even after cleanup - data will not persist",{error:i,data:{key:e,valueSize:t.length}})}else a("error","localStorage quota exceeded and no data to cleanup - data will not persist",{error:r,data:{key:e,valueSize:t.length}})}}removeItem(e){try{this.storage&&this.storage.removeItem(e)}catch{}this.fallbackStorage.delete(e)}clear(){if(!this.storage){this.fallbackStorage.clear();return}try{const e=[];for(let t=0;t<this.storage.length;t++){const r=this.storage.key(t);r?.startsWith("tracelog_")&&e.push(r)}e.forEach(t=>{this.storage.removeItem(t)}),this.fallbackStorage.clear()}catch(e){a("error","Failed to clear storage",{error:e}),this.fallbackStorage.clear()}}isAvailable(){return this.storage!==null}hasQuotaError(){return this.hasQuotaExceededError}cleanupOldData(){if(!this.storage)return!1;try{const e=[],t=[];for(let i=0;i<this.storage.length;i++){const o=this.storage.key(i);o?.startsWith("tracelog_")&&(e.push(o),o.startsWith("tracelog_persisted_events_")&&t.push(o))}if(t.length>0)return t.forEach(i=>{try{this.storage.removeItem(i)}catch{}}),!0;const r=["tracelog_session_","tracelog_user_id","tracelog_device_id","tracelog_config"],s=e.filter(i=>!r.some(o=>i.startsWith(o)));return s.length>0?(s.slice(0,5).forEach(o=>{try{this.storage.removeItem(o)}catch{}}),!0):!1}catch(e){return a("error","Failed to cleanup old data",{error:e}),!1}}initializeStorage(e){if(typeof window>"u")return null;try{const t=e==="localStorage"?window.localStorage:window.sessionStorage,r="__tracelog_test__";return t.setItem(r,"test"),t.removeItem(r),t}catch{return null}}getSessionItem(e){try{return this.sessionStorageRef?this.sessionStorageRef.getItem(e):this.fallbackSessionStorage.get(e)??null}catch{return this.fallbackSessionStorage.get(e)??null}}setSessionItem(e,t){this.fallbackSessionStorage.set(e,t);try{if(this.sessionStorageRef){this.sessionStorageRef.setItem(e,t);return}}catch(r){r instanceof DOMException&&r.name==="QuotaExceededError"&&a("error","sessionStorage quota exceeded - data will not persist",{error:r,data:{key:e,valueSize:t.length}})}}removeSessionItem(e){try{this.sessionStorageRef&&this.sessionStorageRef.removeItem(e)}catch{}this.fallbackSessionStorage.delete(e)}}class Ot extends S{eventManager;reportedByNav=new Map;navigationHistory=[];observers=[];vitalThresholds=Se;lastLongTaskSentAt=0;constructor(e){super(),this.eventManager=e}async startTracking(){await this.initWebVitals(),this.observeLongTasks()}stopTracking(){this.observers.forEach((e,t)=>{try{e.disconnect()}catch(r){a("warn","Failed to disconnect performance observer",{error:r,data:{observerIndex:t}})}}),this.observers.length=0,this.reportedByNav.clear(),this.navigationHistory.length=0}observeWebVitalsFallback(){this.reportTTFB(),this.safeObserve("largest-contentful-paint",r=>{const s=r.getEntries(),i=s[s.length-1];i&&this.sendVital({type:"LCP",value:Number(i.startTime.toFixed(2))})},{type:"largest-contentful-paint",buffered:!0},!0);let e=0,t=this.getNavigationId();this.safeObserve("layout-shift",r=>{const s=this.getNavigationId();s!==t&&(e=0,t=s);const i=r.getEntries();for(const o of i){if(o.hadRecentInput===!0)continue;const l=typeof o.value=="number"?o.value:0;e+=l}this.sendVital({type:"CLS",value:Number(e.toFixed(2))})},{type:"layout-shift",buffered:!0}),this.safeObserve("paint",r=>{for(const s of r.getEntries())s.name==="first-contentful-paint"&&this.sendVital({type:"FCP",value:Number(s.startTime.toFixed(2))})},{type:"paint",buffered:!0},!0),this.safeObserve("event",r=>{let s=0;const i=r.getEntries();for(const o of i){const l=(o.processingEnd??0)-(o.startTime??0);s=Math.max(s,l)}s>0&&this.sendVital({type:"INP",value:Number(s.toFixed(2))})},{type:"event",buffered:!0})}async initWebVitals(){try{const{onLCP:e,onCLS:t,onFCP:r,onTTFB:s,onINP:i}=await Promise.resolve().then(()=>cr),o=l=>c=>{const d=Number(c.value.toFixed(2));this.sendVital({type:l,value:d})};e(o("LCP"),{reportAllChanges:!1}),t(o("CLS"),{reportAllChanges:!1}),r(o("FCP"),{reportAllChanges:!1}),s(o("TTFB"),{reportAllChanges:!1}),i(o("INP"),{reportAllChanges:!1})}catch(e){a("warn","Failed to load web-vitals library, using fallback",{error:e}),this.observeWebVitalsFallback()}}reportTTFB(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return;const t=e.responseStart;typeof t=="number"&&Number.isFinite(t)&&this.sendVital({type:"TTFB",value:Number(t.toFixed(2))})}catch(e){a("warn","Failed to report TTFB",{error:e})}}observeLongTasks(){this.safeObserve("longtask",e=>{const t=e.getEntries();for(const r of t){const s=Number(r.duration.toFixed(2)),i=Date.now();i-this.lastLongTaskSentAt>=Ze&&(this.shouldSendVital("LONG_TASK",s)&&this.trackWebVital("LONG_TASK",s),this.lastLongTaskSentAt=i)}},{type:"longtask",buffered:!0})}sendVital(e){if(!this.shouldSendVital(e.type,e.value))return;const t=this.getNavigationId();if(t){const r=this.reportedByNav.get(t);if(r?.has(e.type))return;if(r)r.add(e.type);else if(this.reportedByNav.set(t,new Set([e.type])),this.navigationHistory.push(t),this.navigationHistory.length>Je){const i=this.navigationHistory.shift();i&&this.reportedByNav.delete(i)}}this.trackWebVital(e.type,e.value)}trackWebVital(e,t){if(!Number.isFinite(t)){a("warn","Invalid web vital value",{data:{type:e,value:t}});return}this.eventManager.track({type:u.WEB_VITALS,web_vitals:{type:e,value:t}})}getNavigationId(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return null;const t=e.startTime||performance.now(),r=Math.random().toString(36).substr(2,5);return`${t.toFixed(2)}_${window.location.pathname}_${r}`}catch(e){return a("warn","Failed to get navigation ID",{error:e}),null}}isObserverSupported(e){if(typeof PerformanceObserver>"u")return!1;const t=PerformanceObserver.supportedEntryTypes;return!t||t.includes(e)}safeObserve(e,t,r,s=!1){try{if(!this.isObserverSupported(e))return!1;const i=new PerformanceObserver((o,l)=>{try{t(o,l)}catch(c){a("warn","Observer callback failed",{error:c,data:{type:e}})}if(s)try{l.disconnect()}catch{}});return i.observe(r??{type:e,buffered:!0}),s||this.observers.push(i),!0}catch(i){return a("warn","Failed to create performance observer",{error:i,data:{type:e}}),!1}}shouldSendVital(e,t){if(typeof t!="number"||!Number.isFinite(t))return a("warn","Invalid web vital value",{data:{type:e,value:t}}),!1;const r=this.vitalThresholds[e];return!(typeof r=="number"&&t<=r)}}class Ct extends S{eventManager;recentErrors=new Map;errorBurstCounter=0;burstWindowStart=0;burstBackoffUntil=0;constructor(e){super(),this.eventManager=e}startTracking(){window.addEventListener("error",this.handleError),window.addEventListener("unhandledrejection",this.handleRejection)}stopTracking(){window.removeEventListener("error",this.handleError),window.removeEventListener("unhandledrejection",this.handleRejection),this.recentErrors.clear(),this.errorBurstCounter=0,this.burstWindowStart=0,this.burstBackoffUntil=0}shouldSample(){const e=Date.now();if(e<this.burstBackoffUntil)return!1;if(e-this.burstWindowStart>tt&&(this.errorBurstCounter=0,this.burstWindowStart=e),this.errorBurstCounter++,this.errorBurstCounter>rt)return this.burstBackoffUntil=e+pe,a("warn","Error burst detected - entering cooldown",{data:{errorsInWindow:this.errorBurstCounter,cooldownMs:pe}}),!1;const r=this.get("config")?.errorSampling??Ie;return Math.random()<r}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");this.shouldSuppressError(C.JS_ERROR,t)||this.eventManager.track({type:u.ERROR,error_data:{type:C.JS_ERROR,message:t,...e.filename&&{filename:e.filename},...e.lineno&&{line:e.lineno},...e.colno&&{column:e.colno}}})};handleRejection=e=>{if(!this.shouldSample())return;const t=this.extractRejectionMessage(e.reason),r=this.sanitize(t);this.shouldSuppressError(C.PROMISE_REJECTION,r)||this.eventManager.track({type:u.ERROR,error_data:{type:C.PROMISE_REJECTION,message:r}})};extractRejectionMessage(e){if(!e)return"Unknown rejection";if(typeof e=="string")return e;if(e instanceof Error)return e.stack??e.message??e.toString();if(typeof e=="object"&&"message"in e)return String(e.message);try{return JSON.stringify(e)}catch{return String(e)}}sanitize(e){let t=e.length>Te?e.slice(0,Te)+"...":e;for(const r of q){const s=new RegExp(r.source,r.flags);t=t.replace(s,"[REDACTED]")}return t}shouldSuppressError(e,t){const r=Date.now(),s=`${e}:${t}`,i=this.recentErrors.get(s);return i&&r-i<_e?(this.recentErrors.set(s,r),!0):(this.recentErrors.set(s,r),this.recentErrors.size>et?(this.recentErrors.clear(),this.recentErrors.set(s,r),!1):(this.recentErrors.size>x&&this.pruneOldErrors(),!1))}pruneOldErrors(){const e=Date.now();for(const[s,i]of this.recentErrors.entries())e-i>_e&&this.recentErrors.delete(s);if(this.recentErrors.size<=x)return;const t=Array.from(this.recentErrors.entries()).sort((s,i)=>s[1]-i[1]),r=this.recentErrors.size-x;for(let s=0;s<r;s+=1){const i=t[s];i&&this.recentErrors.delete(i[0])}}}class bt extends S{isInitialized=!1;suppressNextScrollTimer=null;emitter=new Tt;managers={};handlers={};integrations={};get initialized(){return this.isInitialized}async init(e={}){if(!this.isInitialized){this.managers.storage=new Rt;try{this.setupState(e),await this.setupIntegrations(),this.managers.event=new It(this.managers.storage,this.integrations.googleAnalytics,this.emitter),this.initializeHandlers(),await this.managers.event.recoverPersistedEvents().catch(t=>{a("warn","Failed to recover persisted events",{error:t})}),this.isInitialized=!0}catch(t){this.destroy(!0);const r=t instanceof Error?t.message:String(t);throw new Error(`[TraceLog] TraceLog initialization failed: ${r}`)}}}sendCustomEvent(e,t){if(!this.managers.event)return;const{valid:r,error:s,sanitizedMetadata:i}=St(e,t);if(!r){if(this.get("mode")===b.QA)throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${s}`);return}this.managers.event.track({type:u.CUSTOM,custom_event:{name:e,...i&&{metadata:i}}})}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}destroy(e=!1){!this.isInitialized&&!e||(this.integrations.googleAnalytics?.cleanup(),Object.values(this.handlers).filter(Boolean).forEach(t=>{try{t.stopTracking()}catch(r){a("warn","Failed to stop tracking",{error:r})}}),this.suppressNextScrollTimer&&(clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=null),this.managers.event?.flushImmediatelySync(),this.managers.event?.stop(),this.emitter.removeAllListeners(),this.set("hasStartSession",!1),this.set("suppressNextScroll",!1),this.set("sessionId",null),this.isInitialized=!1,this.handlers={})}setupState(e={}){this.set("config",e);const t=pt.getId(this.managers.storage);this.set("userId",t);const r=lt(e);this.set("collectApiUrl",r);const s=Ye();this.set("device",s);const i=Z(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i);const o=it()?b.QA:void 0;o&&this.set("mode",o)}async setupIntegrations(){if(this.get("config").integrations?.googleAnalytics?.measurementId?.trim())try{this.integrations.googleAnalytics=new Lt,await this.integrations.googleAnalytics.initialize()}catch{this.integrations.googleAnalytics=void 0}}initializeHandlers(){this.handlers.session=new At(this.managers.storage,this.managers.event),this.handlers.session.startTracking();const e=()=>{this.set("suppressNextScroll",!0),this.suppressNextScrollTimer&&clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=window.setTimeout(()=>{this.set("suppressNextScroll",!1)},500)};this.handlers.pageView=new wt(this.managers.event,e),this.handlers.pageView.startTracking(),this.handlers.click=new yt(this.managers.event),this.handlers.click.startTracking(),this.handlers.scroll=new Nt(this.managers.event),this.handlers.scroll.startTracking(),this.handlers.performance=new Ot(this.managers.event),this.handlers.performance.startTracking().catch(t=>{a("warn","Failed to start performance tracking",{error:t})}),this.handlers.error=new Ct(this.managers.event),this.handlers.error.startTracking(),this.get("config").viewport&&(this.handlers.viewport=new Mt(this.managers.event),this.handlers.viewport.startTracking())}}const O=[];let g=null,D=!1,W=!1;const Pt=async n=>{if(!(typeof window>"u"||typeof document>"u")&&!window.__traceLogDisabled&&!g&&!D){D=!0;try{const e=Et(n??{}),t=new bt;try{O.forEach(({event:i,callback:o})=>{t.on(i,o)}),O.length=0;const r=t.init(e),s=new Promise((i,o)=>{setTimeout(()=>{o(new Error("[TraceLog] Initialization timeout after 10000ms"))},1e4)});await Promise.race([r,s]),g=t}catch(r){try{t.destroy(!0)}catch(s){a("error","Failed to cleanup partially initialized app",{error:s})}throw r}}catch(e){throw g=null,e}finally{D=!1}}},Dt=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(W)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");g.sendCustomEvent(n,e)}},Vt=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g||D){O.push({event:n,callback:e});return}g.on(n,e)}},kt=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g){const t=O.findIndex(r=>r.event===n&&r.callback===e);t!==-1&&O.splice(t,1);return}g.off(n,e)}},Ht=()=>typeof window>"u"||typeof document>"u"?!1:g!==null,Ut=()=>{if(!(typeof window>"u"||typeof document>"u")){if(W)throw new Error("[TraceLog] Destroy operation already in progress");if(!g)throw new Error("[TraceLog] App not initialized");W=!0;try{g.destroy(),g=null,D=!1,O.length=0}catch(n){g=null,D=!1,O.length=0,a("warn","Error during destroy, forced cleanup completed",{error:n})}finally{W=!1}}},Ft={WEB_VITALS_THRESHOLDS:Se},Gt={PII_PATTERNS:q},xt={LOW_ACTIVITY_EVENT_COUNT:50,HIGH_ACTIVITY_EVENT_COUNT:1e3,MIN_EVENTS_FOR_DYNAMIC_CALCULATION:100,MIN_EVENTS_FOR_TREND_ANALYSIS:30,BOUNCE_RATE_SESSION_THRESHOLD:1,MIN_ENGAGED_SESSION_DURATION_MS:30*1e3,MIN_SCROLL_DEPTH_ENGAGEMENT:25},Wt={INACTIVITY_TIMEOUT_MS:1800*1e3,SHORT_SESSION_THRESHOLD_MS:30*1e3,MEDIUM_SESSION_THRESHOLD_MS:300*1e3,LONG_SESSION_THRESHOLD_MS:1800*1e3,MAX_REALISTIC_SESSION_DURATION_MS:480*60*1e3},Xt={MOBILE_MAX_WIDTH:768,TABLET_MAX_WIDTH:1024,MOBILE_PERFORMANCE_FACTOR:1.5,TABLET_PERFORMANCE_FACTOR:1.2},Bt={MIN_TEXT_LENGTH_FOR_ANALYSIS:10,MIN_CLICKS_FOR_HOT_ELEMENT:10,MIN_SCROLL_COMPLETION_PERCENT:80,MIN_TIME_ON_PAGE_FOR_READ_MS:15*1e3},$t={SIGNIFICANT_CHANGE_PERCENT:20,MAJOR_CHANGE_PERCENT:50,MIN_EVENTS_FOR_INSIGHT:100,MIN_SESSIONS_FOR_INSIGHT:10,MIN_CORRELATION_STRENGTH:.7,LOW_ERROR_RATE_PERCENT:1,HIGH_ERROR_RATE_PERCENT:5,CRITICAL_ERROR_RATE_PERCENT:10},zt={SHORT_TERM_TREND_HOURS:24,MEDIUM_TERM_TREND_DAYS:7,LONG_TERM_TREND_DAYS:30,MIN_DATA_POINTS_FOR_TREND:5,WEEKLY_PATTERN_MIN_WEEKS:4,DAILY_PATTERN_MIN_DAYS:14},Yt={MIN_SEGMENT_SIZE:10,MIN_COHORT_SIZE:5,COHORT_ANALYSIS_DAYS:[1,3,7,14,30],MIN_FUNNEL_EVENTS:20},Qt={DEFAULT_EVENTS_LIMIT:5,DEFAULT_SESSIONS_LIMIT:5,DEFAULT_PAGES_LIMIT:5,MAX_EVENTS_FOR_DEEP_ANALYSIS:1e4,MAX_TIME_RANGE_DAYS:365,ANALYTICS_BATCH_SIZE:1e3},jt={ANOMALY_THRESHOLD_SIGMA:2.5,STRONG_ANOMALY_THRESHOLD_SIGMA:3,TRAFFIC_DROP_ALERT_PERCENT:-30,TRAFFIC_SPIKE_ALERT_PERCENT:200,MIN_BASELINE_DAYS:7,MIN_EVENTS_FOR_ANOMALY_DETECTION:50},Kt={PAGE_URL_EXCLUDED:"excluded",PAGE_URL_UNKNOWN:"unknown"},qt={init:Pt,event:Dt,on:Vt,off:kt,isInitialized:Ht,destroy:Ut};var te,Le=-1,V=function(n){addEventListener("pageshow",(function(e){e.persisted&&(Le=e.timeStamp,n(e))}),!0)},re=function(){var n=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},X=function(){var n=re();return n&&n.activationStart||0},I=function(n,e){var t=re(),r="navigate";return Le>=0?r="back-forward-cache":t&&(document.prerendering||X()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-"))),{name:n,value:e===void 0?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},U=function(n,e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(n)){var r=new PerformanceObserver((function(s){Promise.resolve().then((function(){e(s.getEntries())}))}));return r.observe(Object.assign({type:n,buffered:!0},t||{})),r}}catch{}},p=function(n,e,t,r){var s,i;return function(o){e.value>=0&&(o||r)&&((i=e.value-(s||0))||s===void 0)&&(s=e.value,e.delta=i,e.rating=(function(l,c){return l>c[1]?"poor":l>c[0]?"needs-improvement":"good"})(e.value,t),n(e))}},ne=function(n){requestAnimationFrame((function(){return requestAnimationFrame((function(){return n()}))}))},B=function(n){document.addEventListener("visibilitychange",(function(){document.visibilityState==="hidden"&&n()}))},se=function(n){var e=!1;return function(){e||(n(),e=!0)}},k=-1,Re=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},$=function(n){document.visibilityState==="hidden"&&k>-1&&(k=n.type==="visibilitychange"?n.timeStamp:0,Zt())},Oe=function(){addEventListener("visibilitychange",$,!0),addEventListener("prerenderingchange",$,!0)},Zt=function(){removeEventListener("visibilitychange",$,!0),removeEventListener("prerenderingchange",$,!0)},Ce=function(){return k<0&&(k=Re(),Oe(),V((function(){setTimeout((function(){k=Re(),Oe()}),0)}))),{get firstHiddenTime(){return k}}},z=function(n){document.prerendering?addEventListener("prerenderingchange",(function(){return n()}),!0):n()},ie=[1800,3e3],be=function(n,e){e=e||{},z((function(){var t,r=Ce(),s=I("FCP"),i=U("paint",(function(o){o.forEach((function(l){l.name==="first-contentful-paint"&&(i.disconnect(),l.startTime<r.firstHiddenTime&&(s.value=Math.max(l.startTime-X(),0),s.entries.push(l),t(!0)))}))}));i&&(t=p(n,s,ie,e.reportAllChanges),V((function(o){s=I("FCP"),t=p(n,s,ie,e.reportAllChanges),ne((function(){s.value=performance.now()-o.timeStamp,t(!0)}))})))}))},oe=[.1,.25],Jt=function(n,e){e=e||{},be(se((function(){var t,r=I("CLS",0),s=0,i=[],o=function(c){c.forEach((function(d){if(!d.hadRecentInput){var _=i[0],m=i[i.length-1];s&&d.startTime-m.startTime<1e3&&d.startTime-_.startTime<5e3?(s+=d.value,i.push(d)):(s=d.value,i=[d])}})),s>r.value&&(r.value=s,r.entries=i,t())},l=U("layout-shift",o);l&&(t=p(n,r,oe,e.reportAllChanges),B((function(){o(l.takeRecords()),t(!0)})),V((function(){s=0,r=I("CLS",0),t=p(n,r,oe,e.reportAllChanges),ne((function(){return t()}))})),setTimeout(t,0))})))},Pe=0,ae=1/0,Y=0,er=function(n){n.forEach((function(e){e.interactionId&&(ae=Math.min(ae,e.interactionId),Y=Math.max(Y,e.interactionId),Pe=Y?(Y-ae)/7+1:0)}))},De=function(){return te?Pe:performance.interactionCount||0},tr=function(){"interactionCount"in performance||te||(te=U("event",er,{type:"event",buffered:!0,durationThreshold:0}))},v=[],Q=new Map,Ve=0,rr=function(){var n=Math.min(v.length-1,Math.floor((De()-Ve)/50));return v[n]},nr=[],sr=function(n){if(nr.forEach((function(s){return s(n)})),n.interactionId||n.entryType==="first-input"){var e=v[v.length-1],t=Q.get(n.interactionId);if(t||v.length<10||n.duration>e.latency){if(t)n.duration>t.latency?(t.entries=[n],t.latency=n.duration):n.duration===t.latency&&n.startTime===t.entries[0].startTime&&t.entries.push(n);else{var r={id:n.interactionId,latency:n.duration,entries:[n]};Q.set(r.id,r),v.push(r)}v.sort((function(s,i){return i.latency-s.latency})),v.length>10&&v.splice(10).forEach((function(s){return Q.delete(s.id)}))}}},ke=function(n){var e=self.requestIdleCallback||self.setTimeout,t=-1;return n=se(n),document.visibilityState==="hidden"?n():(t=e(n),B(n)),t},le=[200,500],ir=function(n,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},z((function(){var t;tr();var r,s=I("INP"),i=function(l){ke((function(){l.forEach(sr);var c=rr();c&&c.latency!==s.value&&(s.value=c.latency,s.entries=c.entries,r())}))},o=U("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});r=p(n,s,le,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),B((function(){i(o.takeRecords()),r(!0)})),V((function(){Ve=De(),v.length=0,Q.clear(),s=I("INP"),r=p(n,s,le,e.reportAllChanges)})))})))},ce=[2500,4e3],ue={},or=function(n,e){e=e||{},z((function(){var t,r=Ce(),s=I("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach((function(d){d.startTime<r.firstHiddenTime&&(s.value=Math.max(d.startTime-X(),0),s.entries=[d],t())}))},o=U("largest-contentful-paint",i);if(o){t=p(n,s,ce,e.reportAllChanges);var l=se((function(){ue[s.id]||(i(o.takeRecords()),o.disconnect(),ue[s.id]=!0,t(!0))}));["keydown","click"].forEach((function(c){addEventListener(c,(function(){return ke(l)}),{once:!0,capture:!0})})),B(l),V((function(c){s=I("LCP"),t=p(n,s,ce,e.reportAllChanges),ne((function(){s.value=performance.now()-c.timeStamp,ue[s.id]=!0,t(!0)}))}))}}))},de=[800,1800],ar=function n(e){document.prerendering?z((function(){return n(e)})):document.readyState!=="complete"?addEventListener("load",(function(){return n(e)}),!0):setTimeout(e,0)},lr=function(n,e){e=e||{};var t=I("TTFB"),r=p(n,t,de,e.reportAllChanges);ar((function(){var s=re();s&&(t.value=Math.max(s.responseStart-X(),0),t.entries=[s],r(!0),V((function(){t=I("TTFB",0),(r=p(n,t,de,e.reportAllChanges))(!0)})))}))};const cr=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:oe,FCPThresholds:ie,INPThresholds:le,LCPThresholds:ce,TTFBThresholds:de,onCLS:Jt,onFCP:be,onINP:ir,onLCP:or,onTTFB:lr},Symbol.toStringTag,{value:"Module"}));h.ANALYTICS_QUERY_LIMITS=Qt,h.ANOMALY_DETECTION=jt,h.AppConfigValidationError=f,h.CONTENT_ANALYTICS=Bt,h.DATA_PROTECTION=Gt,h.DEVICE_ANALYTICS=Xt,h.DeviceType=w,h.ENGAGEMENT_THRESHOLDS=xt,h.EmitterEvent=G,h.ErrorType=C,h.EventType=u,h.INSIGHT_THRESHOLDS=$t,h.InitializationTimeoutError=Xe,h.IntegrationValidationError=N,h.MAX_ARRAY_LENGTH=100,h.MAX_CUSTOM_EVENT_ARRAY_SIZE=10,h.MAX_CUSTOM_EVENT_KEYS=10,h.MAX_CUSTOM_EVENT_NAME_LENGTH=120,h.MAX_CUSTOM_EVENT_STRING_SIZE=8192,h.MAX_METADATA_NESTING_DEPTH=1,h.MAX_NESTED_OBJECT_KEYS=20,h.MAX_STRING_LENGTH=1e3,h.MAX_STRING_LENGTH_IN_ARRAY=500,h.Mode=b,h.PERFORMANCE_CONFIG=Ft,h.PermanentError=R,h.SEGMENTATION_ANALYTICS=Yt,h.SESSION_ANALYTICS=Wt,h.SPECIAL_PAGE_URLS=Kt,h.SamplingRateValidationError=j,h.ScrollDirection=H,h.SessionTimeoutValidationError=fe,h.SpecialApiUrl=F,h.TEMPORAL_ANALYSIS=zt,h.TraceLogValidationError=P,h.isPrimaryScrollEvent=xe,h.isSecondaryScrollEvent=We,h.tracelog=qt,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);
|