@usermaven/sdk-js 1.4.1-rc.62 → 1.4.2

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.
@@ -1,1325 +0,0 @@
1
- var v = /* @__PURE__ */ ((i) => (i[i.DEBUG = 0] = "DEBUG", i[i.INFO = 1] = "INFO", i[i.WARN = 2] = "WARN", i[i.ERROR = 3] = "ERROR", i))(v || {});
2
- class V {
3
- constructor(e) {
4
- this.level = e;
5
- }
6
- debug(e, ...t) {
7
- this.level <= 0 && console.debug("[Usermaven Debug]:", e, ...t);
8
- }
9
- info(e, ...t) {
10
- this.level <= 1 && console.info("[Usermaven Info]:", e, ...t);
11
- }
12
- warn(e, ...t) {
13
- this.level <= 2 && console.warn("[Usermaven Warning]:", e, ...t);
14
- }
15
- error(e, ...t) {
16
- this.level <= 3 && console.error("[Usermaven Error]:", e, ...t);
17
- }
18
- }
19
- function h(i = 0) {
20
- return new V(i);
21
- }
22
- const I = {
23
- logLevel: v.ERROR,
24
- useBeaconApi: !1,
25
- forceUseFetch: !1,
26
- trackingHost: "t.usermaven.com",
27
- autocapture: !1,
28
- rageClick: !1,
29
- formTracking: !1,
30
- autoPageview: !1,
31
- disableEventPersistence: !1,
32
- gaHook: !1,
33
- segmentHook: !1,
34
- randomizeUrl: !1,
35
- capture3rdPartyCookies: ["_ga", "_fbp", "_ym_uid", "ajs_user_id", "ajs_anonymous_id"],
36
- idMethod: "cookie",
37
- ipPolicy: "keep",
38
- cookiePolicy: "keep",
39
- minSendTimeout: 0,
40
- maxSendTimeout: 2e3,
41
- maxSendAttempts: 4,
42
- propertiesStringMaxLength: null,
43
- propertyBlacklist: [],
44
- crossDomainLinking: !0,
45
- maskAllText: !1,
46
- maskAllElementAttributes: !1
47
- };
48
- class Q {
49
- constructor(e) {
50
- this.domain = e, this.cookieDomain = this.getCookieDomain();
51
- }
52
- set(e, t, s = 365, n = !0, r = !1) {
53
- const o = /* @__PURE__ */ new Date();
54
- o.setTime(o.getTime() + s * 24 * 60 * 60 * 1e3);
55
- const c = `expires=${o.toUTCString()}`, l = n ? "; Secure" : "", a = r ? "; HttpOnly" : "";
56
- document.cookie = `${e}=${t};${c};path=/;domain=${this.cookieDomain}${l}${a}`;
57
- }
58
- get(e) {
59
- const t = e + "=", s = document.cookie.split(";");
60
- for (let n = 0; n < s.length; n++) {
61
- let r = s[n].trim();
62
- if (r.indexOf(t) === 0)
63
- return decodeURIComponent(r.substring(t.length));
64
- }
65
- return null;
66
- }
67
- delete(e, t = "/") {
68
- document.cookie = `${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${t};domain=${this.cookieDomain}`;
69
- }
70
- getCookieDomain() {
71
- return typeof window > "u" || this.domain ? this.domain || "" : this.extractRoot(window.location.hostname);
72
- }
73
- extractRoot(e) {
74
- if (this.isIpAddress(e) || e === "localhost")
75
- return e;
76
- let t = this.extractTopLevelDomain(e);
77
- return t || (t = this.extractRootDomain(e)), "." + t;
78
- }
79
- isIpAddress(e) {
80
- const t = e.split(".");
81
- return t.length === 4 && t.every((s) => !isNaN(Number(s)));
82
- }
83
- extractHostname(e) {
84
- let t;
85
- return e.indexOf("//") > -1 ? t = e.split("/")[2] : t = e.split("/")[0], t = t.split(":")[0], t = t.split("?")[0], t;
86
- }
87
- extractRootDomain(e) {
88
- let t = this.extractHostname(e);
89
- const s = t.split("."), n = s.length;
90
- return n > 2 && (s[n - 1].length == 2 ? (t = s[n - 2] + "." + s[n - 1], s[n - 2].length == 2 && (t = s[n - 3] + "." + t)) : t = s[n - 2] + "." + s[n - 1]), t;
91
- }
92
- extractTopLevelDomain(e) {
93
- const t = /[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i, s = e.match(t);
94
- return s ? s[0] : "";
95
- }
96
- }
97
- const W = Object.prototype, X = W.hasOwnProperty, K = Array.prototype, E = K.forEach, T = {};
98
- function Z(i, e, t) {
99
- if (Array.isArray(i)) {
100
- if (E && i.forEach === E)
101
- i.forEach(e, t);
102
- else if ("length" in i && i.length === +i.length) {
103
- for (let s = 0, n = i.length; s < n; s++)
104
- if (s in i && e.call(t, i[s], s) === T)
105
- return;
106
- }
107
- }
108
- }
109
- const A = function(i) {
110
- return i.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
111
- }, G = function(i) {
112
- for (const e in i)
113
- typeof i[e] == "function" && (i[e] = i[e].bind(i));
114
- };
115
- function S(i, e, t) {
116
- if (i != null) {
117
- if (E && Array.isArray(i) && i.forEach === E)
118
- i.forEach(e, t);
119
- else if ("length" in i && i.length === +i.length) {
120
- for (let s = 0, n = i.length; s < n; s++)
121
- if (s in i && e.call(t, i[s], s) === T)
122
- return;
123
- } else
124
- for (const s in i)
125
- if (X.call(i, s) && e.call(t, i[s], s) === T)
126
- return;
127
- }
128
- }
129
- const Y = function(i, ...e) {
130
- return Z(e, function(t) {
131
- for (const s in t)
132
- t[s] !== void 0 && (i[s] = t[s]);
133
- }), i;
134
- };
135
- function _(i, e) {
136
- return i.indexOf(e) !== -1;
137
- }
138
- const F = function(i) {
139
- try {
140
- return /^\s*\bfunction\b/.test(i);
141
- } catch {
142
- return !1;
143
- }
144
- }, j = function(i) {
145
- return i === void 0;
146
- }, p = function() {
147
- const i = function(s, n, r, o, c) {
148
- if (!s) {
149
- h().error("No valid element provided to register_event");
150
- return;
151
- }
152
- if (s.addEventListener && !o)
153
- s.addEventListener(n, r, !!c);
154
- else {
155
- const l = "on" + n, a = s[l];
156
- s[l] = e(s, r, a);
157
- }
158
- };
159
- function e(s, n, r) {
160
- return function(o) {
161
- if (o = o || t(window.event), !o)
162
- return;
163
- let c = !0, l;
164
- F(r) && (l = r(o));
165
- const a = n.call(s, o);
166
- return (l === !1 || a === !1) && (c = !1), c;
167
- };
168
- }
169
- function t(s) {
170
- return s && (s.preventDefault = t.preventDefault, s.stopPropagation = t.stopPropagation), s;
171
- }
172
- return t.preventDefault = function() {
173
- this.returnValue = !1;
174
- }, t.stopPropagation = function() {
175
- this.cancelBubble = !0;
176
- }, i;
177
- }(), ee = function(i) {
178
- return function(...e) {
179
- try {
180
- return i.apply(this, e);
181
- } catch (t) {
182
- h().error("Implementation error. Please turn on debug and contact support@usermaven.com.", t);
183
- }
184
- };
185
- }, z = function(i) {
186
- for (const e in i)
187
- typeof i[e] == "function" && (i[e] = ee(i[e]));
188
- };
189
- function N(i) {
190
- for (let e in i)
191
- (i[e] === "" || i[e] === null || i[e] === void 0 || typeof i[e] == "object" && Object.keys(i[e]).length === 0) && delete i[e];
192
- return i;
193
- }
194
- function u() {
195
- try {
196
- return typeof window < "u" && window.document !== void 0 && window.document.createElement !== void 0;
197
- } catch {
198
- return h().warn("window is not available"), !1;
199
- }
200
- }
201
- function f(i = 5) {
202
- const e = new Uint8Array(i);
203
- return crypto.getRandomValues(e), Array.from(e, (t) => t.toString(36).padStart(2, "0")).join("").slice(0, i);
204
- }
205
- function te(i) {
206
- return i.replace(
207
- /([-_][a-z])/g,
208
- (e) => e.toUpperCase().replace("-", "").replace("_", "")
209
- );
210
- }
211
- function C(i) {
212
- return typeof i != "object" || i === null ? i : Array.isArray(i) ? i.map(C) : Object.keys(i).reduce((e, t) => {
213
- const s = te(t);
214
- return e[s] = C(i[t]), e;
215
- }, {});
216
- }
217
- function P(i) {
218
- switch (typeof i.className) {
219
- case "string":
220
- return i.className;
221
- case "object":
222
- return ("baseVal" in i.className ? i.className.baseVal : null) || i.getAttribute("class") || "";
223
- default:
224
- return "";
225
- }
226
- }
227
- function O(i) {
228
- let e = "";
229
- return M(i) && !q(i) && i.childNodes && i.childNodes.length && S(i.childNodes, function(t) {
230
- B(t) && t.textContent && (e += A(t.textContent).split(/(\s+)/).filter(H).join("").replace(/[\r\n]/g, " ").replace(/[ ]+/g, " ").substring(0, 255));
231
- }), A(e);
232
- }
233
- function R(i) {
234
- return !!i && i.nodeType === 1;
235
- }
236
- function d(i, e) {
237
- return !!i && !!i.tagName && i.tagName.toLowerCase() === e.toLowerCase();
238
- }
239
- function B(i) {
240
- return !!i && i.nodeType === 3;
241
- }
242
- function x(i) {
243
- return !!i && i.nodeType === 11;
244
- }
245
- const b = ["a", "button", "form", "input", "select", "textarea", "label"];
246
- function ie(i, e) {
247
- if (!i || d(i, "html") || !R(i))
248
- return !1;
249
- let t = i;
250
- for (; t && !d(t, "body"); ) {
251
- if (t.classList && t.classList.contains("um-no-capture"))
252
- return !1;
253
- t.parentNode && x(t.parentNode) ? t = t.parentNode.host : t = t.parentNode;
254
- }
255
- let s = !1;
256
- for (t = i; t && !d(t, "body"); ) {
257
- if (t.parentNode && x(t.parentNode)) {
258
- t = t.parentNode.host, t && b.indexOf(t.tagName.toLowerCase()) > -1 && (s = !0);
259
- continue;
260
- }
261
- const o = t.parentNode;
262
- if (!o) break;
263
- if (b.indexOf(o.tagName.toLowerCase()) > -1)
264
- s = !0;
265
- else {
266
- const c = window.getComputedStyle(o);
267
- c && c.getPropertyValue("cursor") === "pointer" && (s = !0);
268
- }
269
- t = o;
270
- }
271
- const n = window.getComputedStyle(i);
272
- if (n && n.getPropertyValue("cursor") === "pointer" && e.type === "click")
273
- return !0;
274
- const r = i.tagName.toLowerCase();
275
- switch (r) {
276
- case "html":
277
- return !1;
278
- case "form":
279
- return e.type === "submit";
280
- case "input":
281
- return e.type === "change" || e.type === "click";
282
- case "select":
283
- case "textarea":
284
- return e.type === "change" || e.type === "click";
285
- default:
286
- return s ? e.type === "click" : e.type === "click" && (b.indexOf(r) > -1 || i.getAttribute("contenteditable") === "true");
287
- }
288
- }
289
- function M(i) {
290
- if (!i || !R(i))
291
- return !1;
292
- if (typeof i.hasAttribute == "function") {
293
- if (i.hasAttribute(w.FORCE_CAPTURE_ATTR))
294
- return !0;
295
- if (i.hasAttribute(w.PREVENT_CAPTURE_ATTR))
296
- return !1;
297
- }
298
- let e = i;
299
- for (; e && e.parentElement && !d(e, "body"); ) {
300
- const n = P(e).split(" ");
301
- if (_(n, "ph-sensitive") || _(n, "ph-no-capture"))
302
- return !1;
303
- e = e.parentElement;
304
- }
305
- if (_(P(i).split(" "), "ph-include"))
306
- return !0;
307
- const t = i.type;
308
- if (typeof t == "string")
309
- switch (t.toLowerCase()) {
310
- case "hidden":
311
- case "password":
312
- return !1;
313
- }
314
- const s = i.name || i.id || "";
315
- return !(typeof s == "string" && /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i.test(s.replace(/[^a-zA-Z0-9]/g, "")));
316
- }
317
- function q(i) {
318
- const e = ["button", "checkbox", "submit", "reset"];
319
- return !!(d(i, "input") && !e.includes(i.type) || d(i, "select") || d(i, "textarea") || i.getAttribute("contenteditable") === "true");
320
- }
321
- function H(i) {
322
- return !(i === null || j(i) || typeof i == "string" && (i = A(i), /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((i || "").replace(/[- ]/g, "")) || /(^\d{3}-?\d{2}-?\d{4}$)/.test(i)));
323
- }
324
- function se(i) {
325
- return typeof i == "string" ? i.substring(0, 10) === "_ngcontent" || i.substring(0, 7) === "_nghost" : !1;
326
- }
327
- function $() {
328
- return f(10);
329
- }
330
- function ne(i) {
331
- return /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(String(i).toLowerCase());
332
- }
333
- function re(i, e) {
334
- let t;
335
- return function(...s) {
336
- const n = () => {
337
- clearTimeout(t), i(...s);
338
- };
339
- clearTimeout(t), t = setTimeout(n, e);
340
- };
341
- }
342
- function oe(i) {
343
- const e = {}, t = i.replace(/^\?/, "").split("&");
344
- for (let s = 0; s < t.length; s++) {
345
- const n = t[s].split("=");
346
- n[0] !== "" && (e[decodeURIComponent(n[0])] = decodeURIComponent(n[1] || ""));
347
- }
348
- return e;
349
- }
350
- function L(i) {
351
- return typeof i == "string" || i instanceof String;
352
- }
353
- function k(i) {
354
- return i !== null && typeof i == "object" && i.constructor === Object;
355
- }
356
- function ae(i) {
357
- if (i === null)
358
- return v.ERROR;
359
- const e = i.toUpperCase(), t = v[e];
360
- return t || t === 0 ? t : v.ERROR;
361
- }
362
- class ce {
363
- constructor(e) {
364
- this.maxScrollDepth = 0, this.milestones = [25, 50, 75, 90], this.lastScrollDepth = 0, this.client = e, this.documentElement = document.documentElement, this.debouncedHandleScroll = re(this.handleScroll.bind(this), 250), this.initializeEventListener();
365
- }
366
- initializeEventListener() {
367
- window.addEventListener("scroll", this.debouncedHandleScroll);
368
- }
369
- track() {
370
- const e = this.getScrollDepth();
371
- e > this.lastScrollDepth && (this.lastScrollDepth = e, this.checkMilestones(e));
372
- }
373
- send(e = "$scroll") {
374
- if (!this.lastScrollDepth)
375
- return;
376
- const t = {
377
- percent: this.lastScrollDepth,
378
- window_height: this.getWindowHeight(),
379
- document_height: this.getDocumentHeight(),
380
- scroll_distance: this.getScrollDistance()
381
- };
382
- this.client.track(e, t);
383
- }
384
- handleScroll() {
385
- this.track();
386
- }
387
- getScrollDepth() {
388
- const e = this.getWindowHeight(), t = this.getDocumentHeight(), s = this.getScrollDistance(), n = t - e;
389
- return Math.min(100, Math.floor(s / n * 100));
390
- }
391
- getWindowHeight() {
392
- return window.innerHeight || this.documentElement.clientHeight || document.body.clientHeight || 0;
393
- }
394
- getDocumentHeight() {
395
- return Math.max(
396
- document.body.scrollHeight || 0,
397
- this.documentElement.scrollHeight || 0,
398
- document.body.offsetHeight || 0,
399
- this.documentElement.offsetHeight || 0,
400
- document.body.clientHeight || 0,
401
- this.documentElement.clientHeight || 0
402
- );
403
- }
404
- getScrollDistance() {
405
- return window.pageYOffset || this.documentElement.scrollTop || document.body.scrollTop || 0;
406
- }
407
- checkMilestones(e) {
408
- this.milestones.filter((s) => e >= s).forEach((s) => {
409
- this.send(), this.milestones = this.milestones.filter((n) => n !== s);
410
- });
411
- }
412
- }
413
- const y = class y {
414
- constructor(e, t, s = h()) {
415
- this.logger = s, this.scrollDepth = null, this.client = e, this.options = t, this.scrollDepth = new ce(e), G(this), z(this);
416
- }
417
- init() {
418
- if (!(document && document.body)) {
419
- this.logger.debug("Document not ready yet, trying again in 500 milliseconds..."), setTimeout(() => this.init(), 500);
420
- return;
421
- }
422
- this.addDomEventHandlers();
423
- }
424
- addDomEventHandlers() {
425
- const e = (t) => {
426
- t = t || window.event, this.captureEvent(t);
427
- };
428
- p(document, "submit", e, !1, !0), p(document, "change", e, !1, !0), p(document, "click", e, !1, !0), p(document, "visibilitychange", e, !1, !0), p(document, "scroll", e, !1, !0), p(window, "popstate", e, !1, !0);
429
- }
430
- isPageRefresh() {
431
- if ("PerformanceNavigationTiming" in window) {
432
- const e = performance.getEntriesByType("navigation");
433
- if (e.length > 0)
434
- return e[0].type === "reload";
435
- }
436
- return performance.navigation && performance.navigation.type === 1;
437
- }
438
- captureEvent(e) {
439
- var s, n;
440
- let t = this.getEventTarget(e);
441
- if (B(t) && (t = t.parentNode || null), e.type === "scroll")
442
- return (s = this.scrollDepth) == null || s.track(), !0;
443
- if (e.type === "visibilitychange" && document.visibilityState === "hidden" || e.type === "popstate")
444
- return this.isPageRefresh() || (n = this.scrollDepth) == null || n.send(), !0;
445
- if (t && this.shouldCaptureElement(t, e)) {
446
- const r = this.getElementList(t), o = this.getElementsJson(r, e), c = Y(
447
- this.getDefaultProperties(e.type),
448
- {
449
- $elements: o
450
- }
451
- );
452
- return this.client.track("$autocapture", c), !0;
453
- }
454
- }
455
- shouldCaptureElement(e, t) {
456
- return !e || typeof e.hasAttribute != "function" ? !1 : e.hasAttribute(y.FORCE_CAPTURE_ATTR) ? !0 : e.hasAttribute(y.PREVENT_CAPTURE_ATTR) ? !1 : ie(e, t);
457
- }
458
- getEventTarget(e) {
459
- var t;
460
- return typeof e.target > "u" ? e.srcElement || null : (t = e.target) != null && t.shadowRoot ? e.composedPath()[0] || null : e.target || null;
461
- }
462
- getElementList(e) {
463
- const t = [e];
464
- let s = e;
465
- for (; s.parentNode && !d(s, "body"); )
466
- x(s.parentNode) ? (t.push(s.parentNode.host), s = s.parentNode.host) : (t.push(s.parentNode), s = s.parentNode);
467
- return t;
468
- }
469
- getElementsJson(e, t) {
470
- const s = [];
471
- let n = null, r = !1;
472
- return S(e, (o) => {
473
- if (d(o, "a")) {
474
- const l = o.getAttribute("href");
475
- l !== null && M(o) && H(l) && (n = l);
476
- }
477
- const c = P(o).split(" ");
478
- _(c, "ph-no-capture") && (r = !0), s.push(this.getPropertiesFromElement(o));
479
- }), this.options.maskAllText || (s[0].$el_text = this.sanitizeText(O(e[0]))), n !== null && (s[0].attr__href = n), r ? [] : s;
480
- }
481
- getPropertiesFromElement(e) {
482
- const t = {
483
- tag_name: e.tagName.toLowerCase()
484
- };
485
- b.indexOf(t.tag_name) > -1 && !this.options.maskAllText && (t.$el_text = this.sanitizeText(O(e)));
486
- const s = P(e);
487
- s.length > 0 && (t.classes = s.split(" ").filter((c) => c !== "")), S(e.attributes, (c) => {
488
- q(e) && ["name", "id", "class"].indexOf(c.name) === -1 || !this.options.maskAllElementAttributes && H(c.value) && !se(c.name) && (t["attr__" + c.name] = this.sanitizeAttributeValue(c.name, c.value));
489
- });
490
- let n = 1, r = 1, o = e;
491
- for (; o = this.previousElementSibling(o); )
492
- n++, o.tagName === e.tagName && r++;
493
- return t.nth_child = n, t.nth_of_type = r, t;
494
- }
495
- previousElementSibling(e) {
496
- if (e.previousElementSibling)
497
- return e.previousElementSibling;
498
- do
499
- e = e.previousSibling;
500
- while (e && !R(e));
501
- return e;
502
- }
503
- getDefaultProperties(e) {
504
- return {
505
- $event_type: e,
506
- $ce_version: 1
507
- };
508
- }
509
- // Input sanitization and XSS prevention methods
510
- sanitizeText(e) {
511
- e = e.replace(/<[^>]*?>/g, ""), e = this.encodeHtml(e);
512
- const t = this.options.propertiesStringMaxLength || 255;
513
- return e.length > t && (e = e.substring(0, t) + "..."), e;
514
- }
515
- sanitizeUrl(e) {
516
- if (!e) return "";
517
- try {
518
- const t = new URL(e, window.location.href);
519
- return t.protocol !== "http:" && t.protocol !== "https:" ? "" : encodeURI(t.toString());
520
- } catch {
521
- return this.encodeHtml(e);
522
- }
523
- }
524
- sanitizeAttributeValue(e, t) {
525
- switch (e.toLowerCase()) {
526
- case "href":
527
- case "src":
528
- return this.sanitizeUrl(t);
529
- default:
530
- return this.encodeHtml(t);
531
- }
532
- }
533
- encodeHtml(e) {
534
- return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
535
- }
536
- static enabledForProject(e, t = 10, s = 10) {
537
- if (!e)
538
- return !1;
539
- let n = 0;
540
- for (let r = 0; r < e.length; r++)
541
- n += e.charCodeAt(r);
542
- return n % t < s;
543
- }
544
- static isBrowserSupported() {
545
- return F(document.querySelectorAll);
546
- }
547
- };
548
- y.FORCE_CAPTURE_ATTR = "data-um-force-capture", y.PREVENT_CAPTURE_ATTR = "data-um-no-capture";
549
- let w = y;
550
- class le {
551
- constructor(e) {
552
- this.client = e, this.lastPageUrl = window.location.href, this.trackInitialPageview(), this.initializePageviewTracking();
553
- }
554
- trackInitialPageview() {
555
- this.trackPageview();
556
- }
557
- initializePageviewTracking() {
558
- window.addEventListener("popstate", this.handlePageview.bind(this));
559
- const e = history.pushState;
560
- history.pushState = (...t) => {
561
- e.apply(history, t), this.handlePageview();
562
- }, window.addEventListener("hashchange", this.handlePageview.bind(this)), setInterval(this.checkForUrlChange.bind(this), 1e3);
563
- }
564
- handlePageview() {
565
- this.trackPageview();
566
- }
567
- checkForUrlChange() {
568
- window.location.href !== this.lastPageUrl && this.trackPageview();
569
- }
570
- trackPageview() {
571
- const e = window.location.href;
572
- e !== this.lastPageUrl && (this.lastPageUrl = e, this.client.track("pageview", {
573
- url: e,
574
- referrer: document.referrer,
575
- title: document.title
576
- }));
577
- }
578
- }
579
- class ue {
580
- constructor(e, t, s = h()) {
581
- this.trackingHost = e, this.logger = s, this.config = t;
582
- }
583
- async send(e) {
584
- const t = this.config.key, s = this.constructUrl(t), n = new Blob([JSON.stringify(e)], { type: "application/json" });
585
- if (navigator.sendBeacon(s, n))
586
- this.logger.debug(`Successfully queued ${e.length} event(s) via Beacon API`);
587
- else
588
- throw new Error("Failed to queue events via Beacon API");
589
- }
590
- constructUrl(e) {
591
- const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", s = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "", n = u() ? "/api/v1/event" : "/api/v1/s2s/event";
592
- return this.config.randomizeUrl ? `${this.trackingHost}/api.${f()}?p_${f()}=${e}${t}${s}` : `${this.trackingHost}${n}?token=${e}${t}${s}`;
593
- }
594
- // Note: Beacon API doesn't support custom headers, so we can't use them here.
595
- // If custom headers are crucial, you might want to fall back to XHR or Fetch in those cases.
596
- }
597
- class U {
598
- constructor(e, t, s = h()) {
599
- this.trackingHost = e, this.logger = s, this.config = t;
600
- }
601
- async send(e) {
602
- const t = this.config.key, s = this.constructUrl(t), n = JSON.stringify(e), r = {
603
- "Content-Type": "application/json",
604
- ...this.getCustomHeaders()
605
- }, o = await fetch(s, {
606
- method: "POST",
607
- headers: r,
608
- body: n
609
- });
610
- if (!o.ok)
611
- throw new Error(`HTTP error! status: ${o.status}`);
612
- this.logger.debug(`Successfully sent ${e.length} event(s)`), this.postHandle(o.status, await o.text());
613
- }
614
- constructUrl(e) {
615
- const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", s = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "", n = u() ? "/api/v1/event" : "/api/v1/s2s/event";
616
- return this.config.randomizeUrl ? `${this.trackingHost}/api.${f()}?p_${f()}=${e}${t}${s}` : `${this.trackingHost}${n}?token=${e}${t}${s}`;
617
- }
618
- getCustomHeaders() {
619
- return typeof this.config.customHeaders == "function" ? this.config.customHeaders() : this.config.customHeaders ? this.config.customHeaders : {};
620
- }
621
- postHandle(e, t) {
622
- this.logger.debug(`Response received. Status: ${e}, Body: ${t}`);
623
- }
624
- }
625
- class he {
626
- constructor(e, t, s = h()) {
627
- this.trackingHost = e, this.logger = s, this.config = t;
628
- }
629
- send(e) {
630
- return new Promise((t, s) => {
631
- const n = new XMLHttpRequest(), r = this.config.key, o = this.constructUrl(r);
632
- n.open("POST", o, !0), n.setRequestHeader("Content-Type", "application/json");
633
- const c = this.getCustomHeaders();
634
- Object.keys(c).forEach((l) => {
635
- n.setRequestHeader(l, c[l]);
636
- }), n.onload = () => {
637
- n.status >= 200 && n.status < 300 ? (this.logger.debug(`Successfully sent ${e.length} event(s)`), t()) : s(new Error(`HTTP error! status: ${n.status}`));
638
- }, n.onerror = () => {
639
- s(new Error("Network error"));
640
- }, n.send(JSON.stringify(e));
641
- });
642
- }
643
- constructUrl(e) {
644
- const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", s = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "", n = u() ? "/api/v1/event" : "/api/v1/s2s/event";
645
- return this.config.randomizeUrl ? `${this.trackingHost}/api.${f()}?p_${f()}=${e}${t}${s}` : `${this.trackingHost}${n}?token=${e}${t}${s}`;
646
- }
647
- getCustomHeaders() {
648
- return typeof this.config.customHeaders == "function" ? this.config.customHeaders() : this.config.customHeaders ? this.config.customHeaders : {};
649
- }
650
- postHandle(e, t) {
651
- this.logger.debug(`Response received. Status: ${e}, Body: ${t}`);
652
- }
653
- }
654
- class J {
655
- constructor(e, t) {
656
- this.storage = {}, this.prefix = `usermaven_${e}_`, this.load(), this.logger = t || h();
657
- }
658
- set(e, t) {
659
- this.storage[e] = t, this.save();
660
- }
661
- get(e) {
662
- return this.storage[e];
663
- }
664
- remove(e) {
665
- delete this.storage[e], this.save();
666
- }
667
- clear() {
668
- this.storage = {}, this.save();
669
- }
670
- save() {
671
- if (!u()) {
672
- this.logger.warn("localStorage is not available in this environment");
673
- return;
674
- }
675
- try {
676
- localStorage.setItem(this.prefix + "data", JSON.stringify(this.storage));
677
- } catch (e) {
678
- this.logger.error("Error saving to localStorage:", e);
679
- }
680
- }
681
- load() {
682
- if (!u()) {
683
- this.logger.warn("localStorage is not available in this environment");
684
- return;
685
- }
686
- try {
687
- const e = localStorage.getItem(this.prefix + "data");
688
- e && (this.storage = JSON.parse(e));
689
- } catch (e) {
690
- this.logger.error("Error loading from localStorage:", e);
691
- }
692
- }
693
- }
694
- class ge {
695
- constructor() {
696
- this.storage = {};
697
- }
698
- set(e, t) {
699
- this.storage[e] = t;
700
- }
701
- get(e) {
702
- return this.storage[e];
703
- }
704
- remove(e) {
705
- delete this.storage[e];
706
- }
707
- save() {
708
- }
709
- clear() {
710
- this.storage = {};
711
- }
712
- }
713
- class D {
714
- // Default to true for server-side
715
- constructor(e, t = 3, s = 1e3, n = 10, r = 1e3, o = h()) {
716
- this.transport = e, this.maxRetries = t, this.retryInterval = s, this.batchSize = n, this.batchInterval = r, this.logger = o, this.queue = [], this.processing = !1, this.batchTimeoutId = null, this.isOnline = !0, this.persistence = new J("offline_queue"), u() && (this.isOnline = navigator.onLine, this.loadQueueFromStorage(), this.initNetworkListeners(), this.scheduleBatch());
717
- }
718
- add(e) {
719
- const t = { payload: e, retries: 0, timestamp: Date.now() };
720
- this.queue.push(t), u() ? this.saveQueueToStorage() : this.processBatch();
721
- }
722
- initNetworkListeners() {
723
- u() && (window.addEventListener("online", () => {
724
- this.isOnline = !0, this.processBatch();
725
- }), window.addEventListener("offline", () => {
726
- this.isOnline = !1;
727
- }));
728
- }
729
- scheduleBatch() {
730
- u() && (this.batchTimeoutId !== null && clearTimeout(this.batchTimeoutId), this.batchTimeoutId = window.setTimeout(() => this.processBatch(), this.batchInterval));
731
- }
732
- async processBatch() {
733
- if ((!u() || this.isOnline) && !this.processing && this.queue.length > 0) {
734
- this.processing = !0;
735
- const e = this.queue.splice(0, this.batchSize), t = e.map((s) => s.payload);
736
- try {
737
- await this.transport.send(t), this.logger.debug(`Successfully sent batch of ${e.length} payloads`), u() && this.saveQueueToStorage();
738
- } catch (s) {
739
- this.logger.error("Failed to send batch", s), await this.handleBatchFailure(e);
740
- }
741
- this.processing = !1;
742
- }
743
- u() && this.scheduleBatch();
744
- }
745
- async handleBatchFailure(e) {
746
- for (const t of e)
747
- t.retries < this.maxRetries ? (t.retries++, this.queue.unshift(t), this.logger.warn(`Retry attempt ${t.retries} for payload`)) : this.logger.error("Max retries reached, discarding payload", t.payload);
748
- u() && (this.saveQueueToStorage(), await new Promise((t) => setTimeout(t, this.retryInterval)));
749
- }
750
- loadQueueFromStorage() {
751
- if (u()) {
752
- const e = this.persistence.get("queue");
753
- e && (this.queue = JSON.parse(e));
754
- }
755
- }
756
- saveQueueToStorage() {
757
- u() && this.persistence.set("queue", JSON.stringify(this.queue));
758
- }
759
- }
760
- class de {
761
- constructor(e) {
762
- this.clicks = [], this.threshold = 3, this.timeWindow = 2e3, this.distanceThreshold = 30, this.client = e, this.initializeEventListener(), z(this);
763
- }
764
- initializeEventListener() {
765
- document.addEventListener("click", this.handleClick.bind(this));
766
- }
767
- handleClick(e) {
768
- const t = e.target;
769
- this.shouldCaptureElement(t) && this.click(e.clientX, e.clientY, Date.now());
770
- }
771
- shouldCaptureElement(e) {
772
- return !e.closest(".um-no-capture");
773
- }
774
- click(e, t, s) {
775
- const n = { x: e, y: t, timestamp: s };
776
- this.clicks.push(n), this.clicks = this.clicks.filter((r) => s - r.timestamp < this.timeWindow), this.clicks.length >= this.threshold && this.checkRageClick();
777
- }
778
- checkRageClick() {
779
- const e = this.clicks[0], s = (this.clicks[this.clicks.length - 1].timestamp - e.timestamp) / 1e3;
780
- this.clicks.every((r, o) => {
781
- if (o === 0) return !0;
782
- const c = this.clicks[o - 1];
783
- return Math.sqrt(Math.pow(r.x - c.x, 2) + Math.pow(r.y - c.y, 2)) < this.distanceThreshold;
784
- }) && this.sendRageClickEvent(s);
785
- }
786
- sendRageClickEvent(e) {
787
- const t = this.clicks[this.clicks.length - 1];
788
- document.elementFromPoint(t.x, t.y) && this.client.track("$rage_click", {
789
- no_of_clicks: this.clicks.length,
790
- time: e.toFixed(2)
791
- }), this.clicks = [];
792
- }
793
- }
794
- class fe {
795
- constructor(e, t, s = h()) {
796
- this.trackingHost = e, this.logger = s, this.config = t;
797
- }
798
- async send(e) {
799
- const t = this.config.key, s = new (void 0)(this.constructUrl(t)), n = {
800
- hostname: s.hostname,
801
- port: 443,
802
- path: `${s.pathname}${s.search}`,
803
- method: "POST",
804
- headers: {
805
- "Content-Type": "application/json",
806
- ...this.getCustomHeaders()
807
- }
808
- };
809
- return new Promise((r, o) => {
810
- const c = (void 0)(n, (l) => {
811
- l.on("data", (a) => {
812
- }), l.on("end", () => {
813
- const a = l.statusCode || 0;
814
- a >= 200 && a < 300 ? (this.logger.debug(`Successfully sent ${e.length} event(s)`), r()) : o(new Error(`HTTP error! status: ${a}`));
815
- });
816
- });
817
- c.on("error", (l) => {
818
- o(l);
819
- }), c.write(JSON.stringify(e)), c.end();
820
- });
821
- }
822
- constructUrl(e) {
823
- const t = this.config.cookiePolicy !== "keep" ? `&cookie_policy=${this.config.cookiePolicy}` : "", s = this.config.ipPolicy !== "keep" ? `&ip_policy=${this.config.ipPolicy}` : "";
824
- return `${this.trackingHost}/api/v1/s2s/event?token=${e}${t}${s}`;
825
- }
826
- getCustomHeaders() {
827
- return typeof this.config.customHeaders == "function" ? this.config.customHeaders() : this.config.customHeaders ? this.config.customHeaders : {};
828
- }
829
- }
830
- class m {
831
- constructor(e, t = "all", s = {}) {
832
- this.instance = e, this.trackingType = t, this.options = s, document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", this.initialize.bind(this)) : this.initialize();
833
- }
834
- initialize() {
835
- this.trackingType !== "none" && this.setupFormTracking();
836
- }
837
- setupFormTracking() {
838
- var e;
839
- this.formElements = this.trackingType === "tagged" ? document.querySelectorAll("form[data-um-form]") : document.querySelectorAll("form"), (e = this.formElements) == null || e.forEach((t) => {
840
- t.addEventListener("submit", this.handleFormSubmit.bind(this));
841
- });
842
- }
843
- handleFormSubmit(e) {
844
- const t = e.target, s = this._getFormDetails(t);
845
- this.instance.track("$form", N(s)), this.options.trackFieldChanges && this.trackFieldChanges(t);
846
- }
847
- trackFieldChanges(e) {
848
- e.querySelectorAll("input, select, textarea").forEach((s) => {
849
- s.addEventListener("change", (n) => {
850
- const r = this._getFieldProps(n.target, 0);
851
- this.instance.track("$form_field_change", N(r));
852
- });
853
- });
854
- }
855
- static getInstance(e, t = "all", s = {}) {
856
- return m.instance || (m.instance = new m(e, t, s)), m.instance;
857
- }
858
- _getFormDetails(e) {
859
- const t = {
860
- form_id: e.id,
861
- form_name: e.name || "",
862
- form_action: e.action,
863
- form_method: e.method,
864
- form_class: e.className,
865
- form_attributes: this._getElementAttributes(e)
866
- }, s = e.querySelectorAll("input, select, textarea");
867
- return Array.from(s).filter((r) => !r.classList.contains("um-no-capture")).forEach((r, o) => {
868
- const c = this._getFieldProps(r, o);
869
- Object.assign(t, c);
870
- }), t;
871
- }
872
- _getFieldProps(e, t) {
873
- const s = Object.keys(e.dataset).length ? JSON.stringify(e.dataset) : void 0, n = this.getSafeText(e);
874
- return {
875
- [`field_${t + 1}_tag`]: e.tagName.toLowerCase(),
876
- [`field_${t + 1}_type`]: e instanceof HTMLInputElement ? e.type : void 0,
877
- [`field_${t + 1}_data_attributes`]: s,
878
- [`field_${t + 1}_id`]: e.id,
879
- [`field_${t + 1}_value`]: n,
880
- [`field_${t + 1}_class`]: e.className,
881
- [`field_${t + 1}_name`]: e.name,
882
- [`field_${t + 1}_attributes`]: this._getElementAttributes(e)
883
- };
884
- }
885
- _getElementAttributes(e) {
886
- return Object.keys(e.dataset).length ? JSON.parse(JSON.stringify(e.dataset)) : {};
887
- }
888
- getSafeText(e) {
889
- let t = "";
890
- return "value" in e && e.type !== "password" ? t = e.value : e.hasChildNodes() ? t = Array.from(e.childNodes).filter(
891
- (n) => n.nodeType === Node.TEXT_NODE
892
- ).map((n) => n.textContent).join("") : t = e.textContent || "", this._scrubPotentiallySensitiveValues(t);
893
- }
894
- _scrubPotentiallySensitiveValues(e) {
895
- return this._shouldCaptureValue(e) ? e : "<redacted>";
896
- }
897
- _shouldCaptureValue(e) {
898
- return !(this._isNullish(e) || this._isString(e) && (e = this._trim(e), /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((e || "").replace(/[- ]/g, "")) || /(^\d{3}-?\d{2}-?\d{4}$)/.test(e)));
899
- }
900
- _isNullish(e) {
901
- return e == null;
902
- }
903
- _isString(e) {
904
- return typeof e == "string" || e instanceof String;
905
- }
906
- _trim(e) {
907
- if (typeof String.prototype.trim == "function")
908
- return e.trim();
909
- let t = 0, s = e.length - 1;
910
- const n = [
911
- " ",
912
- `
913
- `,
914
- "\r",
915
- " ",
916
- "\f",
917
- "\v",
918
- " ",
919
- " ",
920
- " ",
921
- " ",
922
- " ",
923
- " ",
924
- " ",
925
- " ",
926
- " ",
927
- " ",
928
- " ",
929
- " ",
930
- " ",
931
- "\u2028",
932
- "\u2029",
933
- " ",
934
- " ",
935
- " "
936
- ].join("");
937
- for (; t <= s && n.indexOf(e[t]) > -1; )
938
- t++;
939
- for (; s >= t && n.indexOf(e[s]) > -1; )
940
- s--;
941
- return e.slice(t, s + 1);
942
- }
943
- }
944
- class pe {
945
- constructor(e) {
946
- this.config = this.mergeConfig(e, I), this.logger = h(this.config.logLevel), this.namespace = e.namespace || "usermaven", this.transport = this.initializeTransport(this.config), this.persistence = this.initializePersistence(), this.retryQueue = new D(
947
- this.transport,
948
- this.config.maxSendAttempts || 3,
949
- this.config.minSendTimeout || 1e3,
950
- 10,
951
- 200,
952
- // Reduced interval to .2 second
953
- this.logger
954
- ), u() && this.initializeBrowserFeatures(), this.anonymousId = this.getOrCreateAnonymousId(), this.logger.info(`Usermaven client initialized for namespace: ${this.namespace}`);
955
- }
956
- initializeBrowserFeatures() {
957
- if (this.cookieManager = new Q(this.config.cookieDomain), this.config.autocapture && w.enabledForProject(this.config.key) && (this.autoCapture = new w(this, this.config, this.logger), this.autoCapture.init()), this.config.formTracking) {
958
- const e = this.config.formTracking === !0 ? "all" : this.config.formTracking;
959
- this.formTracking = m.getInstance(this, e || "none", {
960
- trackFieldChanges: !1
961
- });
962
- }
963
- this.config.autoPageview && (this.pageviewTracking = new le(this)), this.config.crossDomainLinking && this.manageCrossDomainLinking(), this.config.rageClick && (this.rageClick = new de(this)), this.setupPageLeaveTracking();
964
- }
965
- /**
966
- * Recursively merge the provided configuration with the existing defaultConfig
967
- * @param config
968
- * @param defaultConfig
969
- */
970
- mergeConfig(e, t) {
971
- const s = JSON.parse(JSON.stringify(e));
972
- let n = { ...t, ...s };
973
- return Object.keys(t).forEach((r) => {
974
- k(t[r]) && (n[r] = this.mergeConfig(e[r], t[r]));
975
- }), n;
976
- }
977
- init(e) {
978
- this.config = { ...this.config, ...e }, this.logger = h(this.config.logLevel), this.namespace = e.namespace || this.namespace, this.transport = this.initializeTransport(e), this.persistence = this.initializePersistence(), this.retryQueue = new D(
979
- this.transport,
980
- this.config.maxSendAttempts || 3,
981
- this.config.minSendTimeout || 1e3,
982
- 10,
983
- 250,
984
- // Reduced interval to .25 second
985
- this.logger
986
- ), u() && this.initializeBrowserFeatures(), this.anonymousId = this.getOrCreateAnonymousId(), this.logger.info(`Usermaven client reinitialized for namespace: ${this.namespace}`);
987
- }
988
- manageCrossDomainLinking() {
989
- if (!this.config.crossDomainLinking || !this.config.domains)
990
- return;
991
- const e = this.config.domains.split(",").map((s) => s.trim()), t = this.config.cookieName || `${this.namespace}_id_${this.config.key}`;
992
- document.addEventListener("click", (s) => {
993
- var c;
994
- const n = this.findClosestLink(s.target);
995
- if (!n) return;
996
- const r = n.getAttribute("href");
997
- if (!r || !r.startsWith("http")) return;
998
- const o = new URL(r);
999
- if (o.hostname !== window.location.hostname && e.includes(o.hostname)) {
1000
- const l = (c = this.cookieManager) == null ? void 0 : c.get(t);
1001
- l && (o.searchParams.append("_um", l), n.setAttribute("href", o.toString()));
1002
- }
1003
- }), this.logger.debug("Cross-domain linking initialized");
1004
- }
1005
- findClosestLink(e) {
1006
- for (; e && e.tagName !== "A"; )
1007
- e = e.parentElement;
1008
- return e;
1009
- }
1010
- initializeTransport(e) {
1011
- if (!u())
1012
- return new fe(e.trackingHost, e);
1013
- const t = "XMLHttpRequest" in window, s = typeof fetch < "u", n = typeof navigator < "u" && "sendBeacon" in navigator;
1014
- if (e.useBeaconApi && n)
1015
- return new ue(e.trackingHost, e, this.logger);
1016
- if (e.forceUseFetch && s)
1017
- return new U(e.trackingHost, e, this.logger);
1018
- if (t)
1019
- return new he(e.trackingHost, e, this.logger);
1020
- if (s)
1021
- return new U(e.trackingHost, e, this.logger);
1022
- throw new Error("No suitable transport method available");
1023
- }
1024
- initializePersistence() {
1025
- return this.config.disableEventPersistence || !u() ? new ge() : new J(`${this.namespace}_${this.config.key}`, this.logger);
1026
- }
1027
- getOrCreateAnonymousId() {
1028
- var s, n;
1029
- if (!u())
1030
- return $();
1031
- if (this.config.privacyPolicy === "strict" || this.config.cookiePolicy === "strict")
1032
- return "";
1033
- const e = this.config.cookieName || `${this.namespace}_id_${this.config.key}`;
1034
- let t = (s = this.cookieManager) == null ? void 0 : s.get(e);
1035
- if (!t) {
1036
- if (this.config.crossDomainLinking) {
1037
- const c = new URLSearchParams(window.location.search).get("_um"), a = window.location.hash.substring(1).split("~"), g = a.length > 1 ? a[1] : void 0;
1038
- t = c || g || $();
1039
- }
1040
- t || (t = $());
1041
- const r = 365 * 10;
1042
- (n = this.cookieManager) == null || n.set(e, t, r, document.location.protocol !== "http:", !1);
1043
- }
1044
- return t;
1045
- }
1046
- generateFingerprint() {
1047
- const e = navigator.userAgent, t = `${screen.width}x${screen.height}`, s = screen.colorDepth, n = Intl.DateTimeFormat().resolvedOptions().timeZone, r = `${e}|${t}|${s}|${n}`;
1048
- return this.hashString(r);
1049
- }
1050
- hashString(e) {
1051
- let t = 0;
1052
- for (let s = 0; s < e.length; s++) {
1053
- const n = e.charCodeAt(s);
1054
- t = (t << 5) - t + n, t = t & t;
1055
- }
1056
- return t.toString(36);
1057
- }
1058
- async id(e, t = !1) {
1059
- if (!k(e))
1060
- throw new Error("User data must be an object");
1061
- if (e.email && !ne(e.email))
1062
- throw new Error("Invalid email provided");
1063
- if (!e.id || !L(e.id))
1064
- throw new Error("User ID must be a string");
1065
- const s = e.id;
1066
- if (this.persistence.set("userId", s), this.persistence.set("userProps", e), !t) {
1067
- const n = {
1068
- ...e,
1069
- anonymous_id: this.anonymousId
1070
- };
1071
- await this.track("user_identify", n);
1072
- }
1073
- this.logger.info("User identified:", e);
1074
- }
1075
- track(e, t, s = !1) {
1076
- this.trackInternal(e, t, s);
1077
- }
1078
- trackInternal(e, t, s = !1) {
1079
- if (!L(e))
1080
- throw new Error("Event name must be a string");
1081
- if (t !== void 0 && (typeof t != "object" || t === null || Array.isArray(t)))
1082
- throw new Error("Event payload must be a non-null object and not an array");
1083
- const n = this.createEventPayload(e, t);
1084
- try {
1085
- if (s) {
1086
- this.transport.send(n), this.logger.debug(`Event sent: ${e}`, [n]);
1087
- return;
1088
- }
1089
- this.retryQueue.add(n), this.logger.debug(`Event tracked: ${e}`, [n]);
1090
- } catch (r) {
1091
- throw this.logger.error(`Failed to track event: ${e}`, r), new Error(`Failed to track event: ${e}`);
1092
- }
1093
- }
1094
- rawTrack(e) {
1095
- if (!k(e))
1096
- throw new Error("Event payload must be an object");
1097
- this.track("raw", e);
1098
- }
1099
- async group(e, t = !1) {
1100
- if (!k(e))
1101
- throw new Error("Company properties must be an object");
1102
- if (!e.id || !e.name || !e.created_at)
1103
- throw new Error("Company properties must include id, name, and created_at");
1104
- this.persistence.set("companyProps", e), t || await this.track("group", e), this.logger.info("Company identified:", e);
1105
- }
1106
- createEventPayload(e, t) {
1107
- const s = this.persistence.get("userProps") || {}, n = this.persistence.get("companyProps") || void 0, r = this.persistence.get("userId"), o = this.persistence.get("global_props") || {}, c = this.persistence.get(`props_${e}`) || {};
1108
- let l = t || {};
1109
- const a = {
1110
- event_id: "",
1111
- user: {
1112
- anonymous_id: this.anonymousId,
1113
- id: r,
1114
- ...s
1115
- },
1116
- ...n && { company: n },
1117
- ids: this.getThirdPartyIds(),
1118
- utc_time: (/* @__PURE__ */ new Date()).toISOString(),
1119
- local_tz_offset: (/* @__PURE__ */ new Date()).getTimezoneOffset(),
1120
- api_key: this.config.key,
1121
- src: "usermaven",
1122
- event_type: e,
1123
- namespace: this.namespace,
1124
- ...o,
1125
- ...c
1126
- };
1127
- if (e === "$autocapture") {
1128
- const g = this.processAutocaptureAttributes(t || {});
1129
- a.autocapture_attributes = g;
1130
- } else
1131
- Array.isArray(this.config.propertyBlacklist) && this.config.propertyBlacklist.forEach((g) => {
1132
- delete l[g];
1133
- }), a.event_attributes = l;
1134
- return u() && (a.referer = document.referrer, a.url = window.location.href, a.page_title = document.title, a.doc_path = window.location.pathname, a.doc_host = window.location.hostname, a.doc_search = window.location.search, a.screen_resolution = `${window.screen.width}x${window.screen.height}`, a.vp_size = `${window.innerWidth}x${window.innerHeight}`, a.user_agent = navigator.userAgent, a.user_language = navigator.language, a.doc_encoding = document.characterSet, a.utm = this.getUtmParams()), a;
1135
- }
1136
- processAutocaptureAttributes(e) {
1137
- let t = {};
1138
- const s = e.$elements || [];
1139
- return s.length && (t = { ...s[0] }), t.el_text = t.$el_text || "", t.event_type = e.$event_type || "", ["$ce_version", "$event_type", "$initial_referrer", "$initial_referring_domain", "$referrer", "$referring_domain", "$elements"].forEach((n) => {
1140
- delete t[n];
1141
- }), delete t.$el_text, delete t.nth_child, delete t.nth_of_type, t;
1142
- }
1143
- getCookie(e) {
1144
- var t;
1145
- return ((t = this.cookieManager) == null ? void 0 : t.get(e)) || null;
1146
- }
1147
- getThirdPartyIds() {
1148
- const e = {};
1149
- if (u()) {
1150
- const t = this.getCookie("_fbp");
1151
- t && (e.fbp = t);
1152
- }
1153
- return e;
1154
- }
1155
- getUtmParams() {
1156
- const e = {}, t = oe(window.location.search);
1157
- return ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"].forEach((n) => {
1158
- t[n] && (e[n.replace("utm_", "")] = t[n]);
1159
- }), e;
1160
- }
1161
- pageview() {
1162
- u() ? this.track("pageview", {
1163
- url: window.location.href,
1164
- referrer: document.referrer,
1165
- title: document.title
1166
- }, !0) : this.logger.warn("Pageview tracking is not available in server-side environments");
1167
- }
1168
- setupPageLeaveTracking() {
1169
- if (!u()) return;
1170
- let e = !1, t = !1;
1171
- const s = () => {
1172
- !e && !t && (e = !0, this.track("$pageleave", {
1173
- url: window.location.href,
1174
- referrer: document.referrer,
1175
- title: document.title
1176
- }));
1177
- };
1178
- window.addEventListener("beforeunload", (r) => {
1179
- t = !0, setTimeout(() => {
1180
- t = !1;
1181
- }, 100);
1182
- }), document.addEventListener("visibilitychange", () => {
1183
- document.visibilityState === "hidden" && !t && s();
1184
- });
1185
- const n = history.pushState;
1186
- history.pushState = function() {
1187
- return s(), n.apply(this, arguments);
1188
- }, window.addEventListener("popstate", s);
1189
- }
1190
- getConfig() {
1191
- return this.config;
1192
- }
1193
- getLogger() {
1194
- return this.logger;
1195
- }
1196
- async reset(e = !1) {
1197
- if (this.persistence.clear(), e && this.cookieManager) {
1198
- const t = this.config.cookieName || `${this.namespace}_id_${this.config.key}`;
1199
- this.cookieManager.delete(t), this.anonymousId = this.getOrCreateAnonymousId();
1200
- }
1201
- this.logger.info("core state reset", { resetAnonId: e, namespace: this.namespace });
1202
- }
1203
- set(e, t) {
1204
- if (!k(e))
1205
- throw new Error("Properties must be an object");
1206
- const s = t == null ? void 0 : t.eventType, n = (t == null ? void 0 : t.persist) ?? !0;
1207
- if (s) {
1208
- let r = this.persistence.get(`props_${s}`) || {};
1209
- r = { ...r, ...e }, this.persistence.set(`props_${s}`, r);
1210
- } else {
1211
- let r = this.persistence.get("global_props") || {};
1212
- r = { ...r, ...e }, this.persistence.set("global_props", r);
1213
- }
1214
- n && this.persistence.save(), this.logger.debug("Properties set", {
1215
- properties: e,
1216
- eventType: s || "global",
1217
- persist: n
1218
- });
1219
- }
1220
- setUserId(e) {
1221
- this.persistence.set("userId", e);
1222
- let t = this.persistence.get("userProps") || {};
1223
- t.id = e, this.persistence.set("userProps", t), this.persistence.save();
1224
- }
1225
- unset(e, t) {
1226
- const s = t == null ? void 0 : t.eventType, n = (t == null ? void 0 : t.persist) ?? !0;
1227
- if (s) {
1228
- let r = this.persistence.get(`props_${s}`) || {};
1229
- delete r[e], this.persistence.set(`props_${s}`, r);
1230
- } else {
1231
- let r = this.persistence.get("global_props") || {};
1232
- delete r[e], this.persistence.set("global_props", r);
1233
- }
1234
- n && this.persistence.save(), this.logger.debug(`Property unset: ${e}`, `Event type: ${s || "global"}`);
1235
- }
1236
- }
1237
- function me(i) {
1238
- const e = JSON.parse(JSON.stringify(i)), t = C(e), s = { ...I, ...t };
1239
- if (!s.key)
1240
- throw new Error("API key is required!");
1241
- if (!s.trackingHost)
1242
- throw new Error("Tracking host is required!");
1243
- return new pe(s);
1244
- }
1245
- function ye(i) {
1246
- var n;
1247
- const e = {
1248
- key: i.getAttribute("data-key") || void 0,
1249
- trackingHost: i.getAttribute("data-tracking-host") || "https://events.usermaven.com",
1250
- logLevel: ae(i.getAttribute("data-log-level")),
1251
- autocapture: i.getAttribute("data-autocapture") === "true",
1252
- formTracking: i.getAttribute("data-form-tracking") === "false" ? !1 : i.getAttribute("data-form-tracking") === "true" ? "all" : i.getAttribute("data-form-tracking"),
1253
- autoPageview: i.getAttribute("data-auto-pageview") === "true",
1254
- useBeaconApi: i.getAttribute("data-use-beacon-api") === "true",
1255
- forceUseFetch: i.getAttribute("data-force-use-fetch") === "true",
1256
- gaHook: i.getAttribute("data-ga-hook") === "true",
1257
- segmentHook: i.getAttribute("data-segment-hook") === "true",
1258
- randomizeUrl: i.getAttribute("data-randomize-url") === "true",
1259
- capture3rdPartyCookies: i.getAttribute("data-capture-3rd-party-cookies") === "false" ? !1 : void 0,
1260
- idMethod: i.getAttribute("data-id-method") || void 0,
1261
- privacyPolicy: i.getAttribute("data-privacy-policy") === "strict" ? "strict" : void 0,
1262
- ipPolicy: i.getAttribute("data-ip-policy") || void 0,
1263
- cookiePolicy: i.getAttribute("data-cookie-policy") || void 0,
1264
- minSendTimeout: parseInt(i.getAttribute("data-min-send-timeout") || "", 10) || void 0,
1265
- maxSendTimeout: parseInt(i.getAttribute("data-max-send-timeout") || "", 10) || void 0,
1266
- maxSendAttempts: parseInt(i.getAttribute("data-max-send-attempts") || "", 10) || void 0,
1267
- propertiesStringMaxLength: parseInt(i.getAttribute("data-properties-string-max-length") || "", 10) || null,
1268
- propertyBlacklist: ((n = i.getAttribute("data-property-blacklist")) == null ? void 0 : n.split(",")) || void 0,
1269
- exclude: i.getAttribute("data-exclude") || void 0,
1270
- namespace: i.getAttribute("data-namespace") || void 0,
1271
- crossDomainLinking: i.getAttribute("data-cross-domain-linking") !== "false",
1272
- domains: i.getAttribute("data-domains") || void 0,
1273
- maskAllText: i.getAttribute("data-mask-all-text") === "true",
1274
- maskAllElementAttributes: i.getAttribute("data-mask-all-element-attributes") === "true"
1275
- }, t = me(e), s = e.namespace || "usermaven";
1276
- u() && t.pageview(), we(s, t);
1277
- }
1278
- function we(i, e) {
1279
- let t = !1;
1280
- const s = [], n = [];
1281
- function r() {
1282
- for (; s.length > 0; ) {
1283
- const a = s.shift();
1284
- a && window[i].apply(null, a);
1285
- }
1286
- }
1287
- function o() {
1288
- n.forEach((a) => a()), n.length = 0;
1289
- }
1290
- window[i] = function(...a) {
1291
- const g = a[0];
1292
- if (g === "onLoad") {
1293
- typeof a[1] == "function" && (t ? a[1]() : n.push(a[1]));
1294
- return;
1295
- }
1296
- if (!t) {
1297
- s.push(a);
1298
- return;
1299
- }
1300
- if (typeof e[g] == "function")
1301
- return e[g].apply(e, a.slice(1));
1302
- console.error(`Method ${g} not found on UsermavenClient`);
1303
- };
1304
- const c = `${i}Q`, l = window[c] || [];
1305
- for (window[c] = l, l.push = function(...a) {
1306
- return window[i].apply(null, a), Array.prototype.push.apply(this, a);
1307
- }, setTimeout(() => {
1308
- t = !0, r(), o(), console.log(`Usermaven client for namespace ${i} is ready`);
1309
- }, 0); l.length > 0; ) {
1310
- const a = l.shift();
1311
- a && s.push(a);
1312
- }
1313
- }
1314
- u() && function(i, e) {
1315
- const t = i.currentScript;
1316
- function s() {
1317
- t && t.src.includes("lib.js") && ye(t);
1318
- }
1319
- typeof e < "u" && (i.readyState === "loading" ? i.addEventListener("DOMContentLoaded", s) : s());
1320
- }(document, window);
1321
- export {
1322
- v as LogLevel,
1323
- pe as UsermavenClient,
1324
- me as usermavenClient
1325
- };