@tracelog/lib 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -146
- package/dist/browser/tracelog.esm.js +433 -423
- package/dist/browser/tracelog.esm.js.map +1 -1
- package/dist/browser/tracelog.js +2 -2
- package/dist/browser/tracelog.js.map +1 -1
- package/dist/public-api.cjs +117 -77
- package/dist/public-api.cjs.map +1 -1
- package/dist/public-api.d.mts +8 -35
- package/dist/public-api.d.ts +8 -35
- package/dist/public-api.js +117 -73
- package/dist/public-api.js.map +1 -1
- package/package.json +1 -1
package/dist/browser/tracelog.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
(function(d){"use strict";const A="data-tlog",Ge=["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"]'],xe=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],We=["token","auth","key","session","reset","password","api_key","apikey","secret","access_token","refresh_token","verification","code","otp"],f={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"},Xe=[/<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||{});const Be=n=>n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!0,$e=n=>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 E extends P{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class Te extends P{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class K extends P{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class L extends P{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class ze extends P{constructor(e,t,r="runtime"){super(e,"INITIALIZATION_TIMEOUT",r),this.timeoutMs=t}}const Ye=(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?Ye(e,r):`[TraceLog] ${e}`,l=n==="error"?"error":n==="warn"?"warn":"log";if(!(n==="debug"||n==="info"&&!i))if(s!==void 0){const c=je(s);console[l](o,c)}else s!==void 0?console[l](o,s):console[l](o)},je=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 q,Se;const Qe=()=>{typeof window<"u"&&!q&&(q=window.matchMedia("(pointer: coarse)"),Se=window.matchMedia("(hover: none)"))},Ke=()=>{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;Qe();const e=window.innerWidth,t=q?.matches??!1,r=Se?.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",_e=`${M}:qa_mode`,qe=`${M}:uid`,Ze=n=>n?`${M}:${n}:queue`:`${M}:queue`,Je=n=>n?`${M}:${n}:session`:`${M}:session`,et=n=>n?`${M}:${n}:broadcast`:`${M}:broadcast`,tt={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},Z={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},Ie={LCP:4e3,FCP:3e3,CLS:.25,INP:500,TTFB:1800,LONG_TASK:50},x="needs-improvement",J=(n=x)=>{switch(n){case"all":return{LCP:0,FCP:0,CLS:0,INP:0,TTFB:0,LONG_TASK:0};case"needs-improvement":return Z;case"poor":return Ie;default:return Z}},rt=1e3,nt=50,ee=[/\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],pe=500,ve=5e3,W=50,st=W*2,Ae=1,it=1e3,ot=10,we=5e3,at=6e4,ye="tlog_mode",lt="qa",ct=()=>{if(sessionStorage.getItem(_e)==="true")return!0;const e=new URLSearchParams(window.location.search),r=e.get(ye)===lt;if(r){sessionStorage.setItem(_e,"true"),e.delete(ye);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},Le=()=>{const n=new URLSearchParams(window.location.search),e={};return xe.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},ut=()=>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)}),dt=()=>{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}`},Me=(n,e=!1)=>{try{const t=new URL(n),r=t.protocol==="https:",s=t.protocol==="http:";return r||e&&s}catch{return!1}},ht=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(!Me(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(!Me(e,t))throw new Error("Invalid URL");return e}return""},te=(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([...We,...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}},Ne=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 Xe){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()},re=(n,e=0)=>{if(e>3||n==null)return null;if(typeof n=="string")return Ne(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=>re(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=Ne(i);if(l){const c=re(o,e+1);c!==null&&(t[l]=c)}}return t}return null},Et=n=>{if(typeof n!="object"||n===null)return{};try{const e=re(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}`)}},ft=n=>{if(n!==void 0&&(n===null||typeof n!="object"))throw new E("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 Te(f.INVALID_SESSION_TIMEOUT,"config");if(n.globalMetadata!==void 0&&(typeof n.globalMetadata!="object"||n.globalMetadata===null))throw new E(f.INVALID_GLOBAL_METADATA,"config");if(n.integrations&&mt(n.integrations),n.sensitiveQueryParams!==void 0){if(!Array.isArray(n.sensitiveQueryParams))throw new E(f.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of n.sensitiveQueryParams)if(typeof e!="string")throw new E("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 K(f.INVALID_ERROR_SAMPLING_RATE,"config");if(n.samplingRate!==void 0&&(typeof n.samplingRate!="number"||n.samplingRate<0||n.samplingRate>1))throw new K(f.INVALID_SAMPLING_RATE,"config");if(n.primaryScrollSelector!==void 0){if(typeof n.primaryScrollSelector!="string"||!n.primaryScrollSelector.trim())throw new E(f.INVALID_PRIMARY_SCROLL_SELECTOR,"config");if(n.primaryScrollSelector!=="window")try{document.querySelector(n.primaryScrollSelector)}catch{throw new E(`${f.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${n.primaryScrollSelector}"`,"config")}}if(n.pageViewThrottleMs!==void 0&&(typeof n.pageViewThrottleMs!="number"||n.pageViewThrottleMs<0))throw new E(f.INVALID_PAGE_VIEW_THROTTLE,"config");if(n.clickThrottleMs!==void 0&&(typeof n.clickThrottleMs!="number"||n.clickThrottleMs<0))throw new E(f.INVALID_CLICK_THROTTLE,"config");if(n.maxSameEventPerMinute!==void 0&&(typeof n.maxSameEventPerMinute!="number"||n.maxSameEventPerMinute<=0))throw new E(f.INVALID_MAX_SAME_EVENT_PER_MINUTE,"config");if(n.viewport!==void 0&>(n.viewport),n.webVitalsMode!==void 0){if(typeof n.webVitalsMode!="string")throw new E(`Invalid webVitalsMode type: ${typeof n.webVitalsMode}. Must be a string`,"config");const e=["all","needs-improvement","poor"];if(!e.includes(n.webVitalsMode))throw new E(`Invalid webVitalsMode: "${n.webVitalsMode}". Must be one of: ${e.join(", ")}`,"config")}if(n.webVitalsThresholds!==void 0){if(typeof n.webVitalsThresholds!="object"||n.webVitalsThresholds===null||Array.isArray(n.webVitalsThresholds))throw new E("webVitalsThresholds must be an object","config");const e=["LCP","FCP","CLS","INP","TTFB","LONG_TASK"];for(const[t,r]of Object.entries(n.webVitalsThresholds)){if(!e.includes(t))throw new E(`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,"config");if(typeof r!="number"||!Number.isFinite(r)||r<0)throw new E(`Invalid Web Vitals threshold value for ${t}: ${r}. Must be a non-negative finite number`,"config")}}}},gt=n=>{if(typeof n!="object"||n===null)throw new E(f.INVALID_VIEWPORT_CONFIG,"config");if(!n.elements||!Array.isArray(n.elements))throw new E(f.INVALID_VIEWPORT_ELEMENTS,"config");if(n.elements.length===0)throw new E(f.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 E(f.INVALID_VIEWPORT_ELEMENT,"config");const r=t.selector.trim();if(e.has(r))throw new E(`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 E(f.INVALID_VIEWPORT_ELEMENT_ID,"config");if(t.name!==void 0&&(typeof t.name!="string"||!t.name.trim()))throw new E(f.INVALID_VIEWPORT_ELEMENT_NAME,"config")}if(n.threshold!==void 0&&(typeof n.threshold!="number"||n.threshold<0||n.threshold>1))throw new E(f.INVALID_VIEWPORT_THRESHOLD,"config");if(n.minDwellTime!==void 0&&(typeof n.minDwellTime!="number"||n.minDwellTime<0))throw new E(f.INVALID_VIEWPORT_MIN_DWELL_TIME,"config");if(n.cooldownPeriod!==void 0&&(typeof n.cooldownPeriod!="number"||n.cooldownPeriod<0))throw new E(f.INVALID_VIEWPORT_COOLDOWN_PERIOD,"config");if(n.maxTrackedElements!==void 0&&(typeof n.maxTrackedElements!="number"||n.maxTrackedElements<=0))throw new E(f.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS,"config")},mt=n=>{if(n){if(n.tracelog&&(!n.tracelog.projectId||typeof n.tracelog.projectId!="string"||n.tracelog.projectId.trim()===""))throw new L(f.INVALID_TRACELOG_PROJECT_ID,"config");if(n.custom){if(!n.custom.collectApiUrl||typeof n.custom.collectApiUrl!="string"||n.custom.collectApiUrl.trim()==="")throw new L(f.INVALID_CUSTOM_API_URL,"config");if(n.custom.allowHttp!==void 0&&typeof n.custom.allowHttp!="boolean")throw new L("allowHttp must be a boolean","config");const e=n.custom.collectApiUrl.trim();if(!e.startsWith("http://")&&!e.startsWith("https://"))throw new L('Custom API URL must start with "http://" or "https://"',"config");if(!(n.custom.allowHttp??!1)&&e.startsWith("http://"))throw new L("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 L(f.INVALID_GOOGLE_ANALYTICS_ID,"config");if(!n.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))throw new L('Google Analytics measurement ID must start with "G-" or "UA-"',"config")}}},Tt=n=>{ft(n);const e={...n??{},sessionTimeout:n?.sessionTimeout??9e5,globalMetadata:n?.globalMetadata??{},sensitiveQueryParams:n?.sensitiveQueryParams??[],errorSampling:n?.errorSampling??Ae,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},St=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},Re=(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=>St(o)))return!1;continue}if(r==="object"&&e===0){if(!Re(t,e+1))return!1;continue}return!1}}return!0},_t=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},Oe=(n,e,t)=>{const r=Et(e),s=`${t} "${n}" metadata error`;if(!Re(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 h of c)if(typeof h=="string"&&h.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}},It=(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=Oe(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 Oe(n,e,t)},pt=(n,e)=>{const t=_t(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=It(n,e,"customEvent");return r.valid||a("error","Event metadata validation failed",{showToClient:!0,data:{eventName:n,error:r.error}}),r};class vt{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 ne={};class T{get(e){return ne[e]}set(e,t){ne[e]=t}getState(){return{...ne}}}class At extends T{storeManager;lastPermanentErrorLog=null;recoveryInProgress=!1;constructor(e){super(),this.storeManager=e}getQueueStorageKey(){const e=this.get("userId")||"anonymous";return Ze(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>=at)&&(a("error",e,{data:{status:t.statusCode,message:t.message}}),this.lastPermanentErrorLog={statusCode:t.statusCode,timestamp:r})}}class wt extends T{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 At(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:h,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:h,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 S=e;if(!y){if(this.sessionEventCounts.total>=1e3){a("warn","Session event limit reached",{data:{type:S,total:this.sessionEventCounts.total,limit:1e3}});return}const N=this.getTypeLimitForEvent(S);if(N){const me=this.sessionEventCounts[S];if(me!==void 0&&me>=N){a("warn","Session event type limit reached",{data:{type:S,count:me,limit:N}});return}}}if(S===u.CUSTOM&&o?.name){const N=this.get("config")?.maxSameEventPerMinute??60;if(!this.checkPerEventRateLimit(o.name,N))return}const hr=S===u.SESSION_START,Er=t||this.get("pageUrl"),ge=this.buildEventPayload({type:S,page_url:Er,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,session_end_reason:h,viewport_data:_});if(!(!y&&!this.shouldSample())){if(hr){const N=this.get("sessionId");if(!N){a("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){a("warn","Duplicate session_start detected",{data:{sessionId:N}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(ge)){if(this.get("mode")===b.QA&&S===u.CUSTOM&&o){console.log("[TraceLog] Event",{name:o.name,...o.metadata&&{metadata:o.metadata}}),this.emitEvent(ge);return}this.addToQueue(ge),y||(this.sessionEventCounts.total++,this.sessionEventCounts[S]!==void 0&&this.sessionEventCounts[S]++)}}}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:dt(),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&&Le()&&{utm:Le()}}}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 yt{static getId(e){const t=qe,r=e.getItem(t);if(r)return r;const s=ut();return e.setItem(t,s),s}}class Lt extends T{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(et(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 Je(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 Mt extends T{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 Lt(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 Nt extends T{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=te(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=te(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 Rt extends T{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 h=this.generateClickData(s,l,c);this.eventManager.track({type:u.CLICK,click_data:h})},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 Ge)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),h=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},...h.href&&{href:h.href},...h.title&&{title:h.title},...h.alt&&{alt:h.alt},...h.role&&{role:h.role},...h["aria-label"]&&{ariaLabel:h["aria-label"]},...Object.keys(h).length>0&&{dataAttributes:h}}}sanitizeText(e){let t=e;for(const r of ee){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 Ot extends T{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(h=>h.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 h=this.calculateScrollData(l);if(h){const _=Date.now();this.processScrollEvent(l,h,_)}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),h=this.getScrollHeight(t),_=this.getScrollDirection(i,r),m=this.calculateScrollDepth(i,h,c);let y;s>0?y=o-s:e.firstScrollEventTime!==null?y=o-e.firstScrollEventTime:y=250;const S=Math.round(l/y*1e3);return m>e.maxDepthReached&&(e.maxDepthReached=m),e.lastScrollPos=i,{depth:m,direction:_,velocity:S,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 Ct extends T{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 bt extends T{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=`
|
|
1
|
+
(function(h){"use strict";const A="data-tlog",$e=["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"]'],ze=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],Qe=["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"},je=[/<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 G=(n=>(n.Localhost="localhost:8080",n.Fail="localhost:9999",n))(G||{}),w=(n=>(n.Mobile="mobile",n.Tablet="tablet",n.Desktop="desktop",n.Unknown="unknown",n))(w||{}),x=(n=>(n.EVENT="event",n.QUEUE="queue",n))(x||{});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||{}),U=(n=>(n.UP="up",n.DOWN="down",n))(U||{}),O=(n=>(n.JS_ERROR="js_error",n.PROMISE_REJECTION="promise_rejection",n))(O||{}),C=(n=>(n.QA="qa",n))(C||{});const Ye=n=>n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!0,Ke=n=>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 _e extends P{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class q extends P{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class L extends P{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class qe extends P{constructor(e,t,r="runtime"){super(e,"INITIALIZATION_TIMEOUT",r),this.timeoutMs=t}}const Ze=(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}`}if(e instanceof Error)return`[TraceLog] ${n}: ${e.message}`;if(typeof e=="string")return`[TraceLog] ${n}: ${e}`;if(typeof e=="object")try{return`[TraceLog] ${n}: ${JSON.stringify(e)}`}catch{return`[TraceLog] ${n}: [Unable to serialize error]`}return`[TraceLog] ${n}: ${String(e)}`}return`[TraceLog] ${n}`},a=(n,e,t)=>{const{error:r,data:s,showToClient:i=!1,style:o}=t??{},l=r?Ze(e,r):`[TraceLog] ${e}`,c=n==="error"?"error":n==="warn"?"warn":"log";if(n==="debug"||n==="info"&&!i)return;const d=o!==void 0&&o!=="",g=d?`%c${l}`:l;if(s!==void 0){const m=Z(s);d?console[c](g,o,m):console[c](g,m)}else d?console[c](g,o):console[c](g)},Z=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();if(t.some(o=>i.includes(o))){e[r]="[REDACTED]";continue}s!==null&&typeof s=="object"&&!Array.isArray(s)?e[r]=Z(s):Array.isArray(s)?e[r]=s.map(o=>o!==null&&typeof o=="object"&&!Array.isArray(o)?Z(o):o):e[r]=s}return e};let J,pe;const Je=()=>{typeof window<"u"&&!J&&(J=window.matchMedia("(pointer: coarse)"),pe=window.matchMedia("(hover: none)"))},et=()=>{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;Je();const e=window.innerWidth,t=J?.matches??!1,r=pe?.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}},Ie="background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",ve="background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",M="tlog",H=`${M}:qa_mode`,tt=`${M}:uid`,Ae="tlog_mode",we="qa",ye="qa_off",rt=n=>n?`${M}:${n}:queue`:`${M}:queue`,nt=n=>n?`${M}:${n}:session`:`${M}:session`,st=n=>n?`${M}:${n}:broadcast`:`${M}:broadcast`,it={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},ee={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},Le={LCP:4e3,FCP:3e3,CLS:.25,INP:500,TTFB:1800,LONG_TASK:50},W="needs-improvement",te=(n=W)=>{switch(n){case"all":return{LCP:0,FCP:0,CLS:0,INP:0,TTFB:0,LONG_TASK:0};case"needs-improvement":return ee;case"poor":return Le;default:return ee}},ot=1e3,at=50,re=[/\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],Me=500,Ne=5e3,B=50,lt=B*2,Re=1,ct=1e3,ut=10,be=5e3,dt=6e4,ht=()=>{if(typeof window>"u"||typeof document>"u")return!1;try{const n=new URLSearchParams(window.location.search),e=n.get(Ae),t=sessionStorage.getItem(H);let r=null;if(e===we?(r=!0,sessionStorage.setItem(H,"true"),a("info","QA Mode ACTIVE",{showToClient:!0,style:Ie})):e===ye&&(r=!1,sessionStorage.removeItem(H),a("info","QA Mode DISABLED",{showToClient:!0,style:ve})),e===we||e===ye)try{n.delete(Ae);const s=n.toString(),i=window.location.pathname+(s?"?"+s:"")+window.location.hash;window.history.replaceState({},"",i)}catch{}return r??t==="true"}catch{return!1}},ft=n=>{if(!(typeof window>"u"||typeof document>"u"))try{n?(sessionStorage.setItem(H,"true"),a("info","QA Mode ENABLED",{showToClient:!0,style:Ie})):(sessionStorage.removeItem(H),a("info","QA Mode DISABLED",{showToClient:!0,style:ve}))}catch{a("warn","Cannot set QA mode: sessionStorage unavailable")}},Oe=()=>{const n=new URLSearchParams(window.location.search),e={};return ze.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},Et=()=>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)}),gt=()=>{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}`},Ce=(n,e=!1)=>{try{const t=new URL(n),r=t.protocol==="https:",s=t.protocol==="http:";return r||e&&s}catch{return!1}},mt=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(!Ce(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(!Ce(e,t))throw new Error("Invalid URL");return e}return""},ne=(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([...Qe,...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}},Pe=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 je){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()},se=(n,e=0)=>{if(e>3||n==null)return null;if(typeof n=="string")return Pe(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=>se(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=Pe(i);if(l){const c=se(o,e+1);c!==null&&(t[l]=c)}}return t}return null},St=n=>{if(typeof n!="object"||n===null)return{};try{const e=se(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}`)}},Tt=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 _e(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&&pt(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 q(E.INVALID_ERROR_SAMPLING_RATE,"config");if(n.samplingRate!==void 0&&(typeof n.samplingRate!="number"||n.samplingRate<0||n.samplingRate>1))throw new q(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");if(n.viewport!==void 0&&_t(n.viewport),n.webVitalsMode!==void 0){if(typeof n.webVitalsMode!="string")throw new f(`Invalid webVitalsMode type: ${typeof n.webVitalsMode}. Must be a string`,"config");const e=["all","needs-improvement","poor"];if(!e.includes(n.webVitalsMode))throw new f(`Invalid webVitalsMode: "${n.webVitalsMode}". Must be one of: ${e.join(", ")}`,"config")}if(n.webVitalsThresholds!==void 0){if(typeof n.webVitalsThresholds!="object"||n.webVitalsThresholds===null||Array.isArray(n.webVitalsThresholds))throw new f("webVitalsThresholds must be an object","config");const e=["LCP","FCP","CLS","INP","TTFB","LONG_TASK"];for(const[t,r]of Object.entries(n.webVitalsThresholds)){if(!e.includes(t))throw new f(`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,"config");if(typeof r!="number"||!Number.isFinite(r)||r<0)throw new f(`Invalid Web Vitals threshold value for ${t}: ${r}. Must be a non-negative finite number`,"config")}}}},_t=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")},pt=n=>{if(n){if(n.tracelog&&(!n.tracelog.projectId||typeof n.tracelog.projectId!="string"||n.tracelog.projectId.trim()===""))throw new L(E.INVALID_TRACELOG_PROJECT_ID,"config");if(n.custom){if(!n.custom.collectApiUrl||typeof n.custom.collectApiUrl!="string"||n.custom.collectApiUrl.trim()==="")throw new L(E.INVALID_CUSTOM_API_URL,"config");if(n.custom.allowHttp!==void 0&&typeof n.custom.allowHttp!="boolean")throw new L("allowHttp must be a boolean","config");const e=n.custom.collectApiUrl.trim();if(!e.startsWith("http://")&&!e.startsWith("https://"))throw new L('Custom API URL must start with "http://" or "https://"',"config");if(!(n.custom.allowHttp??!1)&&e.startsWith("http://"))throw new L("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 L(E.INVALID_GOOGLE_ANALYTICS_ID,"config");if(!n.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))throw new L('Google Analytics measurement ID must start with "G-" or "UA-"',"config")}}},It=n=>{Tt(n);const e={...n??{},sessionTimeout:n?.sessionTimeout??9e5,globalMetadata:n?.globalMetadata??{},sensitiveQueryParams:n?.sensitiveQueryParams??[],errorSampling:n?.errorSampling??Re,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},vt=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},De=(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=>vt(o)))return!1;continue}if(r==="object"&&e===0){if(!De(t,e+1))return!1;continue}return!1}}return!0},At=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},Ve=(n,e,t)=>{const r=St(e),s=`${t} "${n}" metadata error`;if(!De(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}},wt=(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=Ve(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 Ve(n,e,t)},yt=(n,e)=>{const t=At(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=wt(n,e,"customEvent");return r.valid||a("error","Event metadata validation failed",{showToClient:!0,data:{eventName:n,error:r.error}}),r};class Lt{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 ie={};class T{get(e){return ie[e]}set(e,t){ie[e]=t}getState(){return{...ie}}}class Mt extends T{storeManager;lastPermanentErrorLog=null;recoveryInProgress=!1;constructor(e){super(),this.storeManager=e}getQueueStorageKey(){const e=this.get("userId")||"anonymous";return rt(e)}sendEventsQueueSync(e){return this.shouldSkipSend()?!0:this.get("config")?.integrations?.custom?.collectApiUrl===G.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===G.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>=dt)&&(a("error",e,{data:{status:t.statusCode,message:t.message}}),this.lastPermanentErrorLog={statusCode:t.statusCode,timestamp:r})}}class Nt extends T{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 Mt(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:g}){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:g});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 _=e;if(!y){if(this.sessionEventCounts.total>=1e3){a("warn","Session event limit reached",{data:{type:_,total:this.sessionEventCounts.total,limit:1e3}});return}const N=this.getTypeLimitForEvent(_);if(N){const Te=this.sessionEventCounts[_];if(Te!==void 0&&Te>=N){a("warn","Session event type limit reached",{data:{type:_,count:Te,limit:N}});return}}}if(_===u.CUSTOM&&o?.name){const N=this.get("config")?.maxSameEventPerMinute??60;if(!this.checkPerEventRateLimit(o.name,N))return}const hr=_===u.SESSION_START,fr=t||this.get("pageUrl"),Se=this.buildEventPayload({type:_,page_url:fr,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:g});if(!(!y&&!this.shouldSample())){if(hr){const N=this.get("sessionId");if(!N){a("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){a("warn","Duplicate session_start detected",{data:{sessionId:N}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(Se)){if(this.get("mode")===C.QA&&_===u.CUSTOM&&o){a("info","Event",{showToClient:!0,data:{name:o.name,...o.metadata&&{metadata:o.metadata}}}),this.emitEvent(Se);return}this.addToQueue(Se),y||(this.sessionEventCounts.total++,this.sessionEventCounts[_]!==void 0&&this.sessionEventCounts[_]++)}}}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:gt(),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&&Oe()&&{utm:Oe()}}}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")===C.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(x.EVENT,e)}emitEventsQueue(e){this.emitter&&this.emitter.emit(x.QUEUE,e)}}class Rt{static getId(e){const t=tt,r=e.getItem(t);if(r)return r;const s=Et();return e.setItem(t,s),s}}class bt extends T{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(st(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 nt(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 Ot extends T{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 bt(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 Ct extends T{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=ne(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=ne(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 Pt extends T{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 g=this.extractTrackingData(o);if(g){const m=this.createCustomEventData(g);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 $e)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 re){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 Dt extends T{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:U.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 g=Date.now();this.processScrollEvent(l,d,g)}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?U.DOWN:U.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),g=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 _=Math.round(l/y*1e3);return m>e.maxDepthReached&&(e.maxDepthReached=m),e.lastScrollPos=i,{depth:m,direction:g,velocity:_,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 Vt extends T{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 kt extends T{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
2
|
window.dataLayer = window.dataLayer || [];
|
|
3
3
|
function gtag(){dataLayer.push(arguments);}
|
|
4
4
|
gtag('js', new Date());
|
|
5
5
|
gtag('config', '${e}', {
|
|
6
6
|
'user_id': '${t}'
|
|
7
7
|
});
|
|
8
|
-
`,document.head.appendChild(r)}}class Pt{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 Dt extends T{eventManager;reportedByNav=new Map;navigationHistory=[];observers=[];vitalThresholds;lastLongTaskSentAt=0;constructor(e){super(),this.eventManager=e,this.vitalThresholds=J(x)}async startTracking(){const e=this.get("config"),t=e?.webVitalsMode??x;this.vitalThresholds=J(t),e?.webVitalsThresholds&&(this.vitalThresholds={...this.vitalThresholds,...e.webVitalsThresholds}),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(()=>dr),o=l=>c=>{const h=Number(c.value.toFixed(2));this.sendVital({type:l,value:h})};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>=rt&&(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>nt){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 Vt extends T{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>it&&(this.errorBurstCounter=0,this.burstWindowStart=e),this.errorBurstCounter++,this.errorBurstCounter>ot)return this.burstBackoffUntil=e+we,a("warn","Error burst detected - entering cooldown",{data:{errorsInWindow:this.errorBurstCounter,cooldownMs:we}}),!1;const r=this.get("config")?.errorSampling??Ae;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>pe?e.slice(0,pe)+"...":e;for(const r of ee){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<ve?(this.recentErrors.set(s,r),!0):(this.recentErrors.set(s,r),this.recentErrors.size>st?(this.recentErrors.clear(),this.recentErrors.set(s,r),!1):(this.recentErrors.size>W&&this.pruneOldErrors(),!1))}pruneOldErrors(){const e=Date.now();for(const[s,i]of this.recentErrors.entries())e-i>ve&&this.recentErrors.delete(s);if(this.recentErrors.size<=W)return;const t=Array.from(this.recentErrors.entries()).sort((s,i)=>s[1]-i[1]),r=this.recentErrors.size-W;for(let s=0;s<r;s+=1){const i=t[s];i&&this.recentErrors.delete(i[0])}}}class kt extends T{isInitialized=!1;suppressNextScrollTimer=null;emitter=new vt;managers={};handlers={};integrations={};get initialized(){return this.isInitialized}async init(e={}){if(!this.isInitialized){this.managers.storage=new Pt;try{this.setupState(e),await this.setupIntegrations(),this.managers.event=new wt(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}=pt(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=yt.getId(this.managers.storage);this.set("userId",t);const r=ht(e);this.set("collectApiUrl",r);const s=Ke();this.set("device",s);const i=te(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i);const o=ct()?b.QA:void 0;o&&this.set("mode",o)}async setupIntegrations(){if(this.get("config").integrations?.googleAnalytics?.measurementId?.trim())try{this.integrations.googleAnalytics=new bt,await this.integrations.googleAnalytics.initialize()}catch{this.integrations.googleAnalytics=void 0}}initializeHandlers(){this.handlers.session=new Mt(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 Nt(this.managers.event,e),this.handlers.pageView.startTracking(),this.handlers.click=new Rt(this.managers.event),this.handlers.click.startTracking(),this.handlers.scroll=new Ot(this.managers.event),this.handlers.scroll.startTracking(),this.handlers.performance=new Dt(this.managers.event),this.handlers.performance.startTracking().catch(t=>{a("warn","Failed to start performance tracking",{error:t})}),this.handlers.error=new Vt(this.managers.event),this.handlers.error.startTracking(),this.get("config").viewport&&(this.handlers.viewport=new Ct(this.managers.event),this.handlers.viewport.startTracking())}}const O=[];let g=null,D=!1,X=!1;const Ht=async n=>{if(!(typeof window>"u"||typeof document>"u")&&!window.__traceLogDisabled&&!g&&!D){D=!0;try{const e=Tt(n??{}),t=new kt;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}}},Ut=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(X)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");g.sendCustomEvent(n,e)}},Ft=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g||D){O.push({event:n,callback:e});return}g.on(n,e)}},Gt=(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)}},xt=()=>typeof window>"u"||typeof document>"u"?!1:g!==null,Wt=()=>{if(!(typeof window>"u"||typeof document>"u")){if(X)throw new Error("[TraceLog] Destroy operation already in progress");if(!g)throw new Error("[TraceLog] App not initialized");X=!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{X=!1}}},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},Bt={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},$t={MOBILE_MAX_WIDTH:768,TABLET_MAX_WIDTH:1024,MOBILE_PERFORMANCE_FACTOR:1.5,TABLET_PERFORMANCE_FACTOR:1.2},zt={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},Yt={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},jt={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},Qt={MIN_SEGMENT_SIZE:10,MIN_COHORT_SIZE:5,COHORT_ANALYSIS_DAYS:[1,3,7,14,30],MIN_FUNNEL_EVENTS:20},Kt={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},qt={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},Zt={PAGE_URL_EXCLUDED:"excluded",PAGE_URL_UNKNOWN:"unknown"},Jt={init:Ht,event:Ut,on:Ft,off:Gt,isInitialized:xt,destroy:Wt};var se,Ce=-1,V=function(n){addEventListener("pageshow",(function(e){e.persisted&&(Ce=e.timeStamp,n(e))}),!0)},ie=function(){var n=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},B=function(){var n=ie();return n&&n.activationStart||0},I=function(n,e){var t=ie(),r="navigate";return Ce>=0?r="back-forward-cache":t&&(document.prerendering||B()>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))}},oe=function(n){requestAnimationFrame((function(){return requestAnimationFrame((function(){return n()}))}))},$=function(n){document.addEventListener("visibilitychange",(function(){document.visibilityState==="hidden"&&n()}))},ae=function(n){var e=!1;return function(){e||(n(),e=!0)}},k=-1,be=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},z=function(n){document.visibilityState==="hidden"&&k>-1&&(k=n.type==="visibilitychange"?n.timeStamp:0,er())},Pe=function(){addEventListener("visibilitychange",z,!0),addEventListener("prerenderingchange",z,!0)},er=function(){removeEventListener("visibilitychange",z,!0),removeEventListener("prerenderingchange",z,!0)},De=function(){return k<0&&(k=be(),Pe(),V((function(){setTimeout((function(){k=be(),Pe()}),0)}))),{get firstHiddenTime(){return k}}},Y=function(n){document.prerendering?addEventListener("prerenderingchange",(function(){return n()}),!0):n()},le=[1800,3e3],Ve=function(n,e){e=e||{},Y((function(){var t,r=De(),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-B(),0),s.entries.push(l),t(!0)))}))}));i&&(t=p(n,s,le,e.reportAllChanges),V((function(o){s=I("FCP"),t=p(n,s,le,e.reportAllChanges),oe((function(){s.value=performance.now()-o.timeStamp,t(!0)}))})))}))},ce=[.1,.25],tr=function(n,e){e=e||{},Ve(ae((function(){var t,r=I("CLS",0),s=0,i=[],o=function(c){c.forEach((function(h){if(!h.hadRecentInput){var _=i[0],m=i[i.length-1];s&&h.startTime-m.startTime<1e3&&h.startTime-_.startTime<5e3?(s+=h.value,i.push(h)):(s=h.value,i=[h])}})),s>r.value&&(r.value=s,r.entries=i,t())},l=U("layout-shift",o);l&&(t=p(n,r,ce,e.reportAllChanges),$((function(){o(l.takeRecords()),t(!0)})),V((function(){s=0,r=I("CLS",0),t=p(n,r,ce,e.reportAllChanges),oe((function(){return t()}))})),setTimeout(t,0))})))},ke=0,ue=1/0,j=0,rr=function(n){n.forEach((function(e){e.interactionId&&(ue=Math.min(ue,e.interactionId),j=Math.max(j,e.interactionId),ke=j?(j-ue)/7+1:0)}))},He=function(){return se?ke:performance.interactionCount||0},nr=function(){"interactionCount"in performance||se||(se=U("event",rr,{type:"event",buffered:!0,durationThreshold:0}))},v=[],Q=new Map,Ue=0,sr=function(){var n=Math.min(v.length-1,Math.floor((He()-Ue)/50));return v[n]},ir=[],or=function(n){if(ir.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)}))}}},Fe=function(n){var e=self.requestIdleCallback||self.setTimeout,t=-1;return n=ae(n),document.visibilityState==="hidden"?n():(t=e(n),$(n)),t},de=[200,500],ar=function(n,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},Y((function(){var t;nr();var r,s=I("INP"),i=function(l){Fe((function(){l.forEach(or);var c=sr();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,de,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),$((function(){i(o.takeRecords()),r(!0)})),V((function(){Ue=He(),v.length=0,Q.clear(),s=I("INP"),r=p(n,s,de,e.reportAllChanges)})))})))},he=[2500,4e3],Ee={},lr=function(n,e){e=e||{},Y((function(){var t,r=De(),s=I("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach((function(h){h.startTime<r.firstHiddenTime&&(s.value=Math.max(h.startTime-B(),0),s.entries=[h],t())}))},o=U("largest-contentful-paint",i);if(o){t=p(n,s,he,e.reportAllChanges);var l=ae((function(){Ee[s.id]||(i(o.takeRecords()),o.disconnect(),Ee[s.id]=!0,t(!0))}));["keydown","click"].forEach((function(c){addEventListener(c,(function(){return Fe(l)}),{once:!0,capture:!0})})),$(l),V((function(c){s=I("LCP"),t=p(n,s,he,e.reportAllChanges),oe((function(){s.value=performance.now()-c.timeStamp,Ee[s.id]=!0,t(!0)}))}))}}))},fe=[800,1800],cr=function n(e){document.prerendering?Y((function(){return n(e)})):document.readyState!=="complete"?addEventListener("load",(function(){return n(e)}),!0):setTimeout(e,0)},ur=function(n,e){e=e||{};var t=I("TTFB"),r=p(n,t,fe,e.reportAllChanges);cr((function(){var s=ie();s&&(t.value=Math.max(s.responseStart-B(),0),t.entries=[s],r(!0),V((function(){t=I("TTFB",0),(r=p(n,t,fe,e.reportAllChanges))(!0)})))}))};const dr=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:ce,FCPThresholds:le,INPThresholds:de,LCPThresholds:he,TTFBThresholds:fe,onCLS:tr,onFCP:Ve,onINP:ar,onLCP:lr,onTTFB:ur},Symbol.toStringTag,{value:"Module"}));d.ANALYTICS_QUERY_LIMITS=Kt,d.ANOMALY_DETECTION=qt,d.AppConfigValidationError=E,d.CONTENT_ANALYTICS=zt,d.DEFAULT_WEB_VITALS_MODE=x,d.DEVICE_ANALYTICS=$t,d.DeviceType=w,d.ENGAGEMENT_THRESHOLDS=Xt,d.EmitterEvent=G,d.ErrorType=C,d.EventType=u,d.INSIGHT_THRESHOLDS=Yt,d.InitializationTimeoutError=ze,d.IntegrationValidationError=L,d.MAX_ARRAY_LENGTH=100,d.MAX_CUSTOM_EVENT_ARRAY_SIZE=10,d.MAX_CUSTOM_EVENT_KEYS=10,d.MAX_CUSTOM_EVENT_NAME_LENGTH=120,d.MAX_CUSTOM_EVENT_STRING_SIZE=8192,d.MAX_METADATA_NESTING_DEPTH=1,d.MAX_NESTED_OBJECT_KEYS=20,d.MAX_STRING_LENGTH=1e3,d.MAX_STRING_LENGTH_IN_ARRAY=500,d.Mode=b,d.PII_PATTERNS=ee,d.PermanentError=R,d.SEGMENTATION_ANALYTICS=Qt,d.SESSION_ANALYTICS=Bt,d.SPECIAL_PAGE_URLS=Zt,d.SamplingRateValidationError=K,d.ScrollDirection=H,d.SessionTimeoutValidationError=Te,d.SpecialApiUrl=F,d.TEMPORAL_ANALYSIS=jt,d.TraceLogValidationError=P,d.WEB_VITALS_GOOD_THRESHOLDS=tt,d.WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS=Z,d.WEB_VITALS_POOR_THRESHOLDS=Ie,d.getWebVitalsThresholds=J,d.isPrimaryScrollEvent=Be,d.isSecondaryScrollEvent=$e,d.tracelog=Jt,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);
|
|
8
|
+
`,document.head.appendChild(r)}}class Ut{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 Ht extends T{eventManager;reportedByNav=new Map;navigationHistory=[];observers=[];vitalThresholds;lastLongTaskSentAt=0;constructor(e){super(),this.eventManager=e,this.vitalThresholds=te(W)}async startTracking(){const e=this.get("config"),t=e?.webVitalsMode??W;this.vitalThresholds=te(t),e?.webVitalsThresholds&&(this.vitalThresholds={...this.vitalThresholds,...e.webVitalsThresholds}),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(()=>dr),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>=ot&&(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>at){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 Ft extends T{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>ct&&(this.errorBurstCounter=0,this.burstWindowStart=e),this.errorBurstCounter++,this.errorBurstCounter>ut)return this.burstBackoffUntil=e+be,a("warn","Error burst detected - entering cooldown",{data:{errorsInWindow:this.errorBurstCounter,cooldownMs:be}}),!1;const r=this.get("config")?.errorSampling??Re;return Math.random()<r}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");this.shouldSuppressError(O.JS_ERROR,t)||this.eventManager.track({type:u.ERROR,error_data:{type:O.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(O.PROMISE_REJECTION,r)||this.eventManager.track({type:u.ERROR,error_data:{type:O.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>Me?e.slice(0,Me)+"...":e;for(const r of re){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<Ne?(this.recentErrors.set(s,r),!0):(this.recentErrors.set(s,r),this.recentErrors.size>lt?(this.recentErrors.clear(),this.recentErrors.set(s,r),!1):(this.recentErrors.size>B&&this.pruneOldErrors(),!1))}pruneOldErrors(){const e=Date.now();for(const[s,i]of this.recentErrors.entries())e-i>Ne&&this.recentErrors.delete(s);if(this.recentErrors.size<=B)return;const t=Array.from(this.recentErrors.entries()).sort((s,i)=>s[1]-i[1]),r=this.recentErrors.size-B;for(let s=0;s<r;s+=1){const i=t[s];i&&this.recentErrors.delete(i[0])}}}class Gt extends T{isInitialized=!1;suppressNextScrollTimer=null;emitter=new Lt;managers={};handlers={};integrations={};get initialized(){return this.isInitialized}async init(e={}){if(!this.isInitialized){this.managers.storage=new Ut;try{this.setupState(e),await this.setupIntegrations(),this.managers.event=new Nt(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}=yt(e,t);if(!r){if(this.get("mode")===C.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=Rt.getId(this.managers.storage);this.set("userId",t);const r=mt(e);this.set("collectApiUrl",r);const s=et();this.set("device",s);const i=ne(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i);const o=ht()?C.QA:void 0;o&&this.set("mode",o)}async setupIntegrations(){if(this.get("config").integrations?.googleAnalytics?.measurementId?.trim())try{this.integrations.googleAnalytics=new kt,await this.integrations.googleAnalytics.initialize()}catch{this.integrations.googleAnalytics=void 0}}initializeHandlers(){this.handlers.session=new Ot(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 Ct(this.managers.event,e),this.handlers.pageView.startTracking(),this.handlers.click=new Pt(this.managers.event),this.handlers.click.startTracking(),this.handlers.scroll=new Dt(this.managers.event),this.handlers.scroll.startTracking(),this.handlers.performance=new Ht(this.managers.event),this.handlers.performance.startTracking().catch(t=>{a("warn","Failed to start performance tracking",{error:t})}),this.handlers.error=new Ft(this.managers.event),this.handlers.error.startTracking(),this.get("config").viewport&&(this.handlers.viewport=new Vt(this.managers.event),this.handlers.viewport.startTracking())}}const b=[];let S=null,D=!1,X=!1;const xt=async n=>{if(!(typeof window>"u"||typeof document>"u")&&!window.__traceLogDisabled&&!S&&!D){D=!0;try{const e=It(n??{}),t=new Gt;try{b.forEach(({event:i,callback:o})=>{t.on(i,o)}),b.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]),S=t}catch(r){try{t.destroy(!0)}catch(s){a("error","Failed to cleanup partially initialized app",{error:s})}throw r}}catch(e){throw S=null,e}finally{D=!1}}},Wt=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!S)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(X)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");S.sendCustomEvent(n,e)}},Bt=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!S||D){b.push({event:n,callback:e});return}S.on(n,e)}},Xt=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!S){const t=b.findIndex(r=>r.event===n&&r.callback===e);t!==-1&&b.splice(t,1);return}S.off(n,e)}},$t=()=>typeof window>"u"||typeof document>"u"?!1:S!==null,zt=()=>{if(!(typeof window>"u"||typeof document>"u")){if(X)throw new Error("[TraceLog] Destroy operation already in progress");if(!S)throw new Error("[TraceLog] App not initialized");X=!0;try{S.destroy(),S=null,D=!1,b.length=0}catch(n){S=null,D=!1,b.length=0,a("warn","Error during destroy, forced cleanup completed",{error:n})}finally{X=!1}}},Qt=n=>{typeof window>"u"||typeof document>"u"||ft(n)},jt={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},Yt={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,MIN_EVENTS_FOR_DURATION:2},Kt={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},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},Zt={PAGE_URL_EXCLUDED:"excluded",PAGE_URL_UNKNOWN:"unknown"},Jt={init:xt,event:Wt,on:Bt,off:Xt,isInitialized:$t,destroy:zt,setQaMode:Qt};var oe,ke=-1,V=function(n){addEventListener("pageshow",(function(e){e.persisted&&(ke=e.timeStamp,n(e))}),!0)},ae=function(){var n=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},$=function(){var n=ae();return n&&n.activationStart||0},p=function(n,e){var t=ae(),r="navigate";return ke>=0?r="back-forward-cache":t&&(document.prerendering||$()>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}},F=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{}},I=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))}},le=function(n){requestAnimationFrame((function(){return requestAnimationFrame((function(){return n()}))}))},z=function(n){document.addEventListener("visibilitychange",(function(){document.visibilityState==="hidden"&&n()}))},ce=function(n){var e=!1;return function(){e||(n(),e=!0)}},k=-1,Ue=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},Q=function(n){document.visibilityState==="hidden"&&k>-1&&(k=n.type==="visibilitychange"?n.timeStamp:0,er())},He=function(){addEventListener("visibilitychange",Q,!0),addEventListener("prerenderingchange",Q,!0)},er=function(){removeEventListener("visibilitychange",Q,!0),removeEventListener("prerenderingchange",Q,!0)},Fe=function(){return k<0&&(k=Ue(),He(),V((function(){setTimeout((function(){k=Ue(),He()}),0)}))),{get firstHiddenTime(){return k}}},j=function(n){document.prerendering?addEventListener("prerenderingchange",(function(){return n()}),!0):n()},ue=[1800,3e3],Ge=function(n,e){e=e||{},j((function(){var t,r=Fe(),s=p("FCP"),i=F("paint",(function(o){o.forEach((function(l){l.name==="first-contentful-paint"&&(i.disconnect(),l.startTime<r.firstHiddenTime&&(s.value=Math.max(l.startTime-$(),0),s.entries.push(l),t(!0)))}))}));i&&(t=I(n,s,ue,e.reportAllChanges),V((function(o){s=p("FCP"),t=I(n,s,ue,e.reportAllChanges),le((function(){s.value=performance.now()-o.timeStamp,t(!0)}))})))}))},de=[.1,.25],tr=function(n,e){e=e||{},Ge(ce((function(){var t,r=p("CLS",0),s=0,i=[],o=function(c){c.forEach((function(d){if(!d.hadRecentInput){var g=i[0],m=i[i.length-1];s&&d.startTime-m.startTime<1e3&&d.startTime-g.startTime<5e3?(s+=d.value,i.push(d)):(s=d.value,i=[d])}})),s>r.value&&(r.value=s,r.entries=i,t())},l=F("layout-shift",o);l&&(t=I(n,r,de,e.reportAllChanges),z((function(){o(l.takeRecords()),t(!0)})),V((function(){s=0,r=p("CLS",0),t=I(n,r,de,e.reportAllChanges),le((function(){return t()}))})),setTimeout(t,0))})))},xe=0,he=1/0,Y=0,rr=function(n){n.forEach((function(e){e.interactionId&&(he=Math.min(he,e.interactionId),Y=Math.max(Y,e.interactionId),xe=Y?(Y-he)/7+1:0)}))},We=function(){return oe?xe:performance.interactionCount||0},nr=function(){"interactionCount"in performance||oe||(oe=F("event",rr,{type:"event",buffered:!0,durationThreshold:0}))},v=[],K=new Map,Be=0,sr=function(){var n=Math.min(v.length-1,Math.floor((We()-Be)/50));return v[n]},ir=[],or=function(n){if(ir.forEach((function(s){return s(n)})),n.interactionId||n.entryType==="first-input"){var e=v[v.length-1],t=K.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]};K.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 K.delete(s.id)}))}}},Xe=function(n){var e=self.requestIdleCallback||self.setTimeout,t=-1;return n=ce(n),document.visibilityState==="hidden"?n():(t=e(n),z(n)),t},fe=[200,500],ar=function(n,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},j((function(){var t;nr();var r,s=p("INP"),i=function(l){Xe((function(){l.forEach(or);var c=sr();c&&c.latency!==s.value&&(s.value=c.latency,s.entries=c.entries,r())}))},o=F("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});r=I(n,s,fe,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),z((function(){i(o.takeRecords()),r(!0)})),V((function(){Be=We(),v.length=0,K.clear(),s=p("INP"),r=I(n,s,fe,e.reportAllChanges)})))})))},Ee=[2500,4e3],ge={},lr=function(n,e){e=e||{},j((function(){var t,r=Fe(),s=p("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach((function(d){d.startTime<r.firstHiddenTime&&(s.value=Math.max(d.startTime-$(),0),s.entries=[d],t())}))},o=F("largest-contentful-paint",i);if(o){t=I(n,s,Ee,e.reportAllChanges);var l=ce((function(){ge[s.id]||(i(o.takeRecords()),o.disconnect(),ge[s.id]=!0,t(!0))}));["keydown","click"].forEach((function(c){addEventListener(c,(function(){return Xe(l)}),{once:!0,capture:!0})})),z(l),V((function(c){s=p("LCP"),t=I(n,s,Ee,e.reportAllChanges),le((function(){s.value=performance.now()-c.timeStamp,ge[s.id]=!0,t(!0)}))}))}}))},me=[800,1800],cr=function n(e){document.prerendering?j((function(){return n(e)})):document.readyState!=="complete"?addEventListener("load",(function(){return n(e)}),!0):setTimeout(e,0)},ur=function(n,e){e=e||{};var t=p("TTFB"),r=I(n,t,me,e.reportAllChanges);cr((function(){var s=ae();s&&(t.value=Math.max(s.responseStart-$(),0),t.entries=[s],r(!0),V((function(){t=p("TTFB",0),(r=I(n,t,me,e.reportAllChanges))(!0)})))}))};const dr=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:de,FCPThresholds:ue,INPThresholds:fe,LCPThresholds:Ee,TTFBThresholds:me,onCLS:tr,onFCP:Ge,onINP:ar,onLCP:lr,onTTFB:ur},Symbol.toStringTag,{value:"Module"}));h.ANALYTICS_QUERY_LIMITS=qt,h.AppConfigValidationError=f,h.DEFAULT_SESSION_TIMEOUT=9e5,h.DEFAULT_WEB_VITALS_MODE=W,h.DeviceType=w,h.ENGAGEMENT_THRESHOLDS=jt,h.EmitterEvent=x,h.ErrorType=O,h.EventType=u,h.INSIGHT_THRESHOLDS=Kt,h.InitializationTimeoutError=qe,h.IntegrationValidationError=L,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=C,h.PII_PATTERNS=re,h.PermanentError=R,h.SESSION_ANALYTICS=Yt,h.SPECIAL_PAGE_URLS=Zt,h.SamplingRateValidationError=q,h.ScrollDirection=U,h.SessionTimeoutValidationError=_e,h.SpecialApiUrl=G,h.TraceLogValidationError=P,h.WEB_VITALS_GOOD_THRESHOLDS=it,h.WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS=ee,h.WEB_VITALS_POOR_THRESHOLDS=Le,h.getWebVitalsThresholds=te,h.isPrimaryScrollEvent=Ye,h.isSecondaryScrollEvent=Ke,h.tracelog=Jt,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);
|