@tracelog/lib 0.11.5 → 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 +178 -107
- package/dist/browser/tracelog.esm.js +805 -731
- 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 +218 -95
- package/dist/public-api.cjs.map +1 -1
- package/dist/public-api.d.mts +128 -98
- package/dist/public-api.d.ts +128 -98
- package/dist/public-api.js +212 -89
- package/dist/public-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
const sr = 9e5;
|
|
2
|
+
const nr = 120, ir = 8192, or = 10, ar = 10, lr = 20, cr = 1;
|
|
3
|
+
const ur = 1e3, dr = 500, hr = 100;
|
|
4
|
+
const w = "data-tlog", $e = [
|
|
4
5
|
"button",
|
|
5
6
|
"a",
|
|
6
7
|
'input[type="button"]',
|
|
@@ -32,7 +33,7 @@ const A = "data-tlog", He = [
|
|
|
32
33
|
".menu-item",
|
|
33
34
|
"[data-testid]",
|
|
34
35
|
'[tabindex="0"]'
|
|
35
|
-
],
|
|
36
|
+
], Xe = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"], ze = [
|
|
36
37
|
"token",
|
|
37
38
|
"auth",
|
|
38
39
|
"key",
|
|
@@ -48,7 +49,7 @@ const A = "data-tlog", He = [
|
|
|
48
49
|
"code",
|
|
49
50
|
"otp"
|
|
50
51
|
];
|
|
51
|
-
const
|
|
52
|
+
const f = {
|
|
52
53
|
INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",
|
|
53
54
|
INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1",
|
|
54
55
|
INVALID_ERROR_SAMPLING_RATE: "Error sampling must be between 0 and 1",
|
|
@@ -71,7 +72,7 @@ const h = {
|
|
|
71
72
|
INVALID_VIEWPORT_MIN_DWELL_TIME: "Viewport minDwellTime must be a non-negative number",
|
|
72
73
|
INVALID_VIEWPORT_COOLDOWN_PERIOD: "Viewport cooldownPeriod must be a non-negative number",
|
|
73
74
|
INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS: "Viewport maxTrackedElements must be a positive number"
|
|
74
|
-
},
|
|
75
|
+
}, Qe = [
|
|
75
76
|
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
76
77
|
/javascript:/gi,
|
|
77
78
|
/on\w+\s*=/gi,
|
|
@@ -79,95 +80,150 @@ const h = {
|
|
|
79
80
|
/<embed\b[^>]*>/gi,
|
|
80
81
|
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
|
|
81
82
|
];
|
|
82
|
-
var
|
|
83
|
+
var Z = /* @__PURE__ */ ((s) => (s.Localhost = "localhost:8080", s.Fail = "localhost:9999", s))(Z || {}), A = /* @__PURE__ */ ((s) => (s.Mobile = "mobile", s.Tablet = "tablet", s.Desktop = "desktop", s.Unknown = "unknown", s))(A || {}), J = /* @__PURE__ */ ((s) => (s.EVENT = "event", s.QUEUE = "queue", s))(J || {});
|
|
83
84
|
class R extends Error {
|
|
84
85
|
constructor(e, t) {
|
|
85
86
|
super(e), this.statusCode = t, this.name = "PermanentError", Error.captureStackTrace && Error.captureStackTrace(this, R);
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
var u = /* @__PURE__ */ ((
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
function ir(n) {
|
|
93
|
-
return n.type === u.SCROLL && "scroll_data" in n && n.scroll_data.is_primary === !1;
|
|
94
|
-
}
|
|
95
|
-
class V extends Error {
|
|
89
|
+
var u = /* @__PURE__ */ ((s) => (s.PAGE_VIEW = "page_view", s.CLICK = "click", s.SCROLL = "scroll", s.SESSION_START = "session_start", s.SESSION_END = "session_end", s.CUSTOM = "custom", s.WEB_VITALS = "web_vitals", s.ERROR = "error", s.VIEWPORT_VISIBLE = "viewport_visible", s))(u || {}), x = /* @__PURE__ */ ((s) => (s.UP = "up", s.DOWN = "down", s))(x || {}), P = /* @__PURE__ */ ((s) => (s.JS_ERROR = "js_error", s.PROMISE_REJECTION = "promise_rejection", s))(P || {}), V = /* @__PURE__ */ ((s) => (s.QA = "qa", s))(V || {});
|
|
90
|
+
const fr = (s) => s.type === u.SCROLL && "scroll_data" in s && s.scroll_data.is_primary === !0, Er = (s) => s.type === u.SCROLL && "scroll_data" in s && s.scroll_data.is_primary === !1;
|
|
91
|
+
class k extends Error {
|
|
96
92
|
constructor(e, t, r) {
|
|
97
93
|
super(e), this.errorCode = t, this.layer = r, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
|
|
98
94
|
}
|
|
99
95
|
}
|
|
100
|
-
class
|
|
96
|
+
class h extends k {
|
|
101
97
|
constructor(e, t = "config") {
|
|
102
98
|
super(e, "APP_CONFIG_INVALID", t);
|
|
103
99
|
}
|
|
104
100
|
}
|
|
105
|
-
class
|
|
101
|
+
class je extends k {
|
|
106
102
|
constructor(e, t = "config") {
|
|
107
103
|
super(e, "SESSION_TIMEOUT_INVALID", t);
|
|
108
104
|
}
|
|
109
105
|
}
|
|
110
|
-
class
|
|
106
|
+
class Ee extends k {
|
|
111
107
|
constructor(e, t = "config") {
|
|
112
108
|
super(e, "SAMPLING_RATE_INVALID", t);
|
|
113
109
|
}
|
|
114
110
|
}
|
|
115
|
-
class M extends
|
|
111
|
+
class M extends k {
|
|
116
112
|
constructor(e, t = "config") {
|
|
117
113
|
super(e, "INTEGRATION_INVALID", t);
|
|
118
114
|
}
|
|
119
115
|
}
|
|
120
|
-
class
|
|
116
|
+
class gr extends k {
|
|
121
117
|
constructor(e, t, r = "runtime") {
|
|
122
118
|
super(e, "INITIALIZATION_TIMEOUT", r), this.timeoutMs = t;
|
|
123
119
|
}
|
|
124
120
|
}
|
|
125
|
-
const
|
|
121
|
+
const Ke = (s, e) => {
|
|
126
122
|
if (e) {
|
|
127
123
|
if (e instanceof Error) {
|
|
128
124
|
const t = e.message.replace(/\s+at\s+.*$/gm, "").replace(/\(.*?:\d+:\d+\)/g, "");
|
|
129
|
-
return `[TraceLog] ${
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
125
|
+
return `[TraceLog] ${s}: ${t}`;
|
|
126
|
+
}
|
|
127
|
+
if (e instanceof Error)
|
|
128
|
+
return `[TraceLog] ${s}: ${e.message}`;
|
|
129
|
+
if (typeof e == "string")
|
|
130
|
+
return `[TraceLog] ${s}: ${e}`;
|
|
131
|
+
if (typeof e == "object")
|
|
132
|
+
try {
|
|
133
|
+
return `[TraceLog] ${s}: ${JSON.stringify(e)}`;
|
|
134
|
+
} catch {
|
|
135
|
+
return `[TraceLog] ${s}: [Unable to serialize error]`;
|
|
136
|
+
}
|
|
137
|
+
return `[TraceLog] ${s}: ${String(e)}`;
|
|
138
|
+
}
|
|
139
|
+
return `[TraceLog] ${s}`;
|
|
140
|
+
}, a = (s, e, t) => {
|
|
141
|
+
const { error: r, data: n, showToClient: i = !1, style: o } = t ?? {}, l = r ? Ke(e, r) : `[TraceLog] ${e}`, c = s === "error" ? "error" : s === "warn" ? "warn" : "log";
|
|
142
|
+
if (s === "debug" || s === "info" && !i)
|
|
143
|
+
return;
|
|
144
|
+
const d = o !== void 0 && o !== "", E = d ? `%c${l}` : l;
|
|
145
|
+
if (n !== void 0) {
|
|
146
|
+
const g = ee(n);
|
|
147
|
+
d ? console[c](E, o, g) : console[c](E, g);
|
|
148
|
+
} else
|
|
149
|
+
d ? console[c](E, o) : console[c](E);
|
|
150
|
+
}, ee = (s) => {
|
|
142
151
|
const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
|
|
143
|
-
for (const [r,
|
|
152
|
+
for (const [r, n] of Object.entries(s)) {
|
|
144
153
|
const i = r.toLowerCase();
|
|
145
|
-
t.some((o) => i.includes(o))
|
|
154
|
+
if (t.some((o) => i.includes(o))) {
|
|
155
|
+
e[r] = "[REDACTED]";
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
n !== null && typeof n == "object" && !Array.isArray(n) ? e[r] = ee(n) : Array.isArray(n) ? e[r] = n.map(
|
|
159
|
+
(o) => o !== null && typeof o == "object" && !Array.isArray(o) ? ee(o) : o
|
|
160
|
+
) : e[r] = n;
|
|
146
161
|
}
|
|
147
162
|
return e;
|
|
148
163
|
};
|
|
149
|
-
let
|
|
150
|
-
const
|
|
151
|
-
typeof window < "u" && !
|
|
152
|
-
},
|
|
164
|
+
let te, Re;
|
|
165
|
+
const Ye = () => {
|
|
166
|
+
typeof window < "u" && !te && (te = window.matchMedia("(pointer: coarse)"), Re = window.matchMedia("(hover: none)"));
|
|
167
|
+
}, qe = () => {
|
|
153
168
|
try {
|
|
154
|
-
const
|
|
155
|
-
if (
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
const e = window.innerWidth, t =
|
|
159
|
-
return e <= 767 || o &&
|
|
160
|
-
} catch (
|
|
161
|
-
return a("warn", "Device detection failed, defaulting to desktop", { error:
|
|
162
|
-
}
|
|
163
|
-
}, L = "tlog",
|
|
164
|
-
LCP:
|
|
169
|
+
const s = navigator;
|
|
170
|
+
if (s.userAgentData && typeof s.userAgentData.mobile == "boolean")
|
|
171
|
+
return s.userAgentData.platform && /ipad|tablet/i.test(s.userAgentData.platform) ? A.Tablet : s.userAgentData.mobile ? A.Mobile : A.Desktop;
|
|
172
|
+
Ye();
|
|
173
|
+
const e = window.innerWidth, t = te?.matches ?? !1, r = Re?.matches ?? !1, n = "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);
|
|
174
|
+
return e <= 767 || o && n ? A.Mobile : e >= 768 && e <= 1024 || l || t && r && n ? A.Tablet : A.Desktop;
|
|
175
|
+
} catch (s) {
|
|
176
|
+
return a("warn", "Device detection failed, defaulting to desktop", { error: s }), A.Desktop;
|
|
177
|
+
}
|
|
178
|
+
}, be = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", Ce = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;", L = "tlog", D = `${L}:qa_mode`, Ze = `${L}:uid`, ge = "tlog_mode", me = "qa", Se = "qa_off", Je = (s) => s ? `${L}:${s}:queue` : `${L}:queue`, et = (s) => s ? `${L}:${s}:session` : `${L}:session`, tt = (s) => s ? `${L}:${s}:broadcast` : `${L}:broadcast`, mr = {
|
|
179
|
+
LCP: 2500,
|
|
180
|
+
// Good: ≤ 2.5s
|
|
165
181
|
FCP: 1800,
|
|
166
|
-
|
|
182
|
+
// Good: ≤ 1.8s
|
|
183
|
+
CLS: 0.1,
|
|
184
|
+
// Good: ≤ 0.1
|
|
185
|
+
INP: 200,
|
|
186
|
+
// Good: ≤ 200ms
|
|
187
|
+
TTFB: 800,
|
|
188
|
+
// Good: ≤ 800ms
|
|
189
|
+
LONG_TASK: 50
|
|
190
|
+
}, Te = {
|
|
191
|
+
LCP: 2500,
|
|
192
|
+
// Needs improvement: > 2.5s (same as good boundary)
|
|
193
|
+
FCP: 1800,
|
|
194
|
+
// Needs improvement: > 1.8s
|
|
195
|
+
CLS: 0.1,
|
|
196
|
+
// Needs improvement: > 0.1
|
|
167
197
|
INP: 200,
|
|
198
|
+
// Needs improvement: > 200ms
|
|
168
199
|
TTFB: 800,
|
|
200
|
+
// Needs improvement: > 800ms
|
|
169
201
|
LONG_TASK: 50
|
|
170
|
-
},
|
|
202
|
+
}, rt = {
|
|
203
|
+
LCP: 4e3,
|
|
204
|
+
// Poor: > 4s
|
|
205
|
+
FCP: 3e3,
|
|
206
|
+
// Poor: > 3s
|
|
207
|
+
CLS: 0.25,
|
|
208
|
+
// Poor: > 0.25
|
|
209
|
+
INP: 500,
|
|
210
|
+
// Poor: > 500ms
|
|
211
|
+
TTFB: 1800,
|
|
212
|
+
// Poor: > 1800ms
|
|
213
|
+
LONG_TASK: 50
|
|
214
|
+
}, re = "needs-improvement", pe = (s = re) => {
|
|
215
|
+
switch (s) {
|
|
216
|
+
case "all":
|
|
217
|
+
return { LCP: 0, FCP: 0, CLS: 0, INP: 0, TTFB: 0, LONG_TASK: 0 };
|
|
218
|
+
// Track everything
|
|
219
|
+
case "needs-improvement":
|
|
220
|
+
return Te;
|
|
221
|
+
case "poor":
|
|
222
|
+
return rt;
|
|
223
|
+
default:
|
|
224
|
+
return Te;
|
|
225
|
+
}
|
|
226
|
+
}, st = 1e3, nt = 50, Oe = [
|
|
171
227
|
// Email addresses
|
|
172
228
|
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,
|
|
173
229
|
// US Phone numbers (various formats)
|
|
@@ -182,38 +238,56 @@ const Xe = () => {
|
|
|
182
238
|
/Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,
|
|
183
239
|
// Passwords in connection strings (protocol://user:password@host)
|
|
184
240
|
/:\/\/[^:/]+:([^@]+)@/gi
|
|
185
|
-
],
|
|
186
|
-
if (
|
|
187
|
-
return !
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
241
|
+
], _e = 500, Ie = 5e3, F = 50, it = F * 2, Pe = 1, ot = 1e3, at = 10, ve = 5e3, lt = 6e4, ct = () => {
|
|
242
|
+
if (typeof window > "u" || typeof document > "u")
|
|
243
|
+
return !1;
|
|
244
|
+
try {
|
|
245
|
+
const s = new URLSearchParams(window.location.search), e = s.get(ge), t = sessionStorage.getItem(D);
|
|
246
|
+
let r = null;
|
|
247
|
+
if (e === me ? (r = !0, sessionStorage.setItem(D, "true"), a("info", "QA Mode ACTIVE", {
|
|
248
|
+
showToClient: !0,
|
|
249
|
+
style: be
|
|
250
|
+
})) : e === Se && (r = !1, sessionStorage.removeItem(D), a("info", "QA Mode DISABLED", {
|
|
251
|
+
showToClient: !0,
|
|
252
|
+
style: Ce
|
|
253
|
+
})), e === me || e === Se)
|
|
254
|
+
try {
|
|
255
|
+
s.delete(ge);
|
|
256
|
+
const n = s.toString(), i = window.location.pathname + (n ? "?" + n : "") + window.location.hash;
|
|
257
|
+
window.history.replaceState({}, "", i);
|
|
258
|
+
} catch {
|
|
259
|
+
}
|
|
260
|
+
return r ?? t === "true";
|
|
261
|
+
} catch {
|
|
262
|
+
return !1;
|
|
263
|
+
}
|
|
264
|
+
}, ut = (s) => {
|
|
265
|
+
if (!(typeof window > "u" || typeof document > "u"))
|
|
192
266
|
try {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
267
|
+
s ? (sessionStorage.setItem(D, "true"), a("info", "QA Mode ENABLED", {
|
|
268
|
+
showToClient: !0,
|
|
269
|
+
style: be
|
|
270
|
+
})) : (sessionStorage.removeItem(D), a("info", "QA Mode DISABLED", {
|
|
271
|
+
showToClient: !0,
|
|
272
|
+
style: Ce
|
|
273
|
+
}));
|
|
274
|
+
} catch {
|
|
275
|
+
a("warn", "Cannot set QA mode: sessionStorage unavailable");
|
|
196
276
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
return r;
|
|
203
|
-
}, Te = () => {
|
|
204
|
-
const n = new URLSearchParams(window.location.search), e = {};
|
|
205
|
-
return Ue.forEach((r) => {
|
|
206
|
-
const s = n.get(r);
|
|
207
|
-
if (s) {
|
|
277
|
+
}, we = () => {
|
|
278
|
+
const s = new URLSearchParams(window.location.search), e = {};
|
|
279
|
+
return Xe.forEach((r) => {
|
|
280
|
+
const n = s.get(r);
|
|
281
|
+
if (n) {
|
|
208
282
|
const i = r.split("utm_")[1];
|
|
209
|
-
e[i] =
|
|
283
|
+
e[i] = n;
|
|
210
284
|
}
|
|
211
285
|
}), Object.keys(e).length ? e : void 0;
|
|
212
|
-
},
|
|
286
|
+
}, dt = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (s) => {
|
|
213
287
|
const e = Math.random() * 16 | 0;
|
|
214
|
-
return (
|
|
215
|
-
}),
|
|
216
|
-
const
|
|
288
|
+
return (s === "x" ? e : e & 3 | 8).toString(16);
|
|
289
|
+
}), ht = () => {
|
|
290
|
+
const s = Date.now();
|
|
217
291
|
let e = "";
|
|
218
292
|
try {
|
|
219
293
|
if (typeof crypto < "u" && crypto.getRandomValues) {
|
|
@@ -222,211 +296,240 @@ const Xe = () => {
|
|
|
222
296
|
}
|
|
223
297
|
} catch {
|
|
224
298
|
}
|
|
225
|
-
return e || (e = Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")), `${
|
|
226
|
-
},
|
|
299
|
+
return e || (e = Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")), `${s}-${e}`;
|
|
300
|
+
}, ye = (s, e = !1) => {
|
|
227
301
|
try {
|
|
228
|
-
const t = new URL(
|
|
229
|
-
return r || e &&
|
|
302
|
+
const t = new URL(s), r = t.protocol === "https:", n = t.protocol === "http:";
|
|
303
|
+
return r || e && n;
|
|
230
304
|
} catch {
|
|
231
305
|
return !1;
|
|
232
306
|
}
|
|
233
|
-
},
|
|
234
|
-
if (
|
|
307
|
+
}, ft = (s) => {
|
|
308
|
+
if (s.integrations?.tracelog?.projectId)
|
|
235
309
|
try {
|
|
236
310
|
const r = new URL(window.location.href).hostname;
|
|
237
311
|
if (!r || typeof r != "string")
|
|
238
312
|
throw new Error("Invalid hostname");
|
|
239
|
-
const
|
|
240
|
-
if (!
|
|
313
|
+
const n = r.split(".");
|
|
314
|
+
if (!n || !Array.isArray(n) || n.length === 0 || n.length === 1 && n[0] === "")
|
|
241
315
|
throw new Error("Invalid hostname structure");
|
|
242
|
-
const i =
|
|
316
|
+
const i = s.integrations.tracelog.projectId, o = n.slice(-2).join(".");
|
|
243
317
|
if (!o)
|
|
244
318
|
throw new Error("Invalid domain");
|
|
245
319
|
const l = `https://${i}.${o}/collect`;
|
|
246
|
-
if (!
|
|
320
|
+
if (!ye(l))
|
|
247
321
|
throw new Error("Invalid URL");
|
|
248
322
|
return l;
|
|
249
323
|
} catch (t) {
|
|
250
324
|
throw new Error(`Invalid URL configuration: ${t instanceof Error ? t.message : String(t)}`);
|
|
251
325
|
}
|
|
252
|
-
const e =
|
|
326
|
+
const e = s.integrations?.custom?.collectApiUrl;
|
|
253
327
|
if (e) {
|
|
254
|
-
const t =
|
|
255
|
-
if (!
|
|
328
|
+
const t = s.integrations?.custom?.allowHttp ?? !1;
|
|
329
|
+
if (!ye(e, t))
|
|
256
330
|
throw new Error("Invalid URL");
|
|
257
331
|
return e;
|
|
258
332
|
}
|
|
259
333
|
return "";
|
|
260
|
-
},
|
|
261
|
-
if (!
|
|
262
|
-
return a("warn", "Invalid URL provided to normalizeUrl", { data: { url: String(
|
|
334
|
+
}, se = (s, e = []) => {
|
|
335
|
+
if (!s || typeof s != "string")
|
|
336
|
+
return a("warn", "Invalid URL provided to normalizeUrl", { data: { url: String(s) } }), s || "";
|
|
263
337
|
try {
|
|
264
|
-
const t = new URL(
|
|
338
|
+
const t = new URL(s), r = t.searchParams, n = [.../* @__PURE__ */ new Set([...ze, ...e])];
|
|
265
339
|
let i = !1;
|
|
266
340
|
const o = [];
|
|
267
|
-
return
|
|
341
|
+
return n.forEach((c) => {
|
|
268
342
|
r.has(c) && (r.delete(c), i = !0, o.push(c));
|
|
269
|
-
}), !i &&
|
|
343
|
+
}), !i && s.includes("?") ? s : (t.search = r.toString(), t.toString());
|
|
270
344
|
} catch (t) {
|
|
271
|
-
const r =
|
|
272
|
-
return a("warn", "URL normalization failed, returning original", { error: t, data: { url: r } }),
|
|
345
|
+
const r = s && typeof s == "string" ? s.slice(0, 100) : String(s);
|
|
346
|
+
return a("warn", "URL normalization failed, returning original", { error: t, data: { url: r } }), s;
|
|
273
347
|
}
|
|
274
|
-
},
|
|
275
|
-
if (!
|
|
348
|
+
}, Ae = (s) => {
|
|
349
|
+
if (!s || typeof s != "string" || s.trim().length === 0)
|
|
276
350
|
return "";
|
|
277
|
-
let e =
|
|
278
|
-
|
|
351
|
+
let e = s;
|
|
352
|
+
s.length > 1e3 && (e = s.slice(0, Math.max(0, 1e3)));
|
|
279
353
|
let t = 0;
|
|
280
|
-
for (const
|
|
354
|
+
for (const n of Qe) {
|
|
281
355
|
const i = e;
|
|
282
|
-
e = e.replace(
|
|
356
|
+
e = e.replace(n, ""), i !== e && t++;
|
|
283
357
|
}
|
|
284
358
|
return t > 0 && a("warn", "XSS patterns detected and removed", {
|
|
285
359
|
data: {
|
|
286
360
|
patternMatches: t,
|
|
287
|
-
originalValue:
|
|
361
|
+
originalValue: s.slice(0, 100)
|
|
288
362
|
}
|
|
289
363
|
}), e = e.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'").replaceAll("/", "/"), e.trim();
|
|
290
|
-
},
|
|
291
|
-
if (e > 3 ||
|
|
364
|
+
}, ne = (s, e = 0) => {
|
|
365
|
+
if (e > 3 || s == null)
|
|
292
366
|
return null;
|
|
293
|
-
if (typeof
|
|
294
|
-
return
|
|
295
|
-
if (typeof
|
|
296
|
-
return !Number.isFinite(
|
|
297
|
-
if (typeof
|
|
298
|
-
return
|
|
299
|
-
if (Array.isArray(
|
|
300
|
-
return
|
|
301
|
-
if (typeof
|
|
302
|
-
const t = {},
|
|
303
|
-
for (const [i, o] of
|
|
304
|
-
const l =
|
|
367
|
+
if (typeof s == "string")
|
|
368
|
+
return Ae(s);
|
|
369
|
+
if (typeof s == "number")
|
|
370
|
+
return !Number.isFinite(s) || s < -Number.MAX_SAFE_INTEGER || s > Number.MAX_SAFE_INTEGER ? 0 : s;
|
|
371
|
+
if (typeof s == "boolean")
|
|
372
|
+
return s;
|
|
373
|
+
if (Array.isArray(s))
|
|
374
|
+
return s.slice(0, 100).map((n) => ne(n, e + 1)).filter((n) => n !== null);
|
|
375
|
+
if (typeof s == "object") {
|
|
376
|
+
const t = {}, n = Object.entries(s).slice(0, 20);
|
|
377
|
+
for (const [i, o] of n) {
|
|
378
|
+
const l = Ae(i);
|
|
305
379
|
if (l) {
|
|
306
|
-
const c =
|
|
380
|
+
const c = ne(o, e + 1);
|
|
307
381
|
c !== null && (t[l] = c);
|
|
308
382
|
}
|
|
309
383
|
}
|
|
310
384
|
return t;
|
|
311
385
|
}
|
|
312
386
|
return null;
|
|
313
|
-
},
|
|
314
|
-
if (typeof
|
|
387
|
+
}, Et = (s) => {
|
|
388
|
+
if (typeof s != "object" || s === null)
|
|
315
389
|
return {};
|
|
316
390
|
try {
|
|
317
|
-
const e =
|
|
391
|
+
const e = ne(s);
|
|
318
392
|
return typeof e == "object" && e !== null ? e : {};
|
|
319
393
|
} catch (e) {
|
|
320
394
|
const t = e instanceof Error ? e.message : String(e);
|
|
321
395
|
throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`);
|
|
322
396
|
}
|
|
323
|
-
},
|
|
324
|
-
if (
|
|
325
|
-
throw new
|
|
326
|
-
if (
|
|
327
|
-
if (
|
|
328
|
-
throw new
|
|
329
|
-
if (
|
|
330
|
-
throw new f
|
|
331
|
-
if (
|
|
332
|
-
if (!Array.isArray(
|
|
333
|
-
throw new f
|
|
334
|
-
for (const e of
|
|
397
|
+
}, gt = (s) => {
|
|
398
|
+
if (s !== void 0 && (s === null || typeof s != "object"))
|
|
399
|
+
throw new h("Configuration must be an object", "config");
|
|
400
|
+
if (s) {
|
|
401
|
+
if (s.sessionTimeout !== void 0 && (typeof s.sessionTimeout != "number" || s.sessionTimeout < 3e4 || s.sessionTimeout > 864e5))
|
|
402
|
+
throw new je(f.INVALID_SESSION_TIMEOUT, "config");
|
|
403
|
+
if (s.globalMetadata !== void 0 && (typeof s.globalMetadata != "object" || s.globalMetadata === null))
|
|
404
|
+
throw new h(f.INVALID_GLOBAL_METADATA, "config");
|
|
405
|
+
if (s.integrations && St(s.integrations), s.sensitiveQueryParams !== void 0) {
|
|
406
|
+
if (!Array.isArray(s.sensitiveQueryParams))
|
|
407
|
+
throw new h(f.INVALID_SENSITIVE_QUERY_PARAMS, "config");
|
|
408
|
+
for (const e of s.sensitiveQueryParams)
|
|
335
409
|
if (typeof e != "string")
|
|
336
|
-
throw new
|
|
337
|
-
}
|
|
338
|
-
if (
|
|
339
|
-
throw new
|
|
340
|
-
if (
|
|
341
|
-
throw new
|
|
342
|
-
if (
|
|
343
|
-
if (typeof
|
|
344
|
-
throw new f
|
|
345
|
-
if (
|
|
410
|
+
throw new h("All sensitive query params must be strings", "config");
|
|
411
|
+
}
|
|
412
|
+
if (s.errorSampling !== void 0 && (typeof s.errorSampling != "number" || s.errorSampling < 0 || s.errorSampling > 1))
|
|
413
|
+
throw new Ee(f.INVALID_ERROR_SAMPLING_RATE, "config");
|
|
414
|
+
if (s.samplingRate !== void 0 && (typeof s.samplingRate != "number" || s.samplingRate < 0 || s.samplingRate > 1))
|
|
415
|
+
throw new Ee(f.INVALID_SAMPLING_RATE, "config");
|
|
416
|
+
if (s.primaryScrollSelector !== void 0) {
|
|
417
|
+
if (typeof s.primaryScrollSelector != "string" || !s.primaryScrollSelector.trim())
|
|
418
|
+
throw new h(f.INVALID_PRIMARY_SCROLL_SELECTOR, "config");
|
|
419
|
+
if (s.primaryScrollSelector !== "window")
|
|
346
420
|
try {
|
|
347
|
-
document.querySelector(
|
|
421
|
+
document.querySelector(s.primaryScrollSelector);
|
|
348
422
|
} catch {
|
|
349
|
-
throw new
|
|
350
|
-
`${
|
|
423
|
+
throw new h(
|
|
424
|
+
`${f.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${s.primaryScrollSelector}"`,
|
|
351
425
|
"config"
|
|
352
426
|
);
|
|
353
427
|
}
|
|
354
428
|
}
|
|
355
|
-
if (
|
|
356
|
-
throw new f
|
|
357
|
-
if (
|
|
358
|
-
throw new f
|
|
359
|
-
if (
|
|
360
|
-
throw new f
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
429
|
+
if (s.pageViewThrottleMs !== void 0 && (typeof s.pageViewThrottleMs != "number" || s.pageViewThrottleMs < 0))
|
|
430
|
+
throw new h(f.INVALID_PAGE_VIEW_THROTTLE, "config");
|
|
431
|
+
if (s.clickThrottleMs !== void 0 && (typeof s.clickThrottleMs != "number" || s.clickThrottleMs < 0))
|
|
432
|
+
throw new h(f.INVALID_CLICK_THROTTLE, "config");
|
|
433
|
+
if (s.maxSameEventPerMinute !== void 0 && (typeof s.maxSameEventPerMinute != "number" || s.maxSameEventPerMinute <= 0))
|
|
434
|
+
throw new h(f.INVALID_MAX_SAME_EVENT_PER_MINUTE, "config");
|
|
435
|
+
if (s.viewport !== void 0 && mt(s.viewport), s.webVitalsMode !== void 0) {
|
|
436
|
+
if (typeof s.webVitalsMode != "string")
|
|
437
|
+
throw new h(
|
|
438
|
+
`Invalid webVitalsMode type: ${typeof s.webVitalsMode}. Must be a string`,
|
|
439
|
+
"config"
|
|
440
|
+
);
|
|
441
|
+
const e = ["all", "needs-improvement", "poor"];
|
|
442
|
+
if (!e.includes(s.webVitalsMode))
|
|
443
|
+
throw new h(
|
|
444
|
+
`Invalid webVitalsMode: "${s.webVitalsMode}". Must be one of: ${e.join(", ")}`,
|
|
445
|
+
"config"
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
if (s.webVitalsThresholds !== void 0) {
|
|
449
|
+
if (typeof s.webVitalsThresholds != "object" || s.webVitalsThresholds === null || Array.isArray(s.webVitalsThresholds))
|
|
450
|
+
throw new h("webVitalsThresholds must be an object", "config");
|
|
451
|
+
const e = ["LCP", "FCP", "CLS", "INP", "TTFB", "LONG_TASK"];
|
|
452
|
+
for (const [t, r] of Object.entries(s.webVitalsThresholds)) {
|
|
453
|
+
if (!e.includes(t))
|
|
454
|
+
throw new h(
|
|
455
|
+
`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,
|
|
456
|
+
"config"
|
|
457
|
+
);
|
|
458
|
+
if (typeof r != "number" || !Number.isFinite(r) || r < 0)
|
|
459
|
+
throw new h(
|
|
460
|
+
`Invalid Web Vitals threshold value for ${t}: ${r}. Must be a non-negative finite number`,
|
|
461
|
+
"config"
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}, mt = (s) => {
|
|
467
|
+
if (typeof s != "object" || s === null)
|
|
468
|
+
throw new h(f.INVALID_VIEWPORT_CONFIG, "config");
|
|
469
|
+
if (!s.elements || !Array.isArray(s.elements))
|
|
470
|
+
throw new h(f.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
471
|
+
if (s.elements.length === 0)
|
|
472
|
+
throw new h(f.INVALID_VIEWPORT_ELEMENTS, "config");
|
|
370
473
|
const e = /* @__PURE__ */ new Set();
|
|
371
|
-
for (const t of
|
|
474
|
+
for (const t of s.elements) {
|
|
372
475
|
if (!t.selector || typeof t.selector != "string" || !t.selector.trim())
|
|
373
|
-
throw new f
|
|
476
|
+
throw new h(f.INVALID_VIEWPORT_ELEMENT, "config");
|
|
374
477
|
const r = t.selector.trim();
|
|
375
478
|
if (e.has(r))
|
|
376
|
-
throw new
|
|
479
|
+
throw new h(
|
|
377
480
|
`Duplicate viewport selector found: "${r}". Each selector should appear only once.`,
|
|
378
481
|
"config"
|
|
379
482
|
);
|
|
380
483
|
if (e.add(r), t.id !== void 0 && (typeof t.id != "string" || !t.id.trim()))
|
|
381
|
-
throw new f
|
|
484
|
+
throw new h(f.INVALID_VIEWPORT_ELEMENT_ID, "config");
|
|
382
485
|
if (t.name !== void 0 && (typeof t.name != "string" || !t.name.trim()))
|
|
383
|
-
throw new f
|
|
384
|
-
}
|
|
385
|
-
if (
|
|
386
|
-
throw new f
|
|
387
|
-
if (
|
|
388
|
-
throw new f
|
|
389
|
-
if (
|
|
390
|
-
throw new f
|
|
391
|
-
if (
|
|
392
|
-
throw new f
|
|
393
|
-
},
|
|
394
|
-
if (
|
|
395
|
-
if (
|
|
396
|
-
throw new M(
|
|
397
|
-
if (
|
|
398
|
-
if (!
|
|
399
|
-
throw new M(
|
|
400
|
-
if (
|
|
486
|
+
throw new h(f.INVALID_VIEWPORT_ELEMENT_NAME, "config");
|
|
487
|
+
}
|
|
488
|
+
if (s.threshold !== void 0 && (typeof s.threshold != "number" || s.threshold < 0 || s.threshold > 1))
|
|
489
|
+
throw new h(f.INVALID_VIEWPORT_THRESHOLD, "config");
|
|
490
|
+
if (s.minDwellTime !== void 0 && (typeof s.minDwellTime != "number" || s.minDwellTime < 0))
|
|
491
|
+
throw new h(f.INVALID_VIEWPORT_MIN_DWELL_TIME, "config");
|
|
492
|
+
if (s.cooldownPeriod !== void 0 && (typeof s.cooldownPeriod != "number" || s.cooldownPeriod < 0))
|
|
493
|
+
throw new h(f.INVALID_VIEWPORT_COOLDOWN_PERIOD, "config");
|
|
494
|
+
if (s.maxTrackedElements !== void 0 && (typeof s.maxTrackedElements != "number" || s.maxTrackedElements <= 0))
|
|
495
|
+
throw new h(f.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS, "config");
|
|
496
|
+
}, St = (s) => {
|
|
497
|
+
if (s) {
|
|
498
|
+
if (s.tracelog && (!s.tracelog.projectId || typeof s.tracelog.projectId != "string" || s.tracelog.projectId.trim() === ""))
|
|
499
|
+
throw new M(f.INVALID_TRACELOG_PROJECT_ID, "config");
|
|
500
|
+
if (s.custom) {
|
|
501
|
+
if (!s.custom.collectApiUrl || typeof s.custom.collectApiUrl != "string" || s.custom.collectApiUrl.trim() === "")
|
|
502
|
+
throw new M(f.INVALID_CUSTOM_API_URL, "config");
|
|
503
|
+
if (s.custom.allowHttp !== void 0 && typeof s.custom.allowHttp != "boolean")
|
|
401
504
|
throw new M("allowHttp must be a boolean", "config");
|
|
402
|
-
const e =
|
|
505
|
+
const e = s.custom.collectApiUrl.trim();
|
|
403
506
|
if (!e.startsWith("http://") && !e.startsWith("https://"))
|
|
404
507
|
throw new M('Custom API URL must start with "http://" or "https://"', "config");
|
|
405
|
-
if (!(
|
|
508
|
+
if (!(s.custom.allowHttp ?? !1) && e.startsWith("http://"))
|
|
406
509
|
throw new M(
|
|
407
510
|
"Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)",
|
|
408
511
|
"config"
|
|
409
512
|
);
|
|
410
513
|
}
|
|
411
|
-
if (
|
|
412
|
-
if (!
|
|
413
|
-
throw new M(
|
|
414
|
-
if (!
|
|
514
|
+
if (s.googleAnalytics) {
|
|
515
|
+
if (!s.googleAnalytics.measurementId || typeof s.googleAnalytics.measurementId != "string" || s.googleAnalytics.measurementId.trim() === "")
|
|
516
|
+
throw new M(f.INVALID_GOOGLE_ANALYTICS_ID, "config");
|
|
517
|
+
if (!s.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))
|
|
415
518
|
throw new M('Google Analytics measurement ID must start with "G-" or "UA-"', "config");
|
|
416
519
|
}
|
|
417
520
|
}
|
|
418
|
-
},
|
|
419
|
-
|
|
521
|
+
}, Tt = (s) => {
|
|
522
|
+
gt(s);
|
|
420
523
|
const e = {
|
|
421
|
-
...
|
|
422
|
-
sessionTimeout:
|
|
423
|
-
globalMetadata:
|
|
424
|
-
sensitiveQueryParams:
|
|
425
|
-
errorSampling:
|
|
426
|
-
samplingRate:
|
|
427
|
-
pageViewThrottleMs:
|
|
428
|
-
clickThrottleMs:
|
|
429
|
-
maxSameEventPerMinute:
|
|
524
|
+
...s ?? {},
|
|
525
|
+
sessionTimeout: s?.sessionTimeout ?? 9e5,
|
|
526
|
+
globalMetadata: s?.globalMetadata ?? {},
|
|
527
|
+
sensitiveQueryParams: s?.sensitiveQueryParams ?? [],
|
|
528
|
+
errorSampling: s?.errorSampling ?? Pe,
|
|
529
|
+
samplingRate: s?.samplingRate ?? 1,
|
|
530
|
+
pageViewThrottleMs: s?.pageViewThrottleMs ?? 1e3,
|
|
531
|
+
clickThrottleMs: s?.clickThrottleMs ?? 300,
|
|
532
|
+
maxSameEventPerMinute: s?.maxSameEventPerMinute ?? 60
|
|
430
533
|
};
|
|
431
534
|
return e.integrations?.custom && (e.integrations.custom = {
|
|
432
535
|
...e.integrations.custom,
|
|
@@ -438,11 +541,11 @@ const Xe = () => {
|
|
|
438
541
|
cooldownPeriod: e.viewport.cooldownPeriod ?? 6e4,
|
|
439
542
|
maxTrackedElements: e.viewport.maxTrackedElements ?? 100
|
|
440
543
|
}), e;
|
|
441
|
-
},
|
|
442
|
-
if (typeof
|
|
544
|
+
}, pt = (s) => {
|
|
545
|
+
if (typeof s == "string")
|
|
443
546
|
return !0;
|
|
444
|
-
if (typeof
|
|
445
|
-
const e = Object.entries(
|
|
547
|
+
if (typeof s == "object" && s !== null && !Array.isArray(s)) {
|
|
548
|
+
const e = Object.entries(s);
|
|
446
549
|
if (e.length > 20)
|
|
447
550
|
return !1;
|
|
448
551
|
for (const [, t] of e) {
|
|
@@ -455,10 +558,10 @@ const Xe = () => {
|
|
|
455
558
|
return !0;
|
|
456
559
|
}
|
|
457
560
|
return !1;
|
|
458
|
-
},
|
|
459
|
-
if (typeof
|
|
561
|
+
}, De = (s, e = 0) => {
|
|
562
|
+
if (typeof s != "object" || s === null || e > 1)
|
|
460
563
|
return !1;
|
|
461
|
-
for (const t of Object.values(
|
|
564
|
+
for (const t of Object.values(s)) {
|
|
462
565
|
if (t == null)
|
|
463
566
|
continue;
|
|
464
567
|
const r = typeof t;
|
|
@@ -469,12 +572,12 @@ const Xe = () => {
|
|
|
469
572
|
if (typeof t[0] == "string") {
|
|
470
573
|
if (!t.every((o) => typeof o == "string"))
|
|
471
574
|
return !1;
|
|
472
|
-
} else if (!t.every((o) =>
|
|
575
|
+
} else if (!t.every((o) => pt(o)))
|
|
473
576
|
return !1;
|
|
474
577
|
continue;
|
|
475
578
|
}
|
|
476
579
|
if (r === "object" && e === 0) {
|
|
477
|
-
if (!
|
|
580
|
+
if (!De(t, e + 1))
|
|
478
581
|
return !1;
|
|
479
582
|
continue;
|
|
480
583
|
}
|
|
@@ -482,27 +585,27 @@ const Xe = () => {
|
|
|
482
585
|
}
|
|
483
586
|
}
|
|
484
587
|
return !0;
|
|
485
|
-
},
|
|
588
|
+
}, _t = (s) => typeof s != "string" ? {
|
|
486
589
|
valid: !1,
|
|
487
590
|
error: "Event name must be a string"
|
|
488
|
-
} :
|
|
591
|
+
} : s.length === 0 ? {
|
|
489
592
|
valid: !1,
|
|
490
593
|
error: "Event name cannot be empty"
|
|
491
|
-
} :
|
|
594
|
+
} : s.length > 120 ? {
|
|
492
595
|
valid: !1,
|
|
493
596
|
error: "Event name is too long (max 120 characters)"
|
|
494
|
-
} :
|
|
597
|
+
} : s.includes("<") || s.includes(">") || s.includes("&") ? {
|
|
495
598
|
valid: !1,
|
|
496
599
|
error: "Event name contains invalid characters"
|
|
497
|
-
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(
|
|
600
|
+
} : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(s.toLowerCase()) ? {
|
|
498
601
|
valid: !1,
|
|
499
602
|
error: "Event name cannot be a reserved word"
|
|
500
|
-
} : { valid: !0 },
|
|
501
|
-
const r =
|
|
502
|
-
if (!
|
|
603
|
+
} : { valid: !0 }, Le = (s, e, t) => {
|
|
604
|
+
const r = Et(e), n = `${t} "${s}" metadata error`;
|
|
605
|
+
if (!De(r))
|
|
503
606
|
return {
|
|
504
607
|
valid: !1,
|
|
505
|
-
error: `${
|
|
608
|
+
error: `${n}: object has invalid types. Valid types are string, number, boolean or string arrays.`
|
|
506
609
|
};
|
|
507
610
|
let i;
|
|
508
611
|
try {
|
|
@@ -510,58 +613,58 @@ const Xe = () => {
|
|
|
510
613
|
} catch {
|
|
511
614
|
return {
|
|
512
615
|
valid: !1,
|
|
513
|
-
error: `${
|
|
616
|
+
error: `${n}: object contains circular references or cannot be serialized.`
|
|
514
617
|
};
|
|
515
618
|
}
|
|
516
619
|
if (i.length > 8192)
|
|
517
620
|
return {
|
|
518
621
|
valid: !1,
|
|
519
|
-
error: `${
|
|
622
|
+
error: `${n}: object is too large (max ${8192 / 1024} KB).`
|
|
520
623
|
};
|
|
521
624
|
if (Object.keys(r).length > 10)
|
|
522
625
|
return {
|
|
523
626
|
valid: !1,
|
|
524
|
-
error: `${
|
|
627
|
+
error: `${n}: object has too many keys (max 10 keys).`
|
|
525
628
|
};
|
|
526
629
|
for (const [l, c] of Object.entries(r)) {
|
|
527
630
|
if (Array.isArray(c)) {
|
|
528
631
|
if (c.length > 10)
|
|
529
632
|
return {
|
|
530
633
|
valid: !1,
|
|
531
|
-
error: `${
|
|
634
|
+
error: `${n}: array property "${l}" is too large (max 10 items).`
|
|
532
635
|
};
|
|
533
636
|
for (const d of c)
|
|
534
637
|
if (typeof d == "string" && d.length > 500)
|
|
535
638
|
return {
|
|
536
639
|
valid: !1,
|
|
537
|
-
error: `${
|
|
640
|
+
error: `${n}: array property "${l}" contains strings that are too long (max 500 characters).`
|
|
538
641
|
};
|
|
539
642
|
}
|
|
540
643
|
if (typeof c == "string" && c.length > 1e3)
|
|
541
644
|
return {
|
|
542
645
|
valid: !1,
|
|
543
|
-
error: `${
|
|
646
|
+
error: `${n}: property "${l}" is too long (max 1000 characters).`
|
|
544
647
|
};
|
|
545
648
|
}
|
|
546
649
|
return {
|
|
547
650
|
valid: !0,
|
|
548
651
|
sanitizedMetadata: r
|
|
549
652
|
};
|
|
550
|
-
},
|
|
653
|
+
}, It = (s, e, t) => {
|
|
551
654
|
if (Array.isArray(e)) {
|
|
552
|
-
const r = [],
|
|
655
|
+
const r = [], n = `${t} "${s}" metadata error`;
|
|
553
656
|
for (let i = 0; i < e.length; i++) {
|
|
554
657
|
const o = e[i];
|
|
555
658
|
if (typeof o != "object" || o === null || Array.isArray(o))
|
|
556
659
|
return {
|
|
557
660
|
valid: !1,
|
|
558
|
-
error: `${
|
|
661
|
+
error: `${n}: array item at index ${i} must be an object.`
|
|
559
662
|
};
|
|
560
|
-
const l =
|
|
663
|
+
const l = Le(s, o, t);
|
|
561
664
|
if (!l.valid)
|
|
562
665
|
return {
|
|
563
666
|
valid: !1,
|
|
564
|
-
error: `${
|
|
667
|
+
error: `${n}: array item at index ${i} is invalid: ${l.error}`
|
|
565
668
|
};
|
|
566
669
|
l.sanitizedMetadata && r.push(l.sanitizedMetadata);
|
|
567
670
|
}
|
|
@@ -570,26 +673,26 @@ const Xe = () => {
|
|
|
570
673
|
sanitizedMetadata: r
|
|
571
674
|
};
|
|
572
675
|
}
|
|
573
|
-
return
|
|
574
|
-
},
|
|
575
|
-
const t =
|
|
676
|
+
return Le(s, e, t);
|
|
677
|
+
}, vt = (s, e) => {
|
|
678
|
+
const t = _t(s);
|
|
576
679
|
if (!t.valid)
|
|
577
680
|
return a("error", "Event name validation failed", {
|
|
578
681
|
showToClient: !0,
|
|
579
|
-
data: { eventName:
|
|
682
|
+
data: { eventName: s, error: t.error }
|
|
580
683
|
}), t;
|
|
581
684
|
if (!e)
|
|
582
685
|
return { valid: !0 };
|
|
583
|
-
const r =
|
|
686
|
+
const r = It(s, e, "customEvent");
|
|
584
687
|
return r.valid || a("error", "Event metadata validation failed", {
|
|
585
688
|
showToClient: !0,
|
|
586
689
|
data: {
|
|
587
|
-
eventName:
|
|
690
|
+
eventName: s,
|
|
588
691
|
error: r.error
|
|
589
692
|
}
|
|
590
693
|
}), r;
|
|
591
694
|
};
|
|
592
|
-
class
|
|
695
|
+
class wt {
|
|
593
696
|
listeners = /* @__PURE__ */ new Map();
|
|
594
697
|
on(e, t) {
|
|
595
698
|
this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(t);
|
|
@@ -597,33 +700,33 @@ class mt {
|
|
|
597
700
|
off(e, t) {
|
|
598
701
|
const r = this.listeners.get(e);
|
|
599
702
|
if (r) {
|
|
600
|
-
const
|
|
601
|
-
|
|
703
|
+
const n = r.indexOf(t);
|
|
704
|
+
n > -1 && r.splice(n, 1);
|
|
602
705
|
}
|
|
603
706
|
}
|
|
604
707
|
emit(e, t) {
|
|
605
708
|
const r = this.listeners.get(e);
|
|
606
|
-
r && r.forEach((
|
|
607
|
-
|
|
709
|
+
r && r.forEach((n) => {
|
|
710
|
+
n(t);
|
|
608
711
|
});
|
|
609
712
|
}
|
|
610
713
|
removeAllListeners() {
|
|
611
714
|
this.listeners.clear();
|
|
612
715
|
}
|
|
613
716
|
}
|
|
614
|
-
const
|
|
615
|
-
class
|
|
717
|
+
const K = {};
|
|
718
|
+
class T {
|
|
616
719
|
get(e) {
|
|
617
|
-
return
|
|
720
|
+
return K[e];
|
|
618
721
|
}
|
|
619
722
|
set(e, t) {
|
|
620
|
-
|
|
723
|
+
K[e] = t;
|
|
621
724
|
}
|
|
622
725
|
getState() {
|
|
623
|
-
return { ...
|
|
726
|
+
return { ...K };
|
|
624
727
|
}
|
|
625
728
|
}
|
|
626
|
-
class
|
|
729
|
+
class yt extends T {
|
|
627
730
|
storeManager;
|
|
628
731
|
lastPermanentErrorLog = null;
|
|
629
732
|
recoveryInProgress = !1;
|
|
@@ -632,10 +735,10 @@ class St extends S {
|
|
|
632
735
|
}
|
|
633
736
|
getQueueStorageKey() {
|
|
634
737
|
const e = this.get("userId") || "anonymous";
|
|
635
|
-
return
|
|
738
|
+
return Je(e);
|
|
636
739
|
}
|
|
637
740
|
sendEventsQueueSync(e) {
|
|
638
|
-
return this.shouldSkipSend() ? !0 : this.get("config")?.integrations?.custom?.collectApiUrl ===
|
|
741
|
+
return this.shouldSkipSend() ? !0 : this.get("config")?.integrations?.custom?.collectApiUrl === Z.Fail ? (a("warn", "Fail mode: simulating network failure (sync)", {
|
|
639
742
|
data: { events: e.events.length }
|
|
640
743
|
}), !1) : this.sendQueueSyncInternal(e);
|
|
641
744
|
}
|
|
@@ -676,13 +779,13 @@ class St extends S {
|
|
|
676
779
|
async send(e) {
|
|
677
780
|
if (this.shouldSkipSend())
|
|
678
781
|
return this.simulateSuccessfulSend();
|
|
679
|
-
if (this.get("config")?.integrations?.custom?.collectApiUrl ===
|
|
782
|
+
if (this.get("config")?.integrations?.custom?.collectApiUrl === Z.Fail)
|
|
680
783
|
return a("warn", "Fail mode: simulating network failure", {
|
|
681
784
|
data: { events: e.events.length }
|
|
682
785
|
}), !1;
|
|
683
|
-
const { url: r, payload:
|
|
786
|
+
const { url: r, payload: n } = this.prepareRequest(e);
|
|
684
787
|
try {
|
|
685
|
-
return (await this.sendWithTimeout(r,
|
|
788
|
+
return (await this.sendWithTimeout(r, n)).ok;
|
|
686
789
|
} catch (i) {
|
|
687
790
|
if (i instanceof R)
|
|
688
791
|
throw i;
|
|
@@ -696,7 +799,7 @@ class St extends S {
|
|
|
696
799
|
}
|
|
697
800
|
}
|
|
698
801
|
async sendWithTimeout(e, t) {
|
|
699
|
-
const r = new AbortController(),
|
|
802
|
+
const r = new AbortController(), n = setTimeout(() => {
|
|
700
803
|
r.abort();
|
|
701
804
|
}, 1e4);
|
|
702
805
|
try {
|
|
@@ -714,7 +817,7 @@ class St extends S {
|
|
|
714
817
|
throw i.status >= 400 && i.status < 500 ? new R(`HTTP ${i.status}: ${i.statusText}`, i.status) : new Error(`HTTP ${i.status}: ${i.statusText}`);
|
|
715
818
|
return i;
|
|
716
819
|
} finally {
|
|
717
|
-
clearTimeout(
|
|
820
|
+
clearTimeout(n);
|
|
718
821
|
}
|
|
719
822
|
}
|
|
720
823
|
sendQueueSyncInternal(e) {
|
|
@@ -727,10 +830,10 @@ class St extends S {
|
|
|
727
830
|
events: e.events.length
|
|
728
831
|
}
|
|
729
832
|
}), this.persistEvents(e), !1;
|
|
730
|
-
const
|
|
833
|
+
const n = new Blob([r], { type: "application/json" });
|
|
731
834
|
if (!this.isSendBeaconAvailable())
|
|
732
835
|
return a("warn", "sendBeacon not available, persisting events for recovery"), this.persistEvents(e), !1;
|
|
733
|
-
const i = navigator.sendBeacon(t,
|
|
836
|
+
const i = navigator.sendBeacon(t, n);
|
|
734
837
|
return i || (a("warn", "sendBeacon rejected request, persisting events for recovery"), this.persistEvents(e)), i;
|
|
735
838
|
}
|
|
736
839
|
prepareRequest(e) {
|
|
@@ -776,8 +879,8 @@ class St extends S {
|
|
|
776
879
|
const r = {
|
|
777
880
|
...e,
|
|
778
881
|
timestamp: Date.now()
|
|
779
|
-
},
|
|
780
|
-
return this.storeManager.setItem(
|
|
882
|
+
}, n = this.getQueueStorageKey();
|
|
883
|
+
return this.storeManager.setItem(n, JSON.stringify(r)), !!this.storeManager.getItem(n);
|
|
781
884
|
} catch (t) {
|
|
782
885
|
return a("warn", "Failed to persist events", { error: t }), !1;
|
|
783
886
|
}
|
|
@@ -802,12 +905,12 @@ class St extends S {
|
|
|
802
905
|
}
|
|
803
906
|
logPermanentError(e, t) {
|
|
804
907
|
const r = Date.now();
|
|
805
|
-
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || r - this.lastPermanentErrorLog.timestamp >=
|
|
908
|
+
(!this.lastPermanentErrorLog || this.lastPermanentErrorLog.statusCode !== t.statusCode || r - this.lastPermanentErrorLog.timestamp >= lt) && (a("error", e, {
|
|
806
909
|
data: { status: t.statusCode, message: t.message }
|
|
807
910
|
}), this.lastPermanentErrorLog = { statusCode: t.statusCode, timestamp: r });
|
|
808
911
|
}
|
|
809
912
|
}
|
|
810
|
-
class
|
|
913
|
+
class At extends T {
|
|
811
914
|
googleAnalytics;
|
|
812
915
|
dataSender;
|
|
813
916
|
emitter;
|
|
@@ -829,14 +932,14 @@ class Tt extends S {
|
|
|
829
932
|
};
|
|
830
933
|
lastSessionId = null;
|
|
831
934
|
constructor(e, t = null, r = null) {
|
|
832
|
-
super(), this.googleAnalytics = t, this.dataSender = new
|
|
935
|
+
super(), this.googleAnalytics = t, this.dataSender = new yt(e), this.emitter = r;
|
|
833
936
|
}
|
|
834
937
|
async recoverPersistedEvents() {
|
|
835
938
|
await this.dataSender.recoverPersistedEvents({
|
|
836
939
|
onSuccess: (e, t, r) => {
|
|
837
940
|
if (t && t.length > 0) {
|
|
838
|
-
const
|
|
839
|
-
this.removeProcessedEvents(
|
|
941
|
+
const n = t.map((i) => i.id);
|
|
942
|
+
this.removeProcessedEvents(n), r && this.emitEventsQueue(r);
|
|
840
943
|
}
|
|
841
944
|
},
|
|
842
945
|
onFailure: () => {
|
|
@@ -848,13 +951,13 @@ class Tt extends S {
|
|
|
848
951
|
type: e,
|
|
849
952
|
page_url: t,
|
|
850
953
|
from_page_url: r,
|
|
851
|
-
scroll_data:
|
|
954
|
+
scroll_data: n,
|
|
852
955
|
click_data: i,
|
|
853
956
|
custom_event: o,
|
|
854
957
|
web_vitals: l,
|
|
855
958
|
error_data: c,
|
|
856
959
|
session_end_reason: d,
|
|
857
|
-
viewport_data:
|
|
960
|
+
viewport_data: E
|
|
858
961
|
}) {
|
|
859
962
|
if (!e) {
|
|
860
963
|
a("error", "Event type is required - event will be ignored");
|
|
@@ -868,13 +971,13 @@ class Tt extends S {
|
|
|
868
971
|
type: e,
|
|
869
972
|
page_url: t,
|
|
870
973
|
from_page_url: r,
|
|
871
|
-
scroll_data:
|
|
974
|
+
scroll_data: n,
|
|
872
975
|
click_data: i,
|
|
873
976
|
custom_event: o,
|
|
874
977
|
web_vitals: l,
|
|
875
978
|
error_data: c,
|
|
876
979
|
session_end_reason: d,
|
|
877
|
-
viewport_data:
|
|
980
|
+
viewport_data: E
|
|
878
981
|
});
|
|
879
982
|
return;
|
|
880
983
|
}
|
|
@@ -889,74 +992,77 @@ class Tt extends S {
|
|
|
889
992
|
const v = e === u.SESSION_START || e === u.SESSION_END;
|
|
890
993
|
if (!v && !this.checkRateLimit())
|
|
891
994
|
return;
|
|
892
|
-
const
|
|
995
|
+
const S = e;
|
|
893
996
|
if (!v) {
|
|
894
997
|
if (this.sessionEventCounts.total >= 1e3) {
|
|
895
998
|
a("warn", "Session event limit reached", {
|
|
896
999
|
data: {
|
|
897
|
-
type:
|
|
1000
|
+
type: S,
|
|
898
1001
|
total: this.sessionEventCounts.total,
|
|
899
1002
|
limit: 1e3
|
|
900
1003
|
}
|
|
901
1004
|
});
|
|
902
1005
|
return;
|
|
903
1006
|
}
|
|
904
|
-
const
|
|
905
|
-
if (
|
|
906
|
-
const
|
|
907
|
-
if (
|
|
1007
|
+
const y = this.getTypeLimitForEvent(S);
|
|
1008
|
+
if (y) {
|
|
1009
|
+
const j = this.sessionEventCounts[S];
|
|
1010
|
+
if (j !== void 0 && j >= y) {
|
|
908
1011
|
a("warn", "Session event type limit reached", {
|
|
909
1012
|
data: {
|
|
910
|
-
type:
|
|
911
|
-
count:
|
|
912
|
-
limit:
|
|
1013
|
+
type: S,
|
|
1014
|
+
count: j,
|
|
1015
|
+
limit: y
|
|
913
1016
|
}
|
|
914
1017
|
});
|
|
915
1018
|
return;
|
|
916
1019
|
}
|
|
917
1020
|
}
|
|
918
1021
|
}
|
|
919
|
-
if (
|
|
920
|
-
const
|
|
921
|
-
if (!this.checkPerEventRateLimit(o.name,
|
|
1022
|
+
if (S === u.CUSTOM && o?.name) {
|
|
1023
|
+
const y = this.get("config")?.maxSameEventPerMinute ?? 60;
|
|
1024
|
+
if (!this.checkPerEventRateLimit(o.name, y))
|
|
922
1025
|
return;
|
|
923
1026
|
}
|
|
924
|
-
const
|
|
925
|
-
type:
|
|
926
|
-
page_url:
|
|
1027
|
+
const We = S === u.SESSION_START, Be = t || this.get("pageUrl"), Q = this.buildEventPayload({
|
|
1028
|
+
type: S,
|
|
1029
|
+
page_url: Be,
|
|
927
1030
|
from_page_url: r,
|
|
928
|
-
scroll_data:
|
|
1031
|
+
scroll_data: n,
|
|
929
1032
|
click_data: i,
|
|
930
1033
|
custom_event: o,
|
|
931
1034
|
web_vitals: l,
|
|
932
1035
|
error_data: c,
|
|
933
1036
|
session_end_reason: d,
|
|
934
|
-
viewport_data:
|
|
1037
|
+
viewport_data: E
|
|
935
1038
|
});
|
|
936
1039
|
if (!(!v && !this.shouldSample())) {
|
|
937
|
-
if (
|
|
938
|
-
const
|
|
939
|
-
if (!
|
|
1040
|
+
if (We) {
|
|
1041
|
+
const y = this.get("sessionId");
|
|
1042
|
+
if (!y) {
|
|
940
1043
|
a("error", "Session start event requires sessionId - event will be ignored");
|
|
941
1044
|
return;
|
|
942
1045
|
}
|
|
943
1046
|
if (this.get("hasStartSession")) {
|
|
944
1047
|
a("warn", "Duplicate session_start detected", {
|
|
945
|
-
data: { sessionId:
|
|
1048
|
+
data: { sessionId: y }
|
|
946
1049
|
});
|
|
947
1050
|
return;
|
|
948
1051
|
}
|
|
949
1052
|
this.set("hasStartSession", !0);
|
|
950
1053
|
}
|
|
951
|
-
if (!this.isDuplicateEvent(
|
|
952
|
-
if (this.get("mode") ===
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1054
|
+
if (!this.isDuplicateEvent(Q)) {
|
|
1055
|
+
if (this.get("mode") === V.QA && S === u.CUSTOM && o) {
|
|
1056
|
+
a("info", "Event", {
|
|
1057
|
+
showToClient: !0,
|
|
1058
|
+
data: {
|
|
1059
|
+
name: o.name,
|
|
1060
|
+
...o.metadata && { metadata: o.metadata }
|
|
1061
|
+
}
|
|
1062
|
+
}), this.emitEvent(Q);
|
|
957
1063
|
return;
|
|
958
1064
|
}
|
|
959
|
-
this.addToQueue(
|
|
1065
|
+
this.addToQueue(Q), v || (this.sessionEventCounts.total++, this.sessionEventCounts[S] !== void 0 && this.sessionEventCounts[S]++);
|
|
960
1066
|
}
|
|
961
1067
|
}
|
|
962
1068
|
}
|
|
@@ -999,17 +1105,17 @@ class Tt extends S {
|
|
|
999
1105
|
flushEvents(e) {
|
|
1000
1106
|
if (this.eventsQueue.length === 0)
|
|
1001
1107
|
return e ? !0 : Promise.resolve(!0);
|
|
1002
|
-
const t = this.buildEventsPayload(), r = [...this.eventsQueue],
|
|
1108
|
+
const t = this.buildEventsPayload(), r = [...this.eventsQueue], n = r.map((i) => i.id);
|
|
1003
1109
|
if (e) {
|
|
1004
1110
|
const i = this.dataSender.sendEventsQueueSync(t);
|
|
1005
|
-
return i ? (this.removeProcessedEvents(
|
|
1111
|
+
return i ? (this.removeProcessedEvents(n), this.clearSendInterval(), this.emitEventsQueue(t)) : (this.removeProcessedEvents(n), this.clearSendInterval()), i;
|
|
1006
1112
|
} else
|
|
1007
1113
|
return this.dataSender.sendEventsQueue(t, {
|
|
1008
1114
|
onSuccess: () => {
|
|
1009
|
-
this.removeProcessedEvents(
|
|
1115
|
+
this.removeProcessedEvents(n), this.clearSendInterval(), this.emitEventsQueue(t);
|
|
1010
1116
|
},
|
|
1011
1117
|
onFailure: () => {
|
|
1012
|
-
this.removeProcessedEvents(
|
|
1118
|
+
this.removeProcessedEvents(n), this.eventsQueue.length === 0 && this.clearSendInterval(), a("warn", "Async flush failed, removed from queue and persisted for recovery on next page load", {
|
|
1013
1119
|
data: { eventCount: r.length }
|
|
1014
1120
|
});
|
|
1015
1121
|
}
|
|
@@ -1018,7 +1124,7 @@ class Tt extends S {
|
|
|
1018
1124
|
async sendEventsQueue() {
|
|
1019
1125
|
if (!this.get("sessionId") || this.eventsQueue.length === 0)
|
|
1020
1126
|
return;
|
|
1021
|
-
const e = this.buildEventsPayload(), t = [...this.eventsQueue], r = t.map((
|
|
1127
|
+
const e = this.buildEventsPayload(), t = [...this.eventsQueue], r = t.map((n) => n.id);
|
|
1022
1128
|
await this.dataSender.sendEventsQueue(e, {
|
|
1023
1129
|
onSuccess: () => {
|
|
1024
1130
|
this.removeProcessedEvents(r), this.emitEventsQueue(e);
|
|
@@ -1032,11 +1138,11 @@ class Tt extends S {
|
|
|
1032
1138
|
}
|
|
1033
1139
|
buildEventsPayload() {
|
|
1034
1140
|
const e = /* @__PURE__ */ new Map(), t = [];
|
|
1035
|
-
for (const
|
|
1036
|
-
const i = this.createEventSignature(
|
|
1037
|
-
e.has(i) || t.push(i), e.set(i,
|
|
1141
|
+
for (const n of this.eventsQueue) {
|
|
1142
|
+
const i = this.createEventSignature(n);
|
|
1143
|
+
e.has(i) || t.push(i), e.set(i, n);
|
|
1038
1144
|
}
|
|
1039
|
-
const r = t.map((
|
|
1145
|
+
const r = t.map((n) => e.get(n)).filter((n) => !!n).sort((n, i) => n.timestamp - i.timestamp);
|
|
1040
1146
|
return {
|
|
1041
1147
|
user_id: this.get("userId"),
|
|
1042
1148
|
session_id: this.get("sessionId"),
|
|
@@ -1048,7 +1154,7 @@ class Tt extends S {
|
|
|
1048
1154
|
buildEventPayload(e) {
|
|
1049
1155
|
const t = e.type === u.SESSION_START, r = e.page_url ?? this.get("pageUrl");
|
|
1050
1156
|
return {
|
|
1051
|
-
id:
|
|
1157
|
+
id: ht(),
|
|
1052
1158
|
type: e.type,
|
|
1053
1159
|
page_url: r,
|
|
1054
1160
|
timestamp: Date.now(),
|
|
@@ -1061,7 +1167,7 @@ class Tt extends S {
|
|
|
1061
1167
|
...e.error_data && { error_data: e.error_data },
|
|
1062
1168
|
...e.session_end_reason && { session_end_reason: e.session_end_reason },
|
|
1063
1169
|
...e.viewport_data && { viewport_data: e.viewport_data },
|
|
1064
|
-
...t &&
|
|
1170
|
+
...t && we() && { utm: we() }
|
|
1065
1171
|
};
|
|
1066
1172
|
}
|
|
1067
1173
|
/**
|
|
@@ -1069,8 +1175,8 @@ class Tt extends S {
|
|
|
1069
1175
|
* Tracks recent event fingerprints with timestamp-based cleanup
|
|
1070
1176
|
*/
|
|
1071
1177
|
isDuplicateEvent(e) {
|
|
1072
|
-
const t = Date.now(), r = this.createEventFingerprint(e),
|
|
1073
|
-
return
|
|
1178
|
+
const t = Date.now(), r = this.createEventFingerprint(e), n = this.recentEventFingerprints.get(r);
|
|
1179
|
+
return n && t - n < 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", {
|
|
1074
1180
|
data: { hardLimit: 2e3 }
|
|
1075
1181
|
})), !1);
|
|
1076
1182
|
}
|
|
@@ -1080,8 +1186,8 @@ class Tt extends S {
|
|
|
1080
1186
|
*/
|
|
1081
1187
|
pruneOldFingerprints() {
|
|
1082
1188
|
const e = Date.now(), t = 500 * 10;
|
|
1083
|
-
for (const [r,
|
|
1084
|
-
e -
|
|
1189
|
+
for (const [r, n] of this.recentEventFingerprints.entries())
|
|
1190
|
+
e - n > t && this.recentEventFingerprints.delete(r);
|
|
1085
1191
|
a("debug", "Pruned old event fingerprints", {
|
|
1086
1192
|
data: {
|
|
1087
1193
|
remaining: this.recentEventFingerprints.size,
|
|
@@ -1092,8 +1198,8 @@ class Tt extends S {
|
|
|
1092
1198
|
createEventFingerprint(e) {
|
|
1093
1199
|
let t = `${e.type}_${e.page_url}`;
|
|
1094
1200
|
if (e.click_data) {
|
|
1095
|
-
const r = Math.round((e.click_data.x || 0) / 10) * 10,
|
|
1096
|
-
t += `_click_${r}_${
|
|
1201
|
+
const r = Math.round((e.click_data.x || 0) / 10) * 10, n = Math.round((e.click_data.y || 0) / 10) * 10;
|
|
1202
|
+
t += `_click_${r}_${n}`;
|
|
1097
1203
|
}
|
|
1098
1204
|
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;
|
|
1099
1205
|
}
|
|
@@ -1103,7 +1209,7 @@ class Tt extends S {
|
|
|
1103
1209
|
addToQueue(e) {
|
|
1104
1210
|
if (this.eventsQueue.push(e), this.emitEvent(e), this.eventsQueue.length > 100) {
|
|
1105
1211
|
const t = this.eventsQueue.findIndex(
|
|
1106
|
-
(
|
|
1212
|
+
(n) => n.type !== u.SESSION_START && n.type !== u.SESSION_END
|
|
1107
1213
|
), r = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
|
|
1108
1214
|
a("warn", "Event queue overflow, oldest non-critical event removed", {
|
|
1109
1215
|
data: {
|
|
@@ -1123,7 +1229,7 @@ class Tt extends S {
|
|
|
1123
1229
|
}
|
|
1124
1230
|
handleGoogleAnalyticsIntegration(e) {
|
|
1125
1231
|
if (this.googleAnalytics && e.type === u.CUSTOM && e.custom_event) {
|
|
1126
|
-
if (this.get("mode") ===
|
|
1232
|
+
if (this.get("mode") === V.QA)
|
|
1127
1233
|
return;
|
|
1128
1234
|
this.googleAnalytics.trackEvent(e.custom_event.name, e.custom_event.metadata ?? {});
|
|
1129
1235
|
}
|
|
@@ -1167,13 +1273,13 @@ class Tt extends S {
|
|
|
1167
1273
|
this.eventsQueue = this.eventsQueue.filter((r) => !t.has(r.id));
|
|
1168
1274
|
}
|
|
1169
1275
|
emitEvent(e) {
|
|
1170
|
-
this.emitter && this.emitter.emit(
|
|
1276
|
+
this.emitter && this.emitter.emit(J.EVENT, e);
|
|
1171
1277
|
}
|
|
1172
1278
|
emitEventsQueue(e) {
|
|
1173
|
-
this.emitter && this.emitter.emit(
|
|
1279
|
+
this.emitter && this.emitter.emit(J.QUEUE, e);
|
|
1174
1280
|
}
|
|
1175
1281
|
}
|
|
1176
|
-
class
|
|
1282
|
+
class Lt {
|
|
1177
1283
|
/**
|
|
1178
1284
|
* Gets or creates a unique user ID for the given project.
|
|
1179
1285
|
* The user ID is persisted in localStorage and reused across sessions.
|
|
@@ -1183,14 +1289,14 @@ class _t {
|
|
|
1183
1289
|
* @returns Persistent unique user ID
|
|
1184
1290
|
*/
|
|
1185
1291
|
static getId(e) {
|
|
1186
|
-
const t =
|
|
1292
|
+
const t = Ze, r = e.getItem(t);
|
|
1187
1293
|
if (r)
|
|
1188
1294
|
return r;
|
|
1189
|
-
const
|
|
1190
|
-
return e.setItem(t,
|
|
1295
|
+
const n = dt();
|
|
1296
|
+
return e.setItem(t, n), n;
|
|
1191
1297
|
}
|
|
1192
1298
|
}
|
|
1193
|
-
class
|
|
1299
|
+
class Mt extends T {
|
|
1194
1300
|
storageManager;
|
|
1195
1301
|
eventManager;
|
|
1196
1302
|
projectId;
|
|
@@ -1209,14 +1315,14 @@ class pt extends S {
|
|
|
1209
1315
|
return;
|
|
1210
1316
|
}
|
|
1211
1317
|
const e = this.getProjectId();
|
|
1212
|
-
this.broadcastChannel = new BroadcastChannel(
|
|
1213
|
-
const { action: r, sessionId:
|
|
1318
|
+
this.broadcastChannel = new BroadcastChannel(tt(e)), this.broadcastChannel.onmessage = (t) => {
|
|
1319
|
+
const { action: r, sessionId: n, timestamp: i, projectId: o } = t.data ?? {};
|
|
1214
1320
|
if (o === e) {
|
|
1215
1321
|
if (r === "session_end") {
|
|
1216
1322
|
this.resetSessionState();
|
|
1217
1323
|
return;
|
|
1218
1324
|
}
|
|
1219
|
-
|
|
1325
|
+
n && typeof i == "number" && i > Date.now() - 5e3 && (this.set("sessionId", n), this.set("hasStartSession", !0), this.persistSession(n, i), this.isTracking && this.setupSessionTimeout());
|
|
1220
1326
|
}
|
|
1221
1327
|
};
|
|
1222
1328
|
}
|
|
@@ -1278,7 +1384,7 @@ class pt extends S {
|
|
|
1278
1384
|
this.storageManager.setItem(t, JSON.stringify(e));
|
|
1279
1385
|
}
|
|
1280
1386
|
getSessionStorageKey() {
|
|
1281
|
-
return
|
|
1387
|
+
return et(this.getProjectId());
|
|
1282
1388
|
}
|
|
1283
1389
|
getProjectId() {
|
|
1284
1390
|
return this.projectId;
|
|
@@ -1294,8 +1400,8 @@ class pt extends S {
|
|
|
1294
1400
|
this.set("sessionId", t), this.persistSession(t), r || this.eventManager.track({
|
|
1295
1401
|
type: u.SESSION_START
|
|
1296
1402
|
}), this.initCrossTabSync(), this.shareSession(t), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners();
|
|
1297
|
-
} catch (
|
|
1298
|
-
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null),
|
|
1403
|
+
} catch (n) {
|
|
1404
|
+
throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null), n;
|
|
1299
1405
|
}
|
|
1300
1406
|
}
|
|
1301
1407
|
generateSessionId() {
|
|
@@ -1357,7 +1463,7 @@ class pt extends S {
|
|
|
1357
1463
|
this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupCrossTabSync(), this.cleanupLifecycleListeners(), this.isTracking = !1, this.set("hasStartSession", !1);
|
|
1358
1464
|
}
|
|
1359
1465
|
}
|
|
1360
|
-
class
|
|
1466
|
+
class Nt extends T {
|
|
1361
1467
|
eventManager;
|
|
1362
1468
|
storageManager;
|
|
1363
1469
|
sessionManager = null;
|
|
@@ -1376,7 +1482,7 @@ class It extends S {
|
|
|
1376
1482
|
if (!t)
|
|
1377
1483
|
throw new Error("Cannot start session tracking: config not available");
|
|
1378
1484
|
try {
|
|
1379
|
-
this.sessionManager = new
|
|
1485
|
+
this.sessionManager = new Mt(this.storageManager, this.eventManager, t), this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
|
|
1380
1486
|
} catch (r) {
|
|
1381
1487
|
if (this.sessionManager) {
|
|
1382
1488
|
try {
|
|
@@ -1401,7 +1507,7 @@ class It extends S {
|
|
|
1401
1507
|
this.destroyed || (this.sessionManager && (this.sessionManager.destroy(), this.sessionManager = null), this.destroyed = !0, this.set("hasStartSession", !1));
|
|
1402
1508
|
}
|
|
1403
1509
|
}
|
|
1404
|
-
class
|
|
1510
|
+
class Rt extends T {
|
|
1405
1511
|
eventManager;
|
|
1406
1512
|
onTrack;
|
|
1407
1513
|
originalPushState;
|
|
@@ -1423,11 +1529,11 @@ class vt extends S {
|
|
|
1423
1529
|
};
|
|
1424
1530
|
}
|
|
1425
1531
|
trackCurrentPage = () => {
|
|
1426
|
-
const e = window.location.href, t =
|
|
1532
|
+
const e = window.location.href, t = se(e, this.get("config").sensitiveQueryParams);
|
|
1427
1533
|
if (this.get("pageUrl") === t)
|
|
1428
1534
|
return;
|
|
1429
|
-
const r = Date.now(),
|
|
1430
|
-
if (r - this.lastPageViewTime <
|
|
1535
|
+
const r = Date.now(), n = this.get("config").pageViewThrottleMs ?? 1e3;
|
|
1536
|
+
if (r - this.lastPageViewTime < n)
|
|
1431
1537
|
return;
|
|
1432
1538
|
this.lastPageViewTime = r, this.onTrack();
|
|
1433
1539
|
const i = this.get("pageUrl");
|
|
@@ -1441,7 +1547,7 @@ class vt extends S {
|
|
|
1441
1547
|
});
|
|
1442
1548
|
};
|
|
1443
1549
|
trackInitialPageView() {
|
|
1444
|
-
const e =
|
|
1550
|
+
const e = se(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
|
|
1445
1551
|
this.lastPageViewTime = Date.now(), this.eventManager.track({
|
|
1446
1552
|
type: u.PAGE_VIEW,
|
|
1447
1553
|
page_url: e,
|
|
@@ -1449,9 +1555,9 @@ class vt extends S {
|
|
|
1449
1555
|
}), this.onTrack();
|
|
1450
1556
|
}
|
|
1451
1557
|
extractPageViewData() {
|
|
1452
|
-
const { pathname: e, search: t, hash: r } = window.location, { referrer:
|
|
1453
|
-
return !
|
|
1454
|
-
...
|
|
1558
|
+
const { pathname: e, search: t, hash: r } = window.location, { referrer: n } = document, { title: i } = document;
|
|
1559
|
+
return !n && !i && !e && !t && !r ? void 0 : {
|
|
1560
|
+
...n && { referrer: n },
|
|
1455
1561
|
...i && { title: i },
|
|
1456
1562
|
...e && { pathname: e },
|
|
1457
1563
|
...t && { search: t },
|
|
@@ -1459,7 +1565,7 @@ class vt extends S {
|
|
|
1459
1565
|
};
|
|
1460
1566
|
}
|
|
1461
1567
|
}
|
|
1462
|
-
class
|
|
1568
|
+
class bt extends T {
|
|
1463
1569
|
eventManager;
|
|
1464
1570
|
lastClickTimes = /* @__PURE__ */ new Map();
|
|
1465
1571
|
clickHandler;
|
|
@@ -1469,21 +1575,21 @@ class At extends S {
|
|
|
1469
1575
|
}
|
|
1470
1576
|
startTracking() {
|
|
1471
1577
|
this.clickHandler || (this.clickHandler = (e) => {
|
|
1472
|
-
const t = e, r = t.target,
|
|
1473
|
-
if (!
|
|
1578
|
+
const t = e, r = t.target, n = typeof HTMLElement < "u" && r instanceof HTMLElement ? r : typeof HTMLElement < "u" && r instanceof Node && r.parentElement instanceof HTMLElement ? r.parentElement : null;
|
|
1579
|
+
if (!n) {
|
|
1474
1580
|
a("warn", "Click target not found or not an element");
|
|
1475
1581
|
return;
|
|
1476
1582
|
}
|
|
1477
|
-
if (this.shouldIgnoreElement(
|
|
1583
|
+
if (this.shouldIgnoreElement(n))
|
|
1478
1584
|
return;
|
|
1479
1585
|
const i = this.get("config")?.clickThrottleMs ?? 300;
|
|
1480
|
-
if (i > 0 && !this.checkClickThrottle(
|
|
1586
|
+
if (i > 0 && !this.checkClickThrottle(n, i))
|
|
1481
1587
|
return;
|
|
1482
|
-
const o = this.findTrackingElement(
|
|
1588
|
+
const o = this.findTrackingElement(n), l = this.getRelevantClickElement(n), c = this.calculateClickCoordinates(t, n);
|
|
1483
1589
|
if (o) {
|
|
1484
|
-
const
|
|
1485
|
-
if (
|
|
1486
|
-
const g = this.createCustomEventData(
|
|
1590
|
+
const E = this.extractTrackingData(o);
|
|
1591
|
+
if (E) {
|
|
1592
|
+
const g = this.createCustomEventData(E);
|
|
1487
1593
|
this.eventManager.track({
|
|
1488
1594
|
type: u.CUSTOM,
|
|
1489
1595
|
custom_event: {
|
|
@@ -1493,7 +1599,7 @@ class At extends S {
|
|
|
1493
1599
|
});
|
|
1494
1600
|
}
|
|
1495
1601
|
}
|
|
1496
|
-
const d = this.generateClickData(
|
|
1602
|
+
const d = this.generateClickData(n, l, c);
|
|
1497
1603
|
this.eventManager.track({
|
|
1498
1604
|
type: u.CLICK,
|
|
1499
1605
|
click_data: d
|
|
@@ -1504,22 +1610,22 @@ class At extends S {
|
|
|
1504
1610
|
this.clickHandler && (window.removeEventListener("click", this.clickHandler, !0), this.clickHandler = void 0), this.lastClickTimes.clear(), this.lastPruneTime = 0;
|
|
1505
1611
|
}
|
|
1506
1612
|
shouldIgnoreElement(e) {
|
|
1507
|
-
return e.hasAttribute(`${
|
|
1613
|
+
return e.hasAttribute(`${w}-ignore`) ? !0 : e.closest(`[${w}-ignore]`) !== null;
|
|
1508
1614
|
}
|
|
1509
1615
|
/**
|
|
1510
1616
|
* Checks per-element click throttling to prevent double-clicks and rapid spam
|
|
1511
1617
|
* Returns true if the click should be tracked, false if throttled
|
|
1512
1618
|
*/
|
|
1513
1619
|
checkClickThrottle(e, t) {
|
|
1514
|
-
const r = this.getElementSignature(e),
|
|
1515
|
-
this.pruneThrottleCache(
|
|
1620
|
+
const r = this.getElementSignature(e), n = Date.now();
|
|
1621
|
+
this.pruneThrottleCache(n);
|
|
1516
1622
|
const i = this.lastClickTimes.get(r);
|
|
1517
|
-
return i !== void 0 &&
|
|
1623
|
+
return i !== void 0 && n - i < t ? (a("debug", "ClickHandler: Click suppressed by throttle", {
|
|
1518
1624
|
data: {
|
|
1519
1625
|
signature: r,
|
|
1520
|
-
throttleRemaining: t - (
|
|
1626
|
+
throttleRemaining: t - (n - i)
|
|
1521
1627
|
}
|
|
1522
|
-
}), !1) : (this.lastClickTimes.set(r,
|
|
1628
|
+
}), !1) : (this.lastClickTimes.set(r, n), !0);
|
|
1523
1629
|
}
|
|
1524
1630
|
/**
|
|
1525
1631
|
* Prunes stale entries from the throttle cache to prevent memory leaks
|
|
@@ -1531,10 +1637,10 @@ class At extends S {
|
|
|
1531
1637
|
return;
|
|
1532
1638
|
this.lastPruneTime = e;
|
|
1533
1639
|
const t = e - 3e5;
|
|
1534
|
-
for (const [r,
|
|
1535
|
-
|
|
1640
|
+
for (const [r, n] of this.lastClickTimes.entries())
|
|
1641
|
+
n < t && this.lastClickTimes.delete(r);
|
|
1536
1642
|
if (this.lastClickTimes.size > 1e3) {
|
|
1537
|
-
const r = Array.from(this.lastClickTimes.entries()).sort((o, l) => o[1] - l[1]),
|
|
1643
|
+
const r = Array.from(this.lastClickTimes.entries()).sort((o, l) => o[1] - l[1]), n = this.lastClickTimes.size - 1e3, i = r.slice(0, n);
|
|
1538
1644
|
for (const [o] of i)
|
|
1539
1645
|
this.lastClickTimes.delete(o);
|
|
1540
1646
|
a("debug", "ClickHandler: Pruned throttle cache", {
|
|
@@ -1555,8 +1661,8 @@ class At extends S {
|
|
|
1555
1661
|
const t = e.getAttribute("data-testid");
|
|
1556
1662
|
if (t)
|
|
1557
1663
|
return `[data-testid="${t}"]`;
|
|
1558
|
-
const r = e.getAttribute(`${
|
|
1559
|
-
return r ? `[${
|
|
1664
|
+
const r = e.getAttribute(`${w}-name`);
|
|
1665
|
+
return r ? `[${w}-name="${r}"]` : this.getElementPath(e);
|
|
1560
1666
|
}
|
|
1561
1667
|
/**
|
|
1562
1668
|
* Generates a DOM path for an element (e.g., "body>div>button")
|
|
@@ -1565,20 +1671,20 @@ class At extends S {
|
|
|
1565
1671
|
const t = [];
|
|
1566
1672
|
let r = e;
|
|
1567
1673
|
for (; r && r !== document.body; ) {
|
|
1568
|
-
let
|
|
1674
|
+
let n = r.tagName.toLowerCase();
|
|
1569
1675
|
if (r.className) {
|
|
1570
1676
|
const i = r.className.split(" ")[0];
|
|
1571
|
-
i && (
|
|
1677
|
+
i && (n += `.${i}`);
|
|
1572
1678
|
}
|
|
1573
|
-
t.unshift(
|
|
1679
|
+
t.unshift(n), r = r.parentElement;
|
|
1574
1680
|
}
|
|
1575
1681
|
return t.join(">") || "unknown";
|
|
1576
1682
|
}
|
|
1577
1683
|
findTrackingElement(e) {
|
|
1578
|
-
return e.hasAttribute(`${
|
|
1684
|
+
return e.hasAttribute(`${w}-name`) ? e : e.closest(`[${w}-name]`);
|
|
1579
1685
|
}
|
|
1580
1686
|
getRelevantClickElement(e) {
|
|
1581
|
-
for (const t of
|
|
1687
|
+
for (const t of $e)
|
|
1582
1688
|
try {
|
|
1583
1689
|
if (e.matches(t))
|
|
1584
1690
|
return e;
|
|
@@ -1595,11 +1701,11 @@ class At extends S {
|
|
|
1595
1701
|
return Math.max(0, Math.min(1, Number(e.toFixed(3))));
|
|
1596
1702
|
}
|
|
1597
1703
|
calculateClickCoordinates(e, t) {
|
|
1598
|
-
const r = t.getBoundingClientRect(),
|
|
1599
|
-
return { x:
|
|
1704
|
+
const r = t.getBoundingClientRect(), n = e.clientX, i = e.clientY, o = r.width > 0 ? this.clamp((n - r.left) / r.width) : 0, l = r.height > 0 ? this.clamp((i - r.top) / r.height) : 0;
|
|
1705
|
+
return { x: n, y: i, relativeX: o, relativeY: l };
|
|
1600
1706
|
}
|
|
1601
1707
|
extractTrackingData(e) {
|
|
1602
|
-
const t = e.getAttribute(`${
|
|
1708
|
+
const t = e.getAttribute(`${w}-name`), r = e.getAttribute(`${w}-value`);
|
|
1603
1709
|
if (t)
|
|
1604
1710
|
return {
|
|
1605
1711
|
element: e,
|
|
@@ -1608,9 +1714,9 @@ class At extends S {
|
|
|
1608
1714
|
};
|
|
1609
1715
|
}
|
|
1610
1716
|
generateClickData(e, t, r) {
|
|
1611
|
-
const { x:
|
|
1717
|
+
const { x: n, y: i, relativeX: o, relativeY: l } = r, c = this.getRelevantText(e, t), d = this.extractElementAttributes(t);
|
|
1612
1718
|
return {
|
|
1613
|
-
x:
|
|
1719
|
+
x: n,
|
|
1614
1720
|
y: i,
|
|
1615
1721
|
relativeX: o,
|
|
1616
1722
|
relativeY: l,
|
|
@@ -1628,18 +1734,18 @@ class At extends S {
|
|
|
1628
1734
|
}
|
|
1629
1735
|
sanitizeText(e) {
|
|
1630
1736
|
let t = e;
|
|
1631
|
-
for (const r of
|
|
1632
|
-
const
|
|
1633
|
-
t = t.replace(
|
|
1737
|
+
for (const r of Oe) {
|
|
1738
|
+
const n = new RegExp(r.source, r.flags);
|
|
1739
|
+
t = t.replace(n, "[REDACTED]");
|
|
1634
1740
|
}
|
|
1635
1741
|
return t;
|
|
1636
1742
|
}
|
|
1637
1743
|
getRelevantText(e, t) {
|
|
1638
|
-
const r = e.textContent?.trim() ?? "",
|
|
1639
|
-
if (!r && !
|
|
1744
|
+
const r = e.textContent?.trim() ?? "", n = t.textContent?.trim() ?? "";
|
|
1745
|
+
if (!r && !n)
|
|
1640
1746
|
return "";
|
|
1641
1747
|
let i = "";
|
|
1642
|
-
return r && r.length <= 255 ? i = r :
|
|
1748
|
+
return r && r.length <= 255 ? i = r : n.length <= 255 ? i = n : i = n.slice(0, 252) + "...", this.sanitizeText(i);
|
|
1643
1749
|
}
|
|
1644
1750
|
extractElementAttributes(e) {
|
|
1645
1751
|
const t = [
|
|
@@ -1654,9 +1760,9 @@ class At extends S {
|
|
|
1654
1760
|
"alt",
|
|
1655
1761
|
"role"
|
|
1656
1762
|
], r = {};
|
|
1657
|
-
for (const
|
|
1658
|
-
const i = e.getAttribute(
|
|
1659
|
-
i && (r[
|
|
1763
|
+
for (const n of t) {
|
|
1764
|
+
const i = e.getAttribute(n);
|
|
1765
|
+
i && (r[n] = i);
|
|
1660
1766
|
}
|
|
1661
1767
|
return r;
|
|
1662
1768
|
}
|
|
@@ -1667,7 +1773,7 @@ class At extends S {
|
|
|
1667
1773
|
};
|
|
1668
1774
|
}
|
|
1669
1775
|
}
|
|
1670
|
-
class
|
|
1776
|
+
class Ct extends T {
|
|
1671
1777
|
eventManager;
|
|
1672
1778
|
containers = [];
|
|
1673
1779
|
limitWarningLogged = !1;
|
|
@@ -1691,8 +1797,8 @@ class wt extends S {
|
|
|
1691
1797
|
const t = this.findScrollableElements();
|
|
1692
1798
|
if (this.isWindowScrollable() && this.setupScrollContainer(window, "window"), t.length > 0) {
|
|
1693
1799
|
for (const r of t) {
|
|
1694
|
-
const
|
|
1695
|
-
this.setupScrollContainer(r,
|
|
1800
|
+
const n = this.getElementSelector(r);
|
|
1801
|
+
this.setupScrollContainer(r, n);
|
|
1696
1802
|
}
|
|
1697
1803
|
this.applyPrimaryScrollSelectorIfConfigured();
|
|
1698
1804
|
return;
|
|
@@ -1713,8 +1819,8 @@ class wt extends S {
|
|
|
1713
1819
|
if (!document.body)
|
|
1714
1820
|
return [];
|
|
1715
1821
|
const e = [], t = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {
|
|
1716
|
-
acceptNode: (
|
|
1717
|
-
const i =
|
|
1822
|
+
acceptNode: (n) => {
|
|
1823
|
+
const i = n;
|
|
1718
1824
|
if (!i.isConnected || !i.offsetParent)
|
|
1719
1825
|
return NodeFilter.FILTER_SKIP;
|
|
1720
1826
|
const o = getComputedStyle(i);
|
|
@@ -1723,8 +1829,8 @@ class wt extends S {
|
|
|
1723
1829
|
});
|
|
1724
1830
|
let r;
|
|
1725
1831
|
for (; (r = t.nextNode()) && e.length < 10; ) {
|
|
1726
|
-
const
|
|
1727
|
-
this.isElementScrollable(
|
|
1832
|
+
const n = r;
|
|
1833
|
+
this.isElementScrollable(n) && e.push(n);
|
|
1728
1834
|
}
|
|
1729
1835
|
return e;
|
|
1730
1836
|
}
|
|
@@ -1735,7 +1841,7 @@ class wt extends S {
|
|
|
1735
1841
|
if (t.id)
|
|
1736
1842
|
return `#${t.id}`;
|
|
1737
1843
|
if (t.className && typeof t.className == "string") {
|
|
1738
|
-
const r = t.className.split(" ").filter((
|
|
1844
|
+
const r = t.className.split(" ").filter((n) => n.trim())[0];
|
|
1739
1845
|
if (r)
|
|
1740
1846
|
return `.${r}`;
|
|
1741
1847
|
}
|
|
@@ -1747,17 +1853,17 @@ class wt extends S {
|
|
|
1747
1853
|
setupScrollContainer(e, t) {
|
|
1748
1854
|
if (this.containers.some((d) => d.element === e) || e !== window && !this.isElementScrollable(e))
|
|
1749
1855
|
return;
|
|
1750
|
-
const
|
|
1751
|
-
|
|
1856
|
+
const n = this.getScrollTop(e), i = this.calculateScrollDepth(
|
|
1857
|
+
n,
|
|
1752
1858
|
this.getScrollHeight(e),
|
|
1753
1859
|
this.getViewportHeight(e)
|
|
1754
1860
|
), o = this.determineIfPrimary(e), l = {
|
|
1755
1861
|
element: e,
|
|
1756
1862
|
selector: t,
|
|
1757
1863
|
isPrimary: o,
|
|
1758
|
-
lastScrollPos:
|
|
1864
|
+
lastScrollPos: n,
|
|
1759
1865
|
lastDepth: i,
|
|
1760
|
-
lastDirection:
|
|
1866
|
+
lastDirection: x.DOWN,
|
|
1761
1867
|
lastEventTime: 0,
|
|
1762
1868
|
firstScrollEventTime: null,
|
|
1763
1869
|
maxDepthReached: i,
|
|
@@ -1767,8 +1873,8 @@ class wt extends S {
|
|
|
1767
1873
|
this.get("suppressNextScroll") || (l.firstScrollEventTime === null && (l.firstScrollEventTime = Date.now()), this.clearContainerTimer(l), l.debounceTimer = window.setTimeout(() => {
|
|
1768
1874
|
const d = this.calculateScrollData(l);
|
|
1769
1875
|
if (d) {
|
|
1770
|
-
const
|
|
1771
|
-
this.processScrollEvent(l, d,
|
|
1876
|
+
const E = Date.now();
|
|
1877
|
+
this.processScrollEvent(l, d, E);
|
|
1772
1878
|
}
|
|
1773
1879
|
l.debounceTimer = null;
|
|
1774
1880
|
}, 250));
|
|
@@ -1779,8 +1885,8 @@ class wt extends S {
|
|
|
1779
1885
|
if (!this.shouldEmitScrollEvent(e, t, r))
|
|
1780
1886
|
return;
|
|
1781
1887
|
e.lastEventTime = r, e.lastDepth = t.depth, e.lastDirection = t.direction;
|
|
1782
|
-
const
|
|
1783
|
-
this.set("scrollEventCount",
|
|
1888
|
+
const n = this.get("scrollEventCount") ?? 0;
|
|
1889
|
+
this.set("scrollEventCount", n + 1), this.eventManager.track({
|
|
1784
1890
|
type: u.SCROLL,
|
|
1785
1891
|
scroll_data: {
|
|
1786
1892
|
...t,
|
|
@@ -1816,26 +1922,26 @@ class wt extends S {
|
|
|
1816
1922
|
e.debounceTimer !== null && (clearTimeout(e.debounceTimer), e.debounceTimer = null);
|
|
1817
1923
|
}
|
|
1818
1924
|
getScrollDirection(e, t) {
|
|
1819
|
-
return e > t ?
|
|
1925
|
+
return e > t ? x.DOWN : x.UP;
|
|
1820
1926
|
}
|
|
1821
1927
|
calculateScrollDepth(e, t, r) {
|
|
1822
1928
|
if (t <= r)
|
|
1823
1929
|
return 0;
|
|
1824
|
-
const
|
|
1825
|
-
return Math.min(100, Math.max(0, Math.floor(e /
|
|
1930
|
+
const n = t - r;
|
|
1931
|
+
return Math.min(100, Math.max(0, Math.floor(e / n * 100)));
|
|
1826
1932
|
}
|
|
1827
1933
|
calculateScrollData(e) {
|
|
1828
|
-
const { element: t, lastScrollPos: r, lastEventTime:
|
|
1934
|
+
const { element: t, lastScrollPos: r, lastEventTime: n } = e, i = this.getScrollTop(t), o = Date.now(), l = Math.abs(i - r);
|
|
1829
1935
|
if (l < 10 || t === window && !this.isWindowScrollable())
|
|
1830
1936
|
return null;
|
|
1831
|
-
const c = this.getViewportHeight(t), d = this.getScrollHeight(t),
|
|
1937
|
+
const c = this.getViewportHeight(t), d = this.getScrollHeight(t), E = this.getScrollDirection(i, r), g = this.calculateScrollDepth(i, d, c);
|
|
1832
1938
|
let v;
|
|
1833
|
-
|
|
1834
|
-
const
|
|
1939
|
+
n > 0 ? v = o - n : e.firstScrollEventTime !== null ? v = o - e.firstScrollEventTime : v = 250;
|
|
1940
|
+
const S = Math.round(l / v * 1e3);
|
|
1835
1941
|
return g > e.maxDepthReached && (e.maxDepthReached = g), e.lastScrollPos = i, {
|
|
1836
1942
|
depth: g,
|
|
1837
|
-
direction:
|
|
1838
|
-
velocity:
|
|
1943
|
+
direction: E,
|
|
1944
|
+
velocity: S,
|
|
1839
1945
|
max_depth_reached: e.maxDepthReached
|
|
1840
1946
|
};
|
|
1841
1947
|
}
|
|
@@ -1849,30 +1955,30 @@ class wt extends S {
|
|
|
1849
1955
|
return e === window ? document.documentElement.scrollHeight : e.scrollHeight;
|
|
1850
1956
|
}
|
|
1851
1957
|
isElementScrollable(e) {
|
|
1852
|
-
const t = getComputedStyle(e), r = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflow === "auto" || t.overflow === "scroll",
|
|
1853
|
-
return r &&
|
|
1958
|
+
const t = getComputedStyle(e), r = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflow === "auto" || t.overflow === "scroll", n = e.scrollHeight > e.clientHeight;
|
|
1959
|
+
return r && n;
|
|
1854
1960
|
}
|
|
1855
1961
|
applyPrimaryScrollSelector(e) {
|
|
1856
1962
|
let t;
|
|
1857
1963
|
if (e === "window")
|
|
1858
1964
|
t = window;
|
|
1859
1965
|
else {
|
|
1860
|
-
const
|
|
1861
|
-
if (!(
|
|
1966
|
+
const n = document.querySelector(e);
|
|
1967
|
+
if (!(n instanceof HTMLElement)) {
|
|
1862
1968
|
a("warn", `Selector "${e}" did not match an HTMLElement`);
|
|
1863
1969
|
return;
|
|
1864
1970
|
}
|
|
1865
|
-
t =
|
|
1971
|
+
t = n;
|
|
1866
1972
|
}
|
|
1867
|
-
this.containers.forEach((
|
|
1868
|
-
this.updateContainerPrimary(
|
|
1869
|
-
}), !this.containers.some((
|
|
1973
|
+
this.containers.forEach((n) => {
|
|
1974
|
+
this.updateContainerPrimary(n, n.element === t);
|
|
1975
|
+
}), !this.containers.some((n) => n.element === t) && t instanceof HTMLElement && this.isElementScrollable(t) && this.setupScrollContainer(t, e);
|
|
1870
1976
|
}
|
|
1871
1977
|
updateContainerPrimary(e, t) {
|
|
1872
1978
|
e.isPrimary = t;
|
|
1873
1979
|
}
|
|
1874
1980
|
}
|
|
1875
|
-
class
|
|
1981
|
+
class Ot extends T {
|
|
1876
1982
|
eventManager;
|
|
1877
1983
|
trackedElements = /* @__PURE__ */ new Map();
|
|
1878
1984
|
observer = null;
|
|
@@ -1924,8 +2030,8 @@ class yt extends S {
|
|
|
1924
2030
|
let t = this.trackedElements.size;
|
|
1925
2031
|
for (const r of this.config.elements)
|
|
1926
2032
|
try {
|
|
1927
|
-
const
|
|
1928
|
-
for (const i of Array.from(
|
|
2033
|
+
const n = document.querySelectorAll(r.selector);
|
|
2034
|
+
for (const i of Array.from(n)) {
|
|
1929
2035
|
if (t >= e) {
|
|
1930
2036
|
a("warn", "ViewportHandler: Maximum tracked elements reached", {
|
|
1931
2037
|
data: {
|
|
@@ -1936,7 +2042,7 @@ class yt extends S {
|
|
|
1936
2042
|
});
|
|
1937
2043
|
return;
|
|
1938
2044
|
}
|
|
1939
|
-
i.hasAttribute(`${
|
|
2045
|
+
i.hasAttribute(`${w}-ignore`) || this.trackedElements.has(i) || (this.trackedElements.set(i, {
|
|
1940
2046
|
element: i,
|
|
1941
2047
|
selector: r.selector,
|
|
1942
2048
|
id: r.id,
|
|
@@ -1946,8 +2052,8 @@ class yt extends S {
|
|
|
1946
2052
|
lastFiredTime: null
|
|
1947
2053
|
}), this.observer?.observe(i), t++);
|
|
1948
2054
|
}
|
|
1949
|
-
} catch (
|
|
1950
|
-
a("warn", `ViewportHandler: Invalid selector "${r.selector}"`, { error:
|
|
2055
|
+
} catch (n) {
|
|
2056
|
+
a("warn", `ViewportHandler: Invalid selector "${r.selector}"`, { error: n });
|
|
1951
2057
|
}
|
|
1952
2058
|
a("debug", "ViewportHandler: Elements tracked", {
|
|
1953
2059
|
data: { count: t, limit: e }
|
|
@@ -1960,11 +2066,11 @@ class yt extends S {
|
|
|
1960
2066
|
if (!this.config) return;
|
|
1961
2067
|
const t = this.config.minDwellTime ?? 1e3;
|
|
1962
2068
|
for (const r of e) {
|
|
1963
|
-
const
|
|
1964
|
-
|
|
2069
|
+
const n = this.trackedElements.get(r.target);
|
|
2070
|
+
n && (r.isIntersecting ? n.startTime === null && (n.startTime = performance.now(), n.timeoutId = window.setTimeout(() => {
|
|
1965
2071
|
const i = Math.round(r.intersectionRatio * 100) / 100;
|
|
1966
|
-
this.fireViewportEvent(
|
|
1967
|
-
}, t)) :
|
|
2072
|
+
this.fireViewportEvent(n, i);
|
|
2073
|
+
}, t)) : n.startTime !== null && (n.timeoutId !== null && (window.clearTimeout(n.timeoutId), n.timeoutId = null), n.startTime = null));
|
|
1968
2074
|
}
|
|
1969
2075
|
};
|
|
1970
2076
|
/**
|
|
@@ -1975,12 +2081,12 @@ class yt extends S {
|
|
|
1975
2081
|
const r = Math.round(performance.now() - e.startTime);
|
|
1976
2082
|
if (e.element.hasAttribute("data-tlog-ignore"))
|
|
1977
2083
|
return;
|
|
1978
|
-
const
|
|
1979
|
-
if (e.lastFiredTime !== null && i - e.lastFiredTime <
|
|
2084
|
+
const n = this.config?.cooldownPeriod ?? 6e4, i = Date.now();
|
|
2085
|
+
if (e.lastFiredTime !== null && i - e.lastFiredTime < n) {
|
|
1980
2086
|
a("debug", "ViewportHandler: Event suppressed by cooldown period", {
|
|
1981
2087
|
data: {
|
|
1982
2088
|
selector: e.selector,
|
|
1983
|
-
cooldownRemaining:
|
|
2089
|
+
cooldownRemaining: n - (i - e.lastFiredTime)
|
|
1984
2090
|
}
|
|
1985
2091
|
}), e.startTime = null, e.timeoutId = null;
|
|
1986
2092
|
return;
|
|
@@ -2025,15 +2131,15 @@ class yt extends S {
|
|
|
2025
2131
|
cleanupRemovedNodes(e) {
|
|
2026
2132
|
e.forEach((t) => {
|
|
2027
2133
|
if (t.nodeType !== 1) return;
|
|
2028
|
-
const r = t,
|
|
2029
|
-
|
|
2134
|
+
const r = t, n = this.trackedElements.get(r);
|
|
2135
|
+
n && (n.timeoutId !== null && window.clearTimeout(n.timeoutId), this.observer?.unobserve(r), this.trackedElements.delete(r)), Array.from(this.trackedElements.keys()).filter((o) => r.contains(o)).forEach((o) => {
|
|
2030
2136
|
const l = this.trackedElements.get(o);
|
|
2031
2137
|
l && l.timeoutId !== null && window.clearTimeout(l.timeoutId), this.observer?.unobserve(o), this.trackedElements.delete(o);
|
|
2032
2138
|
});
|
|
2033
2139
|
});
|
|
2034
2140
|
}
|
|
2035
2141
|
}
|
|
2036
|
-
class
|
|
2142
|
+
class Pt extends T {
|
|
2037
2143
|
isInitialized = !1;
|
|
2038
2144
|
async initialize() {
|
|
2039
2145
|
if (this.isInitialized)
|
|
@@ -2069,12 +2175,12 @@ class Lt extends S {
|
|
|
2069
2175
|
}
|
|
2070
2176
|
async loadScript(e) {
|
|
2071
2177
|
return new Promise((t, r) => {
|
|
2072
|
-
const
|
|
2073
|
-
|
|
2178
|
+
const n = document.createElement("script");
|
|
2179
|
+
n.id = "tracelog-ga-script", n.async = !0, n.src = `https://www.googletagmanager.com/gtag/js?id=${e}`, n.onload = () => {
|
|
2074
2180
|
t();
|
|
2075
|
-
},
|
|
2181
|
+
}, n.onerror = () => {
|
|
2076
2182
|
r(new Error("Failed to load Google Analytics script"));
|
|
2077
|
-
}, document.head.appendChild(
|
|
2183
|
+
}, document.head.appendChild(n);
|
|
2078
2184
|
});
|
|
2079
2185
|
}
|
|
2080
2186
|
configureGtag(e, t) {
|
|
@@ -2089,7 +2195,7 @@ class Lt extends S {
|
|
|
2089
2195
|
`, document.head.appendChild(r);
|
|
2090
2196
|
}
|
|
2091
2197
|
}
|
|
2092
|
-
class
|
|
2198
|
+
class Dt {
|
|
2093
2199
|
storage;
|
|
2094
2200
|
sessionStorageRef;
|
|
2095
2201
|
fallbackStorage = /* @__PURE__ */ new Map();
|
|
@@ -2205,8 +2311,8 @@ class Mt {
|
|
|
2205
2311
|
} catch {
|
|
2206
2312
|
}
|
|
2207
2313
|
}), !0;
|
|
2208
|
-
const r = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"],
|
|
2209
|
-
return
|
|
2314
|
+
const r = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"], n = e.filter((i) => !r.some((o) => i.startsWith(o)));
|
|
2315
|
+
return n.length > 0 ? (n.slice(0, 5).forEach((o) => {
|
|
2210
2316
|
try {
|
|
2211
2317
|
this.storage.removeItem(o);
|
|
2212
2318
|
} catch {
|
|
@@ -2267,19 +2373,20 @@ class Mt {
|
|
|
2267
2373
|
this.fallbackSessionStorage.delete(e);
|
|
2268
2374
|
}
|
|
2269
2375
|
}
|
|
2270
|
-
class
|
|
2376
|
+
class Vt extends T {
|
|
2271
2377
|
eventManager;
|
|
2272
2378
|
reportedByNav = /* @__PURE__ */ new Map();
|
|
2273
2379
|
navigationHistory = [];
|
|
2274
2380
|
// FIFO queue for tracking navigation order
|
|
2275
2381
|
observers = [];
|
|
2276
|
-
vitalThresholds
|
|
2382
|
+
vitalThresholds;
|
|
2277
2383
|
lastLongTaskSentAt = 0;
|
|
2278
2384
|
constructor(e) {
|
|
2279
|
-
super(), this.eventManager = e;
|
|
2385
|
+
super(), this.eventManager = e, this.vitalThresholds = pe(re);
|
|
2280
2386
|
}
|
|
2281
2387
|
async startTracking() {
|
|
2282
|
-
|
|
2388
|
+
const e = this.get("config"), t = e?.webVitalsMode ?? re;
|
|
2389
|
+
this.vitalThresholds = pe(t), e?.webVitalsThresholds && (this.vitalThresholds = { ...this.vitalThresholds, ...e.webVitalsThresholds }), await this.initWebVitals(), this.observeLongTasks();
|
|
2283
2390
|
}
|
|
2284
2391
|
stopTracking() {
|
|
2285
2392
|
this.observers.forEach((e, t) => {
|
|
@@ -2294,7 +2401,7 @@ class Nt extends S {
|
|
|
2294
2401
|
this.reportTTFB(), this.safeObserve(
|
|
2295
2402
|
"largest-contentful-paint",
|
|
2296
2403
|
(r) => {
|
|
2297
|
-
const
|
|
2404
|
+
const n = r.getEntries(), i = n[n.length - 1];
|
|
2298
2405
|
i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(2)) });
|
|
2299
2406
|
},
|
|
2300
2407
|
{ type: "largest-contentful-paint", buffered: !0 },
|
|
@@ -2304,8 +2411,8 @@ class Nt extends S {
|
|
|
2304
2411
|
this.safeObserve(
|
|
2305
2412
|
"layout-shift",
|
|
2306
2413
|
(r) => {
|
|
2307
|
-
const
|
|
2308
|
-
|
|
2414
|
+
const n = this.getNavigationId();
|
|
2415
|
+
n !== t && (e = 0, t = n);
|
|
2309
2416
|
const i = r.getEntries();
|
|
2310
2417
|
for (const o of i) {
|
|
2311
2418
|
if (o.hadRecentInput === !0)
|
|
@@ -2319,32 +2426,32 @@ class Nt extends S {
|
|
|
2319
2426
|
), this.safeObserve(
|
|
2320
2427
|
"paint",
|
|
2321
2428
|
(r) => {
|
|
2322
|
-
for (const
|
|
2323
|
-
|
|
2429
|
+
for (const n of r.getEntries())
|
|
2430
|
+
n.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(n.startTime.toFixed(2)) });
|
|
2324
2431
|
},
|
|
2325
2432
|
{ type: "paint", buffered: !0 },
|
|
2326
2433
|
!0
|
|
2327
2434
|
), this.safeObserve(
|
|
2328
2435
|
"event",
|
|
2329
2436
|
(r) => {
|
|
2330
|
-
let
|
|
2437
|
+
let n = 0;
|
|
2331
2438
|
const i = r.getEntries();
|
|
2332
2439
|
for (const o of i) {
|
|
2333
2440
|
const l = (o.processingEnd ?? 0) - (o.startTime ?? 0);
|
|
2334
|
-
|
|
2441
|
+
n = Math.max(n, l);
|
|
2335
2442
|
}
|
|
2336
|
-
|
|
2443
|
+
n > 0 && this.sendVital({ type: "INP", value: Number(n.toFixed(2)) });
|
|
2337
2444
|
},
|
|
2338
2445
|
{ type: "event", buffered: !0 }
|
|
2339
2446
|
);
|
|
2340
2447
|
}
|
|
2341
2448
|
async initWebVitals() {
|
|
2342
2449
|
try {
|
|
2343
|
-
const { onLCP: e, onCLS: t, onFCP: r, onTTFB:
|
|
2450
|
+
const { onLCP: e, onCLS: t, onFCP: r, onTTFB: n, onINP: i } = await Promise.resolve().then(() => rr), o = (l) => (c) => {
|
|
2344
2451
|
const d = Number(c.value.toFixed(2));
|
|
2345
2452
|
this.sendVital({ type: l, value: d });
|
|
2346
2453
|
};
|
|
2347
|
-
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), r(o("FCP"), { reportAllChanges: !1 }),
|
|
2454
|
+
e(o("LCP"), { reportAllChanges: !1 }), t(o("CLS"), { reportAllChanges: !1 }), r(o("FCP"), { reportAllChanges: !1 }), n(o("TTFB"), { reportAllChanges: !1 }), i(o("INP"), { reportAllChanges: !1 });
|
|
2348
2455
|
} catch (e) {
|
|
2349
2456
|
a("warn", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
|
|
2350
2457
|
}
|
|
@@ -2366,8 +2473,8 @@ class Nt extends S {
|
|
|
2366
2473
|
(e) => {
|
|
2367
2474
|
const t = e.getEntries();
|
|
2368
2475
|
for (const r of t) {
|
|
2369
|
-
const
|
|
2370
|
-
i - this.lastLongTaskSentAt >=
|
|
2476
|
+
const n = Number(r.duration.toFixed(2)), i = Date.now();
|
|
2477
|
+
i - this.lastLongTaskSentAt >= st && (this.shouldSendVital("LONG_TASK", n) && this.trackWebVital("LONG_TASK", n), this.lastLongTaskSentAt = i);
|
|
2371
2478
|
}
|
|
2372
2479
|
},
|
|
2373
2480
|
{ type: "longtask", buffered: !0 }
|
|
@@ -2383,7 +2490,7 @@ class Nt extends S {
|
|
|
2383
2490
|
return;
|
|
2384
2491
|
if (r)
|
|
2385
2492
|
r.add(e.type);
|
|
2386
|
-
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length >
|
|
2493
|
+
else if (this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type])), this.navigationHistory.push(t), this.navigationHistory.length > nt) {
|
|
2387
2494
|
const i = this.navigationHistory.shift();
|
|
2388
2495
|
i && this.reportedByNav.delete(i);
|
|
2389
2496
|
}
|
|
@@ -2419,7 +2526,7 @@ class Nt extends S {
|
|
|
2419
2526
|
const t = PerformanceObserver.supportedEntryTypes;
|
|
2420
2527
|
return !t || t.includes(e);
|
|
2421
2528
|
}
|
|
2422
|
-
safeObserve(e, t, r,
|
|
2529
|
+
safeObserve(e, t, r, n = !1) {
|
|
2423
2530
|
try {
|
|
2424
2531
|
if (!this.isObserverSupported(e))
|
|
2425
2532
|
return !1;
|
|
@@ -2432,13 +2539,13 @@ class Nt extends S {
|
|
|
2432
2539
|
data: { type: e }
|
|
2433
2540
|
});
|
|
2434
2541
|
}
|
|
2435
|
-
if (
|
|
2542
|
+
if (n)
|
|
2436
2543
|
try {
|
|
2437
2544
|
l.disconnect();
|
|
2438
2545
|
} catch {
|
|
2439
2546
|
}
|
|
2440
2547
|
});
|
|
2441
|
-
return i.observe(r ?? { type: e, buffered: !0 }),
|
|
2548
|
+
return i.observe(r ?? { type: e, buffered: !0 }), n || this.observers.push(i), !0;
|
|
2442
2549
|
} catch (i) {
|
|
2443
2550
|
return a("warn", "Failed to create performance observer", {
|
|
2444
2551
|
error: i,
|
|
@@ -2453,7 +2560,7 @@ class Nt extends S {
|
|
|
2453
2560
|
return !(typeof r == "number" && t <= r);
|
|
2454
2561
|
}
|
|
2455
2562
|
}
|
|
2456
|
-
class
|
|
2563
|
+
class kt extends T {
|
|
2457
2564
|
eventManager;
|
|
2458
2565
|
recentErrors = /* @__PURE__ */ new Map();
|
|
2459
2566
|
errorBurstCounter = 0;
|
|
@@ -2476,14 +2583,14 @@ class Rt extends S {
|
|
|
2476
2583
|
const e = Date.now();
|
|
2477
2584
|
if (e < this.burstBackoffUntil)
|
|
2478
2585
|
return !1;
|
|
2479
|
-
if (e - this.burstWindowStart >
|
|
2480
|
-
return this.burstBackoffUntil = e +
|
|
2586
|
+
if (e - this.burstWindowStart > ot && (this.errorBurstCounter = 0, this.burstWindowStart = e), this.errorBurstCounter++, this.errorBurstCounter > at)
|
|
2587
|
+
return this.burstBackoffUntil = e + ve, a("warn", "Error burst detected - entering cooldown", {
|
|
2481
2588
|
data: {
|
|
2482
2589
|
errorsInWindow: this.errorBurstCounter,
|
|
2483
|
-
cooldownMs:
|
|
2590
|
+
cooldownMs: ve
|
|
2484
2591
|
}
|
|
2485
2592
|
}), !1;
|
|
2486
|
-
const r = this.get("config")?.errorSampling ??
|
|
2593
|
+
const r = this.get("config")?.errorSampling ?? Pe;
|
|
2487
2594
|
return Math.random() < r;
|
|
2488
2595
|
}
|
|
2489
2596
|
handleError = (e) => {
|
|
@@ -2527,34 +2634,34 @@ class Rt extends S {
|
|
|
2527
2634
|
}
|
|
2528
2635
|
}
|
|
2529
2636
|
sanitize(e) {
|
|
2530
|
-
let t = e.length >
|
|
2531
|
-
for (const r of
|
|
2532
|
-
const
|
|
2533
|
-
t = t.replace(
|
|
2637
|
+
let t = e.length > _e ? e.slice(0, _e) + "..." : e;
|
|
2638
|
+
for (const r of Oe) {
|
|
2639
|
+
const n = new RegExp(r.source, r.flags);
|
|
2640
|
+
t = t.replace(n, "[REDACTED]");
|
|
2534
2641
|
}
|
|
2535
2642
|
return t;
|
|
2536
2643
|
}
|
|
2537
2644
|
shouldSuppressError(e, t) {
|
|
2538
|
-
const r = Date.now(),
|
|
2539
|
-
return i && r - i <
|
|
2645
|
+
const r = Date.now(), n = `${e}:${t}`, i = this.recentErrors.get(n);
|
|
2646
|
+
return i && r - i < Ie ? (this.recentErrors.set(n, r), !0) : (this.recentErrors.set(n, r), this.recentErrors.size > it ? (this.recentErrors.clear(), this.recentErrors.set(n, r), !1) : (this.recentErrors.size > F && this.pruneOldErrors(), !1));
|
|
2540
2647
|
}
|
|
2541
2648
|
pruneOldErrors() {
|
|
2542
2649
|
const e = Date.now();
|
|
2543
|
-
for (const [
|
|
2544
|
-
e - i >
|
|
2545
|
-
if (this.recentErrors.size <=
|
|
2650
|
+
for (const [n, i] of this.recentErrors.entries())
|
|
2651
|
+
e - i > Ie && this.recentErrors.delete(n);
|
|
2652
|
+
if (this.recentErrors.size <= F)
|
|
2546
2653
|
return;
|
|
2547
|
-
const t = Array.from(this.recentErrors.entries()).sort((
|
|
2548
|
-
for (let
|
|
2549
|
-
const i = t[
|
|
2654
|
+
const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]), r = this.recentErrors.size - F;
|
|
2655
|
+
for (let n = 0; n < r; n += 1) {
|
|
2656
|
+
const i = t[n];
|
|
2550
2657
|
i && this.recentErrors.delete(i[0]);
|
|
2551
2658
|
}
|
|
2552
2659
|
}
|
|
2553
2660
|
}
|
|
2554
|
-
class
|
|
2661
|
+
class Ut extends T {
|
|
2555
2662
|
isInitialized = !1;
|
|
2556
2663
|
suppressNextScrollTimer = null;
|
|
2557
|
-
emitter = new
|
|
2664
|
+
emitter = new wt();
|
|
2558
2665
|
managers = {};
|
|
2559
2666
|
handlers = {};
|
|
2560
2667
|
integrations = {};
|
|
@@ -2563,9 +2670,9 @@ class Ot extends S {
|
|
|
2563
2670
|
}
|
|
2564
2671
|
async init(e = {}) {
|
|
2565
2672
|
if (!this.isInitialized) {
|
|
2566
|
-
this.managers.storage = new
|
|
2673
|
+
this.managers.storage = new Dt();
|
|
2567
2674
|
try {
|
|
2568
|
-
this.setupState(e), await this.setupIntegrations(), this.managers.event = new
|
|
2675
|
+
this.setupState(e), await this.setupIntegrations(), this.managers.event = new At(this.managers.storage, this.integrations.googleAnalytics, this.emitter), this.initializeHandlers(), await this.managers.event.recoverPersistedEvents().catch((t) => {
|
|
2569
2676
|
a("warn", "Failed to recover persisted events", { error: t });
|
|
2570
2677
|
}), this.isInitialized = !0;
|
|
2571
2678
|
} catch (t) {
|
|
@@ -2578,10 +2685,10 @@ class Ot extends S {
|
|
|
2578
2685
|
sendCustomEvent(e, t) {
|
|
2579
2686
|
if (!this.managers.event)
|
|
2580
2687
|
return;
|
|
2581
|
-
const { valid: r, error:
|
|
2688
|
+
const { valid: r, error: n, sanitizedMetadata: i } = vt(e, t);
|
|
2582
2689
|
if (!r) {
|
|
2583
|
-
if (this.get("mode") ===
|
|
2584
|
-
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${
|
|
2690
|
+
if (this.get("mode") === V.QA)
|
|
2691
|
+
throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${n}`);
|
|
2585
2692
|
return;
|
|
2586
2693
|
}
|
|
2587
2694
|
this.managers.event.track({
|
|
@@ -2609,27 +2716,27 @@ class Ot extends S {
|
|
|
2609
2716
|
}
|
|
2610
2717
|
setupState(e = {}) {
|
|
2611
2718
|
this.set("config", e);
|
|
2612
|
-
const t =
|
|
2719
|
+
const t = Lt.getId(this.managers.storage);
|
|
2613
2720
|
this.set("userId", t);
|
|
2614
|
-
const r =
|
|
2721
|
+
const r = ft(e);
|
|
2615
2722
|
this.set("collectApiUrl", r);
|
|
2616
|
-
const
|
|
2617
|
-
this.set("device",
|
|
2618
|
-
const i =
|
|
2723
|
+
const n = qe();
|
|
2724
|
+
this.set("device", n);
|
|
2725
|
+
const i = se(window.location.href, e.sensitiveQueryParams);
|
|
2619
2726
|
this.set("pageUrl", i);
|
|
2620
|
-
const o =
|
|
2727
|
+
const o = ct() ? V.QA : void 0;
|
|
2621
2728
|
o && this.set("mode", o);
|
|
2622
2729
|
}
|
|
2623
2730
|
async setupIntegrations() {
|
|
2624
2731
|
if (this.get("config").integrations?.googleAnalytics?.measurementId?.trim())
|
|
2625
2732
|
try {
|
|
2626
|
-
this.integrations.googleAnalytics = new
|
|
2733
|
+
this.integrations.googleAnalytics = new Pt(), await this.integrations.googleAnalytics.initialize();
|
|
2627
2734
|
} catch {
|
|
2628
2735
|
this.integrations.googleAnalytics = void 0;
|
|
2629
2736
|
}
|
|
2630
2737
|
}
|
|
2631
2738
|
initializeHandlers() {
|
|
2632
|
-
this.handlers.session = new
|
|
2739
|
+
this.handlers.session = new Nt(
|
|
2633
2740
|
this.managers.storage,
|
|
2634
2741
|
this.managers.event
|
|
2635
2742
|
), this.handlers.session.startTracking();
|
|
@@ -2638,89 +2745,85 @@ class Ot extends S {
|
|
|
2638
2745
|
this.set("suppressNextScroll", !1);
|
|
2639
2746
|
}, 500);
|
|
2640
2747
|
};
|
|
2641
|
-
this.handlers.pageView = new
|
|
2748
|
+
this.handlers.pageView = new Rt(this.managers.event, e), this.handlers.pageView.startTracking(), this.handlers.click = new bt(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new Ct(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new Vt(this.managers.event), this.handlers.performance.startTracking().catch((t) => {
|
|
2642
2749
|
a("warn", "Failed to start performance tracking", { error: t });
|
|
2643
|
-
}), this.handlers.error = new
|
|
2750
|
+
}), this.handlers.error = new kt(this.managers.event), this.handlers.error.startTracking(), this.get("config").viewport && (this.handlers.viewport = new Ot(this.managers.event), this.handlers.viewport.startTracking());
|
|
2644
2751
|
}
|
|
2645
2752
|
}
|
|
2646
2753
|
const N = [];
|
|
2647
|
-
let
|
|
2648
|
-
const
|
|
2649
|
-
if (!(typeof window > "u" || typeof document > "u") && !window.__traceLogDisabled && !
|
|
2754
|
+
let m = null, C = !1, G = !1;
|
|
2755
|
+
const Ht = async (s) => {
|
|
2756
|
+
if (!(typeof window > "u" || typeof document > "u") && !window.__traceLogDisabled && !m && !C) {
|
|
2650
2757
|
C = !0;
|
|
2651
2758
|
try {
|
|
2652
|
-
const e =
|
|
2759
|
+
const e = Tt(s ?? {}), t = new Ut();
|
|
2653
2760
|
try {
|
|
2654
2761
|
N.forEach(({ event: i, callback: o }) => {
|
|
2655
2762
|
t.on(i, o);
|
|
2656
2763
|
}), N.length = 0;
|
|
2657
|
-
const r = t.init(e),
|
|
2764
|
+
const r = t.init(e), n = new Promise((i, o) => {
|
|
2658
2765
|
setTimeout(() => {
|
|
2659
2766
|
o(new Error("[TraceLog] Initialization timeout after 10000ms"));
|
|
2660
2767
|
}, 1e4);
|
|
2661
2768
|
});
|
|
2662
|
-
await Promise.race([r,
|
|
2769
|
+
await Promise.race([r, n]), m = t;
|
|
2663
2770
|
} catch (r) {
|
|
2664
2771
|
try {
|
|
2665
2772
|
t.destroy(!0);
|
|
2666
|
-
} catch (
|
|
2667
|
-
a("error", "Failed to cleanup partially initialized app", { error:
|
|
2773
|
+
} catch (n) {
|
|
2774
|
+
a("error", "Failed to cleanup partially initialized app", { error: n });
|
|
2668
2775
|
}
|
|
2669
2776
|
throw r;
|
|
2670
2777
|
}
|
|
2671
2778
|
} catch (e) {
|
|
2672
|
-
throw
|
|
2779
|
+
throw m = null, e;
|
|
2673
2780
|
} finally {
|
|
2674
2781
|
C = !1;
|
|
2675
2782
|
}
|
|
2676
2783
|
}
|
|
2677
|
-
},
|
|
2784
|
+
}, xt = (s, e) => {
|
|
2678
2785
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
2679
|
-
if (!
|
|
2786
|
+
if (!m)
|
|
2680
2787
|
throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
|
|
2681
|
-
if (
|
|
2788
|
+
if (G)
|
|
2682
2789
|
throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
|
|
2683
|
-
|
|
2790
|
+
m.sendCustomEvent(s, e);
|
|
2684
2791
|
}
|
|
2685
|
-
},
|
|
2792
|
+
}, Ft = (s, e) => {
|
|
2686
2793
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
2687
|
-
if (!
|
|
2688
|
-
N.push({ event:
|
|
2794
|
+
if (!m || C) {
|
|
2795
|
+
N.push({ event: s, callback: e });
|
|
2689
2796
|
return;
|
|
2690
2797
|
}
|
|
2691
|
-
|
|
2798
|
+
m.on(s, e);
|
|
2692
2799
|
}
|
|
2693
|
-
},
|
|
2800
|
+
}, Gt = (s, e) => {
|
|
2694
2801
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
2695
|
-
if (!
|
|
2696
|
-
const t = N.findIndex((r) => r.event ===
|
|
2802
|
+
if (!m) {
|
|
2803
|
+
const t = N.findIndex((r) => r.event === s && r.callback === e);
|
|
2697
2804
|
t !== -1 && N.splice(t, 1);
|
|
2698
2805
|
return;
|
|
2699
2806
|
}
|
|
2700
|
-
|
|
2807
|
+
m.off(s, e);
|
|
2701
2808
|
}
|
|
2702
|
-
},
|
|
2809
|
+
}, Wt = () => typeof window > "u" || typeof document > "u" ? !1 : m !== null, Bt = () => {
|
|
2703
2810
|
if (!(typeof window > "u" || typeof document > "u")) {
|
|
2704
|
-
if (
|
|
2811
|
+
if (G)
|
|
2705
2812
|
throw new Error("[TraceLog] Destroy operation already in progress");
|
|
2706
|
-
if (!
|
|
2813
|
+
if (!m)
|
|
2707
2814
|
throw new Error("[TraceLog] App not initialized");
|
|
2708
|
-
|
|
2815
|
+
G = !0;
|
|
2709
2816
|
try {
|
|
2710
|
-
|
|
2711
|
-
} catch (
|
|
2712
|
-
|
|
2817
|
+
m.destroy(), m = null, C = !1, N.length = 0;
|
|
2818
|
+
} catch (s) {
|
|
2819
|
+
m = null, C = !1, N.length = 0, a("warn", "Error during destroy, forced cleanup completed", { error: s });
|
|
2713
2820
|
} finally {
|
|
2714
|
-
|
|
2821
|
+
G = !1;
|
|
2715
2822
|
}
|
|
2716
2823
|
}
|
|
2717
|
-
},
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
}, lr = {
|
|
2721
|
-
PII_PATTERNS: le
|
|
2722
|
-
// Patterns for sensitive data protection
|
|
2723
|
-
}, cr = {
|
|
2824
|
+
}, $t = (s) => {
|
|
2825
|
+
typeof window > "u" || typeof document > "u" || ut(s);
|
|
2826
|
+
}, Sr = {
|
|
2724
2827
|
LOW_ACTIVITY_EVENT_COUNT: 50,
|
|
2725
2828
|
HIGH_ACTIVITY_EVENT_COUNT: 1e3,
|
|
2726
2829
|
MIN_EVENTS_FOR_DYNAMIC_CALCULATION: 100,
|
|
@@ -2730,28 +2833,17 @@ const Ct = async (n) => {
|
|
|
2730
2833
|
MIN_ENGAGED_SESSION_DURATION_MS: 30 * 1e3,
|
|
2731
2834
|
MIN_SCROLL_DEPTH_ENGAGEMENT: 25
|
|
2732
2835
|
// 25% scroll depth for engagement
|
|
2733
|
-
},
|
|
2836
|
+
}, Tr = {
|
|
2734
2837
|
INACTIVITY_TIMEOUT_MS: 1800 * 1e3,
|
|
2735
2838
|
// 30min for analytics (vs 15min client)
|
|
2736
2839
|
SHORT_SESSION_THRESHOLD_MS: 30 * 1e3,
|
|
2737
2840
|
MEDIUM_SESSION_THRESHOLD_MS: 300 * 1e3,
|
|
2738
2841
|
LONG_SESSION_THRESHOLD_MS: 1800 * 1e3,
|
|
2739
|
-
MAX_REALISTIC_SESSION_DURATION_MS: 480 * 60 * 1e3
|
|
2842
|
+
MAX_REALISTIC_SESSION_DURATION_MS: 480 * 60 * 1e3,
|
|
2740
2843
|
// Filter outliers
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
MOBILE_PERFORMANCE_FACTOR: 1.5,
|
|
2745
|
-
// Mobile typically 1.5x slower
|
|
2746
|
-
TABLET_PERFORMANCE_FACTOR: 1.2
|
|
2747
|
-
}, hr = {
|
|
2748
|
-
MIN_TEXT_LENGTH_FOR_ANALYSIS: 10,
|
|
2749
|
-
MIN_CLICKS_FOR_HOT_ELEMENT: 10,
|
|
2750
|
-
// Popular element threshold
|
|
2751
|
-
MIN_SCROLL_COMPLETION_PERCENT: 80,
|
|
2752
|
-
// Page consumption threshold
|
|
2753
|
-
MIN_TIME_ON_PAGE_FOR_READ_MS: 15 * 1e3
|
|
2754
|
-
}, fr = {
|
|
2844
|
+
MIN_EVENTS_FOR_DURATION: 2
|
|
2845
|
+
// Minimum events required to calculate session duration
|
|
2846
|
+
}, pr = {
|
|
2755
2847
|
SIGNIFICANT_CHANGE_PERCENT: 20,
|
|
2756
2848
|
MAJOR_CHANGE_PERCENT: 50,
|
|
2757
2849
|
MIN_EVENTS_FOR_INSIGHT: 100,
|
|
@@ -2761,19 +2853,7 @@ const Ct = async (n) => {
|
|
|
2761
2853
|
LOW_ERROR_RATE_PERCENT: 1,
|
|
2762
2854
|
HIGH_ERROR_RATE_PERCENT: 5,
|
|
2763
2855
|
CRITICAL_ERROR_RATE_PERCENT: 10
|
|
2764
|
-
},
|
|
2765
|
-
SHORT_TERM_TREND_HOURS: 24,
|
|
2766
|
-
MEDIUM_TERM_TREND_DAYS: 7,
|
|
2767
|
-
LONG_TERM_TREND_DAYS: 30,
|
|
2768
|
-
MIN_DATA_POINTS_FOR_TREND: 5,
|
|
2769
|
-
WEEKLY_PATTERN_MIN_WEEKS: 4,
|
|
2770
|
-
DAILY_PATTERN_MIN_DAYS: 14
|
|
2771
|
-
}, gr = {
|
|
2772
|
-
MIN_SEGMENT_SIZE: 10,
|
|
2773
|
-
MIN_COHORT_SIZE: 5,
|
|
2774
|
-
COHORT_ANALYSIS_DAYS: [1, 3, 7, 14, 30],
|
|
2775
|
-
MIN_FUNNEL_EVENTS: 20
|
|
2776
|
-
}, mr = {
|
|
2856
|
+
}, _r = {
|
|
2777
2857
|
DEFAULT_EVENTS_LIMIT: 5,
|
|
2778
2858
|
DEFAULT_SESSIONS_LIMIT: 5,
|
|
2779
2859
|
DEFAULT_PAGES_LIMIT: 5,
|
|
@@ -2781,260 +2861,254 @@ const Ct = async (n) => {
|
|
|
2781
2861
|
MAX_TIME_RANGE_DAYS: 365,
|
|
2782
2862
|
ANALYTICS_BATCH_SIZE: 1e3
|
|
2783
2863
|
// For historical analysis
|
|
2784
|
-
},
|
|
2785
|
-
ANOMALY_THRESHOLD_SIGMA: 2.5,
|
|
2786
|
-
STRONG_ANOMALY_THRESHOLD_SIGMA: 3,
|
|
2787
|
-
TRAFFIC_DROP_ALERT_PERCENT: -30,
|
|
2788
|
-
TRAFFIC_SPIKE_ALERT_PERCENT: 200,
|
|
2789
|
-
MIN_BASELINE_DAYS: 7,
|
|
2790
|
-
MIN_EVENTS_FOR_ANOMALY_DETECTION: 50
|
|
2791
|
-
}, Tr = {
|
|
2864
|
+
}, Ir = {
|
|
2792
2865
|
PAGE_URL_EXCLUDED: "excluded",
|
|
2793
2866
|
PAGE_URL_UNKNOWN: "unknown"
|
|
2794
|
-
},
|
|
2795
|
-
init:
|
|
2796
|
-
event:
|
|
2797
|
-
on:
|
|
2798
|
-
off:
|
|
2799
|
-
isInitialized:
|
|
2800
|
-
destroy:
|
|
2867
|
+
}, vr = {
|
|
2868
|
+
init: Ht,
|
|
2869
|
+
event: xt,
|
|
2870
|
+
on: Ft,
|
|
2871
|
+
off: Gt,
|
|
2872
|
+
isInitialized: Wt,
|
|
2873
|
+
destroy: Bt,
|
|
2874
|
+
setQaMode: $t
|
|
2801
2875
|
};
|
|
2802
|
-
var
|
|
2876
|
+
var ie, Ve = -1, O = function(s) {
|
|
2803
2877
|
addEventListener("pageshow", (function(e) {
|
|
2804
|
-
e.persisted && (
|
|
2878
|
+
e.persisted && (Ve = e.timeStamp, s(e));
|
|
2805
2879
|
}), !0);
|
|
2806
|
-
},
|
|
2807
|
-
var
|
|
2808
|
-
if (
|
|
2809
|
-
},
|
|
2810
|
-
var
|
|
2811
|
-
return
|
|
2812
|
-
},
|
|
2813
|
-
var t =
|
|
2814
|
-
return
|
|
2815
|
-
},
|
|
2880
|
+
}, de = function() {
|
|
2881
|
+
var s = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
|
|
2882
|
+
if (s && s.responseStart > 0 && s.responseStart < performance.now()) return s;
|
|
2883
|
+
}, $ = function() {
|
|
2884
|
+
var s = de();
|
|
2885
|
+
return s && s.activationStart || 0;
|
|
2886
|
+
}, _ = function(s, e) {
|
|
2887
|
+
var t = de(), r = "navigate";
|
|
2888
|
+
return Ve >= 0 ? r = "back-forward-cache" : t && (document.prerendering || $() > 0 ? r = "prerender" : document.wasDiscarded ? r = "restore" : t.type && (r = t.type.replace(/_/g, "-"))), { name: s, 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 };
|
|
2889
|
+
}, U = function(s, e, t) {
|
|
2816
2890
|
try {
|
|
2817
|
-
if (PerformanceObserver.supportedEntryTypes.includes(
|
|
2818
|
-
var r = new PerformanceObserver((function(
|
|
2891
|
+
if (PerformanceObserver.supportedEntryTypes.includes(s)) {
|
|
2892
|
+
var r = new PerformanceObserver((function(n) {
|
|
2819
2893
|
Promise.resolve().then((function() {
|
|
2820
|
-
e(
|
|
2894
|
+
e(n.getEntries());
|
|
2821
2895
|
}));
|
|
2822
2896
|
}));
|
|
2823
|
-
return r.observe(Object.assign({ type:
|
|
2897
|
+
return r.observe(Object.assign({ type: s, buffered: !0 }, t || {})), r;
|
|
2824
2898
|
}
|
|
2825
2899
|
} catch {
|
|
2826
2900
|
}
|
|
2827
|
-
}, I = function(
|
|
2828
|
-
var
|
|
2901
|
+
}, I = function(s, e, t, r) {
|
|
2902
|
+
var n, i;
|
|
2829
2903
|
return function(o) {
|
|
2830
|
-
e.value >= 0 && (o || r) && ((i = e.value - (
|
|
2904
|
+
e.value >= 0 && (o || r) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = (function(l, c) {
|
|
2831
2905
|
return l > c[1] ? "poor" : l > c[0] ? "needs-improvement" : "good";
|
|
2832
|
-
})(e.value, t),
|
|
2906
|
+
})(e.value, t), s(e));
|
|
2833
2907
|
};
|
|
2834
|
-
},
|
|
2908
|
+
}, he = function(s) {
|
|
2835
2909
|
requestAnimationFrame((function() {
|
|
2836
2910
|
return requestAnimationFrame((function() {
|
|
2837
|
-
return
|
|
2911
|
+
return s();
|
|
2838
2912
|
}));
|
|
2839
2913
|
}));
|
|
2840
|
-
}, X = function(
|
|
2914
|
+
}, X = function(s) {
|
|
2841
2915
|
document.addEventListener("visibilitychange", (function() {
|
|
2842
|
-
document.visibilityState === "hidden" &&
|
|
2916
|
+
document.visibilityState === "hidden" && s();
|
|
2843
2917
|
}));
|
|
2844
|
-
},
|
|
2918
|
+
}, fe = function(s) {
|
|
2845
2919
|
var e = !1;
|
|
2846
2920
|
return function() {
|
|
2847
|
-
e || (
|
|
2921
|
+
e || (s(), e = !0);
|
|
2848
2922
|
};
|
|
2849
|
-
},
|
|
2923
|
+
}, b = -1, Me = function() {
|
|
2850
2924
|
return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
|
|
2851
|
-
},
|
|
2852
|
-
document.visibilityState === "hidden" &&
|
|
2853
|
-
},
|
|
2854
|
-
addEventListener("visibilitychange",
|
|
2855
|
-
},
|
|
2856
|
-
removeEventListener("visibilitychange",
|
|
2857
|
-
},
|
|
2858
|
-
return
|
|
2925
|
+
}, B = function(s) {
|
|
2926
|
+
document.visibilityState === "hidden" && b > -1 && (b = s.type === "visibilitychange" ? s.timeStamp : 0, Xt());
|
|
2927
|
+
}, Ne = function() {
|
|
2928
|
+
addEventListener("visibilitychange", B, !0), addEventListener("prerenderingchange", B, !0);
|
|
2929
|
+
}, Xt = function() {
|
|
2930
|
+
removeEventListener("visibilitychange", B, !0), removeEventListener("prerenderingchange", B, !0);
|
|
2931
|
+
}, ke = function() {
|
|
2932
|
+
return b < 0 && (b = Me(), Ne(), O((function() {
|
|
2859
2933
|
setTimeout((function() {
|
|
2860
|
-
|
|
2934
|
+
b = Me(), Ne();
|
|
2861
2935
|
}), 0);
|
|
2862
2936
|
}))), { get firstHiddenTime() {
|
|
2863
|
-
return
|
|
2937
|
+
return b;
|
|
2864
2938
|
} };
|
|
2865
|
-
},
|
|
2939
|
+
}, z = function(s) {
|
|
2866
2940
|
document.prerendering ? addEventListener("prerenderingchange", (function() {
|
|
2867
|
-
return
|
|
2868
|
-
}), !0) :
|
|
2869
|
-
},
|
|
2870
|
-
e = e || {},
|
|
2871
|
-
var t, r =
|
|
2941
|
+
return s();
|
|
2942
|
+
}), !0) : s();
|
|
2943
|
+
}, oe = [1800, 3e3], Ue = function(s, e) {
|
|
2944
|
+
e = e || {}, z((function() {
|
|
2945
|
+
var t, r = ke(), n = _("FCP"), i = U("paint", (function(o) {
|
|
2872
2946
|
o.forEach((function(l) {
|
|
2873
|
-
l.name === "first-contentful-paint" && (i.disconnect(), l.startTime < r.firstHiddenTime && (
|
|
2947
|
+
l.name === "first-contentful-paint" && (i.disconnect(), l.startTime < r.firstHiddenTime && (n.value = Math.max(l.startTime - $(), 0), n.entries.push(l), t(!0)));
|
|
2874
2948
|
}));
|
|
2875
2949
|
}));
|
|
2876
|
-
i && (t = I(
|
|
2877
|
-
|
|
2878
|
-
|
|
2950
|
+
i && (t = I(s, n, oe, e.reportAllChanges), O((function(o) {
|
|
2951
|
+
n = _("FCP"), t = I(s, n, oe, e.reportAllChanges), he((function() {
|
|
2952
|
+
n.value = performance.now() - o.timeStamp, t(!0);
|
|
2879
2953
|
}));
|
|
2880
2954
|
})));
|
|
2881
2955
|
}));
|
|
2882
|
-
},
|
|
2883
|
-
e = e || {},
|
|
2884
|
-
var t, r =
|
|
2956
|
+
}, ae = [0.1, 0.25], zt = function(s, e) {
|
|
2957
|
+
e = e || {}, Ue(fe((function() {
|
|
2958
|
+
var t, r = _("CLS", 0), n = 0, i = [], o = function(c) {
|
|
2885
2959
|
c.forEach((function(d) {
|
|
2886
2960
|
if (!d.hadRecentInput) {
|
|
2887
|
-
var
|
|
2888
|
-
|
|
2961
|
+
var E = i[0], g = i[i.length - 1];
|
|
2962
|
+
n && d.startTime - g.startTime < 1e3 && d.startTime - E.startTime < 5e3 ? (n += d.value, i.push(d)) : (n = d.value, i = [d]);
|
|
2889
2963
|
}
|
|
2890
|
-
})),
|
|
2891
|
-
}, l =
|
|
2892
|
-
l && (t = I(
|
|
2964
|
+
})), n > r.value && (r.value = n, r.entries = i, t());
|
|
2965
|
+
}, l = U("layout-shift", o);
|
|
2966
|
+
l && (t = I(s, r, ae, e.reportAllChanges), X((function() {
|
|
2893
2967
|
o(l.takeRecords()), t(!0);
|
|
2894
|
-
})),
|
|
2895
|
-
|
|
2968
|
+
})), O((function() {
|
|
2969
|
+
n = 0, r = _("CLS", 0), t = I(s, r, ae, e.reportAllChanges), he((function() {
|
|
2896
2970
|
return t();
|
|
2897
2971
|
}));
|
|
2898
2972
|
})), setTimeout(t, 0));
|
|
2899
2973
|
})));
|
|
2900
|
-
},
|
|
2901
|
-
|
|
2902
|
-
e.interactionId && (Y = Math.min(Y, e.interactionId), H = Math.max(H, e.interactionId),
|
|
2974
|
+
}, He = 0, Y = 1 / 0, H = 0, Qt = function(s) {
|
|
2975
|
+
s.forEach((function(e) {
|
|
2976
|
+
e.interactionId && (Y = Math.min(Y, e.interactionId), H = Math.max(H, e.interactionId), He = H ? (H - Y) / 7 + 1 : 0);
|
|
2903
2977
|
}));
|
|
2904
|
-
},
|
|
2905
|
-
return
|
|
2906
|
-
},
|
|
2907
|
-
"interactionCount" in performance ||
|
|
2908
|
-
},
|
|
2909
|
-
var
|
|
2910
|
-
return
|
|
2911
|
-
},
|
|
2912
|
-
if (
|
|
2913
|
-
return s
|
|
2914
|
-
})),
|
|
2915
|
-
var e =
|
|
2916
|
-
if (t ||
|
|
2917
|
-
if (t)
|
|
2978
|
+
}, xe = function() {
|
|
2979
|
+
return ie ? He : performance.interactionCount || 0;
|
|
2980
|
+
}, jt = function() {
|
|
2981
|
+
"interactionCount" in performance || ie || (ie = U("event", Qt, { type: "event", buffered: !0, durationThreshold: 0 }));
|
|
2982
|
+
}, p = [], W = /* @__PURE__ */ new Map(), Fe = 0, Kt = function() {
|
|
2983
|
+
var s = Math.min(p.length - 1, Math.floor((xe() - Fe) / 50));
|
|
2984
|
+
return p[s];
|
|
2985
|
+
}, Yt = [], qt = function(s) {
|
|
2986
|
+
if (Yt.forEach((function(n) {
|
|
2987
|
+
return n(s);
|
|
2988
|
+
})), s.interactionId || s.entryType === "first-input") {
|
|
2989
|
+
var e = p[p.length - 1], t = W.get(s.interactionId);
|
|
2990
|
+
if (t || p.length < 10 || s.duration > e.latency) {
|
|
2991
|
+
if (t) s.duration > t.latency ? (t.entries = [s], t.latency = s.duration) : s.duration === t.latency && s.startTime === t.entries[0].startTime && t.entries.push(s);
|
|
2918
2992
|
else {
|
|
2919
|
-
var r = { id:
|
|
2920
|
-
|
|
2993
|
+
var r = { id: s.interactionId, latency: s.duration, entries: [s] };
|
|
2994
|
+
W.set(r.id, r), p.push(r);
|
|
2921
2995
|
}
|
|
2922
|
-
|
|
2923
|
-
return i.latency -
|
|
2924
|
-
})),
|
|
2925
|
-
return
|
|
2996
|
+
p.sort((function(n, i) {
|
|
2997
|
+
return i.latency - n.latency;
|
|
2998
|
+
})), p.length > 10 && p.splice(10).forEach((function(n) {
|
|
2999
|
+
return W.delete(n.id);
|
|
2926
3000
|
}));
|
|
2927
3001
|
}
|
|
2928
3002
|
}
|
|
2929
|
-
},
|
|
3003
|
+
}, Ge = function(s) {
|
|
2930
3004
|
var e = self.requestIdleCallback || self.setTimeout, t = -1;
|
|
2931
|
-
return
|
|
2932
|
-
},
|
|
2933
|
-
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {},
|
|
3005
|
+
return s = fe(s), document.visibilityState === "hidden" ? s() : (t = e(s), X(s)), t;
|
|
3006
|
+
}, le = [200, 500], Zt = function(s, e) {
|
|
3007
|
+
"PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, z((function() {
|
|
2934
3008
|
var t;
|
|
2935
|
-
|
|
2936
|
-
var r,
|
|
2937
|
-
|
|
2938
|
-
l.forEach(
|
|
2939
|
-
var c =
|
|
2940
|
-
c && c.latency !==
|
|
3009
|
+
jt();
|
|
3010
|
+
var r, n = _("INP"), i = function(l) {
|
|
3011
|
+
Ge((function() {
|
|
3012
|
+
l.forEach(qt);
|
|
3013
|
+
var c = Kt();
|
|
3014
|
+
c && c.latency !== n.value && (n.value = c.latency, n.entries = c.entries, r());
|
|
2941
3015
|
}));
|
|
2942
|
-
}, o =
|
|
2943
|
-
r = I(
|
|
3016
|
+
}, o = U("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
|
|
3017
|
+
r = I(s, n, le, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), X((function() {
|
|
2944
3018
|
i(o.takeRecords()), r(!0);
|
|
2945
|
-
})),
|
|
2946
|
-
|
|
3019
|
+
})), O((function() {
|
|
3020
|
+
Fe = xe(), p.length = 0, W.clear(), n = _("INP"), r = I(s, n, le, e.reportAllChanges);
|
|
2947
3021
|
})));
|
|
2948
3022
|
})));
|
|
2949
|
-
},
|
|
2950
|
-
e = e || {},
|
|
2951
|
-
var t, r =
|
|
3023
|
+
}, ce = [2500, 4e3], q = {}, Jt = function(s, e) {
|
|
3024
|
+
e = e || {}, z((function() {
|
|
3025
|
+
var t, r = ke(), n = _("LCP"), i = function(c) {
|
|
2952
3026
|
e.reportAllChanges || (c = c.slice(-1)), c.forEach((function(d) {
|
|
2953
|
-
d.startTime < r.firstHiddenTime && (
|
|
3027
|
+
d.startTime < r.firstHiddenTime && (n.value = Math.max(d.startTime - $(), 0), n.entries = [d], t());
|
|
2954
3028
|
}));
|
|
2955
|
-
}, o =
|
|
3029
|
+
}, o = U("largest-contentful-paint", i);
|
|
2956
3030
|
if (o) {
|
|
2957
|
-
t = I(
|
|
2958
|
-
var l =
|
|
2959
|
-
|
|
3031
|
+
t = I(s, n, ce, e.reportAllChanges);
|
|
3032
|
+
var l = fe((function() {
|
|
3033
|
+
q[n.id] || (i(o.takeRecords()), o.disconnect(), q[n.id] = !0, t(!0));
|
|
2960
3034
|
}));
|
|
2961
3035
|
["keydown", "click"].forEach((function(c) {
|
|
2962
3036
|
addEventListener(c, (function() {
|
|
2963
|
-
return
|
|
3037
|
+
return Ge(l);
|
|
2964
3038
|
}), { once: !0, capture: !0 });
|
|
2965
|
-
})), X(l),
|
|
2966
|
-
|
|
2967
|
-
|
|
3039
|
+
})), X(l), O((function(c) {
|
|
3040
|
+
n = _("LCP"), t = I(s, n, ce, e.reportAllChanges), he((function() {
|
|
3041
|
+
n.value = performance.now() - c.timeStamp, q[n.id] = !0, t(!0);
|
|
2968
3042
|
}));
|
|
2969
3043
|
}));
|
|
2970
3044
|
}
|
|
2971
3045
|
}));
|
|
2972
|
-
},
|
|
2973
|
-
document.prerendering ?
|
|
2974
|
-
return
|
|
3046
|
+
}, ue = [800, 1800], er = function s(e) {
|
|
3047
|
+
document.prerendering ? z((function() {
|
|
3048
|
+
return s(e);
|
|
2975
3049
|
})) : document.readyState !== "complete" ? addEventListener("load", (function() {
|
|
2976
|
-
return
|
|
3050
|
+
return s(e);
|
|
2977
3051
|
}), !0) : setTimeout(e, 0);
|
|
2978
|
-
},
|
|
3052
|
+
}, tr = function(s, e) {
|
|
2979
3053
|
e = e || {};
|
|
2980
|
-
var t =
|
|
2981
|
-
|
|
2982
|
-
var
|
|
2983
|
-
|
|
2984
|
-
t =
|
|
3054
|
+
var t = _("TTFB"), r = I(s, t, ue, e.reportAllChanges);
|
|
3055
|
+
er((function() {
|
|
3056
|
+
var n = de();
|
|
3057
|
+
n && (t.value = Math.max(n.responseStart - $(), 0), t.entries = [n], r(!0), O((function() {
|
|
3058
|
+
t = _("TTFB", 0), (r = I(s, t, ue, e.reportAllChanges))(!0);
|
|
2985
3059
|
})));
|
|
2986
3060
|
}));
|
|
2987
3061
|
};
|
|
2988
|
-
const
|
|
3062
|
+
const rr = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2989
3063
|
__proto__: null,
|
|
2990
|
-
CLSThresholds:
|
|
2991
|
-
FCPThresholds:
|
|
2992
|
-
INPThresholds:
|
|
2993
|
-
LCPThresholds:
|
|
2994
|
-
TTFBThresholds:
|
|
2995
|
-
onCLS:
|
|
2996
|
-
onFCP:
|
|
2997
|
-
onINP:
|
|
2998
|
-
onLCP:
|
|
2999
|
-
onTTFB:
|
|
3064
|
+
CLSThresholds: ae,
|
|
3065
|
+
FCPThresholds: oe,
|
|
3066
|
+
INPThresholds: le,
|
|
3067
|
+
LCPThresholds: ce,
|
|
3068
|
+
TTFBThresholds: ue,
|
|
3069
|
+
onCLS: zt,
|
|
3070
|
+
onFCP: Ue,
|
|
3071
|
+
onINP: Zt,
|
|
3072
|
+
onLCP: Jt,
|
|
3073
|
+
onTTFB: tr
|
|
3000
3074
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
3001
3075
|
export {
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
cr as ENGAGEMENT_THRESHOLDS,
|
|
3010
|
-
Z as EmitterEvent,
|
|
3076
|
+
_r as ANALYTICS_QUERY_LIMITS,
|
|
3077
|
+
h as AppConfigValidationError,
|
|
3078
|
+
sr as DEFAULT_SESSION_TIMEOUT,
|
|
3079
|
+
re as DEFAULT_WEB_VITALS_MODE,
|
|
3080
|
+
A as DeviceType,
|
|
3081
|
+
Sr as ENGAGEMENT_THRESHOLDS,
|
|
3082
|
+
J as EmitterEvent,
|
|
3011
3083
|
P as ErrorType,
|
|
3012
3084
|
u as EventType,
|
|
3013
|
-
|
|
3014
|
-
|
|
3085
|
+
pr as INSIGHT_THRESHOLDS,
|
|
3086
|
+
gr as InitializationTimeoutError,
|
|
3015
3087
|
M as IntegrationValidationError,
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3088
|
+
hr as MAX_ARRAY_LENGTH,
|
|
3089
|
+
ar as MAX_CUSTOM_EVENT_ARRAY_SIZE,
|
|
3090
|
+
or as MAX_CUSTOM_EVENT_KEYS,
|
|
3091
|
+
nr as MAX_CUSTOM_EVENT_NAME_LENGTH,
|
|
3092
|
+
ir as MAX_CUSTOM_EVENT_STRING_SIZE,
|
|
3093
|
+
cr as MAX_METADATA_NESTING_DEPTH,
|
|
3094
|
+
lr as MAX_NESTED_OBJECT_KEYS,
|
|
3095
|
+
ur as MAX_STRING_LENGTH,
|
|
3096
|
+
dr as MAX_STRING_LENGTH_IN_ARRAY,
|
|
3097
|
+
V as Mode,
|
|
3098
|
+
Oe as PII_PATTERNS,
|
|
3027
3099
|
R as PermanentError,
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3100
|
+
Tr as SESSION_ANALYTICS,
|
|
3101
|
+
Ir as SPECIAL_PAGE_URLS,
|
|
3102
|
+
Ee as SamplingRateValidationError,
|
|
3103
|
+
x as ScrollDirection,
|
|
3104
|
+
je as SessionTimeoutValidationError,
|
|
3105
|
+
Z as SpecialApiUrl,
|
|
3106
|
+
k as TraceLogValidationError,
|
|
3107
|
+
mr as WEB_VITALS_GOOD_THRESHOLDS,
|
|
3108
|
+
Te as WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS,
|
|
3109
|
+
rt as WEB_VITALS_POOR_THRESHOLDS,
|
|
3110
|
+
pe as getWebVitalsThresholds,
|
|
3111
|
+
fr as isPrimaryScrollEvent,
|
|
3112
|
+
Er as isSecondaryScrollEvent,
|
|
3113
|
+
vr as tracelog
|
|
3040
3114
|
};
|