@crelora/mark 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -4
- package/dist/browser.es.js +393 -222
- package/dist/browser.es.js.map +1 -1
- package/dist/browser.umd.js +1 -1
- package/dist/browser.umd.js.map +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.es.js +125 -80
- package/dist/node.es.js.map +1 -1
- package/dist/types/browser/BrowserStorage.d.ts +9 -0
- package/dist/types/browser/Mark.d.ts +10 -3
- package/dist/types/browser/pageEngagement.d.ts +8 -0
- package/dist/types/browser/pageLifecycle.d.ts +15 -0
- package/dist/types/browser/pageMetrics.d.ts +5 -0
- package/dist/types/browser/pageScrollDepth.d.ts +4 -0
- package/dist/types/core/MarkCore.d.ts +11 -0
- package/dist/types/core/adapters.d.ts +1 -0
- package/dist/types/core/visitorId.d.ts +5 -0
- package/dist/types/node/StatelessStorage.d.ts +1 -0
- package/dist/types/node/index.d.ts +6 -0
- package/dist/types/types.d.ts +17 -0
- package/package.json +1 -1
package/dist/browser.es.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
const
|
|
2
|
-
class
|
|
1
|
+
const N = "https://ingest.onelence.com";
|
|
2
|
+
class p extends Error {
|
|
3
3
|
status;
|
|
4
4
|
retryAfterMs;
|
|
5
5
|
constructor(t, e = {}) {
|
|
6
6
|
super(t), this.name = "TransportError", this.status = e.status, this.retryAfterMs = e.retryAfterMs;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
return !(typeof
|
|
9
|
+
function V(r) {
|
|
10
|
+
return !(typeof r != "number" || r < 400 || r >= 500 || r === 408 || r === 429);
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
if (!
|
|
14
|
-
const t =
|
|
12
|
+
function z(r) {
|
|
13
|
+
if (!r) return;
|
|
14
|
+
const t = r.trim();
|
|
15
15
|
if (!t) return;
|
|
16
16
|
const e = Number(t);
|
|
17
17
|
if (Number.isFinite(e) && e >= 0)
|
|
@@ -22,20 +22,20 @@ function x(c) {
|
|
|
22
22
|
return n > 0 ? n : 0;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
const
|
|
26
|
-
class
|
|
25
|
+
const M = 5, $ = 300, j = 15e3, Y = 2880 * 60 * 1e3;
|
|
26
|
+
class Q {
|
|
27
27
|
constructor(t, e = {}) {
|
|
28
|
-
this.transport = t, this.maxAttempts = e.maxAttempts ??
|
|
28
|
+
this.transport = t, this.maxAttempts = e.maxAttempts ?? M, this.baseBackoffMs = e.baseBackoffMs ?? $, this.maxBackoffMs = e.maxBackoffMs ?? j, this.maxItemAgeMs = e.maxItemAgeMs ?? Y, this.debug = e.debug ?? !1, this.loadPersisted = e.loadPersisted, this.savePersisted = e.savePersisted, this.onError = e.onError;
|
|
29
29
|
const i = this.loadPersisted?.() ?? [];
|
|
30
30
|
if (i.length > 0) {
|
|
31
31
|
const n = Date.now();
|
|
32
|
-
for (const
|
|
33
|
-
const
|
|
34
|
-
if (n -
|
|
32
|
+
for (const o of i) {
|
|
33
|
+
const a = o.enqueuedAt ?? n;
|
|
34
|
+
if (n - a > this.maxItemAgeMs) {
|
|
35
35
|
this.dropped += 1;
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
|
-
this.queue.push({ ...
|
|
38
|
+
this.queue.push({ ...o, enqueuedAt: a });
|
|
39
39
|
}
|
|
40
40
|
this.persist();
|
|
41
41
|
}
|
|
@@ -117,8 +117,8 @@ class U {
|
|
|
117
117
|
delete i.__prefer_beacon, await this.transport.send(e.path, i, { preferBeacon: n }), this.queue.shift(), this.sent += 1, this.persist();
|
|
118
118
|
} catch (i) {
|
|
119
119
|
this.failed += 1, this.onError?.(i, e.data);
|
|
120
|
-
const n = i instanceof
|
|
121
|
-
if (
|
|
120
|
+
const n = i instanceof p ? i.status : void 0;
|
|
121
|
+
if (V(n)) {
|
|
122
122
|
this.queue.shift(), this.dropped += 1, this.persist(), this.debug && console.error("[Mark] Dropping event after non-retriable status", n, e.path);
|
|
123
123
|
continue;
|
|
124
124
|
}
|
|
@@ -126,18 +126,18 @@ class U {
|
|
|
126
126
|
this.queue.shift(), this.dropped += 1, this.persist(), this.debug && console.error("[Mark] Dropping event after max retries", e.path, i);
|
|
127
127
|
continue;
|
|
128
128
|
}
|
|
129
|
-
const
|
|
130
|
-
let
|
|
131
|
-
if (typeof
|
|
132
|
-
|
|
129
|
+
const o = i instanceof p ? i.retryAfterMs : void 0;
|
|
130
|
+
let a;
|
|
131
|
+
if (typeof o == "number")
|
|
132
|
+
a = Math.min(this.maxBackoffMs, Math.max(0, o));
|
|
133
133
|
else {
|
|
134
|
-
const
|
|
135
|
-
|
|
134
|
+
const c = Math.random() * this.baseBackoffMs;
|
|
135
|
+
a = Math.min(
|
|
136
136
|
this.maxBackoffMs,
|
|
137
|
-
this.baseBackoffMs * 2 ** (e.attempts - 1) +
|
|
137
|
+
this.baseBackoffMs * 2 ** (e.attempts - 1) + c
|
|
138
138
|
);
|
|
139
139
|
}
|
|
140
|
-
e.nextAttemptAt = Date.now() +
|
|
140
|
+
e.nextAttemptAt = Date.now() + a, this.persist();
|
|
141
141
|
break;
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -147,7 +147,15 @@ class U {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
|
-
const
|
|
150
|
+
const W = 256;
|
|
151
|
+
function E(r) {
|
|
152
|
+
if (typeof r != "string")
|
|
153
|
+
return;
|
|
154
|
+
const t = r.trim();
|
|
155
|
+
if (!(!t || t.length > W) && !t.includes("@") && !/\s/.test(t))
|
|
156
|
+
return t;
|
|
157
|
+
}
|
|
158
|
+
const G = /* @__PURE__ */ new Set(["event_name", "user_id", "consent_state", "source", "is_conversion"]), X = /* @__PURE__ */ new Set([
|
|
151
159
|
"user_id",
|
|
152
160
|
"visitor_id",
|
|
153
161
|
"click_id",
|
|
@@ -156,13 +164,13 @@ const k = /* @__PURE__ */ new Set(["event_name", "user_id", "consent_state", "so
|
|
|
156
164
|
"consent_state",
|
|
157
165
|
"source"
|
|
158
166
|
]);
|
|
159
|
-
class
|
|
167
|
+
class J {
|
|
160
168
|
constructor(t, e) {
|
|
161
169
|
this.deps = e, this.validateConfig(t), this.config = {
|
|
162
|
-
endpoint: t.endpoint ??
|
|
170
|
+
endpoint: t.endpoint ?? N,
|
|
163
171
|
...t,
|
|
164
172
|
include_page_context: t.include_page_context ?? !0
|
|
165
|
-
}, this.consentRequirement = t.require_consent ?? !1, this.siteId = t.site_id, this.siteHost = t.site_host, this.sessionTimeoutMs = t.session_timeout_ms ?? 1800 * 1e3, this.queue = new
|
|
173
|
+
}, this.consentRequirement = t.require_consent ?? !1, this.siteId = t.site_id, this.siteHost = t.site_host, this.sessionTimeoutMs = t.session_timeout_ms ?? 1800 * 1e3, this.queue = new Q(this.deps.transport, {
|
|
166
174
|
debug: this.config.debug,
|
|
167
175
|
loadPersisted: () => this.deps.storage.getOutbox?.() ?? [],
|
|
168
176
|
savePersisted: (i) => this.deps.storage.setOutbox?.(i),
|
|
@@ -204,19 +212,19 @@ class L {
|
|
|
204
212
|
return this.config.debug && console.warn("[Mark] Tracking blocked due to consent requirement."), !1;
|
|
205
213
|
if (!i && !this.shouldSampleTrack())
|
|
206
214
|
return !0;
|
|
207
|
-
const
|
|
208
|
-
"query" in
|
|
209
|
-
const
|
|
215
|
+
const o = this.sanitizeTrackData(e), a = { ...o };
|
|
216
|
+
"query" in a && delete a.query, "site_id" in a && delete a.site_id, "site_host" in a && delete a.site_host;
|
|
217
|
+
const c = {
|
|
210
218
|
event_name: t,
|
|
211
219
|
message_id: this.createMessageId(),
|
|
212
|
-
...this.getIdentityFields(
|
|
213
|
-
...
|
|
220
|
+
...this.getIdentityFields(o),
|
|
221
|
+
...a
|
|
214
222
|
};
|
|
215
|
-
i && (
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
const d = this.config.before_send ? this.config.before_send(
|
|
219
|
-
return d ? (this.ensureSession(), this.config.batching?.enabled && !i && !n?.preferBeacon ? (this.enqueueBatch(d), !0) : (this.queue.enqueue("/event", { ...d, __prefer_beacon: n?.preferBeacon === !0 }), !0)) : !0;
|
|
223
|
+
i && (c.is_conversion = !0);
|
|
224
|
+
const f = o.site_id ?? this.siteId, l = o.site_host ?? this.siteHost;
|
|
225
|
+
f && (c.site_id = f), l && (c.site_host = l), this.config.include_page_context && typeof window < "u" && (this.applyPageContext(c), !l && c.site && (c.site_host = c.site)), this.applyInternalFlag(c, o.is_internal);
|
|
226
|
+
const d = this.config.before_send ? this.config.before_send(c) : c;
|
|
227
|
+
return d ? (this.ensureSession(), this.applySessionFields(d), this.config.batching?.enabled && !i && !n?.preferBeacon ? (this.enqueueBatch(d), !0) : (this.queue.enqueue("/event", { ...d, __prefer_beacon: n?.preferBeacon === !0 }), !0)) : !0;
|
|
220
228
|
}
|
|
221
229
|
identify(t, e = {}) {
|
|
222
230
|
if (!t) {
|
|
@@ -236,7 +244,7 @@ class L {
|
|
|
236
244
|
};
|
|
237
245
|
this.siteId && (i.site_id = this.siteId), this.siteHost && (i.site_host = this.siteHost), this.applyInternalFlag(i);
|
|
238
246
|
const n = this.config.before_send ? this.config.before_send(i) : i;
|
|
239
|
-
n && this.queue.enqueue("/identify", n);
|
|
247
|
+
n && (this.ensureSession(), this.applySessionFields(n), this.queue.enqueue("/identify", n));
|
|
240
248
|
}
|
|
241
249
|
conversion(t, e = {}) {
|
|
242
250
|
return this.trackInternal(t, e, !0);
|
|
@@ -251,6 +259,15 @@ class L {
|
|
|
251
259
|
getVisitorId() {
|
|
252
260
|
return this.deps.storage.getVisitorId();
|
|
253
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Adopts or replaces the stored visitor id with a trusted first-party value.
|
|
264
|
+
* Use when an external anonymous id (for example a platform client id) arrives
|
|
265
|
+
* after init. Returns false when the id is invalid.
|
|
266
|
+
*/
|
|
267
|
+
setVisitorId(t) {
|
|
268
|
+
const e = E(t);
|
|
269
|
+
return e ? this.deps.storage.setVisitorId ? this.deps.storage.setVisitorId(e) : (this.deps.storage.getVisitorId() === e || this.deps.storage.update({ visitor_id: e }), !0) : (this.config.debug && console.warn("[Mark] setVisitorId called with an invalid visitor id."), !1);
|
|
270
|
+
}
|
|
254
271
|
setConsent(t) {
|
|
255
272
|
const e = this.deps.storage.getConsentStatus();
|
|
256
273
|
this.deps.storage.setConsentStatus(t), t === "denied" ? (this.deps.storage.clearAttribution?.(), this.deps.storage.clearCookieVisitorId?.(), this.deps.storage.setInternal?.(!1)) : t === "granted" && e === "denied" && this.config.rotate_visitor_on_consent_change && this.deps.storage.rotateVisitorId?.();
|
|
@@ -318,8 +335,22 @@ class L {
|
|
|
318
335
|
e === !0 || i ? t.is_internal = !0 : delete t.is_internal;
|
|
319
336
|
}
|
|
320
337
|
getIdentityFields(t) {
|
|
321
|
-
const e = t?.visitor_id ?? this.deps.storage.getVisitorId(), i = t?.user_id ?? this.deps.storage.getUserId?.(), n = t?.click_id ?? this.deps.storage.getLastClickId(),
|
|
322
|
-
|
|
338
|
+
const e = t?.visitor_id ?? this.deps.storage.getVisitorId(), i = t?.user_id ?? this.deps.storage.getUserId?.(), n = t?.click_id ?? this.deps.storage.getLastClickId(), o = t?.campaign_id ?? this.deps.storage.getCampaignId(), a = t?.session_id ?? this.deps.storage.getSessionId?.(), c = this.deps.storage.getQueryParams() ?? {}, f = t?.query ?? {}, l = { ...c, ...f }, d = {};
|
|
339
|
+
e && (d.visitor_id = e), i && (d.user_id = i), n && (d.click_id = n), o && (d.campaign_id = o), a && (d.session_id = a);
|
|
340
|
+
const h = this.deps.storage.getSessionStartedAt?.();
|
|
341
|
+
return a && h && (d.session_started_at = h, d.session_elapsed_ms = Date.now() - Date.parse(h)), Object.keys(l).length > 0 && (d.query = l), d;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Patches session fields after ensureSession when the first event in a session was built
|
|
345
|
+
* before rotation created an id. Rotation events keep the previous session_id from identity.
|
|
346
|
+
*/
|
|
347
|
+
applySessionFields(t) {
|
|
348
|
+
if (!t.session_id) {
|
|
349
|
+
const i = this.deps.storage.getSessionId?.(), n = this.deps.storage.getSessionStartedAt?.();
|
|
350
|
+
i && (t.session_id = i), n && (t.session_started_at = n);
|
|
351
|
+
}
|
|
352
|
+
const e = t.session_started_at;
|
|
353
|
+
t.session_id && typeof e == "string" && (t.session_elapsed_ms = Date.now() - Date.parse(e));
|
|
323
354
|
}
|
|
324
355
|
hasConsent() {
|
|
325
356
|
if (this.config.consent_source?.type === "tcf" && typeof window < "u" && !this.tcfCachedAllowed)
|
|
@@ -332,13 +363,13 @@ class L {
|
|
|
332
363
|
sanitizeTrackData(t) {
|
|
333
364
|
const e = {};
|
|
334
365
|
for (const [i, n] of Object.entries(t))
|
|
335
|
-
|
|
366
|
+
G.has(i) || (e[i] = n);
|
|
336
367
|
return e;
|
|
337
368
|
}
|
|
338
369
|
sanitizeIdentifyTraits(t) {
|
|
339
370
|
const e = {};
|
|
340
371
|
for (const [i, n] of Object.entries(t))
|
|
341
|
-
|
|
372
|
+
X.has(i) || (e[i] = n);
|
|
342
373
|
return e;
|
|
343
374
|
}
|
|
344
375
|
validateConfig(t) {
|
|
@@ -354,6 +385,8 @@ class L {
|
|
|
354
385
|
throw new Error("[Mark] `site_id` cannot be an empty string.");
|
|
355
386
|
if (typeof t.site_host == "string" && !t.site_host.trim())
|
|
356
387
|
throw new Error("[Mark] `site_host` cannot be an empty string.");
|
|
388
|
+
if (t.visitor_id !== void 0 && !E(t.visitor_id))
|
|
389
|
+
throw new Error("[Mark] `visitor_id` must be a non-empty string (max 256 characters).");
|
|
357
390
|
}
|
|
358
391
|
applyPageContext(t) {
|
|
359
392
|
typeof document > "u" || (t.site || (t.site = window.location.host), t.page || (t.page = window.location.pathname), t.title || (t.title = document.title), !t.referrer && document.referrer && (t.referrer = this.scrubReferrer(document.referrer)));
|
|
@@ -383,11 +416,11 @@ class L {
|
|
|
383
416
|
ensureSession() {
|
|
384
417
|
const t = Date.now(), e = this.deps.storage.getSessionId?.(), i = this.deps.storage.getLastActivityAt?.(), n = i ? Date.parse(i) : 0;
|
|
385
418
|
if (!e || !n || t - n >= this.sessionTimeoutMs || this.crossedUtcDay(n, t)) {
|
|
386
|
-
const
|
|
419
|
+
const a = this.createMessageId(), c = new Date(t).toISOString();
|
|
387
420
|
this.deps.storage.update({
|
|
388
|
-
session_id:
|
|
389
|
-
session_started_at:
|
|
390
|
-
last_activity_at:
|
|
421
|
+
session_id: a,
|
|
422
|
+
session_started_at: c,
|
|
423
|
+
last_activity_at: c
|
|
391
424
|
});
|
|
392
425
|
return;
|
|
393
426
|
}
|
|
@@ -433,22 +466,22 @@ class L {
|
|
|
433
466
|
if (t?.type !== "tcf" || typeof window > "u") return;
|
|
434
467
|
const e = t.purposes, i = (n) => {
|
|
435
468
|
try {
|
|
436
|
-
const
|
|
437
|
-
if (typeof
|
|
469
|
+
const o = window;
|
|
470
|
+
if (typeof o.__tcfapi != "function") {
|
|
438
471
|
n > 0 && setTimeout(() => i(n - 1), 200);
|
|
439
472
|
return;
|
|
440
473
|
}
|
|
441
|
-
|
|
442
|
-
if (!
|
|
474
|
+
o.__tcfapi("addEventListener", 2, (a, c) => {
|
|
475
|
+
if (!c || !a) {
|
|
443
476
|
this.tcfCachedAllowed = !1;
|
|
444
477
|
return;
|
|
445
478
|
}
|
|
446
|
-
if (
|
|
479
|
+
if (a.gdprApplies === !1) {
|
|
447
480
|
this.tcfCachedAllowed = !0;
|
|
448
481
|
return;
|
|
449
482
|
}
|
|
450
|
-
const
|
|
451
|
-
this.tcfCachedAllowed = e.every((l) =>
|
|
483
|
+
const f = a.purpose?.consents ?? {};
|
|
484
|
+
this.tcfCachedAllowed = e.every((l) => f[String(l)] === !0);
|
|
452
485
|
});
|
|
453
486
|
} catch {
|
|
454
487
|
this.tcfCachedAllowed = !1;
|
|
@@ -457,12 +490,12 @@ class L {
|
|
|
457
490
|
i(10);
|
|
458
491
|
}
|
|
459
492
|
}
|
|
460
|
-
class
|
|
493
|
+
class Z {
|
|
461
494
|
config;
|
|
462
495
|
endpoint;
|
|
463
496
|
pending = /* @__PURE__ */ new Set();
|
|
464
497
|
constructor(t) {
|
|
465
|
-
this.config = t, this.endpoint = t.endpoint ??
|
|
498
|
+
this.config = t, this.endpoint = t.endpoint ?? N;
|
|
466
499
|
}
|
|
467
500
|
async send(t, e, i) {
|
|
468
501
|
const n = this.sendInternal(t, e, i);
|
|
@@ -477,54 +510,54 @@ class R {
|
|
|
477
510
|
this.pending.size !== 0 && await Promise.allSettled(Array.from(this.pending));
|
|
478
511
|
}
|
|
479
512
|
async sendInternal(t, e, i) {
|
|
480
|
-
const n = this.joinUrl(this.endpoint, t),
|
|
513
|
+
const n = this.joinUrl(this.endpoint, t), o = this.config.key, a = {
|
|
481
514
|
"Content-Type": "application/json",
|
|
482
|
-
[
|
|
515
|
+
[o.startsWith("sk_") ? "x-secret-key" : "x-publishable-key"]: o
|
|
483
516
|
};
|
|
484
517
|
this.config.debug && console.log("[Mark] Sending", n, e);
|
|
485
|
-
const
|
|
518
|
+
const c = JSON.stringify(e);
|
|
486
519
|
if (i?.preferBeacon && typeof navigator < "u" && typeof navigator.sendBeacon == "function") {
|
|
487
|
-
const
|
|
488
|
-
if (navigator.sendBeacon(n,
|
|
520
|
+
const u = new Blob([c], { type: "application/json" });
|
|
521
|
+
if (navigator.sendBeacon(n, u))
|
|
489
522
|
return;
|
|
490
523
|
}
|
|
491
524
|
if (typeof fetch != "function")
|
|
492
|
-
throw this.config.debug && console.error("[Mark] Global fetch is not available in this runtime."), new
|
|
493
|
-
const
|
|
525
|
+
throw this.config.debug && console.error("[Mark] Global fetch is not available in this runtime."), new p("[Mark] Global fetch is not available in this runtime.");
|
|
526
|
+
const f = this.config.request_timeout_ms ?? 1e4, l = new AbortController();
|
|
494
527
|
let d = !1;
|
|
495
|
-
const
|
|
528
|
+
const h = setTimeout(() => {
|
|
496
529
|
d = !0, l.abort();
|
|
497
|
-
},
|
|
530
|
+
}, f);
|
|
498
531
|
try {
|
|
499
|
-
const
|
|
532
|
+
const u = await fetch(n, {
|
|
500
533
|
method: "POST",
|
|
501
|
-
headers:
|
|
502
|
-
body:
|
|
534
|
+
headers: a,
|
|
535
|
+
body: c,
|
|
503
536
|
keepalive: !0,
|
|
504
537
|
signal: l.signal
|
|
505
538
|
});
|
|
506
|
-
if (!
|
|
507
|
-
const g = await this.readErrorSnippet(
|
|
539
|
+
if (!u.ok) {
|
|
540
|
+
const g = await this.readErrorSnippet(u), L = z(u.headers.get("Retry-After"));
|
|
508
541
|
throw this.config.debug && console.error("[Mark] Request rejected", {
|
|
509
542
|
url: n,
|
|
510
|
-
status:
|
|
511
|
-
statusText:
|
|
543
|
+
status: u.status,
|
|
544
|
+
statusText: u.statusText,
|
|
512
545
|
body: g,
|
|
513
|
-
retryAfterMs:
|
|
514
|
-
}), new
|
|
515
|
-
`[Mark] Request rejected with status ${
|
|
516
|
-
{ status:
|
|
546
|
+
retryAfterMs: L
|
|
547
|
+
}), new p(
|
|
548
|
+
`[Mark] Request rejected with status ${u.status}: ${g}`,
|
|
549
|
+
{ status: u.status, retryAfterMs: L }
|
|
517
550
|
);
|
|
518
551
|
}
|
|
519
|
-
} catch (
|
|
520
|
-
if (this.config.debug && console.error("[Mark] Failed to send", n,
|
|
521
|
-
throw
|
|
552
|
+
} catch (u) {
|
|
553
|
+
if (this.config.debug && console.error("[Mark] Failed to send", n, u), u instanceof p)
|
|
554
|
+
throw u;
|
|
522
555
|
if (d)
|
|
523
|
-
throw new
|
|
524
|
-
const g =
|
|
525
|
-
throw new
|
|
556
|
+
throw new p(`[Mark] Request timed out after ${f}ms`, { status: 408 });
|
|
557
|
+
const g = u instanceof Error ? u.message : String(u);
|
|
558
|
+
throw new p(`[Mark] Network error: ${g}`);
|
|
526
559
|
} finally {
|
|
527
|
-
clearTimeout(
|
|
560
|
+
clearTimeout(h);
|
|
528
561
|
}
|
|
529
562
|
}
|
|
530
563
|
joinUrl(t, e) {
|
|
@@ -539,8 +572,8 @@ class R {
|
|
|
539
572
|
}
|
|
540
573
|
}
|
|
541
574
|
}
|
|
542
|
-
const
|
|
543
|
-
class
|
|
575
|
+
const tt = "crelora_mark_data", et = "crelora_mark_outbox", k = "crelora_mark_vid";
|
|
576
|
+
class it {
|
|
544
577
|
data;
|
|
545
578
|
storageKey;
|
|
546
579
|
outboxKey;
|
|
@@ -549,11 +582,13 @@ class H {
|
|
|
549
582
|
bridgeReady = !1;
|
|
550
583
|
bridgeOrigin;
|
|
551
584
|
constructor(t) {
|
|
552
|
-
if (this.options = t ?? {}, this.storageKey = this.options.storageKey ??
|
|
585
|
+
if (this.options = t ?? {}, this.storageKey = this.options.storageKey ?? tt, this.outboxKey = this.options.outboxKey ?? et, typeof window > "u") {
|
|
553
586
|
this.data = {};
|
|
554
587
|
return;
|
|
555
588
|
}
|
|
556
|
-
this.data = this.load()
|
|
589
|
+
this.data = this.load();
|
|
590
|
+
const e = E(this.options.seed_visitor_id);
|
|
591
|
+
!this.data.visitor_id && e && (this.data.visitor_id = e, this.save()), this.data.visitor_id || (this.data.visitor_id = this.generateUUID(), this.save()), typeof window < "u" && this.options.bridge?.url && this.setupBridge(this.options.bridge), window.addEventListener("storage", this.handleStorageEvent);
|
|
557
592
|
}
|
|
558
593
|
getVisitorId() {
|
|
559
594
|
return this.data.visitor_id;
|
|
@@ -602,11 +637,19 @@ class H {
|
|
|
602
637
|
});
|
|
603
638
|
}
|
|
604
639
|
clearCookieVisitorId() {
|
|
605
|
-
this.setCookie(
|
|
640
|
+
this.setCookie(k, "", -1);
|
|
606
641
|
}
|
|
607
642
|
rotateVisitorId() {
|
|
608
643
|
this.update({ visitor_id: this.generateUUID() });
|
|
609
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* Adopts or replaces the stored visitor id with a trusted first-party value.
|
|
647
|
+
* No-op when the id is invalid or already set to the same value.
|
|
648
|
+
*/
|
|
649
|
+
setVisitorId(t) {
|
|
650
|
+
const e = E(t);
|
|
651
|
+
return e ? (this.data.visitor_id === e || this.update({ visitor_id: e }), !0) : !1;
|
|
652
|
+
}
|
|
610
653
|
getOutbox() {
|
|
611
654
|
if (typeof window > "u") return [];
|
|
612
655
|
try {
|
|
@@ -634,7 +677,7 @@ class H {
|
|
|
634
677
|
return JSON.parse(e);
|
|
635
678
|
} catch {
|
|
636
679
|
}
|
|
637
|
-
const t = this.getCookie(
|
|
680
|
+
const t = this.getCookie(k);
|
|
638
681
|
return t ? { visitor_id: t } : {};
|
|
639
682
|
}
|
|
640
683
|
save() {
|
|
@@ -643,7 +686,7 @@ class H {
|
|
|
643
686
|
localStorage.setItem(this.storageKey, JSON.stringify(this.data));
|
|
644
687
|
} catch {
|
|
645
688
|
}
|
|
646
|
-
this.data.visitor_id && this.isCookieEnabled() && (this.setCookie(
|
|
689
|
+
this.data.visitor_id && this.isCookieEnabled() && (this.setCookie(k, this.data.visitor_id, 365), this.options.bridge?.url && this.bridgeReady && this.postBridgeMessage({
|
|
647
690
|
type: "MARK_SYNC_UPDATE",
|
|
648
691
|
visitorId: this.data.visitor_id
|
|
649
692
|
}));
|
|
@@ -662,8 +705,8 @@ class H {
|
|
|
662
705
|
setCookie(t, e, i) {
|
|
663
706
|
if (!(typeof document > "u"))
|
|
664
707
|
try {
|
|
665
|
-
const n = new Date(Date.now() + i * 24 * 60 * 60 * 1e3),
|
|
666
|
-
document.cookie = `${t}=${e};expires=${n.toUTCString()};path=/;SameSite=Lax${
|
|
708
|
+
const n = new Date(Date.now() + i * 24 * 60 * 60 * 1e3), o = this.options.cookie_domain ? `;domain=${this.options.cookie_domain}` : "";
|
|
709
|
+
document.cookie = `${t}=${e};expires=${n.toUTCString()};path=/;SameSite=Lax${o}`;
|
|
667
710
|
} catch {
|
|
668
711
|
}
|
|
669
712
|
}
|
|
@@ -697,10 +740,10 @@ class H {
|
|
|
697
740
|
window.removeEventListener("message", this.handleBridgeMessage);
|
|
698
741
|
}, i);
|
|
699
742
|
window.addEventListener("message", this.handleBridgeMessage);
|
|
700
|
-
const
|
|
743
|
+
const o = () => {
|
|
701
744
|
this.bridgeFrame && document.body && document.body.appendChild(this.bridgeFrame);
|
|
702
745
|
};
|
|
703
|
-
document.body ?
|
|
746
|
+
document.body ? o() : document.addEventListener("DOMContentLoaded", o, { once: !0 }), this.bridgeFrame.addEventListener("load", () => {
|
|
704
747
|
clearTimeout(n), this.bridgeReady = !0, this.postBridgeMessage({
|
|
705
748
|
type: "MARK_SYNC_REQUEST",
|
|
706
749
|
visitorId: this.data.visitor_id
|
|
@@ -739,7 +782,7 @@ class H {
|
|
|
739
782
|
}
|
|
740
783
|
};
|
|
741
784
|
}
|
|
742
|
-
const
|
|
785
|
+
const nt = [
|
|
743
786
|
"click_id",
|
|
744
787
|
"ch_click_id",
|
|
745
788
|
"gclid",
|
|
@@ -751,7 +794,7 @@ const O = [
|
|
|
751
794
|
"ttclid",
|
|
752
795
|
"twclid",
|
|
753
796
|
"li_fat_id"
|
|
754
|
-
],
|
|
797
|
+
], st = ["cid", "campaign_id"], rt = [
|
|
755
798
|
"utm_source",
|
|
756
799
|
"utm_medium",
|
|
757
800
|
"utm_campaign",
|
|
@@ -773,101 +816,232 @@ const O = [
|
|
|
773
816
|
"ttclid",
|
|
774
817
|
"twclid",
|
|
775
818
|
"li_fat_id"
|
|
776
|
-
],
|
|
819
|
+
], ot = {
|
|
777
820
|
referral: "ref",
|
|
778
821
|
affiliate_id: "ref",
|
|
779
822
|
ch_click_id: "click_id",
|
|
780
823
|
cid: "campaign_id"
|
|
781
|
-
},
|
|
782
|
-
function
|
|
783
|
-
const e = new URLSearchParams(
|
|
784
|
-
return n && (
|
|
824
|
+
}, at = ["email", "phone", "token", "auth", "password", "code"], ct = 30, dt = 256;
|
|
825
|
+
function U(r, t = {}) {
|
|
826
|
+
const e = new URLSearchParams(r), i = lt(e), n = R(i, nt), o = R(i, st), a = ut(e, t), c = {};
|
|
827
|
+
return n && (c.last_click_id = n), o && (c.campaign_id = o), Object.keys(a).length > 0 && (c.query_params = a), c;
|
|
785
828
|
}
|
|
786
|
-
function
|
|
787
|
-
const e = {}, i = new Set(
|
|
829
|
+
function ut(r, t) {
|
|
830
|
+
const e = {}, i = new Set(B(t.query_param_denylist, at)), n = F(
|
|
788
831
|
t.max_captured_query_params,
|
|
789
|
-
|
|
790
|
-
),
|
|
832
|
+
ct
|
|
833
|
+
), o = F(
|
|
791
834
|
t.max_query_param_value_length,
|
|
792
|
-
|
|
793
|
-
),
|
|
794
|
-
...
|
|
795
|
-
...
|
|
835
|
+
dt
|
|
836
|
+
), c = t.capture_all_query_params ?? !1 ? null : /* @__PURE__ */ new Set([
|
|
837
|
+
...rt.map(S),
|
|
838
|
+
...B(t.capture_query_params, [])
|
|
796
839
|
]);
|
|
797
|
-
for (const [
|
|
798
|
-
const d =
|
|
840
|
+
for (const [f, l] of r.entries()) {
|
|
841
|
+
const d = S(f);
|
|
799
842
|
if (!d)
|
|
800
843
|
continue;
|
|
801
|
-
const
|
|
802
|
-
if (i.has(d) || i.has(
|
|
844
|
+
const h = ot[d] ?? d;
|
|
845
|
+
if (i.has(d) || i.has(h) || c && !c.has(d))
|
|
803
846
|
continue;
|
|
804
|
-
const
|
|
805
|
-
if (
|
|
806
|
-
if (!(
|
|
847
|
+
const u = l.trim();
|
|
848
|
+
if (u) {
|
|
849
|
+
if (!(h in e) && Object.keys(e).length >= n)
|
|
807
850
|
break;
|
|
808
|
-
e[
|
|
851
|
+
e[h] = u.slice(0, o);
|
|
809
852
|
}
|
|
810
853
|
}
|
|
811
854
|
return e;
|
|
812
855
|
}
|
|
813
|
-
function
|
|
856
|
+
function R(r, t) {
|
|
814
857
|
for (const e of t) {
|
|
815
|
-
const i =
|
|
858
|
+
const i = S(e), n = r[i]?.trim();
|
|
816
859
|
if (n)
|
|
817
860
|
return n;
|
|
818
861
|
}
|
|
819
862
|
}
|
|
820
|
-
function
|
|
863
|
+
function lt(r) {
|
|
821
864
|
const t = {};
|
|
822
|
-
for (const [e, i] of
|
|
823
|
-
const n =
|
|
865
|
+
for (const [e, i] of r.entries()) {
|
|
866
|
+
const n = S(e);
|
|
824
867
|
!n || n in t || (t[n] = i);
|
|
825
868
|
}
|
|
826
869
|
return t;
|
|
827
870
|
}
|
|
828
|
-
function
|
|
829
|
-
return
|
|
871
|
+
function S(r) {
|
|
872
|
+
return r.trim().toLowerCase();
|
|
830
873
|
}
|
|
831
|
-
function
|
|
832
|
-
const e =
|
|
874
|
+
function B(r, t) {
|
|
875
|
+
const e = r ?? t, i = /* @__PURE__ */ new Set();
|
|
833
876
|
for (const n of e) {
|
|
834
877
|
if (typeof n != "string") continue;
|
|
835
|
-
const
|
|
836
|
-
|
|
878
|
+
const o = S(n);
|
|
879
|
+
o && i.add(o);
|
|
837
880
|
}
|
|
838
881
|
return Array.from(i);
|
|
839
882
|
}
|
|
840
|
-
function
|
|
841
|
-
if (typeof
|
|
883
|
+
function F(r, t) {
|
|
884
|
+
if (typeof r != "number" || !Number.isFinite(r))
|
|
842
885
|
return t;
|
|
843
|
-
const e = Math.floor(
|
|
886
|
+
const e = Math.floor(r);
|
|
844
887
|
return e < 0 ? t : e;
|
|
845
888
|
}
|
|
846
|
-
function
|
|
847
|
-
return
|
|
889
|
+
function x(r) {
|
|
890
|
+
return r.length > 1 && r.endsWith("/") ? r.slice(0, -1) : r;
|
|
848
891
|
}
|
|
849
|
-
function
|
|
850
|
-
if (!
|
|
892
|
+
function ft(r) {
|
|
893
|
+
if (!r || r === "?")
|
|
851
894
|
return "";
|
|
852
|
-
const t =
|
|
895
|
+
const t = r.startsWith("?") ? r.slice(1) : r;
|
|
853
896
|
if (!t)
|
|
854
897
|
return "";
|
|
855
898
|
const e = new URLSearchParams(t), i = [];
|
|
856
|
-
e.forEach((
|
|
857
|
-
i.push([
|
|
858
|
-
}), i.sort(([
|
|
859
|
-
const d =
|
|
860
|
-
return d !== 0 ? d :
|
|
899
|
+
e.forEach((a, c) => {
|
|
900
|
+
i.push([c, a]);
|
|
901
|
+
}), i.sort(([a, c], [f, l]) => {
|
|
902
|
+
const d = a.localeCompare(f);
|
|
903
|
+
return d !== 0 ? d : c.localeCompare(l);
|
|
861
904
|
});
|
|
862
905
|
const n = new URLSearchParams();
|
|
863
|
-
for (const [
|
|
864
|
-
n.append(
|
|
865
|
-
const
|
|
866
|
-
return
|
|
906
|
+
for (const [a, c] of i)
|
|
907
|
+
n.append(a, c);
|
|
908
|
+
const o = n.toString();
|
|
909
|
+
return o === "" ? "" : `?${o}`;
|
|
910
|
+
}
|
|
911
|
+
function q(r) {
|
|
912
|
+
const t = x(r.pathname), e = ft(r.search);
|
|
913
|
+
return `${r.origin}${t}${e}${r.hash}`;
|
|
914
|
+
}
|
|
915
|
+
let D = !1, m = null;
|
|
916
|
+
const w = [], y = [], _ = [];
|
|
917
|
+
let v = null, b = null, A = null, I = null;
|
|
918
|
+
function C() {
|
|
919
|
+
if (typeof window > "u") return;
|
|
920
|
+
const r = q(window.location);
|
|
921
|
+
if (r === m) return;
|
|
922
|
+
const t = { previousKey: m, nextKey: r };
|
|
923
|
+
for (const e of w)
|
|
924
|
+
e(t);
|
|
925
|
+
m = r;
|
|
926
|
+
for (const e of y)
|
|
927
|
+
e(t);
|
|
928
|
+
}
|
|
929
|
+
function ht() {
|
|
930
|
+
for (const r of _)
|
|
931
|
+
r();
|
|
932
|
+
}
|
|
933
|
+
function gt(r = {}) {
|
|
934
|
+
if (D || typeof window > "u" || typeof document > "u")
|
|
935
|
+
return;
|
|
936
|
+
D = !0;
|
|
937
|
+
const t = r.trackRouteChanges ?? !0;
|
|
938
|
+
m = q(window.location), I = ht, window.addEventListener("pagehide", I), t && (v = history.pushState, b = history.replaceState, history.pushState = function(...e) {
|
|
939
|
+
const i = v.apply(this, e);
|
|
940
|
+
return C(), i;
|
|
941
|
+
}, history.replaceState = function(...e) {
|
|
942
|
+
const i = b.apply(this, e);
|
|
943
|
+
return C(), i;
|
|
944
|
+
}, A = C, window.addEventListener("popstate", A));
|
|
945
|
+
}
|
|
946
|
+
function pt(r) {
|
|
947
|
+
return w.push(r), () => {
|
|
948
|
+
const t = w.indexOf(r);
|
|
949
|
+
t >= 0 && w.splice(t, 1);
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
function P(r) {
|
|
953
|
+
return y.push(r), () => {
|
|
954
|
+
const t = y.indexOf(r);
|
|
955
|
+
t >= 0 && y.splice(t, 1);
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
function mt(r) {
|
|
959
|
+
return _.push(r), () => {
|
|
960
|
+
const t = _.indexOf(r);
|
|
961
|
+
t >= 0 && _.splice(t, 1);
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
function wt() {
|
|
965
|
+
!D || typeof window > "u" || (v && (history.pushState = v), b && (history.replaceState = b), A && window.removeEventListener("popstate", A), I && window.removeEventListener("pagehide", I), v = null, b = null, A = null, I = null, w.length = 0, y.length = 0, _.length = 0, m = null, D = !1);
|
|
966
|
+
}
|
|
967
|
+
let T = 0;
|
|
968
|
+
function H() {
|
|
969
|
+
T = 0;
|
|
970
|
+
}
|
|
971
|
+
function yt() {
|
|
972
|
+
return T;
|
|
973
|
+
}
|
|
974
|
+
function _t() {
|
|
975
|
+
if (typeof document > "u" || typeof window > "u")
|
|
976
|
+
return 0;
|
|
977
|
+
const r = document.documentElement, t = window.scrollY || r.scrollTop, e = Math.max(1, r.scrollHeight - window.innerHeight);
|
|
978
|
+
return Math.min(100, Math.round(t / e * 100));
|
|
979
|
+
}
|
|
980
|
+
function K() {
|
|
981
|
+
const r = _t();
|
|
982
|
+
return r > T && (T = r), r;
|
|
983
|
+
}
|
|
984
|
+
const vt = [25, 50, 75, 100];
|
|
985
|
+
function bt(r, t = vt) {
|
|
986
|
+
if (typeof window > "u") return;
|
|
987
|
+
const e = /* @__PURE__ */ new Set(), i = () => {
|
|
988
|
+
e.clear(), H();
|
|
989
|
+
};
|
|
990
|
+
i(), P(() => {
|
|
991
|
+
i();
|
|
992
|
+
}), window.addEventListener(
|
|
993
|
+
"scroll",
|
|
994
|
+
() => {
|
|
995
|
+
const n = K();
|
|
996
|
+
for (const o of t)
|
|
997
|
+
n >= o && !e.has(o) && (e.add(o), r.track("scroll_depth", { percent: o }));
|
|
998
|
+
},
|
|
999
|
+
{ passive: !0 }
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
const O = 1e4;
|
|
1003
|
+
function At(r) {
|
|
1004
|
+
return r === !0 ? { minActiveMs: O, useBeacon: !0 } : {
|
|
1005
|
+
minActiveMs: r.min_active_ms ?? O,
|
|
1006
|
+
useBeacon: r.use_beacon !== !1
|
|
1007
|
+
};
|
|
867
1008
|
}
|
|
868
|
-
function
|
|
869
|
-
|
|
870
|
-
|
|
1009
|
+
function It(r, t) {
|
|
1010
|
+
if (typeof window > "u" || typeof document > "u") return;
|
|
1011
|
+
let e = Date.now(), i = 0, n = document.visibilityState === "visible" ? Date.now() : null, o = x(window.location.pathname), a = !1;
|
|
1012
|
+
const c = () => {
|
|
1013
|
+
n !== null && (i += Date.now() - n, n = null);
|
|
1014
|
+
}, f = () => {
|
|
1015
|
+
document.visibilityState === "visible" && n === null && (n = Date.now());
|
|
1016
|
+
}, l = (h) => {
|
|
1017
|
+
if (!a) {
|
|
1018
|
+
a = !0;
|
|
1019
|
+
try {
|
|
1020
|
+
if (c(), K(), i < t.minActiveMs)
|
|
1021
|
+
return;
|
|
1022
|
+
const u = Date.now() - e, g = {
|
|
1023
|
+
page: o,
|
|
1024
|
+
active_time_ms: i,
|
|
1025
|
+
total_time_ms: u,
|
|
1026
|
+
max_scroll_percent: yt()
|
|
1027
|
+
};
|
|
1028
|
+
t.useBeacon && h ? r.trackWithOptions("page_engagement", g, { preferBeacon: !0 }) : r.track("page_engagement", g);
|
|
1029
|
+
} finally {
|
|
1030
|
+
a = !1;
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}, d = () => {
|
|
1034
|
+
e = Date.now(), i = 0, o = x(window.location.pathname), H(), f();
|
|
1035
|
+
};
|
|
1036
|
+
d(), pt(() => {
|
|
1037
|
+
l(!0), c();
|
|
1038
|
+
}), P(() => {
|
|
1039
|
+
d();
|
|
1040
|
+
}), mt(() => {
|
|
1041
|
+
l(!0);
|
|
1042
|
+
}), document.addEventListener("visibilitychange", () => {
|
|
1043
|
+
document.visibilityState === "hidden" ? c() : f();
|
|
1044
|
+
});
|
|
871
1045
|
}
|
|
872
1046
|
class s {
|
|
873
1047
|
static client = null;
|
|
@@ -877,17 +1051,17 @@ class s {
|
|
|
877
1051
|
static lastPageviewDedupeKey = null;
|
|
878
1052
|
static emitAutoPageview = null;
|
|
879
1053
|
static pendingAttribution = {};
|
|
880
|
-
static originalPushState = null;
|
|
881
|
-
static originalReplaceState = null;
|
|
882
|
-
static popstateHandler = null;
|
|
883
1054
|
static beaconDrainHandler = null;
|
|
884
1055
|
static visibilityHandler = null;
|
|
885
1056
|
static onlineHandler = null;
|
|
886
1057
|
static kickTimer = null;
|
|
887
1058
|
static init(t) {
|
|
888
1059
|
if (!s.client) {
|
|
889
|
-
const e = new
|
|
890
|
-
|
|
1060
|
+
const e = new it({
|
|
1061
|
+
...t.cross_domain,
|
|
1062
|
+
seed_visitor_id: t.visitor_id
|
|
1063
|
+
}), i = new Z(t);
|
|
1064
|
+
s.client = new J(t, { storage: e, transport: i }), s.storage = e, s.config = t, s.refreshAttribution(e, t), typeof window < "u" && (s.installPageLifecycleIfNeeded(t), t.autocapture?.pageview && s.installPageviewTracking(t, e), s.installExtendedAutocapture(t), s.installLifecycleFlushing());
|
|
891
1065
|
}
|
|
892
1066
|
return s.client;
|
|
893
1067
|
}
|
|
@@ -942,6 +1116,17 @@ class s {
|
|
|
942
1116
|
if (!(!s.client || !s.storage || !s.config || (s.config.require_consent ?? !1) && s.storage.getConsentStatus() !== "granted"))
|
|
943
1117
|
return s.client.getVisitorId();
|
|
944
1118
|
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Adopts or replaces the stored visitor id with a trusted first-party value.
|
|
1121
|
+
* Updates in-memory storage, localStorage, and the visitor cookie immediately.
|
|
1122
|
+
* Use when an external anonymous id (for example a platform client id) is
|
|
1123
|
+
* available after init. Theme embeds and pixels should call this with the
|
|
1124
|
+
* same source id. Returns false when the id is invalid or the SDK is not
|
|
1125
|
+
* initialized.
|
|
1126
|
+
*/
|
|
1127
|
+
static setVisitorId(t) {
|
|
1128
|
+
return s.client ? s.client.setVisitorId(t) : (s.config?.debug && console.warn("[Mark] Not initialized. Call init() first."), !1);
|
|
1129
|
+
}
|
|
945
1130
|
static flush() {
|
|
946
1131
|
return s.client ? s.client.flush() : Promise.resolve();
|
|
947
1132
|
}
|
|
@@ -976,7 +1161,13 @@ class s {
|
|
|
976
1161
|
return s.client?.getStats() ?? { queued: 0, sent: 0, failed: 0, dropped: 0 };
|
|
977
1162
|
}
|
|
978
1163
|
static destroy() {
|
|
979
|
-
typeof window > "u" || (
|
|
1164
|
+
typeof window > "u" || (wt(), s.beaconDrainHandler && (window.removeEventListener("pagehide", s.beaconDrainHandler), window.removeEventListener("beforeunload", s.beaconDrainHandler)), s.visibilityHandler && typeof document < "u" && document.removeEventListener("visibilitychange", s.visibilityHandler), s.onlineHandler && window.removeEventListener("online", s.onlineHandler), s.kickTimer && clearInterval(s.kickTimer), s.beaconDrainHandler = null, s.visibilityHandler = null, s.onlineHandler = null, s.kickTimer = null, s.pageviewTrackerInstalled = !1);
|
|
1165
|
+
}
|
|
1166
|
+
static installPageLifecycleIfNeeded(t) {
|
|
1167
|
+
const e = t.autocapture;
|
|
1168
|
+
if (!(!!e?.pageview || !!e?.scroll_depth || !!e?.page_engagement)) return;
|
|
1169
|
+
const n = t.track_route_changes ?? !0;
|
|
1170
|
+
gt({ trackRouteChanges: n });
|
|
980
1171
|
}
|
|
981
1172
|
static installPageviewTracking(t, e) {
|
|
982
1173
|
if (s.pageviewTrackerInstalled) return;
|
|
@@ -984,29 +1175,23 @@ class s {
|
|
|
984
1175
|
const i = () => {
|
|
985
1176
|
if (!s.client) return;
|
|
986
1177
|
s.refreshAttribution(e, t);
|
|
987
|
-
const
|
|
988
|
-
if (
|
|
1178
|
+
const o = q(window.location);
|
|
1179
|
+
if (o === s.lastPageviewDedupeKey) return;
|
|
989
1180
|
s.client.track("page_view", {
|
|
990
1181
|
site: window.location.host,
|
|
991
|
-
page:
|
|
1182
|
+
page: x(window.location.pathname),
|
|
992
1183
|
title: document.title,
|
|
993
1184
|
referrer: document.referrer || void 0
|
|
994
|
-
}) && (s.lastPageviewDedupeKey =
|
|
1185
|
+
}) && (s.lastPageviewDedupeKey = o);
|
|
995
1186
|
};
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
const u = r.apply(this, a);
|
|
1000
|
-
return i(), u;
|
|
1001
|
-
}, history.replaceState = function(...a) {
|
|
1002
|
-
const u = o.apply(this, a);
|
|
1003
|
-
return i(), u;
|
|
1004
|
-
}, s.popstateHandler = i, window.addEventListener("popstate", i);
|
|
1187
|
+
s.emitAutoPageview = i, i(), (t.track_route_changes ?? !0) && P(() => {
|
|
1188
|
+
i();
|
|
1189
|
+
});
|
|
1005
1190
|
}
|
|
1006
1191
|
static refreshAttribution(t, e) {
|
|
1007
1192
|
if (typeof window > "u")
|
|
1008
1193
|
return;
|
|
1009
|
-
const i =
|
|
1194
|
+
const i = U(window.location.search, e);
|
|
1010
1195
|
if (Object.keys(i).length !== 0) {
|
|
1011
1196
|
if (s.shouldPersistAttribution(t, e)) {
|
|
1012
1197
|
const n = s.mergeAttributionUpdates(s.pendingAttribution, i);
|
|
@@ -1020,7 +1205,7 @@ class s {
|
|
|
1020
1205
|
const t = s.storage, e = s.config;
|
|
1021
1206
|
if (!t || !e || typeof window > "u")
|
|
1022
1207
|
return;
|
|
1023
|
-
const i =
|
|
1208
|
+
const i = U(window.location.search, e), n = s.mergeAttributionUpdates(s.pendingAttribution, i);
|
|
1024
1209
|
Object.keys(n).length > 0 && t.update(n), s.pendingAttribution = {};
|
|
1025
1210
|
}
|
|
1026
1211
|
static shouldPersistAttribution(t, e) {
|
|
@@ -1039,60 +1224,46 @@ class s {
|
|
|
1039
1224
|
static installExtendedAutocapture(t) {
|
|
1040
1225
|
if (!s.client || typeof document > "u") return;
|
|
1041
1226
|
const e = t.autocapture;
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
href: o.href || void 0
|
|
1054
|
-
});
|
|
1055
|
-
}), e.form_submit && document.addEventListener("submit", (i) => {
|
|
1056
|
-
const n = i.target;
|
|
1057
|
-
n && s.client?.track("form_submit", {
|
|
1058
|
-
form_id: n.id || void 0,
|
|
1059
|
-
form_name: n.name || void 0,
|
|
1060
|
-
action: n.action || void 0
|
|
1061
|
-
});
|
|
1062
|
-
}), e.outbound_link && document.addEventListener("click", (i) => {
|
|
1063
|
-
const n = i.target?.closest("a[href]");
|
|
1064
|
-
if (!(!n || !n.href))
|
|
1065
|
-
try {
|
|
1066
|
-
const r = new URL(n.href, window.location.href), o = new URL(window.location.href);
|
|
1067
|
-
r.origin !== o.origin && s.client?.trackWithOptions("outbound_link_click", { href: r.toString() }, { preferBeacon: !0 });
|
|
1068
|
-
} catch {
|
|
1069
|
-
}
|
|
1070
|
-
}), e.scroll_depth) {
|
|
1071
|
-
const i = [25, 50, 75, 100], n = /* @__PURE__ */ new Set();
|
|
1072
|
-
window.addEventListener(
|
|
1073
|
-
"scroll",
|
|
1074
|
-
() => {
|
|
1075
|
-
const r = document.documentElement, o = window.scrollY || r.scrollTop, a = Math.max(1, r.scrollHeight - window.innerHeight), u = Math.min(100, Math.round(o / a * 100));
|
|
1076
|
-
for (const l of i)
|
|
1077
|
-
u >= l && !n.has(l) && (n.add(l), s.client?.track("scroll_depth", { percent: l }));
|
|
1078
|
-
},
|
|
1079
|
-
{ passive: !0 }
|
|
1080
|
-
);
|
|
1081
|
-
}
|
|
1082
|
-
e.web_vitals && import("./web-vitals-CrnTllyu.js").then((i) => {
|
|
1083
|
-
const n = (r) => {
|
|
1084
|
-
s.client?.track("web_vital", {
|
|
1085
|
-
metric: r.name,
|
|
1086
|
-
value: r.value,
|
|
1087
|
-
rating: r.rating,
|
|
1088
|
-
metric_id: r.id
|
|
1089
|
-
});
|
|
1090
|
-
};
|
|
1091
|
-
i.onLCP(n), i.onCLS(n), i.onINP(n), i.onTTFB(n);
|
|
1092
|
-
}).catch(() => {
|
|
1093
|
-
t.debug && console.warn("[Mark] web-vitals package not available; skipping autocapture.web_vitals.");
|
|
1227
|
+
e && (e.click && document.addEventListener("click", (i) => {
|
|
1228
|
+
const n = i.target;
|
|
1229
|
+
if (!n) return;
|
|
1230
|
+
const o = typeof e.click == "object" ? e.click.selector : void 0, a = o ? n.closest(o) : n.closest("[data-mark-event]");
|
|
1231
|
+
if (!a) return;
|
|
1232
|
+
const c = a.getAttribute("data-mark-event") || "click";
|
|
1233
|
+
s.client?.track(c, {
|
|
1234
|
+
element_id: a.id || void 0,
|
|
1235
|
+
element_classes: a.className || void 0,
|
|
1236
|
+
text: a.textContent?.trim().slice(0, 120) || void 0,
|
|
1237
|
+
href: a.href || void 0
|
|
1094
1238
|
});
|
|
1095
|
-
}
|
|
1239
|
+
}), e.form_submit && document.addEventListener("submit", (i) => {
|
|
1240
|
+
const n = i.target;
|
|
1241
|
+
n && s.client?.track("form_submit", {
|
|
1242
|
+
form_id: n.id || void 0,
|
|
1243
|
+
form_name: n.name || void 0,
|
|
1244
|
+
action: n.action || void 0
|
|
1245
|
+
});
|
|
1246
|
+
}), e.outbound_link && document.addEventListener("click", (i) => {
|
|
1247
|
+
const n = i.target?.closest("a[href]");
|
|
1248
|
+
if (!(!n || !n.href))
|
|
1249
|
+
try {
|
|
1250
|
+
const o = new URL(n.href, window.location.href), a = new URL(window.location.href);
|
|
1251
|
+
o.origin !== a.origin && s.client?.trackWithOptions("outbound_link_click", { href: o.toString() }, { preferBeacon: !0 });
|
|
1252
|
+
} catch {
|
|
1253
|
+
}
|
|
1254
|
+
}), e.scroll_depth && s.client && bt(s.client), e.page_engagement && s.client && It(s.client, At(e.page_engagement)), e.web_vitals && import("./web-vitals-CrnTllyu.js").then((i) => {
|
|
1255
|
+
const n = (o) => {
|
|
1256
|
+
s.client?.track("web_vital", {
|
|
1257
|
+
metric: o.name,
|
|
1258
|
+
value: o.value,
|
|
1259
|
+
rating: o.rating,
|
|
1260
|
+
metric_id: o.id
|
|
1261
|
+
});
|
|
1262
|
+
};
|
|
1263
|
+
i.onLCP(n), i.onCLS(n), i.onINP(n), i.onTTFB(n);
|
|
1264
|
+
}).catch(() => {
|
|
1265
|
+
t.debug && console.warn("[Mark] web-vitals package not available; skipping autocapture.web_vitals.");
|
|
1266
|
+
}));
|
|
1096
1267
|
}
|
|
1097
1268
|
}
|
|
1098
1269
|
typeof window < "u" && (window.Mark = s);
|