humanbehavior-js 0.5.71 β 0.7.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/package.json +1 -1
- package/packages/browser/dist/cjs/index.js +350 -152
- package/packages/browser/dist/cjs/index.js.map +1 -1
- package/packages/browser/dist/esm/index.js +342 -144
- package/packages/browser/dist/esm/index.js.map +1 -1
- package/packages/browser/dist/index.min.js +1 -1
- package/packages/browser/dist/index.min.js.map +1 -1
- package/packages/core/dist/api.d.ts +35 -1
- package/packages/core/dist/api.d.ts.map +1 -1
- package/packages/core/dist/index.js +1 -1
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/index.mjs +1 -1
- package/packages/core/dist/index.mjs.map +1 -1
- package/packages/core/dist/tracker.d.ts +100 -5
- package/packages/core/dist/tracker.d.ts.map +1 -1
- package/packages/core/dist/utils/global-tracker.d.ts +8 -5
- package/packages/core/dist/utils/global-tracker.d.ts.map +1 -1
- package/packages/core/dist/utils/property-manager.d.ts.map +1 -1
- package/packages/react/dist/index.js +1 -1
- package/packages/react/dist/index.js.map +1 -1
- package/packages/react/dist/index.mjs +1 -1
- package/packages/react/dist/index.mjs.map +1 -1
|
@@ -5,7 +5,7 @@ var _a;
|
|
|
5
5
|
var __defProp$1 = Object.defineProperty;
|
|
6
6
|
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
7
|
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
8
|
-
var NodeType$
|
|
8
|
+
var NodeType$3 = /* @__PURE__ */ ((NodeType2) => {
|
|
9
9
|
NodeType2[NodeType2["Document"] = 0] = "Document";
|
|
10
10
|
NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
|
|
11
11
|
NodeType2[NodeType2["Element"] = 2] = "Element";
|
|
@@ -13,9 +13,15 @@ var NodeType$2 = /* @__PURE__ */ ((NodeType2) => {
|
|
|
13
13
|
NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
|
|
14
14
|
NodeType2[NodeType2["Comment"] = 5] = "Comment";
|
|
15
15
|
return NodeType2;
|
|
16
|
-
})(NodeType$
|
|
16
|
+
})(NodeType$3 || {});
|
|
17
17
|
const testableAccessors$1 = {
|
|
18
|
-
Node: [
|
|
18
|
+
Node: [
|
|
19
|
+
"childNodes",
|
|
20
|
+
"parentNode",
|
|
21
|
+
"parentElement",
|
|
22
|
+
"textContent",
|
|
23
|
+
"ownerDocument"
|
|
24
|
+
],
|
|
19
25
|
ShadowRoot: ["host", "styleSheets"],
|
|
20
26
|
Element: ["shadowRoot", "querySelector", "querySelectorAll"],
|
|
21
27
|
MutationObserver: []
|
|
@@ -27,6 +33,9 @@ const testableMethods$1 = {
|
|
|
27
33
|
MutationObserver: ["constructor"]
|
|
28
34
|
};
|
|
29
35
|
const untaintedBasePrototype$1 = {};
|
|
36
|
+
const isAngularZonePresent$1 = () => {
|
|
37
|
+
return !!globalThis.Zone;
|
|
38
|
+
};
|
|
30
39
|
function getUntaintedPrototype$1(key) {
|
|
31
40
|
if (untaintedBasePrototype$1[key])
|
|
32
41
|
return untaintedBasePrototype$1[key];
|
|
@@ -54,7 +63,7 @@ function getUntaintedPrototype$1(key) {
|
|
|
54
63
|
}
|
|
55
64
|
)
|
|
56
65
|
);
|
|
57
|
-
if (isUntaintedAccessors && isUntaintedMethods) {
|
|
66
|
+
if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent$1()) {
|
|
58
67
|
untaintedBasePrototype$1[key] = defaultObj.prototype;
|
|
59
68
|
return defaultObj.prototype;
|
|
60
69
|
}
|
|
@@ -101,6 +110,9 @@ function getUntaintedMethod$1(key, instance, method) {
|
|
|
101
110
|
untaintedMethodCache$1[cacheKey] = untaintedMethod;
|
|
102
111
|
return untaintedMethod.bind(instance);
|
|
103
112
|
}
|
|
113
|
+
function ownerDocument$1(n2) {
|
|
114
|
+
return getUntaintedAccessor$1("Node", n2, "ownerDocument");
|
|
115
|
+
}
|
|
104
116
|
function childNodes$1(n2) {
|
|
105
117
|
return getUntaintedAccessor$1("Node", n2, "childNodes");
|
|
106
118
|
}
|
|
@@ -139,7 +151,34 @@ function querySelectorAll$1(n2, selectors) {
|
|
|
139
151
|
function mutationObserverCtor$1() {
|
|
140
152
|
return getUntaintedPrototype$1("MutationObserver").constructor;
|
|
141
153
|
}
|
|
154
|
+
function patch$1(source, name, replacement) {
|
|
155
|
+
try {
|
|
156
|
+
if (!(name in source)) {
|
|
157
|
+
return () => {
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const original = source[name];
|
|
161
|
+
const wrapped = replacement(original);
|
|
162
|
+
if (typeof wrapped === "function") {
|
|
163
|
+
wrapped.prototype = wrapped.prototype || {};
|
|
164
|
+
Object.defineProperties(wrapped, {
|
|
165
|
+
__rrweb_original__: {
|
|
166
|
+
enumerable: false,
|
|
167
|
+
value: original
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
source[name] = wrapped;
|
|
172
|
+
return () => {
|
|
173
|
+
source[name] = original;
|
|
174
|
+
};
|
|
175
|
+
} catch {
|
|
176
|
+
return () => {
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
142
180
|
const index$1 = {
|
|
181
|
+
ownerDocument: ownerDocument$1,
|
|
143
182
|
childNodes: childNodes$1,
|
|
144
183
|
parentNode: parentNode$1,
|
|
145
184
|
parentElement: parentElement$1,
|
|
@@ -151,7 +190,8 @@ const index$1 = {
|
|
|
151
190
|
shadowRoot: shadowRoot$1,
|
|
152
191
|
querySelector: querySelector$1,
|
|
153
192
|
querySelectorAll: querySelectorAll$1,
|
|
154
|
-
mutationObserver: mutationObserverCtor$1
|
|
193
|
+
mutationObserver: mutationObserverCtor$1,
|
|
194
|
+
patch: patch$1
|
|
155
195
|
};
|
|
156
196
|
function isElement(n2) {
|
|
157
197
|
return n2.nodeType === n2.ELEMENT_NODE;
|
|
@@ -201,9 +241,13 @@ function stringifyStylesheet(s2) {
|
|
|
201
241
|
if (!rules2) {
|
|
202
242
|
return null;
|
|
203
243
|
}
|
|
244
|
+
let sheetHref = s2.href;
|
|
245
|
+
if (!sheetHref && s2.ownerNode) {
|
|
246
|
+
sheetHref = s2.ownerNode.baseURI;
|
|
247
|
+
}
|
|
204
248
|
const stringifiedRules = Array.from(
|
|
205
249
|
rules2,
|
|
206
|
-
(rule2) => stringifyRule(rule2,
|
|
250
|
+
(rule2) => stringifyRule(rule2, sheetHref)
|
|
207
251
|
).join("");
|
|
208
252
|
return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);
|
|
209
253
|
} catch (error) {
|
|
@@ -416,6 +460,111 @@ function absolutifyURLs(cssText, href) {
|
|
|
416
460
|
}
|
|
417
461
|
);
|
|
418
462
|
}
|
|
463
|
+
function normalizeCssString(cssText, _testNoPxNorm = false) {
|
|
464
|
+
if (_testNoPxNorm) {
|
|
465
|
+
return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "");
|
|
466
|
+
} else {
|
|
467
|
+
return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "").replace(/0px/g, "0");
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function splitCssText(cssText, style, _testNoPxNorm = false) {
|
|
471
|
+
const childNodes2 = Array.from(style.childNodes);
|
|
472
|
+
const splits = [];
|
|
473
|
+
let iterCount = 0;
|
|
474
|
+
if (childNodes2.length > 1 && cssText && typeof cssText === "string") {
|
|
475
|
+
let cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);
|
|
476
|
+
const normFactor = cssTextNorm.length / cssText.length;
|
|
477
|
+
for (let i2 = 1; i2 < childNodes2.length; i2++) {
|
|
478
|
+
if (childNodes2[i2].textContent && typeof childNodes2[i2].textContent === "string") {
|
|
479
|
+
const textContentNorm = normalizeCssString(
|
|
480
|
+
childNodes2[i2].textContent,
|
|
481
|
+
_testNoPxNorm
|
|
482
|
+
);
|
|
483
|
+
const jLimit = 100;
|
|
484
|
+
let j = 3;
|
|
485
|
+
for (; j < textContentNorm.length; j++) {
|
|
486
|
+
if (
|
|
487
|
+
// keep consuming css identifiers (to get a decent chunk more quickly)
|
|
488
|
+
textContentNorm[j].match(/[a-zA-Z0-9]/) || // substring needs to be unique to this section
|
|
489
|
+
textContentNorm.indexOf(textContentNorm.substring(0, j), 1) !== -1
|
|
490
|
+
) {
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
for (; j < textContentNorm.length; j++) {
|
|
496
|
+
let startSubstring = textContentNorm.substring(0, j);
|
|
497
|
+
let cssNormSplits = cssTextNorm.split(startSubstring);
|
|
498
|
+
let splitNorm = -1;
|
|
499
|
+
if (cssNormSplits.length === 2) {
|
|
500
|
+
splitNorm = cssNormSplits[0].length;
|
|
501
|
+
} else if (cssNormSplits.length > 2 && cssNormSplits[0] === "" && childNodes2[i2 - 1].textContent !== "") {
|
|
502
|
+
splitNorm = cssTextNorm.indexOf(startSubstring, 1);
|
|
503
|
+
} else if (cssNormSplits.length === 1) {
|
|
504
|
+
startSubstring = startSubstring.substring(
|
|
505
|
+
0,
|
|
506
|
+
startSubstring.length - 1
|
|
507
|
+
);
|
|
508
|
+
cssNormSplits = cssTextNorm.split(startSubstring);
|
|
509
|
+
if (cssNormSplits.length <= 1) {
|
|
510
|
+
splits.push(cssText);
|
|
511
|
+
return splits;
|
|
512
|
+
}
|
|
513
|
+
j = jLimit + 1;
|
|
514
|
+
} else if (j === textContentNorm.length - 1) {
|
|
515
|
+
splitNorm = cssTextNorm.indexOf(startSubstring);
|
|
516
|
+
}
|
|
517
|
+
if (cssNormSplits.length >= 2 && j > jLimit) {
|
|
518
|
+
const prevTextContent = childNodes2[i2 - 1].textContent;
|
|
519
|
+
if (prevTextContent && typeof prevTextContent === "string") {
|
|
520
|
+
const prevMinLength = normalizeCssString(prevTextContent).length;
|
|
521
|
+
splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);
|
|
522
|
+
}
|
|
523
|
+
if (splitNorm === -1) {
|
|
524
|
+
splitNorm = cssNormSplits[0].length;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
if (splitNorm !== -1) {
|
|
528
|
+
let k = Math.floor(splitNorm / normFactor);
|
|
529
|
+
for (; k > 0 && k < cssText.length; ) {
|
|
530
|
+
iterCount += 1;
|
|
531
|
+
if (iterCount > 50 * childNodes2.length) {
|
|
532
|
+
splits.push(cssText);
|
|
533
|
+
return splits;
|
|
534
|
+
}
|
|
535
|
+
const normPart = normalizeCssString(
|
|
536
|
+
cssText.substring(0, k),
|
|
537
|
+
_testNoPxNorm
|
|
538
|
+
);
|
|
539
|
+
if (normPart.length === splitNorm) {
|
|
540
|
+
splits.push(cssText.substring(0, k));
|
|
541
|
+
cssText = cssText.substring(k);
|
|
542
|
+
cssTextNorm = cssTextNorm.substring(splitNorm);
|
|
543
|
+
break;
|
|
544
|
+
} else if (normPart.length < splitNorm) {
|
|
545
|
+
k += Math.max(
|
|
546
|
+
1,
|
|
547
|
+
Math.floor((splitNorm - normPart.length) / normFactor)
|
|
548
|
+
);
|
|
549
|
+
} else {
|
|
550
|
+
k -= Math.max(
|
|
551
|
+
1,
|
|
552
|
+
Math.floor((normPart.length - splitNorm) * normFactor)
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
splits.push(cssText);
|
|
563
|
+
return splits;
|
|
564
|
+
}
|
|
565
|
+
function markCssSplits(cssText, style) {
|
|
566
|
+
return splitCssText(cssText, style).join("/* rr_split */");
|
|
567
|
+
}
|
|
419
568
|
let _id = 1;
|
|
420
569
|
const tagNameRegex = new RegExp("[^a-z0-9-_:]");
|
|
421
570
|
const IGNORED_NODE = -2;
|
|
@@ -522,7 +671,7 @@ function transformAttribute(doc, tagName, name, value) {
|
|
|
522
671
|
return absoluteToDoc(doc, value);
|
|
523
672
|
} else if (name === "xlink:href" && value[0] !== "#") {
|
|
524
673
|
return absoluteToDoc(doc, value);
|
|
525
|
-
} else if (name === "background" &&
|
|
674
|
+
} else if (name === "background" && ["table", "td", "th"].includes(tagName)) {
|
|
526
675
|
return absoluteToDoc(doc, value);
|
|
527
676
|
} else if (name === "srcset") {
|
|
528
677
|
return getAbsoluteSrcsetString(doc, value);
|
|
@@ -534,7 +683,7 @@ function transformAttribute(doc, tagName, name, value) {
|
|
|
534
683
|
return value;
|
|
535
684
|
}
|
|
536
685
|
function ignoreAttribute(tagName, name, _value) {
|
|
537
|
-
return
|
|
686
|
+
return ["video", "audio"].includes(tagName) && name === "autoplay";
|
|
538
687
|
}
|
|
539
688
|
function _isBlockedElement(element, blockClass, blockSelector) {
|
|
540
689
|
try {
|
|
@@ -674,27 +823,28 @@ function serializeNode(n2, options) {
|
|
|
674
823
|
inlineImages,
|
|
675
824
|
recordCanvas,
|
|
676
825
|
keepIframeSrcFn,
|
|
677
|
-
newlyAddedElement = false
|
|
826
|
+
newlyAddedElement = false,
|
|
827
|
+
cssCaptured = false
|
|
678
828
|
} = options;
|
|
679
829
|
const rootId = getRootId(doc, mirror2);
|
|
680
830
|
switch (n2.nodeType) {
|
|
681
831
|
case n2.DOCUMENT_NODE:
|
|
682
832
|
if (n2.compatMode !== "CSS1Compat") {
|
|
683
833
|
return {
|
|
684
|
-
type: NodeType$
|
|
834
|
+
type: NodeType$3.Document,
|
|
685
835
|
childNodes: [],
|
|
686
836
|
compatMode: n2.compatMode
|
|
687
837
|
// probably "BackCompat"
|
|
688
838
|
};
|
|
689
839
|
} else {
|
|
690
840
|
return {
|
|
691
|
-
type: NodeType$
|
|
841
|
+
type: NodeType$3.Document,
|
|
692
842
|
childNodes: []
|
|
693
843
|
};
|
|
694
844
|
}
|
|
695
845
|
case n2.DOCUMENT_TYPE_NODE:
|
|
696
846
|
return {
|
|
697
|
-
type: NodeType$
|
|
847
|
+
type: NodeType$3.DocumentType,
|
|
698
848
|
name: n2.name,
|
|
699
849
|
publicId: n2.publicId,
|
|
700
850
|
systemId: n2.systemId,
|
|
@@ -720,17 +870,18 @@ function serializeNode(n2, options) {
|
|
|
720
870
|
doc,
|
|
721
871
|
needsMask,
|
|
722
872
|
maskTextFn,
|
|
723
|
-
rootId
|
|
873
|
+
rootId,
|
|
874
|
+
cssCaptured
|
|
724
875
|
});
|
|
725
876
|
case n2.CDATA_SECTION_NODE:
|
|
726
877
|
return {
|
|
727
|
-
type: NodeType$
|
|
878
|
+
type: NodeType$3.CDATA,
|
|
728
879
|
textContent: "",
|
|
729
880
|
rootId
|
|
730
881
|
};
|
|
731
882
|
case n2.COMMENT_NODE:
|
|
732
883
|
return {
|
|
733
|
-
type: NodeType$
|
|
884
|
+
type: NodeType$3.Comment,
|
|
734
885
|
textContent: index$1.textContent(n2) || "",
|
|
735
886
|
rootId
|
|
736
887
|
};
|
|
@@ -744,37 +895,26 @@ function getRootId(doc, mirror2) {
|
|
|
744
895
|
return docId === 1 ? void 0 : docId;
|
|
745
896
|
}
|
|
746
897
|
function serializeTextNode(n2, options) {
|
|
747
|
-
|
|
748
|
-
const { needsMask, maskTextFn, rootId } = options;
|
|
898
|
+
const { needsMask, maskTextFn, rootId, cssCaptured } = options;
|
|
749
899
|
const parent = index$1.parentNode(n2);
|
|
750
900
|
const parentTagName = parent && parent.tagName;
|
|
751
|
-
let
|
|
901
|
+
let textContent2 = "";
|
|
752
902
|
const isStyle = parentTagName === "STYLE" ? true : void 0;
|
|
753
903
|
const isScript = parentTagName === "SCRIPT" ? true : void 0;
|
|
754
|
-
if (isStyle && text) {
|
|
755
|
-
try {
|
|
756
|
-
if (n2.nextSibling || n2.previousSibling) {
|
|
757
|
-
} else if ((_a2 = parent.sheet) == null ? void 0 : _a2.cssRules) {
|
|
758
|
-
text = stringifyStylesheet(parent.sheet);
|
|
759
|
-
}
|
|
760
|
-
} catch (err) {
|
|
761
|
-
console.warn(
|
|
762
|
-
`Cannot get CSS styles from text's parentNode. Error: ${err}`,
|
|
763
|
-
n2
|
|
764
|
-
);
|
|
765
|
-
}
|
|
766
|
-
text = absolutifyURLs(text, getHref(options.doc));
|
|
767
|
-
}
|
|
768
904
|
if (isScript) {
|
|
769
|
-
|
|
905
|
+
textContent2 = "SCRIPT_PLACEHOLDER";
|
|
906
|
+
} else if (!cssCaptured) {
|
|
907
|
+
textContent2 = index$1.textContent(n2);
|
|
908
|
+
if (isStyle && textContent2) {
|
|
909
|
+
textContent2 = absolutifyURLs(textContent2, getHref(options.doc));
|
|
910
|
+
}
|
|
770
911
|
}
|
|
771
|
-
if (!isStyle && !isScript &&
|
|
772
|
-
|
|
912
|
+
if (!isStyle && !isScript && textContent2 && needsMask) {
|
|
913
|
+
textContent2 = maskTextFn ? maskTextFn(textContent2, index$1.parentElement(n2)) : textContent2.replace(/[\S]/g, "*");
|
|
773
914
|
}
|
|
774
915
|
return {
|
|
775
|
-
type: NodeType$
|
|
776
|
-
textContent:
|
|
777
|
-
isStyle,
|
|
916
|
+
type: NodeType$3.Text,
|
|
917
|
+
textContent: textContent2 || "",
|
|
778
918
|
rootId
|
|
779
919
|
};
|
|
780
920
|
}
|
|
@@ -822,16 +962,18 @@ function serializeElementNode(n2, options) {
|
|
|
822
962
|
attributes._cssText = cssText;
|
|
823
963
|
}
|
|
824
964
|
}
|
|
825
|
-
if (tagName === "style" && n2.sheet
|
|
826
|
-
|
|
827
|
-
const cssText = stringifyStylesheet(
|
|
965
|
+
if (tagName === "style" && n2.sheet) {
|
|
966
|
+
let cssText = stringifyStylesheet(
|
|
828
967
|
n2.sheet
|
|
829
968
|
);
|
|
830
969
|
if (cssText) {
|
|
970
|
+
if (n2.childNodes.length > 1) {
|
|
971
|
+
cssText = markCssSplits(cssText, n2);
|
|
972
|
+
}
|
|
831
973
|
attributes._cssText = cssText;
|
|
832
974
|
}
|
|
833
975
|
}
|
|
834
|
-
if (
|
|
976
|
+
if (["input", "textarea", "select"].includes(tagName)) {
|
|
835
977
|
const value = n2.value;
|
|
836
978
|
const checked = n2.checked;
|
|
837
979
|
if (attributes.type !== "radio" && attributes.type !== "checkbox" && attributes.type !== "submit" && attributes.type !== "button" && value) {
|
|
@@ -920,7 +1062,7 @@ function serializeElementNode(n2, options) {
|
|
|
920
1062
|
if (image.complete && image.naturalWidth !== 0) recordInlineImage();
|
|
921
1063
|
else image.addEventListener("load", recordInlineImage);
|
|
922
1064
|
}
|
|
923
|
-
if (
|
|
1065
|
+
if (["audio", "video"].includes(tagName)) {
|
|
924
1066
|
const mediaAttributes = attributes;
|
|
925
1067
|
mediaAttributes.rr_mediaState = n2.paused ? "paused" : "played";
|
|
926
1068
|
mediaAttributes.rr_mediaCurrentTime = n2.currentTime;
|
|
@@ -957,7 +1099,7 @@ function serializeElementNode(n2, options) {
|
|
|
957
1099
|
} catch (e2) {
|
|
958
1100
|
}
|
|
959
1101
|
return {
|
|
960
|
-
type: NodeType$
|
|
1102
|
+
type: NodeType$3.Element,
|
|
961
1103
|
tagName,
|
|
962
1104
|
attributes,
|
|
963
1105
|
childNodes: [],
|
|
@@ -974,13 +1116,35 @@ function lowerIfExists(maybeAttr) {
|
|
|
974
1116
|
return maybeAttr.toLowerCase();
|
|
975
1117
|
}
|
|
976
1118
|
}
|
|
1119
|
+
function slimDOMDefaults(_slimDOMOptions) {
|
|
1120
|
+
if (_slimDOMOptions === true || _slimDOMOptions === "all") {
|
|
1121
|
+
return {
|
|
1122
|
+
script: true,
|
|
1123
|
+
comment: true,
|
|
1124
|
+
headFavicon: true,
|
|
1125
|
+
headWhitespace: true,
|
|
1126
|
+
headMetaSocial: true,
|
|
1127
|
+
headMetaRobots: true,
|
|
1128
|
+
headMetaHttpEquiv: true,
|
|
1129
|
+
headMetaVerification: true,
|
|
1130
|
+
// the following are off for slimDOMOptions === true,
|
|
1131
|
+
// as they destroy some (hidden) info:
|
|
1132
|
+
headMetaAuthorship: _slimDOMOptions === "all",
|
|
1133
|
+
headMetaDescKeywords: _slimDOMOptions === "all",
|
|
1134
|
+
headTitleMutations: _slimDOMOptions === "all"
|
|
1135
|
+
};
|
|
1136
|
+
} else if (_slimDOMOptions) {
|
|
1137
|
+
return _slimDOMOptions;
|
|
1138
|
+
}
|
|
1139
|
+
return {};
|
|
1140
|
+
}
|
|
977
1141
|
function slimDOMExcluded(sn, slimDOMOptions) {
|
|
978
|
-
if (slimDOMOptions.comment && sn.type === NodeType$
|
|
1142
|
+
if (slimDOMOptions.comment && sn.type === NodeType$3.Comment) {
|
|
979
1143
|
return true;
|
|
980
|
-
} else if (sn.type === NodeType$
|
|
1144
|
+
} else if (sn.type === NodeType$3.Element) {
|
|
981
1145
|
if (slimDOMOptions.script && // script tag
|
|
982
1146
|
(sn.tagName === "script" || // (module)preload link
|
|
983
|
-
sn.tagName === "link" && (sn.attributes.rel === "preload"
|
|
1147
|
+
sn.tagName === "link" && (sn.attributes.rel === "preload" && sn.attributes.as === "script" || sn.attributes.rel === "modulepreload") || // prefetch link
|
|
984
1148
|
sn.tagName === "link" && sn.attributes.rel === "prefetch" && typeof sn.attributes.href === "string" && extractFileExtension(sn.attributes.href) === "js")) {
|
|
985
1149
|
return true;
|
|
986
1150
|
} else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match(
|
|
@@ -1029,7 +1193,8 @@ function serializeNodeWithId(n2, options) {
|
|
|
1029
1193
|
onStylesheetLoad,
|
|
1030
1194
|
stylesheetLoadTimeout = 5e3,
|
|
1031
1195
|
keepIframeSrcFn = () => false,
|
|
1032
|
-
newlyAddedElement = false
|
|
1196
|
+
newlyAddedElement = false,
|
|
1197
|
+
cssCaptured = false
|
|
1033
1198
|
} = options;
|
|
1034
1199
|
let { needsMask } = options;
|
|
1035
1200
|
let { preserveWhiteSpace = true } = options;
|
|
@@ -1056,7 +1221,8 @@ function serializeNodeWithId(n2, options) {
|
|
|
1056
1221
|
inlineImages,
|
|
1057
1222
|
recordCanvas,
|
|
1058
1223
|
keepIframeSrcFn,
|
|
1059
|
-
newlyAddedElement
|
|
1224
|
+
newlyAddedElement,
|
|
1225
|
+
cssCaptured
|
|
1060
1226
|
});
|
|
1061
1227
|
if (!_serializedNode) {
|
|
1062
1228
|
console.warn(n2, "not serialized");
|
|
@@ -1065,7 +1231,7 @@ function serializeNodeWithId(n2, options) {
|
|
|
1065
1231
|
let id;
|
|
1066
1232
|
if (mirror2.hasNode(n2)) {
|
|
1067
1233
|
id = mirror2.getId(n2);
|
|
1068
|
-
} else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType$
|
|
1234
|
+
} else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType$3.Text && !_serializedNode.textContent.replace(/^\s+|\s+$/gm, "").length) {
|
|
1069
1235
|
id = IGNORED_NODE;
|
|
1070
1236
|
} else {
|
|
1071
1237
|
id = genId();
|
|
@@ -1079,15 +1245,15 @@ function serializeNodeWithId(n2, options) {
|
|
|
1079
1245
|
onSerialize(n2);
|
|
1080
1246
|
}
|
|
1081
1247
|
let recordChild = !skipChild;
|
|
1082
|
-
if (serializedNode.type === NodeType$
|
|
1248
|
+
if (serializedNode.type === NodeType$3.Element) {
|
|
1083
1249
|
recordChild = recordChild && !serializedNode.needBlock;
|
|
1084
1250
|
delete serializedNode.needBlock;
|
|
1085
1251
|
const shadowRootEl = index$1.shadowRoot(n2);
|
|
1086
1252
|
if (shadowRootEl && isNativeShadowDom(shadowRootEl))
|
|
1087
1253
|
serializedNode.isShadowHost = true;
|
|
1088
1254
|
}
|
|
1089
|
-
if ((serializedNode.type === NodeType$
|
|
1090
|
-
if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType$
|
|
1255
|
+
if ((serializedNode.type === NodeType$3.Document || serializedNode.type === NodeType$3.Element) && recordChild) {
|
|
1256
|
+
if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType$3.Element && serializedNode.tagName === "head") {
|
|
1091
1257
|
preserveWhiteSpace = false;
|
|
1092
1258
|
}
|
|
1093
1259
|
const bypassOptions = {
|
|
@@ -1113,10 +1279,14 @@ function serializeNodeWithId(n2, options) {
|
|
|
1113
1279
|
iframeLoadTimeout,
|
|
1114
1280
|
onStylesheetLoad,
|
|
1115
1281
|
stylesheetLoadTimeout,
|
|
1116
|
-
keepIframeSrcFn
|
|
1282
|
+
keepIframeSrcFn,
|
|
1283
|
+
cssCaptured: false
|
|
1117
1284
|
};
|
|
1118
|
-
if (serializedNode.type === NodeType$
|
|
1285
|
+
if (serializedNode.type === NodeType$3.Element && serializedNode.tagName === "textarea" && serializedNode.attributes.value !== void 0) ;
|
|
1119
1286
|
else {
|
|
1287
|
+
if (serializedNode.type === NodeType$3.Element && serializedNode.attributes._cssText !== void 0 && typeof serializedNode.attributes._cssText === "string") {
|
|
1288
|
+
bypassOptions.cssCaptured = true;
|
|
1289
|
+
}
|
|
1120
1290
|
for (const childN of Array.from(index$1.childNodes(n2))) {
|
|
1121
1291
|
const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
|
|
1122
1292
|
if (serializedChildNode) {
|
|
@@ -1139,7 +1309,7 @@ function serializeNodeWithId(n2, options) {
|
|
|
1139
1309
|
if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {
|
|
1140
1310
|
serializedNode.isShadow = true;
|
|
1141
1311
|
}
|
|
1142
|
-
if (serializedNode.type === NodeType$
|
|
1312
|
+
if (serializedNode.type === NodeType$3.Element && serializedNode.tagName === "iframe") {
|
|
1143
1313
|
onceIframeLoaded(
|
|
1144
1314
|
n2,
|
|
1145
1315
|
() => {
|
|
@@ -1181,7 +1351,7 @@ function serializeNodeWithId(n2, options) {
|
|
|
1181
1351
|
iframeLoadTimeout
|
|
1182
1352
|
);
|
|
1183
1353
|
}
|
|
1184
|
-
if (serializedNode.type === NodeType$
|
|
1354
|
+
if (serializedNode.type === NodeType$3.Element && serializedNode.tagName === "link" && typeof serializedNode.attributes.rel === "string" && (serializedNode.attributes.rel === "stylesheet" || serializedNode.attributes.rel === "preload" && typeof serializedNode.attributes.href === "string" && extractFileExtension(serializedNode.attributes.href) === "css")) {
|
|
1185
1355
|
onceStylesheetLoaded(
|
|
1186
1356
|
n2,
|
|
1187
1357
|
() => {
|
|
@@ -1267,22 +1437,7 @@ function snapshot(n2, options) {
|
|
|
1267
1437
|
} : maskAllInputs === false ? {
|
|
1268
1438
|
password: true
|
|
1269
1439
|
} : maskAllInputs;
|
|
1270
|
-
const slimDOMOptions = slimDOM
|
|
1271
|
-
// if true: set of sensible options that should not throw away any information
|
|
1272
|
-
{
|
|
1273
|
-
script: true,
|
|
1274
|
-
comment: true,
|
|
1275
|
-
headFavicon: true,
|
|
1276
|
-
headWhitespace: true,
|
|
1277
|
-
headMetaDescKeywords: slimDOM === "all",
|
|
1278
|
-
// destructive
|
|
1279
|
-
headMetaSocial: true,
|
|
1280
|
-
headMetaRobots: true,
|
|
1281
|
-
headMetaHttpEquiv: true,
|
|
1282
|
-
headMetaAuthorship: true,
|
|
1283
|
-
headMetaVerification: true
|
|
1284
|
-
}
|
|
1285
|
-
) : slimDOM === false ? {} : slimDOM;
|
|
1440
|
+
const slimDOMOptions = slimDOMDefaults(slimDOM);
|
|
1286
1441
|
return serializeNodeWithId(n2, {
|
|
1287
1442
|
doc: n2,
|
|
1288
1443
|
mirror: mirror2,
|
|
@@ -8448,7 +8603,13 @@ class BaseRRNode {
|
|
|
8448
8603
|
}
|
|
8449
8604
|
}
|
|
8450
8605
|
const testableAccessors = {
|
|
8451
|
-
Node: [
|
|
8606
|
+
Node: [
|
|
8607
|
+
"childNodes",
|
|
8608
|
+
"parentNode",
|
|
8609
|
+
"parentElement",
|
|
8610
|
+
"textContent",
|
|
8611
|
+
"ownerDocument"
|
|
8612
|
+
],
|
|
8452
8613
|
ShadowRoot: ["host", "styleSheets"],
|
|
8453
8614
|
Element: ["shadowRoot", "querySelector", "querySelectorAll"],
|
|
8454
8615
|
MutationObserver: []
|
|
@@ -8460,6 +8621,9 @@ const testableMethods = {
|
|
|
8460
8621
|
MutationObserver: ["constructor"]
|
|
8461
8622
|
};
|
|
8462
8623
|
const untaintedBasePrototype = {};
|
|
8624
|
+
const isAngularZonePresent = () => {
|
|
8625
|
+
return !!globalThis.Zone;
|
|
8626
|
+
};
|
|
8463
8627
|
function getUntaintedPrototype(key) {
|
|
8464
8628
|
if (untaintedBasePrototype[key])
|
|
8465
8629
|
return untaintedBasePrototype[key];
|
|
@@ -8487,7 +8651,7 @@ function getUntaintedPrototype(key) {
|
|
|
8487
8651
|
}
|
|
8488
8652
|
)
|
|
8489
8653
|
);
|
|
8490
|
-
if (isUntaintedAccessors && isUntaintedMethods) {
|
|
8654
|
+
if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {
|
|
8491
8655
|
untaintedBasePrototype[key] = defaultObj.prototype;
|
|
8492
8656
|
return defaultObj.prototype;
|
|
8493
8657
|
}
|
|
@@ -8534,6 +8698,9 @@ function getUntaintedMethod(key, instance, method) {
|
|
|
8534
8698
|
untaintedMethodCache[cacheKey] = untaintedMethod;
|
|
8535
8699
|
return untaintedMethod.bind(instance);
|
|
8536
8700
|
}
|
|
8701
|
+
function ownerDocument(n2) {
|
|
8702
|
+
return getUntaintedAccessor("Node", n2, "ownerDocument");
|
|
8703
|
+
}
|
|
8537
8704
|
function childNodes(n2) {
|
|
8538
8705
|
return getUntaintedAccessor("Node", n2, "childNodes");
|
|
8539
8706
|
}
|
|
@@ -8572,7 +8739,34 @@ function querySelectorAll(n2, selectors) {
|
|
|
8572
8739
|
function mutationObserverCtor() {
|
|
8573
8740
|
return getUntaintedPrototype("MutationObserver").constructor;
|
|
8574
8741
|
}
|
|
8742
|
+
function patch(source, name, replacement) {
|
|
8743
|
+
try {
|
|
8744
|
+
if (!(name in source)) {
|
|
8745
|
+
return () => {
|
|
8746
|
+
};
|
|
8747
|
+
}
|
|
8748
|
+
const original = source[name];
|
|
8749
|
+
const wrapped = replacement(original);
|
|
8750
|
+
if (typeof wrapped === "function") {
|
|
8751
|
+
wrapped.prototype = wrapped.prototype || {};
|
|
8752
|
+
Object.defineProperties(wrapped, {
|
|
8753
|
+
__rrweb_original__: {
|
|
8754
|
+
enumerable: false,
|
|
8755
|
+
value: original
|
|
8756
|
+
}
|
|
8757
|
+
});
|
|
8758
|
+
}
|
|
8759
|
+
source[name] = wrapped;
|
|
8760
|
+
return () => {
|
|
8761
|
+
source[name] = original;
|
|
8762
|
+
};
|
|
8763
|
+
} catch {
|
|
8764
|
+
return () => {
|
|
8765
|
+
};
|
|
8766
|
+
}
|
|
8767
|
+
}
|
|
8575
8768
|
const index = {
|
|
8769
|
+
ownerDocument,
|
|
8576
8770
|
childNodes,
|
|
8577
8771
|
parentNode,
|
|
8578
8772
|
parentElement,
|
|
@@ -8584,7 +8778,8 @@ const index = {
|
|
|
8584
8778
|
shadowRoot,
|
|
8585
8779
|
querySelector,
|
|
8586
8780
|
querySelectorAll,
|
|
8587
|
-
mutationObserver: mutationObserverCtor
|
|
8781
|
+
mutationObserver: mutationObserverCtor,
|
|
8782
|
+
patch
|
|
8588
8783
|
};
|
|
8589
8784
|
function on(type, fn, target = document) {
|
|
8590
8785
|
const options = { capture: true, passive: true };
|
|
@@ -8667,32 +8862,6 @@ function hookSetter(target, key, d, isRevoked, win = window) {
|
|
|
8667
8862
|
);
|
|
8668
8863
|
return () => hookSetter(target, key, original || {}, true);
|
|
8669
8864
|
}
|
|
8670
|
-
function patch(source, name, replacement) {
|
|
8671
|
-
try {
|
|
8672
|
-
if (!(name in source)) {
|
|
8673
|
-
return () => {
|
|
8674
|
-
};
|
|
8675
|
-
}
|
|
8676
|
-
const original = source[name];
|
|
8677
|
-
const wrapped = replacement(original);
|
|
8678
|
-
if (typeof wrapped === "function") {
|
|
8679
|
-
wrapped.prototype = wrapped.prototype || {};
|
|
8680
|
-
Object.defineProperties(wrapped, {
|
|
8681
|
-
__rrweb_original__: {
|
|
8682
|
-
enumerable: false,
|
|
8683
|
-
value: original
|
|
8684
|
-
}
|
|
8685
|
-
});
|
|
8686
|
-
}
|
|
8687
|
-
source[name] = wrapped;
|
|
8688
|
-
return () => {
|
|
8689
|
-
source[name] = original;
|
|
8690
|
-
};
|
|
8691
|
-
} catch {
|
|
8692
|
-
return () => {
|
|
8693
|
-
};
|
|
8694
|
-
}
|
|
8695
|
-
}
|
|
8696
8865
|
let nowTimestamp = Date.now;
|
|
8697
8866
|
if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {
|
|
8698
8867
|
nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();
|
|
@@ -8845,13 +9014,13 @@ function getRootShadowHost(n2) {
|
|
|
8845
9014
|
return rootShadowHost;
|
|
8846
9015
|
}
|
|
8847
9016
|
function shadowHostInDom(n2) {
|
|
8848
|
-
const doc =
|
|
9017
|
+
const doc = index.ownerDocument(n2);
|
|
8849
9018
|
if (!doc) return false;
|
|
8850
9019
|
const shadowHost = getRootShadowHost(n2);
|
|
8851
9020
|
return index.contains(doc, shadowHost);
|
|
8852
9021
|
}
|
|
8853
9022
|
function inDom(n2) {
|
|
8854
|
-
const doc =
|
|
9023
|
+
const doc = index.ownerDocument(n2);
|
|
8855
9024
|
if (!doc) return false;
|
|
8856
9025
|
return index.contains(doc, n2) || shadowHostInDom(n2);
|
|
8857
9026
|
}
|
|
@@ -8919,6 +9088,15 @@ var MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {
|
|
|
8919
9088
|
MediaInteractions2[MediaInteractions2["RateChange"] = 4] = "RateChange";
|
|
8920
9089
|
return MediaInteractions2;
|
|
8921
9090
|
})(MediaInteractions || {});
|
|
9091
|
+
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
9092
|
+
NodeType2[NodeType2["Document"] = 0] = "Document";
|
|
9093
|
+
NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
|
|
9094
|
+
NodeType2[NodeType2["Element"] = 2] = "Element";
|
|
9095
|
+
NodeType2[NodeType2["Text"] = 3] = "Text";
|
|
9096
|
+
NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
|
|
9097
|
+
NodeType2[NodeType2["Comment"] = 5] = "Comment";
|
|
9098
|
+
return NodeType2;
|
|
9099
|
+
})(NodeType || {});
|
|
8922
9100
|
function isNodeInLinkedList(n2) {
|
|
8923
9101
|
return "__ln" in n2;
|
|
8924
9102
|
}
|
|
@@ -9013,6 +9191,7 @@ class MutationBuffer {
|
|
|
9013
9191
|
__publicField(this, "addedSet", /* @__PURE__ */ new Set());
|
|
9014
9192
|
__publicField(this, "movedSet", /* @__PURE__ */ new Set());
|
|
9015
9193
|
__publicField(this, "droppedSet", /* @__PURE__ */ new Set());
|
|
9194
|
+
__publicField(this, "removesSubTreeCache", /* @__PURE__ */ new Set());
|
|
9016
9195
|
__publicField(this, "mutationCb");
|
|
9017
9196
|
__publicField(this, "blockClass");
|
|
9018
9197
|
__publicField(this, "blockSelector");
|
|
@@ -9057,9 +9236,18 @@ class MutationBuffer {
|
|
|
9057
9236
|
};
|
|
9058
9237
|
const pushAdd = (n2) => {
|
|
9059
9238
|
const parent = index.parentNode(n2);
|
|
9060
|
-
if (!parent || !inDom(n2)
|
|
9239
|
+
if (!parent || !inDom(n2)) {
|
|
9061
9240
|
return;
|
|
9062
9241
|
}
|
|
9242
|
+
let cssCaptured = false;
|
|
9243
|
+
if (n2.nodeType === Node.TEXT_NODE) {
|
|
9244
|
+
const parentTag = parent.tagName;
|
|
9245
|
+
if (parentTag === "TEXTAREA") {
|
|
9246
|
+
return;
|
|
9247
|
+
} else if (parentTag === "STYLE" && this.addedSet.has(parent)) {
|
|
9248
|
+
cssCaptured = true;
|
|
9249
|
+
}
|
|
9250
|
+
}
|
|
9063
9251
|
const parentId = isShadowRoot(parent) ? this.mirror.getId(getShadowHost(n2)) : this.mirror.getId(parent);
|
|
9064
9252
|
const nextId = getNextId(n2);
|
|
9065
9253
|
if (parentId === -1 || nextId === -1) {
|
|
@@ -9101,7 +9289,8 @@ class MutationBuffer {
|
|
|
9101
9289
|
},
|
|
9102
9290
|
onStylesheetLoad: (link, childSn) => {
|
|
9103
9291
|
this.stylesheetManager.attachLinkElement(link, childSn);
|
|
9104
|
-
}
|
|
9292
|
+
},
|
|
9293
|
+
cssCaptured
|
|
9105
9294
|
});
|
|
9106
9295
|
if (sn) {
|
|
9107
9296
|
adds.push({
|
|
@@ -9116,13 +9305,13 @@ class MutationBuffer {
|
|
|
9116
9305
|
this.mirror.removeNodeFromMap(this.mapRemoves.shift());
|
|
9117
9306
|
}
|
|
9118
9307
|
for (const n2 of this.movedSet) {
|
|
9119
|
-
if (isParentRemoved(this.
|
|
9308
|
+
if (isParentRemoved(this.removesSubTreeCache, n2, this.mirror) && !this.movedSet.has(index.parentNode(n2))) {
|
|
9120
9309
|
continue;
|
|
9121
9310
|
}
|
|
9122
9311
|
pushAdd(n2);
|
|
9123
9312
|
}
|
|
9124
9313
|
for (const n2 of this.addedSet) {
|
|
9125
|
-
if (!isAncestorInSet(this.droppedSet, n2) && !isParentRemoved(this.
|
|
9314
|
+
if (!isAncestorInSet(this.droppedSet, n2) && !isParentRemoved(this.removesSubTreeCache, n2, this.mirror)) {
|
|
9126
9315
|
pushAdd(n2);
|
|
9127
9316
|
} else if (isAncestorInSet(this.movedSet, n2)) {
|
|
9128
9317
|
pushAdd(n2);
|
|
@@ -9218,6 +9407,7 @@ class MutationBuffer {
|
|
|
9218
9407
|
this.addedSet = /* @__PURE__ */ new Set();
|
|
9219
9408
|
this.movedSet = /* @__PURE__ */ new Set();
|
|
9220
9409
|
this.droppedSet = /* @__PURE__ */ new Set();
|
|
9410
|
+
this.removesSubTreeCache = /* @__PURE__ */ new Set();
|
|
9221
9411
|
this.movedMap = {};
|
|
9222
9412
|
this.mutationCb(payload);
|
|
9223
9413
|
});
|
|
@@ -9233,10 +9423,18 @@ class MutationBuffer {
|
|
|
9233
9423
|
this.attributes.push(item);
|
|
9234
9424
|
this.attributeMap.set(textarea, item);
|
|
9235
9425
|
}
|
|
9236
|
-
|
|
9426
|
+
const value = Array.from(
|
|
9237
9427
|
index.childNodes(textarea),
|
|
9238
9428
|
(cn) => index.textContent(cn) || ""
|
|
9239
9429
|
).join("");
|
|
9430
|
+
item.attributes.value = maskInputValue({
|
|
9431
|
+
element: textarea,
|
|
9432
|
+
maskInputOptions: this.maskInputOptions,
|
|
9433
|
+
tagName: textarea.tagName,
|
|
9434
|
+
type: getInputType(textarea),
|
|
9435
|
+
value,
|
|
9436
|
+
maskInputFn: this.maskInputFn
|
|
9437
|
+
});
|
|
9240
9438
|
});
|
|
9241
9439
|
__publicField(this, "processMutation", (m) => {
|
|
9242
9440
|
if (isIgnored(m.target, this.mirror, this.slimDOMOptions)) {
|
|
@@ -9372,6 +9570,7 @@ class MutationBuffer {
|
|
|
9372
9570
|
id: nodeId,
|
|
9373
9571
|
isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target) ? true : void 0
|
|
9374
9572
|
});
|
|
9573
|
+
processRemoves(n2, this.removesSubTreeCache);
|
|
9375
9574
|
}
|
|
9376
9575
|
this.mapRemoves.push(n2);
|
|
9377
9576
|
});
|
|
@@ -9466,20 +9665,24 @@ function deepDelete(addsSet, n2) {
|
|
|
9466
9665
|
addsSet.delete(n2);
|
|
9467
9666
|
index.childNodes(n2).forEach((childN) => deepDelete(addsSet, childN));
|
|
9468
9667
|
}
|
|
9469
|
-
function
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
const parentId = mirror2.getId(node2);
|
|
9477
|
-
if (removes.some((r2) => r2.id === parentId)) {
|
|
9478
|
-
return true;
|
|
9479
|
-
}
|
|
9480
|
-
node2 = index.parentNode(node2);
|
|
9668
|
+
function processRemoves(n2, cache) {
|
|
9669
|
+
const queue = [n2];
|
|
9670
|
+
while (queue.length) {
|
|
9671
|
+
const next = queue.pop();
|
|
9672
|
+
if (cache.has(next)) continue;
|
|
9673
|
+
cache.add(next);
|
|
9674
|
+
index.childNodes(next).forEach((n22) => queue.push(n22));
|
|
9481
9675
|
}
|
|
9482
|
-
return
|
|
9676
|
+
return;
|
|
9677
|
+
}
|
|
9678
|
+
function isParentRemoved(removes, n2, mirror2) {
|
|
9679
|
+
if (removes.size === 0) return false;
|
|
9680
|
+
return _isParentRemoved(removes, n2);
|
|
9681
|
+
}
|
|
9682
|
+
function _isParentRemoved(removes, n2, _mirror2) {
|
|
9683
|
+
const node2 = index.parentNode(n2);
|
|
9684
|
+
if (!node2) return false;
|
|
9685
|
+
return removes.has(node2);
|
|
9483
9686
|
}
|
|
9484
9687
|
function isAncestorInSet(set, n2) {
|
|
9485
9688
|
if (set.size === 0) return false;
|
|
@@ -10817,7 +11020,7 @@ class IframeManager {
|
|
|
10817
11020
|
}
|
|
10818
11021
|
}
|
|
10819
11022
|
patchRootIdOnNode(node2, rootId) {
|
|
10820
|
-
if (node2.type !== NodeType
|
|
11023
|
+
if (node2.type !== NodeType.Document && !node2.rootId) node2.rootId = rootId;
|
|
10821
11024
|
if ("childNodes" in node2) {
|
|
10822
11025
|
node2.childNodes.forEach((child) => {
|
|
10823
11026
|
this.patchRootIdOnNode(child, rootId);
|
|
@@ -11641,21 +11844,7 @@ function record(options = {}) {
|
|
|
11641
11844
|
select: true,
|
|
11642
11845
|
password: true
|
|
11643
11846
|
} : _maskInputOptions !== void 0 ? _maskInputOptions : { password: true };
|
|
11644
|
-
const slimDOMOptions = _slimDOMOptions
|
|
11645
|
-
script: true,
|
|
11646
|
-
comment: true,
|
|
11647
|
-
headFavicon: true,
|
|
11648
|
-
headWhitespace: true,
|
|
11649
|
-
headMetaSocial: true,
|
|
11650
|
-
headMetaRobots: true,
|
|
11651
|
-
headMetaHttpEquiv: true,
|
|
11652
|
-
headMetaVerification: true,
|
|
11653
|
-
// the following are off for slimDOMOptions === true,
|
|
11654
|
-
// as they destroy some (hidden) info:
|
|
11655
|
-
headMetaAuthorship: _slimDOMOptions === "all",
|
|
11656
|
-
headMetaDescKeywords: _slimDOMOptions === "all",
|
|
11657
|
-
headTitleMutations: _slimDOMOptions === "all"
|
|
11658
|
-
} : _slimDOMOptions ? _slimDOMOptions : {};
|
|
11847
|
+
const slimDOMOptions = slimDOMDefaults(_slimDOMOptions);
|
|
11659
11848
|
polyfill$1();
|
|
11660
11849
|
let lastFullSnapshotEvent;
|
|
11661
11850
|
let incrementalSnapshotCount = 0;
|
|
@@ -11998,7 +12187,7 @@ function record(options = {}) {
|
|
|
11998
12187
|
handlers.push(observe(document));
|
|
11999
12188
|
recording = true;
|
|
12000
12189
|
};
|
|
12001
|
-
if (
|
|
12190
|
+
if (["interactive", "complete"].includes(document.readyState)) {
|
|
12002
12191
|
init();
|
|
12003
12192
|
} else {
|
|
12004
12193
|
handlers.push(
|
|
@@ -12025,7 +12214,16 @@ function record(options = {}) {
|
|
|
12025
12214
|
);
|
|
12026
12215
|
}
|
|
12027
12216
|
return () => {
|
|
12028
|
-
handlers.forEach((
|
|
12217
|
+
handlers.forEach((handler) => {
|
|
12218
|
+
try {
|
|
12219
|
+
handler();
|
|
12220
|
+
} catch (error) {
|
|
12221
|
+
const msg = String(error).toLowerCase();
|
|
12222
|
+
if (!msg.includes("cross-origin")) {
|
|
12223
|
+
console.warn(error);
|
|
12224
|
+
}
|
|
12225
|
+
}
|
|
12226
|
+
});
|
|
12029
12227
|
processedNodeManager.destroy();
|
|
12030
12228
|
recording = false;
|
|
12031
12229
|
unregisterErrorHandler();
|
|
@@ -12171,7 +12369,7 @@ function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) {
|
|
|
12171
12369
|
return buf;
|
|
12172
12370
|
}
|
|
12173
12371
|
|
|
12174
|
-
var s;!function(e){e[e.NONE=0]="NONE",e[e.ERROR=1]="ERROR",e[e.WARN=2]="WARN",e[e.INFO=3]="INFO",e[e.DEBUG=4]="DEBUG";}(s||(s={}));const i=new class{constructor(e){this.config={level:s.ERROR,enableConsole:true,enableStorage:false},this.isBrowser="undefined"!=typeof window,e&&(this.config={...this.config,...e});}setConfig(e){this.config={...this.config,...e};}shouldLog(e){return e<=this.config.level}formatMessage(e,t,...s){return `[HumanBehavior ${e}] ${(new Date).toISOString()}: ${t}`}error(e,...t){if(!this.shouldLog(s.ERROR))return;const i=this.formatMessage("ERROR",e);this.config.enableConsole&&console.error(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}warn(e,...t){if(!this.shouldLog(s.WARN))return;const i=this.formatMessage("WARN",e);this.config.enableConsole&&console.warn(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}info(e,...t){if(!this.shouldLog(s.INFO))return;const i=this.formatMessage("INFO",e);this.config.enableConsole&&console.log(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}debug(e,...t){if(!this.shouldLog(s.DEBUG))return;const i=this.formatMessage("DEBUG",e);this.config.enableConsole&&console.log(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}logToStorage(e,t){try{const s=JSON.parse(localStorage.getItem("human_behavior_logs")||"[]"),i={message:e,args:t.length>0?t:void 0,timestamp:Date.now()};s.push(i),s.length>1e3&&s.splice(0,s.length-1e3),localStorage.setItem("human_behavior_logs",JSON.stringify(s));}catch(e){}}getLogs(){if(!this.isBrowser)return [];try{return JSON.parse(localStorage.getItem("human_behavior_logs")||"[]")}catch(e){return []}}clearLogs(){this.isBrowser&&localStorage.removeItem("human_behavior_logs");}};let n=false;const r=()=>n,o=(e,...t)=>{n=true;try{i.error(e,...t);}finally{n=false;}},a=(e,...t)=>{n=true;try{i.warn(e,...t);}finally{n=false;}},d=(e,...t)=>{n=true;try{i.info(e,...t);}finally{n=false;}},l=(e,...t)=>{n=true;try{i.debug(e,...t);}finally{n=false;}};class c{constructor(e){this._isPolling=false,this._pollIntervalMs=3e3,this._queue=[],this._queue=[],this._areWeOnline=true,this._sendRequest=e,"undefined"!=typeof window&&"onLine"in window.navigator&&(this._areWeOnline=window.navigator.onLine,window.addEventListener("online",()=>{this._areWeOnline=true,this._flush();}),window.addEventListener("offline",()=>{this._areWeOnline=false;}));}get length(){return this._queue.length}async retriableRequest(e){const t=e.retriesPerformedSoFar||0;if(t>0){const s=new URL(e.url);s.searchParams.set("retry_count",t.toString()),e.url=s.toString();}try{await this._sendRequest(e);}catch(s){if(this._shouldRetry(s,t)&&t<10)return void this._enqueue(e);e.callback&&e.callback({statusCode:s.status||0,text:s.message||"Request failed"});}}_shouldRetry(e,t){return e.status>=400&&e.status<500?408===e.status||429===e.status:e.status>=500||!e.status}_enqueue(e){const t=e.retriesPerformedSoFar||0;e.retriesPerformedSoFar=t+1;const s=function(e){const t=3e3*2**e,s=t/2,i=Math.min(18e5,t),n=(Math.random()-.5)*(i-s);return Math.ceil(i+n)}(t),i=Date.now()+s;this._queue.push({retryAt:i,requestOptions:e});let n=`Enqueued failed request for retry in ${Math.round(s/1e3)}s`;"undefined"==typeof navigator||navigator.onLine||(n+=" (Browser is offline)"),a(n),this._isPolling||(this._isPolling=true,this._poll());}_poll(){this._poller&&clearTimeout(this._poller),this._poller=setTimeout(()=>{this._areWeOnline&&this._queue.length>0&&this._flush(),this._poll();},this._pollIntervalMs);}_flush(){const e=Date.now(),t=[],s=this._queue.filter(s=>s.retryAt<e||(t.push(s),false));if(this._queue=t,s.length>0)for(const{requestOptions:e}of s)this.retriableRequest(e).catch(e=>{o("Failed to retry request:",e);});}unload(){this._poller&&(clearTimeout(this._poller),this._poller=void 0);for(const{requestOptions:e}of this._queue)try{this._sendBeaconRequest(e);}catch(e){o("Failed to send request via sendBeacon on unload:",e);}this._queue=[];}_sendBeaconRequest(e){if("undefined"!=typeof navigator&&navigator.sendBeacon)try{const t=new URL(e.url);t.searchParams.set("beacon","1");let s=null;e.body&&("string"==typeof e.body?s=new Blob([e.body],{type:"application/json"}):e.body instanceof Blob&&(s=e.body));navigator.sendBeacon(t.toString(),s)||a("sendBeacon returned false for unload request");}catch(e){o("Error sending beacon request:",e);}}}class h{constructor(e,t=1e3){this.storageKey="human_behavior_queue",this.maxQueueSize=t;}getQueue(){if("undefined"==typeof window||!window.localStorage)return [];try{const e=window.localStorage.getItem(this.storageKey);if(!e)return [];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){return a("Failed to read persisted queue:",e),[]}}setQueue(e){if("undefined"!=typeof window&&window.localStorage)try{const t=e.slice(-this.maxQueueSize);window.localStorage.setItem(this.storageKey,JSON.stringify(t)),l(`Persisted ${t.length} events to storage`);}catch(t){if("QuotaExceededError"===t.name||22===t.code){a("Storage quota exceeded, clearing old events");try{const t=e.slice(-Math.floor(this.maxQueueSize/2));window.localStorage.setItem(this.storageKey,JSON.stringify(t));}catch(e){a("Failed to save smaller queue, clearing storage"),this.clearQueue();}}else a("Failed to persist queue:",t);}}addToQueue(e){const t=this.getQueue();t.push(e),t.length>this.maxQueueSize&&(t.shift(),l("Queue is full, the oldest event is dropped.")),this.setQueue(t);}removeFromQueue(e){const t=this.getQueue();t.splice(0,e),this.setQueue(t);}clearQueue(){if("undefined"!=typeof window&&window.localStorage)try{window.localStorage.removeItem(this.storageKey);}catch(e){a("Failed to clear persisted queue:",e);}}getQueueLength(){return this.getQueue().length}}const u="0.5.69",m=1048576,p=52428.8;function g(e,t,s){return (new TextEncoder).encode(w({sessionId:s,events:[...e,t]})).length>m}function w(e){return JSON.stringify(e,(e,t)=>"bigint"==typeof t?t.toString():t)}function f(e,t){if(!e||"object"!=typeof e)return [];if((new TextEncoder).encode(w({sessionId:t,events:[e]})).length<=m)return [e];const s={...e},i=["screenshot","html","dom","fullText","innerHTML","outerHTML"];i.forEach(e=>{s[e]&&delete s[e];});if((new TextEncoder).encode(w({sessionId:t,events:[s]})).length<=m)return [s];return [{type:e.type,timestamp:e.timestamp,url:e.url,pathname:e.pathname,...Object.fromEntries(Object.entries(e).filter(([e,t])=>!i.includes(e)&&"object"!=typeof t&&"string"!=typeof t||"string"==typeof t&&t.length<1e3))}]}class y{constructor({apiKey:e,ingestionUrl:t}){this.monthlyLimitReached=false,this.sessionId="",this.endUserId=null,this.cspBlocked=false,this.requestTimeout=1e4,this.currentBatchSize=100,this.apiKey=e,this.baseUrl=t,this.persistence=new h(e),this.retryQueue=new c(e=>this._sendRequestInternal(e)),this._loadPersistedEvents();}setTrackingContext(e,t){this.sessionId=e,this.endUserId=t;}async _loadPersistedEvents(){const e=this.persistence.getQueue();if(0!==e.length){l(`Loading ${e.length} persisted events from storage`);for(const t of e)try{await this.sendEventsChunked(t.events,t.sessionId,t.endUserId||void 0,t.windowId,t.automaticProperties),this.persistence.removeFromQueue(1);}catch(e){a("Failed to send persisted event, will retry later:",e);}}}async _sendRequestInternal(e){const t="undefined"!=typeof AbortController?new AbortController:null;let s=null;t&&(s=setTimeout(()=>{t.abort();},this.requestTimeout));try{const i=e.estimatedSize||0,n="POST"===e.method&&i<p,r=await fetch(e.url,{method:e.method||"GET",headers:e.headers||{},body:e.body,signal:t?.signal,keepalive:n});s&&clearTimeout(s);const o=await r.text();let a=null;try{a=JSON.parse(o);}catch{}if(e.callback&&e.callback({statusCode:r.status,text:o,json:a}),!r.ok)throw {status:r.status,message:o}}catch(e){if(s&&clearTimeout(s),"AbortError"===e.name)throw {status:0,message:"Request timeout"};throw e}}unload(){this.retryQueue.unload();}checkMonthlyLimit(){return !this.monthlyLimitReached}async init(e,t){if(!this.checkMonthlyLimit())return {sessionId:e,endUserId:t};let s=null,i=null;"undefined"!=typeof window&&(s=window.location.href,i=document.referrer),d("API init called with:",{sessionId:e,userId:t,entryURL:s,referrer:i,baseUrl:this.baseUrl});try{const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/init`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Referer:i||""},body:w({sessionId:e,endUserId:t,entryURL:s,referrer:i,sdkVersion:u})});if(d("API init response status:",n.status),!n.ok){if(429===n.status)return this.monthlyLimitReached=!0,{sessionId:e,endUserId:t};const s=await n.text();throw o("API init failed:",n.status,s),new Error(`Failed to initialize ingestion: ${n.statusText} - ${s}`)}const r=await n.json();return !0===r.monthlyLimitReached&&(this.monthlyLimitReached=!0,d("Monthly limit reached detected from server response")),d("API init success:",r),{sessionId:r.sessionId,endUserId:r.endUserId}}catch(e){throw o("API init error:",e),e}}async sendEvents(e,t,s){const i=e.filter(e=>e&&"object"==typeof e),n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:t,events:i,endUserId:s,sdkVersion:u})});if(!n.ok){if(429===n.status)throw this.monthlyLimitReached=true,new Error("429: Monthly video processing limit reached");throw new Error(`Failed to send events: ${n.statusText}`)} true===(await n.json()).monthlyLimitReached&&(this.monthlyLimitReached=true,d("Monthly limit reached detected from events response"));}async sendEventsChunked(e,t,s,i,n){if(!this.checkMonthlyLimit())return [];try{const r=[];let o=[];for(const a of e)if(a&&"object"==typeof a)if(g(o,a,t)){if(o.length>0){l(`[SDK] Sending chunk with ${o.length} events`);const e=await this.trackedFetch(`${this.baseUrl}/api/ingestion/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:t,events:o,endUserId:s,windowId:i,automaticProperties:n,sdkVersion:u})});if(!e.ok){if(429===e.status)return this.monthlyLimitReached=!0,r.flat();throw new Error(`Failed to send events: ${e.statusText}`)}const a=await e.json();!0===a.monthlyLimitReached&&(this.monthlyLimitReached=!0,d("Monthly limit reached detected from chunked events response")),r.push(a),o=[];}o=f(a,t);}else o.push(a);if(o.length>0){const e=await this._sendChunkWithRetry(o,t,s,i,n||o[0]?.automaticProperties);e&&r.push(e);}return r.flat()}catch(r){throw o("Error sending events:",r),this._persistEvents(e,t,s,i,n),r}}async _sendChunkWithRetry(e,t,s,i,n){let r=Math.min(this.currentBatchSize,e.length),o=0;for(;o<e.length;){const l=w({sessionId:t,events:e.slice(o,o+r),endUserId:s,windowId:i,automaticProperties:n,sdkVersion:u}),c=(new TextEncoder).encode(l).length;try{const h=await this.trackedFetch(`${this.baseUrl}/api/ingestion/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:l},c);if(!h.ok){if(429===h.status)return this.monthlyLimitReached=!0,this._persistEvents(e.slice(o),t,s,i,n),null;if(413===h.status){a(`413 error: reducing batch size from ${r} to ${Math.max(1,Math.floor(r/2))}`),this.currentBatchSize=Math.max(1,Math.floor(r/2)),r=this.currentBatchSize;continue}return await this.retryQueue.retriableRequest({url:`${this.baseUrl}/api/ingestion/events`,method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:l,estimatedSize:c,callback:e=>{200===e.statusCode&&e.json&&!0===e.json.monthlyLimitReached&&(this.monthlyLimitReached=!0);}}),this._persistEvents(e.slice(o),t,s,i,n),null}const u=await h.json();if(!0===u.monthlyLimitReached&&(this.monthlyLimitReached=!0,d("Monthly limit reached detected from chunked events response")),o+=r,o>=e.length)return u}catch(r){return a("Network error sending chunk, adding to retry queue:",r),await this.retryQueue.retriableRequest({url:`${this.baseUrl}/api/ingestion/events`,method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:l,estimatedSize:c,callback:e=>{200===e.statusCode&&e.json&&true===e.json.monthlyLimitReached&&(this.monthlyLimitReached=true);}}),this._persistEvents(e.slice(o),t,s,i,n),null}}return null}_persistEvents(e,t,s,i,n){0!==e.length&&this.persistence.addToQueue({sessionId:t,events:e,endUserId:s,windowId:i,automaticProperties:n,timestamp:Date.now()});}async sendUserData(e,t,s){try{const i={userId:e,userAttributes:t,sessionId:s,posthogName:t.email||t.name||null};l("Sending user data to server:",i);const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/user`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w(i)});if(!n.ok)throw new Error(`Failed to send user data: ${n.statusText} with API key: ${this.apiKey}`);const r=await n.json();return l("Server response:",r),r}catch(e){throw o("Error sending user data:",e),e}}async sendUserAuth(e,t,s,i){try{const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/user/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({userId:e,userAttributes:t,sessionId:s,authFields:i})});if(!n.ok)throw new Error(`Failed to authenticate user: ${n.statusText} with API key: ${this.apiKey}`);return await n.json()}catch(e){throw o("Error authenticating user:",e),e}}sendBeaconEvents(e,t,s,i,n){const r={sessionId:t,events:e,endUserId:s||null,windowId:i,automaticProperties:n,sdkVersion:u,apiKey:this.apiKey},o=new Blob([w(r)],{type:"application/json"});return navigator.sendBeacon(`${this.baseUrl}/api/ingestion/events`,o)}async sendCustomEvent(e,t,s,i){d("[SDK] Sending custom event",{sessionId:e,eventName:t,eventProperties:s,endUserId:i});try{const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/customEvent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:e,eventName:t,eventProperties:s||{},endUserId:i||null})});if(d("[SDK] Custom event response",{status:n.status,statusText:n.statusText}),!n.ok){const e=await n.text();throw o("[SDK] Failed to send custom event",{status:n.status,statusText:n.statusText,errorText:e}),new Error(`Failed to send custom event: ${n.status} ${n.statusText} - ${e}`)}const r=await n.json();return l("[SDK] Custom event success",r),r}catch(i){throw o("[SDK] Error sending custom event",i,{sessionId:e,eventName:t,eventProperties:s}),i}}async sendCustomEventBatch(e,t,s){try{const i=await this.trackedFetch(`${this.baseUrl}/api/ingestion/customEvent/batch`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:e,events:t,endUserId:s||null})});if(!i.ok)throw new Error(`Failed to send custom event batch: ${i.statusText}`);return await i.json()}catch(e){throw o("Error sending custom event batch:",e),e}}async sendLog(e){try{if(l("[SDK] Sending log to server:",{level:e.level,message:e.message.substring(0,50),sessionId:e.sessionId}),!this.baseUrl)return;if(!e.sessionId)return;const t=await fetch(`${this.baseUrl}/api/ingestion/logs`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w(e)});t.ok?l("[SDK] Log sent successfully"):a("[SDK] Failed to send log to server:",t.status,t.statusText);}catch(e){a("[SDK] Failed to send log to server:",e);}}async sendNetworkError(e){try{if(l("[SDK] Sending network error to server:",{errorType:e.errorType,url:e.url.substring(0,50),sessionId:e.sessionId}),!this.baseUrl)return;if(!e.sessionId)return;const t=await fetch(`${this.baseUrl}/api/ingestion/network`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w(e)});t.ok?l("[SDK] Network error sent successfully"):a("[SDK] Failed to send network error to server:",t.status,t.statusText);}catch(e){a("[SDK] Failed to send network error to server:",e);}}async trackedFetch(e,s,i){const n=Date.now(),r=v1(),o=this.shouldSkipNetworkTracking(e);if(this.cspBlocked&&"POST"===s.method&&"undefined"!=typeof navigator&&"function"==typeof navigator.sendBeacon)return this.trackedFetchWithBeaconFallback(e,s,o);try{const t="undefined"!=typeof AbortController?new AbortController:null;let a=null;t&&(a=setTimeout(()=>{t.abort();},this.requestTimeout));const d="POST"===s.method&&void 0!==i&&i<p,l=await fetch(e,{...s,signal:t?.signal,keepalive:d});a&&clearTimeout(a);const c=Date.now()-n;return l.ok||o||await this.sendNetworkError({requestId:r,url:e,method:s.method||"GET",status:l.status,statusText:l.statusText,duration:c,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyHttpError(l.status),errorMessage:l.statusText,startTimeMs:n,spanName:`${s.method||"GET"} ${e}`,spanStatus:"error",attributes:{"http.status_code":l.status,"http.status_text":l.statusText}}).catch(()=>{}),l}catch(t){const i=Date.now()-n;if("AbortError"===t.name){const e=new Error("Request timeout");e.name="TimeoutError",t=e;}if(this.isCSPViolation(t)&&"POST"===s.method&&"undefined"!=typeof navigator&&"function"==typeof navigator.sendBeacon)return this.cspBlocked=true,a("[SDK] CSP violation detected, falling back to sendBeacon for future requests"),this.trackedFetchWithBeaconFallback(e,s,o);throw o||await this.sendNetworkError({requestId:r,url:e,method:s.method||"GET",status:null,statusText:null,duration:i,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyNetworkError(t),errorMessage:t.message,errorName:t.name,startTimeMs:n,spanName:`${s.method||"GET"} ${e}`,spanStatus:"error",attributes:{"error.name":t.name,"error.message":t.message}}).catch(()=>{}),t}}async trackedFetchWithBeaconFallback(e,t,s){try{let s=null,i="";if(t.body)if("string"==typeof t.body)try{s=JSON.parse(t.body),i=t.body;}catch{i=t.body;}else {if(t.body instanceof Blob){a("[SDK] Cannot extract apiKey from Blob body for sendBeacon, using URL param"),e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;return navigator.sendBeacon(e,t.body)?new Response(null,{status:200,statusText:"OK",headers:new Headers}):new Response(null,{status:500,statusText:"sendBeacon failed",headers:new Headers})}i=w(t.body),s=t.body;}if(e.includes("/api/ingestion/"))if(s&&"object"==typeof s)s.apiKey=this.apiKey,i=w(s);else if(i)try{const e=JSON.parse(i);e.apiKey=this.apiKey,i=w(e);}catch{e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;}else e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;else e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;const n=i?new Blob([i],{type:"application/json"}):null;return navigator.sendBeacon(e,n)?(l("[SDK] Successfully sent request via sendBeacon (CSP fallback)"),new Response(null,{status:200,statusText:"OK",headers:new Headers})):(a("[SDK] sendBeacon returned false - browser may be throttling"),new Response(null,{status:200,statusText:"OK (sendBeacon best-effort)",headers:new Headers}))}catch(e){return o("[SDK] sendBeacon fallback failed:",e),new Response(null,{status:500,statusText:"Failed to send via sendBeacon",headers:new Headers})}}isCSPViolation(e){const t=(e?.message||"").toLowerCase();return "typeerror"===(e?.name||"").toLowerCase()&&t.includes("failed to fetch")||t.includes("content security policy")||t.includes("csp")||t.includes("violates")||t.includes("refused to connect")&&t.includes("violates")}shouldSkipNetworkTracking(e){if(!e||!this.baseUrl)return false;try{const t=new URL(e),s=new URL(this.baseUrl);return !(t.origin!==s.origin||!t.pathname.startsWith("/api/ingestion/"))||!!e.includes(this.baseUrl)}catch(t){return e.includes(this.baseUrl)}}classifyHttpError(e){return e>=400&&e<500?"client_error":e>=500?"server_error":"unknown_error"}classifyNetworkError(e){const t=e.message||"",s=e.name||"";return this.isCSPViolation(e)?"csp_violation":t.includes("ERR_BLOCKED_BY_CLIENT")||t.includes("ERR_BLOCKED_BY_RESPONSE")||t.includes("blocked:other")||t.includes("net::ERR_BLOCKED_BY_CLIENT")||t.includes("net::ERR_BLOCKED_BY_RESPONSE")||"TypeError"===s&&t.includes("Failed to fetch")&&(t.includes("blocked")||t.includes("ERR_BLOCKED"))?"blocked_by_client":t.includes("CORS")||t.includes("Access-Control")?"cors_error":t.includes("timeout")||"TimeoutError"===s?"timeout_error":t.includes("Failed to fetch")||t.includes("NetworkError")?"network_error":"unknown_error"}}class v{constructor(e){if(this.redactedText="[REDACTED]",this.unredactedFields=new Set,this.redactedFields=new Set,this.redactionMode="privacy-first",this.excludeSelectors=['[data-no-redact="true"]',".human-behavior-no-redact"],e?.redactedText&&(this.redactedText=e.redactedText),e?.excludeSelectors&&(this.excludeSelectors=[...this.excludeSelectors,...e.excludeSelectors]),e?.redactionStrategy)if(this.redactionMode=e.redactionStrategy.mode,"privacy-first"===this.redactionMode)e.redactionStrategy.unredactFields&&this.setFieldsToUnredact(e.redactionStrategy.unredactFields);else {const t=['input[type="password"]','[data-hb-redact="true"]'],s=e.redactionStrategy.redactFields&&e.redactionStrategy.redactFields.length>0?e.redactionStrategy.redactFields:t;this.setFieldsToRedact(s);}e?.legacyRedactFields&&this.setFieldsToUnredact(e.legacyRedactFields),e?.userFields&&this.setFieldsToUnredact(e.userFields);}setFieldsToRedact(e){this.redactedFields.clear();['input[type="password"]','input[type="password" i]','[type="password"]','[type="password" i]',...e].forEach(e=>{this.redactedFields.add(e);}),this.redactedFields.size>0?l(`Redaction: Active for ${this.redactedFields.size} field(s):`,Array.from(this.redactedFields)):l("Redaction: No fields to redact"),this.applyRedactionClasses();}setFieldsToUnredact(e){this.unredactedFields.clear();const t=e.filter(e=>!this.isPasswordSelector(e)||(a(`Cannot unredact password field: ${e} - Password fields are always protected`),false));t.forEach(e=>this.unredactedFields.add(e)),t.length>0?l(`Unredaction: Active for ${t.length} field(s):`,t):l("Unredaction: No valid fields to unredact"),this.applyUnredactionClasses();}redactFields(e){e.forEach(e=>{this.unredactedFields.delete(e);}),this.unredactedFields.size>0?l(`Unredaction: Removed ${e.length} field(s), ${this.unredactedFields.size} remaining:`,Array.from(this.unredactedFields)):l("Unredaction: All fields redacted"),this.applyUnredactionClasses();}clearUnredactedFields(){this.unredactedFields.clear(),l("Unredaction: All fields cleared, everything redacted"),this.removeUnredactionClasses();}hasUnredactedFields(){return this.unredactedFields.size>0}getRedactionMode(){return this.redactionMode}getUnredactedFields(){return Array.from(this.unredactedFields)}getMaskTextSelector(){return "privacy-first"===this.redactionMode?0===this.unredactedFields.size?null:Array.from(this.unredactedFields).join(","):0===this.redactedFields.size?null:Array.from(this.redactedFields).join(",")}applyRedactionClasses(){0!==this.redactedFields.size&&("undefined"!=typeof document&&"loading"!==document.readyState?this.redactedFields.forEach(e=>{try{const t=document.querySelectorAll(e);t.forEach(e=>{e&&e.classList&&e.classList.add("rr-mask");}),l(`Added rr-mask class to ${t.length} element(s) for selector: ${e}`);}catch(t){a(`Invalid selector: ${e}`);}}):l("DOM not ready, deferring redaction class application"));}applyUnredactionClasses(){0!==this.unredactedFields.size&&("undefined"!=typeof document&&"loading"!==document.readyState?this.unredactedFields.forEach(e=>{try{const t=document.querySelectorAll(e);t.forEach(e=>{e&&e.classList&&e.classList.remove("rr-mask");}),l(`Removed rr-mask class from ${t.length} element(s) for selector: ${e}`);}catch(t){a(`Invalid selector: ${e}`);}}):l("DOM not ready, deferring unredaction class application"));}removeUnredactionClasses(){l("Unredaction classes removed");}isPasswordSelector(e){return ['input[type="password"]','input[type="password" i]','[type="password"]','[type="password" i]'].some(t=>e.toLowerCase().includes(t.toLowerCase().replace(/[\[\]]/g,"")))}getOriginalValue(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)return e.value}isElementUnredacted(e){return this.shouldUnredactElement(e)}shouldUnredactElement(e){if("privacy-first"===this.redactionMode){if(0===this.unredactedFields.size)return false;for(const t of this.unredactedFields)try{if(e.matches(t))return !0}catch(e){a(`Invalid selector: ${t}`);}return false}if(0===this.redactedFields.size)return true;for(const t of this.redactedFields)try{if(e.matches(t))return !1}catch(e){a(`Invalid selector: ${t}`);}return true}}new v;const _="undefined"!=typeof window;function S(){if(!_)return "unknown";const e=navigator.userAgent.toLowerCase(),t=window.screen.width,s=window.screen.height;return /mobile|android|iphone|ipad|ipod|blackberry|windows phone/i.test(e)?/ipad/i.test(e)||t>=768&&s>=1024?"tablet":"mobile":/windows|macintosh|linux/i.test(e)?"desktop":"unknown"}function k(e){try{return new URL(e).hostname}catch{return ""}}function I(){if(!_)return {device_type:"unknown",browser:"unknown",browser_version:"unknown",os:"unknown",os_version:"unknown",screen_resolution:"unknown",viewport_size:"unknown",color_depth:0,timezone:"unknown",language:"unknown",languages:[]};const{browser:e,browser_version:t}=function(){if(!_)return {browser:"unknown",browser_version:"unknown"};const e=navigator.userAgent;if(/chrome/i.test(e)&&!/edge/i.test(e)){const t=e.match(/chrome\/(\d+)/i);return {browser:"chrome",browser_version:t?t[1]:"unknown"}}if(/firefox/i.test(e)){const t=e.match(/firefox\/(\d+)/i);return {browser:"firefox",browser_version:t?t[1]:"unknown"}}if(/safari/i.test(e)&&!/chrome/i.test(e)){const t=e.match(/version\/(\d+)/i);return {browser:"safari",browser_version:t?t[1]:"unknown"}}if(/edge/i.test(e)){const t=e.match(/edge\/(\d+)/i);return {browser:"edge",browser_version:t?t[1]:"unknown"}}if(/msie|trident/i.test(e)){const t=e.match(/msie (\d+)/i)||e.match(/rv:(\d+)/i);return {browser:"ie",browser_version:t?t[1]:"unknown"}}return {browser:"unknown",browser_version:"unknown"}}(),{os:s,os_version:i}=function(){if(!_)return {os:"unknown",os_version:"unknown"};const e=navigator.userAgent;if(/windows/i.test(e)){const t=e.match(/windows nt (\d+\.\d+)/i);let s="unknown";if(t){const e=parseFloat(t[1]);s=10===e?"10":6.3===e?"8.1":6.2===e?"8":6.1===e?"7":t[1];}return {os:"windows",os_version:s}}if(/macintosh|mac os x/i.test(e)){const t=e.match(/mac os x (\d+[._]\d+)/i);return {os:"macos",os_version:t?t[1].replace("_","."):"unknown"}}if(/iphone|ipad|ipod/i.test(e)){const t=e.match(/os (\d+[._]\d+)/i);return {os:"ios",os_version:t?t[1].replace("_","."):"unknown"}}if(/android/i.test(e)){const t=e.match(/android (\d+\.\d+)/i);return {os:"android",os_version:t?t[1]:"unknown"}}return /linux/i.test(e)?{os:"linux",os_version:"unknown"}:{os:"unknown",os_version:"unknown"}}();return {device_type:S(),browser:e,browser_version:t,os:s,os_version:i,screen_resolution:`${window.screen.width}x${window.screen.height}`,viewport_size:`${window.innerWidth}x${window.innerHeight}`,color_depth:window.screen.colorDepth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,language:navigator.language,languages:[...navigator.languages||[navigator.language]],raw_user_agent:navigator.userAgent}}function b(){if(!_)return {current_url:"",pathname:"",search:"",hash:"",title:"",referrer:"",referrer_domain:"",initial_referrer:"",initial_referrer_domain:""};const e=window.location.href,t=document.referrer,s=function(e){const t=new URL(e),s={};return ["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(e=>{const i=t.searchParams.get(e);i&&(s[e]=i);}),s}(e);return {current_url:e,pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,title:document.title,referrer:t,referrer_domain:k(t),initial_referrer:t,initial_referrer_domain:k(t),initial_host:window.location.hostname,...s}}function T(){return {...I(),...b()}}function E(){if(!_)return {};const e=b();return {initial_referrer:e.initial_referrer,initial_referrer_domain:e.initial_referrer_domain,initial_url:e.current_url,initial_pathname:e.pathname,initial_utm_source:e.utm_source,initial_utm_medium:e.utm_medium,initial_utm_campaign:e.utm_campaign,initial_utm_term:e.utm_term,initial_utm_content:e.utm_content}}function C(){if(!_)return {};const e=b();return {current_url:e.current_url,pathname:e.pathname,search:e.search,hash:e.hash,title:e.title,referrer:e.referrer,referrer_domain:e.referrer_domain,utm_source:e.utm_source,utm_medium:e.utm_medium,utm_campaign:e.utm_campaign,utm_term:e.utm_term,utm_content:e.utm_content}}class U{constructor(e={}){this.sessionProperties={},this.userProperties={},this.initialProperties={},this.isInitialized=false,this.config={enableAutomaticProperties:true,enableSessionProperties:true,enableUserProperties:true,propertyDenylist:[],...e},this.automaticProperties=T(),this.initialize();}initialize(){this.isInitialized||(this.initialProperties=E(),this.loadSessionProperties(),this.isInitialized=true);}getEventProperties(e={}){const t={...e};return this.config.enableAutomaticProperties&&Object.assign(t,this.getAutomaticProperties()),this.config.enableSessionProperties&&Object.assign(t,this.sessionProperties),this.config.enableUserProperties&&Object.assign(t,this.userProperties),this.sessionProperties.$initial_properties_captured||(Object.assign(t,this.initialProperties),this.setSessionProperty("$initial_properties_captured",true)),this.applyDenylist(t),t}getAutomaticProperties(){return {...this.automaticProperties,...C()}}getAutomaticPropertiesWithGeoIP(e={}){return {...this.automaticProperties,...C(),...e}}setSessionProperty(e,t){this.sessionProperties[e]=t,this.saveSessionProperties();}setSessionProperties(e){Object.assign(this.sessionProperties,e),this.saveSessionProperties();}getSessionProperty(e){return this.sessionProperties[e]}removeSessionProperty(e){delete this.sessionProperties[e],this.saveSessionProperties();}setUserProperty(e,t){this.userProperties[e]=t;}setUserProperties(e){Object.assign(this.userProperties,e);}getUserProperty(e){return this.userProperties[e]}removeUserProperty(e){delete this.userProperties[e];}setOnce(e,t,s="user"){"session"===s?e in this.sessionProperties||this.setSessionProperty(e,t):e in this.userProperties||this.setUserProperty(e,t);}clearSessionProperties(){this.sessionProperties={},this.saveSessionProperties();}clearUserProperties(){this.userProperties={};}reset(){this.clearSessionProperties(),this.clearUserProperties(),this.initialProperties={},this.isInitialized=false,this.initialize();}loadSessionProperties(){if("undefined"!=typeof sessionStorage)try{const e=sessionStorage.getItem("hb_session_properties");e&&(this.sessionProperties=JSON.parse(e));}catch(e){console.warn("Failed to load session properties:",e);}}saveSessionProperties(){if("undefined"!=typeof sessionStorage)try{sessionStorage.setItem("hb_session_properties",JSON.stringify(this.sessionProperties));}catch(e){console.warn("Failed to save session properties:",e);}}applyDenylist(e){this.config.propertyDenylist&&0!==this.config.propertyDenylist.length&&this.config.propertyDenylist.forEach(t=>{delete e[t];});}updateAutomaticProperties(){this.automaticProperties=T();}getAllProperties(){return {automatic:this.getAutomaticProperties(),session:{...this.sessionProperties},user:{...this.userProperties},initial:{...this.initialProperties}}}}const P="undefined"!=typeof window;class F{get isTrackerStarted(){return this.isStarted}setupDomReadyHandler(){if(P)if("complete"===document.readyState||"interactive"===document.readyState)this.onDomReady();else if(document.addEventListener){document.addEventListener("DOMContentLoaded",()=>this.onDomReady(),{capture:false});const e=setInterval(()=>{"interactive"!==document.readyState&&"complete"!==document.readyState||(clearInterval(e),this.onDomReady());},10);setTimeout(()=>clearInterval(e),5e3);}else this.onDomReady();else this.onDomReady();}onDomReady(){this.isDomReady||(this.isDomReady=true,l("π― DOM is ready, processing queued requests"),this.requestQueue.forEach(e=>{this.processRequest(e);}),this.requestQueue=[],this.domReadyHandlers.forEach(e=>e()),this.domReadyHandlers=[]);}queueRequest(e){this.isDomReady?this.processRequest(e):this.requestQueue.push(e);}async processRequest(e){switch(l("Processing queued request:",e),e.type){case "addEvent":await this.addEvent(e.event);break;case "identifyUser":await this.identifyUser(e.userProperties);break;case "trackPageView":this.trackPageView();break;default:a("Unknown request type:",e.type);}}registerDomReadyHandler(e){this.isDomReady?e():this.domReadyHandlers.push(e);}static init(e,t){if(P&&false!==t?.suppressConsoleErrors){const e=console.error;console.error=(...t)=>{const s=t.join(" ");s.includes("SecurityError: Failed to execute 'toDataURL'")||s.includes("Tainted canvases may not be exported")||s.includes("Cannot inline img src=")||s.includes("Cross-Origin")||s.includes("CORS")||s.includes("Access-Control-Allow-Origin")||s.includes("Failed to load resource")||s.includes("net::ERR_BLOCKED_BY_CLIENT")||s.includes("NetworkError when attempting to fetch resource")||s.includes("Failed to fetch")||s.includes("TypeError: NetworkError")||s.includes("HumanBehavior ERROR")||s.includes("Failed to track custom event")||s.includes("Error sending custom event")||e.apply(console,t);};const t=console.warn;console.warn=(...e)=>{const s=e.join(" ");s.includes("Cannot inline img src=")||s.includes("Cross-Origin")||s.includes("CORS")||s.includes("Access-Control-Allow-Origin")||s.includes("Failed to load resource")||s.includes("net::ERR_BLOCKED_BY_CLIENT")||s.includes("NetworkError when attempting to fetch resource")||s.includes("Failed to fetch")||s.includes("Custom event network error")||s.includes("Request blocked by ad blocker")||t.apply(console,e);},window.addEventListener("error",e=>{const t=e.message||"";if(t.includes("SecurityError")||t.includes("Tainted canvases")||t.includes("toDataURL")||t.includes("Cross-Origin")||t.includes("CORS")||t.includes("NetworkError")||t.includes("Failed to fetch"))return e.preventDefault(),false});}if(P&&window.__humanBehaviorGlobalTracker)return l("Tracker already initialized, returning existing instance"),window.__humanBehaviorGlobalTracker;t?.logLevel&&this.configureLogging({level:t.logLevel});const s=new F(e,t?.ingestionUrl,{enableAutomaticProperties:t?.enableAutomaticProperties,propertyDenylist:t?.propertyDenylist,redactionStrategy:t?.redactionStrategy,redactFields:t?.redactFields,maxQueueSize:t?.maxQueueSize,enableConsoleTracking:t?.enableConsoleTracking,enableNetworkTracking:t?.enableNetworkTracking});return s.recordCanvas=t?.recordCanvas??false,t?.redactFields&&s.setUnredactedFields(t.redactFields),false!==t?.enableAutomaticTracking&&s.setupAutomaticTracking(t?.automaticTrackingOptions),s.start(),s}constructor(e,s,i){if(this.eventQueue=[],this.pendingCustomEvents=[],this.pendingLogs=[],this.pendingNetworkErrors=[],this._sessionActivityTimestamp=null,this._sessionStartTimestamp=null,this.userProperties={},this.isProcessing=false,this.flushInterval=null,this.FLUSH_INTERVAL_MS=3e3,this.endUserId=null,this.initialized=false,this.initializationPromise=null,this.monthlyLimitReached=false,this.isDomReady=false,this.requestQueue=[],this.domReadyHandlers=[],this.originalConsole=null,this.consoleTrackingEnabled=false,this.originalFetch=null,this.networkTrackingEnabled=false,this.enableConsoleTrackingFlag=true,this.enableNetworkTrackingFlag=true,this.navigationTrackingEnabled=false,this.currentUrl="",this.previousUrl="",this.originalPushState=null,this.originalReplaceState=null,this.navigationListeners=[],this._connectionBlocked=false,this.recordInstance=null,this.sessionStartTime=Date.now(),this.rrwebRecord=null,this.fullSnapshotTimeout=null,this.recordCanvas=false,this.isStarted=false,this.minimumDurationMilliseconds=5e3,this._isIdle="unknown",this._lastActivityTimestamp=Date.now(),this.IDLE_THRESHOLD_MS=3e5,this.rageClickTracker={clicks:[]},this.RAGE_CLICK_THRESHOLD_PX=30,this.RAGE_CLICK_TIMEOUT_MS=1e3,this.RAGE_CLICK_CLICK_COUNT=3,this.deadClickTracker={pendingClicks:new Map},this.DEAD_CLICK_SCROLL_THRESHOLD_MS=100,this.DEAD_CLICK_SELECTION_THRESHOLD_MS=100,this.DEAD_CLICK_MUTATION_THRESHOLD_MS=2e3,this.DEAD_CLICK_ABSOLUTE_TIMEOUT_MS=1400,!e)throw new Error("Human Behavior API Key is required");const n=s||"https://ingest.humanbehavior.co";if(this.api=new y({apiKey:e,ingestionUrl:n}),this.apiKey=e,this.ingestionUrl=n,this.MAX_QUEUE_SIZE=i?.maxQueueSize??1e3,this.enableConsoleTrackingFlag=false!==i?.enableConsoleTracking,this.enableNetworkTrackingFlag=false!==i?.enableNetworkTracking,this.redactionManager=new v({redactionStrategy:i?.redactionStrategy,legacyRedactFields:i?.redactFields}),this.propertyManager=new U({enableAutomaticProperties:false!==i?.enableAutomaticProperties,propertyDenylist:i?.propertyDenylist||[]}),P){const e="human_behavior_end_user_id",s=this.getCookie(e);this.endUserId=s||v1(),s?l(`Reusing existing endUserId: ${this.endUserId}`):(this.setCookie(e,this.endUserId,365),l(`Generated new endUserId: ${this.endUserId}`));}else this.endUserId=v1();if(P){const e=this.apiKey||"default";this._window_id_storage_key=`human_behavior_${e}_window_id`,this._primary_window_exists_storage_key=`human_behavior_${e}_primary_window_exists`,this.sessionId=this.getOrCreateSessionId(),this.windowId=this.getOrCreateWindowId(),this.currentUrl=window.location.href,window.__humanBehaviorGlobalTracker=this,this.setupWindowUnloadListener();}else this._window_id_storage_key="",this._primary_window_exists_storage_key="",this.sessionId=v1(),this.windowId=v1();this.api.setTrackingContext(this.sessionId,this.endUserId),this.initializationPromise=this.init().catch(e=>{o("Initialization failed:",e);});}async init(){try{P?(this.setupPageUnloadHandler(),this.setupNavigationTracking()):d("HumanBehaviorTracker initialized in server environment. Session tracking is disabled."),this.initialized=!0,d(`HumanBehaviorTracker initialized with sessionId: ${this.sessionId}, endUserId: ${this.endUserId}`);}catch(e){o("Failed to initialize HumanBehaviorTracker:",e),this.initialized=true;}}async ensureInitialized(){this.initializationPromise&&await this.initializationPromise;}setupNavigationTracking(){if(!P||this.navigationTrackingEnabled)return;this.navigationTrackingEnabled=true,l("Setting up navigation tracking"),this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState,history.pushState=(...e)=>{this.previousUrl=this.currentUrl,this.currentUrl=window.location.href,this.originalPushState.apply(history,e),this.trackNavigationEvent("pushState",this.previousUrl,this.currentUrl),this.takeFullSnapshot();},history.replaceState=(...e)=>{this.previousUrl=this.currentUrl,this.currentUrl=window.location.href,this.originalReplaceState.apply(history,e),this.trackNavigationEvent("replaceState",this.previousUrl,this.currentUrl),this.takeFullSnapshot();};const e=()=>{this.previousUrl=this.currentUrl,this.currentUrl=window.location.href,this.trackNavigationEvent("popstate",this.previousUrl,this.currentUrl),this.takeFullSnapshot();};window.addEventListener("popstate",e),this.navigationListeners.push(()=>{window.removeEventListener("popstate",e);});const t=()=>{this.previousUrl=this.currentUrl,this.currentUrl=window.location.href,this.trackNavigationEvent("hashchange",this.previousUrl,this.currentUrl);};window.addEventListener("hashchange",t),this.navigationListeners.push(()=>{window.removeEventListener("hashchange",t);}),this.trackNavigationEvent("pageLoad","",this.currentUrl);}async trackNavigationEvent(e,t,s){if(this.initialized)try{const i={type:e,from:t,to:s,timestamp:(new Date).toISOString(),pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,referrer:document.referrer};if(await this.addEvent({type:5,data:{payload:{eventType:"navigation",...i}},timestamp:Date.now()}),"pageLoad"===e||"pushState"===e||"replaceState"===e||"popstate"===e||"hashchange"===e){const s={url:window.location.href,fromUrl:t,navigationType:e,pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,referrer:document.referrer,timestamp:Date.now()};await this.customEvent("$page_viewed",s);}l(`Navigation tracked: ${e} from ${t} to ${s}`);}catch(e){o("Failed to track navigation event:",e);}}async trackPageView(e){if(this.initialized){this.propertyManager.updateAutomaticProperties();try{const t={url:e||window.location.href,pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,referrer:document.referrer,timestamp:(new Date).toISOString()},s=this.propertyManager.getEventProperties(t);await this.addEvent({type:5,data:{payload:{eventType:"pageview",...s}},timestamp:Date.now()}),l(`Pageview tracked: ${t.url}`);}catch(e){o("Failed to track pageview event:",e);}}}async customEvent(e,s){this.endUserId||(a(`endUserId not available, using anonymous ID for event: ${e}`),this.endUserId=v1()),P&&this.checkAndRefreshSession();const i=this.propertyManager.getEventProperties(s);if(this.shouldSkipDueToMinimumDuration())return l(`Custom event '${e}' queued due to session duration below minimum`),void this.pendingCustomEvents.push({eventName:e,properties:i,timestamp:Date.now()});await this.flushPendingCustomEvents();try{await this.api.sendCustomEvent(this.sessionId,e,i,this.endUserId),l(`Custom event tracked: ${e}`,i);}catch(t){o("Failed to track custom event:",t),t.message?.includes("500")||t.message?.includes("Internal Server Error")||t.message?.includes("Failed to send custom event")?a("Custom event endpoint failed, using fallback"):t.message?.includes("ERR_BLOCKED_BY_CLIENT")?a("Custom event request blocked by ad blocker, using fallback"):t.message?.includes("Failed to fetch")&&a("Custom event network error, using fallback");try{const t={eventName:e,properties:i||{},timestamp:(new Date).toISOString(),url:window.location.href,pathname:window.location.pathname};await this.addEvent({type:5,data:{payload:{eventType:"custom",...t}},timestamp:Date.now()}),l(`Custom event added to event stream as fallback: ${e}`);}catch(e){o("Failed to add custom event to event stream as fallback:",e);}}}setupAutomaticTracking(e){if(!P)return;const t={trackButtons:false!==e?.trackButtons,trackLinks:false,trackForms:false!==e?.trackForms,includeText:false!==e?.includeText,includeClasses:e?.includeClasses||false};l("Setting up automatic tracking with config:",t),t.trackButtons&&this.setupAutomaticButtonTracking(t),t.trackForms&&this.setupAutomaticFormTracking(t),this.setupRageClickDetection();}setupAutomaticButtonTracking(e){document.addEventListener("click",async t=>{const s=t.target;if("BUTTON"===s.tagName||s.closest("button")){const t="BUTTON"===s.tagName?s:s.closest("button"),i={buttonId:t.id||null,buttonType:t.type||"button",page:window.location.pathname,timestamp:Date.now()};e.includeText&&(i.buttonText=t.textContent?.trim()||null),e.includeClasses&&(i.buttonClass=t.className||null),Object.keys(i).forEach(e=>{null===i[e]&&delete i[e];}),await this.customEvent("$button_clicked",i);}});}setupRageClickDetection(){P&&document.addEventListener("click",async e=>{const t=e.target,s=e.clientX,i=e.clientY,n=Date.now();if(this.isRageClick(s,i,n,t)){const e=t.closest('button, a, [role="button"], [role="link"]')||t,r={x:s,y:i,page:window.location.pathname,element:e.tagName.toLowerCase(),clickCount:this.RAGE_CLICK_CLICK_COUNT,timestamp:n};e.id&&(r.elementId=e.id),e.className&&(r.elementClass=e.className),e.textContent&&(r.elementText=e.textContent.trim().substring(0,100)),Object.keys(r).forEach(e=>{null!==r[e]&&void 0!==r[e]||delete r[e];}),await this.customEvent("$rageclick",r),this.rageClickTracker.clicks=[];}});}isRageClick(e,t,s,i){const n=this.rageClickTracker.clicks,r=n[n.length-1];if(r&&Math.abs(e-r.x)+Math.abs(t-r.y)<this.RAGE_CLICK_THRESHOLD_PX&&s-r.timestamp<this.RAGE_CLICK_TIMEOUT_MS){if(n.push({x:e,y:t,timestamp:s,element:i}),n.length>=this.RAGE_CLICK_CLICK_COUNT)return true}else this.rageClickTracker.clicks=[{x:e,y:t,timestamp:s,element:i}];return false}isInteractiveElement(e){const t=e.tagName.toLowerCase();if("button"===t||"a"===t)return true;if(["input","select","textarea"].includes(t))return true;const s=e.getAttribute("role");if(s&&["button","link","tab","menuitem","checkbox","radio"].includes(s))return true;if(e.onclick||e.getAttribute("onclick"))return true;try{if("pointer"===window.getComputedStyle(e).cursor)return !0}catch(e){}return !!e.closest('button, a, [role="button"], [role="link"], [role="tab"], [role="menuitem"]')}setupAutomaticLinkTracking(e){}setupAutomaticFormTracking(e){document.addEventListener("submit",async t=>{const s=t.target,i=new FormData(s),n={formId:s.id||null,formAction:s.action||null,formMethod:s.method||"get",fields:Array.from(i.keys()),page:window.location.pathname,timestamp:Date.now()};e.includeClasses&&(n.formClass=s.className||null),Object.keys(n).forEach(e=>{null===n[e]&&delete n[e];}),await this.customEvent("$form_submitted",n);});}cleanupNavigationTracking(){this.navigationTrackingEnabled&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.navigationListeners.forEach(e=>e()),this.navigationListeners=[],this.navigationTrackingEnabled=false,l("Navigation tracking cleaned up"));}static logToStorage(e){d(e);}static configureLogging(e){i.setConfig({level:{none:0,error:1,warn:2,info:3,debug:4}[e.level||"error"],enableConsole:false!==e.enableConsole,enableStorage:e.enableStorage||false});}enableConsoleTracking(){P&&!this.consoleTrackingEnabled&&(this.originalConsole={log:console.log,warn:console.warn,error:console.error},console.log=(...e)=>{this.trackConsoleEvent("log",e),this.originalConsole.log(...e);},console.warn=(...e)=>{this.trackConsoleEvent("warn",e),this.originalConsole.warn(...e);},console.error=(...e)=>{this.trackConsoleEvent("error",e),this.originalConsole.error(...e);},this.consoleTrackingEnabled=true,l("Console tracking enabled"));}enableNetworkTracking(){P&&!this.networkTrackingEnabled&&"undefined"!=typeof fetch&&(this.originalFetch=window.fetch.bind(window),window.fetch=async(e,s)=>{const i=Date.now(),n=v1(),r="string"==typeof e?e:e instanceof URL?e.toString():e.url,o=(s?.method||("object"==typeof e&&"method"in e?e.method:void 0)||"GET").toUpperCase(),a=this.shouldSkipNetworkTracking(r),d=1e4;let c=null,h=false;a||(c=setTimeout(()=>{const e=Date.now()-i;if(!h){h=true;const t={requestId:n,url:r,method:o,status:null,statusText:null,duration:e,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:"long_loading",errorMessage:`Request took longer than 10000ms (${e}ms elapsed)`,startTimeMs:i,spanName:`${o} ${r}`,spanStatus:"slow",attributes:{"http.method":o,"http.url":r,"request.duration_ms":e,"request.long_loading_threshold_ms":d}};return this.shouldSkipDueToMinimumDuration()?(l("Long-loading network error queued due to session duration below minimum"),void this.pendingNetworkErrors.push({errorData:t,timestamp:Date.now()})):(this.flushPendingNetworkErrors(),void this.api.sendNetworkError(t).catch(()=>{}))}},d));try{const t=await this.originalFetch(e,s),d=Date.now()-i;if(c&&clearTimeout(c),!t.ok&&!a){const e={requestId:n,url:r,method:o,status:t.status,statusText:t.statusText,duration:d,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyHttpError(t.status),errorMessage:t.statusText,startTimeMs:i,spanName:`${o} ${r}`,spanStatus:"error",attributes:{"http.status_code":t.status,"http.status_text":t.statusText}};if(this.shouldSkipDueToMinimumDuration())return l("Failed request network error queued due to session duration below minimum"),this.pendingNetworkErrors.push({errorData:e,timestamp:Date.now()}),t;this.flushPendingNetworkErrors(),this.api.sendNetworkError(e).catch(()=>{});}return t}catch(e){const t=Date.now()-i;if(c&&clearTimeout(c),!a){const s={requestId:n,url:r,method:o,status:null,statusText:null,duration:t,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyNetworkError(e),errorMessage:e.message,errorName:e.name,startTimeMs:i,spanName:`${o} ${r}`,spanStatus:"error",attributes:{"error.name":e.name,"error.message":e.message}};if(this.shouldSkipDueToMinimumDuration())throw l("Network error queued due to session duration below minimum"),this.pendingNetworkErrors.push({errorData:s,timestamp:Date.now()}),e;this.flushPendingNetworkErrors(),this.api.sendNetworkError(s).catch(()=>{});}throw e}},this.networkTrackingEnabled=true,l("Network tracking enabled"));}async flushPendingCustomEvents(){if(0===this.pendingCustomEvents.length)return;const e=[...this.pendingCustomEvents];this.pendingCustomEvents=[],l(`Flushing ${e.length} pending custom events`);for(const{eventName:t,properties:s}of e)try{await this.api.sendCustomEvent(this.sessionId,t,s,this.endUserId);}catch(e){o("Failed to flush pending custom event:",e);}}async flushPendingLogs(){if(0===this.pendingLogs.length)return;const e=[...this.pendingLogs];this.pendingLogs=[],l(`Flushing ${e.length} pending logs`);for(const{logData:t}of e)try{await this.api.sendLog(t);}catch(e){o("Failed to flush pending log:",e);}}async flushPendingNetworkErrors(){if(0===this.pendingNetworkErrors.length)return;const e=[...this.pendingNetworkErrors];this.pendingNetworkErrors=[],l(`Flushing ${e.length} pending network errors`);for(const{errorData:t}of e)try{await this.api.sendNetworkError(t);}catch(e){o("Failed to flush pending network error:",e);}}enablePageLoadTracking(){P&&"undefined"!=typeof window&&("complete"===document.readyState?this.trackPageLoad():window.addEventListener("load",()=>{this.trackPageLoad();}),l("Page load tracking enabled"));}trackPageLoad(){if(P&&"undefined"!=typeof performance)try{const e=performance.getEntriesByType("navigation")[0];if(!e)return;const s=e.loadEventEnd-e.fetchStart;if(s>3e3){const i=v1(),n=e.domContentLoadedEventEnd-e.fetchStart,r=e.domComplete-e.fetchStart,o={requestId:i,url:window.location.href,method:"GET",status:200,statusText:"OK",duration:s,timestampMs:e.loadEventEnd+performance.timeOrigin,sessionId:this.sessionId,endUserId:this.endUserId,errorType:"slow_page_load",errorMessage:`Page load took ${s}ms`,startTimeMs:e.fetchStart+performance.timeOrigin,spanName:"page_load",spanStatus:"slow",attributes:{"page.url":window.location.href,"page.load_time":s,"page.dom_content_loaded":n,"page.dom_complete":r}};if(this.shouldSkipDueToMinimumDuration())return l("Slow page load network error queued due to session duration below minimum"),void this.pendingNetworkErrors.push({errorData:o,timestamp:Date.now()});this.flushPendingNetworkErrors(),this.api.sendNetworkError(o).catch(()=>{});}}catch(e){a("Failed to track page load:",e);}}shouldSkipNetworkTracking(e){if(!e||!this.ingestionUrl)return false;try{const t=new URL(e),s=new URL(this.ingestionUrl);return !(t.origin!==s.origin||!t.pathname.startsWith("/api/ingestion/"))||!!e.includes(this.ingestionUrl)}catch(t){return e.includes(this.ingestionUrl)}}classifyHttpError(e){return e>=400&&e<500?"client_error":e>=500?"server_error":"unknown_error"}classifyNetworkError(e){const t=e.message||"",s=e.name||"";return t.includes("blocked")||t.includes("ERR_BLOCKED_BY_CLIENT")||t.includes("net::ERR_BLOCKED_BY_CLIENT")||"TypeError"===s&&t.includes("Failed to fetch")?"blocked_by_client":t.includes("CORS")||t.includes("Cross-Origin")||t.includes("Access-Control-Allow-Origin")||"TypeError"===s&&t.includes("CORS")?"cors_error":t.includes("timeout")||t.includes("TIMEOUT")||t.includes("NetworkError")||"NetworkError"===s?"network_error":t.includes("abort")||"AbortError"===s?"aborted":"unknown_error"}disableConsoleTracking(){P&&this.consoleTrackingEnabled&&(this.originalConsole&&(console.log=this.originalConsole.log,console.warn=this.originalConsole.warn,console.error=this.originalConsole.error),this.consoleTrackingEnabled=false,l("Console tracking disabled"));}trackConsoleEvent(e,t){if(this.initialized)if("log"!==e)try{if(r())return void(this.originalConsole&&this.originalConsole[e](...t));const s=(new Error).stack||"";if(this.isSDKStackFrame(s))return void(this.originalConsole&&this.originalConsole[e](...t));const i={level:e,message:t.map(e=>"object"==typeof e?JSON.stringify(e):String(e)).join(" "),timestampMs:Date.now(),url:P?window.location.href:"",userAgent:P?navigator.userAgent:"",stack:s,sessionId:this.sessionId,endUserId:this.endUserId};if(this.shouldSkipDueToMinimumDuration())return l(`Console ${e} queued due to session duration below minimum`),void this.pendingLogs.push({logData:i,timestamp:Date.now()});this.flushPendingLogs(),this.api.sendLog(i).catch(e=>{this.addEvent({type:5,data:{payload:{eventType:"console",...i}},timestamp:Date.now()}).catch(()=>{});});}catch(e){o("Error in trackConsoleEvent:",e);}else this.originalConsole&&this.originalConsole.log(...t);}isSDKStackFrame(e){if(!e)return false;const t=["humanbehavior-js","@humanbehavior/core","@humanbehavior/browser","tracker.ts","api.ts","logger.ts","utils/logger","packages/core","packages/browser","index.mjs","index.js"],s=e.split("\n");e.toLowerCase();let i=false;for(let e=0;e<s.length;e++){const n=s[e].trim().toLowerCase();if(!n||"error"===n||n.startsWith("error:"))continue;if(!t.some(e=>n.includes(e.toLowerCase()))){i=true;break}}return !i}setupPageUnloadHandler(){if(!P)return;l("Setting up page unload handler"),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState?(l("Page hidden - sending pending events"),this.flushEvents()):"visible"===document.visibilityState&&(l("Page visible - taking full snapshot for multi-window replay"),this.takeFullSnapshot());});const e="onpagehide"in window?"pagehide":"beforeunload";window.addEventListener(e,()=>{l("Page unloading - sending final events via sendBeacon");const e=this.minimumDurationMilliseconds,t=this.getSessionDuration();if(null!==t&&t>=0&&t<e)return void l(`Session duration (${t}ms) below minimum (${e}ms), not sending on unload`);const s=[...this.eventQueue];if(P&&window.__hb_pending_snapshots){const e=window.__hb_pending_snapshots;Array.isArray(e)&&e.length>0&&(l("Including pending FullSnapshot(s) in sendBeacon for short session"),s.unshift(...e),delete window.__hb_pending_snapshots);}if(s.length>0&&this.api)try{const e=this.propertyManager.getAutomaticProperties();this.api.sendBeaconEvents(s,this.sessionId,this.endUserId||void 0,this.windowId,e),this.eventQueue=[];}catch(e){a("Failed to send events via sendBeacon on unload:",e);}this.api&&this.api.unload();});const t=()=>{localStorage.setItem("human_behavior_last_activity",Date.now().toString());};window.addEventListener("click",t),window.addEventListener("keydown",t),window.addEventListener("scroll",t),window.addEventListener("mousemove",t);}viewLogs(){try{const e=i.getLogs();d("HumanBehavior Logs:",e),i.clearLogs();}catch(e){o("Failed to read logs:",e);}}async identifyUser({userProperties:e}){const t=this.endUserId;this.userProperties=e,l("Identifying user:",{userProperties:e,originalEndUserId:t,sessionId:this.sessionId}),!P||this.propertyManager.getAutomaticProperties();const s=await this.api.sendUserData(t||"",e,this.sessionId);if(s.actualUserId||s.wasExistingUser){const e=s.actualUserId||t;if(e&&e!==t){const s="human_behavior_end_user_id";if(this.setCookie(s,e,365),P)try{localStorage.setItem(s,e);}catch(e){l("Failed to set canonical endUserId in localStorage:",e);}l(`π Preexisting user detected. Future sessions will use canonical ID: ${e} (current session stays: ${t})`);}}return t||""}getUserAttributes(){return {...this.userProperties}}async start(){if(!P)return;if(this.isStarted)return void l("HumanBehaviorTracker already started, skipping start() call.");this.isStarted=true,this._lastActivityTimestamp=null!==this._sessionActivityTimestamp?this._sessionActivityTimestamp:Date.now(),this._isIdle="unknown",this.flushInterval=window.setInterval(()=>{this.flushEvents();},this.FLUSH_INTERVAL_MS),this.enableConsoleTrackingFlag&&this.enableConsoleTracking(),this.enableNetworkTrackingFlag&&this.enableNetworkTracking(),this.enablePageLoadTracking();const t=()=>{if(this.recordInstance)return void l("π― Recording already started, skipping duplicate start");l("π― DOM ready, starting session recording"),this.rrwebRecord=record;const t=record({emit:e=>{this.addRecordingEvent(e),2===e.type&&l(`π― FullSnapshot generated at ${(new Date).toISOString()}`);},maskTextSelector:this.redactionManager.getMaskTextSelector()||void 0,maskTextFn:void 0,maskAllInputs:"privacy-first"===this.redactionManager.getRedactionMode(),maskInputOptions:{password:true,text:true,textarea:true,email:true,number:true,tel:true,url:true,search:true,date:true,time:true,month:true,week:true},maskInputFn:(e,t)=>{try{const s=this.redactionManager.getRedactionMode();if(!(t instanceof HTMLElement))return e;if("privacy-first"===s)return "*".repeat(e.length||1);const i=this.redactionManager.shouldUnredactElement(t);t.id,t.name,t.type;return i?e:"*".repeat(e.length||1)}catch{return e}},slimDOMOptions:{},collectFonts:false,inlineStylesheet:true,recordCrossOriginIframes:false,recordCanvas:this.recordCanvas,sampling:this.recordCanvas?{canvas:4}:void 0,dataURLOptions:this.recordCanvas?{type:"image/webp",quality:.4}:void 0,hooks:{input:e=>{try{if("privacy-first"===this.redactionManager.getRedactionMode())return;const t="undefined"!=typeof document?document.querySelector(`[data-rrweb-id="${e.id}"]`):null;if(t&&t instanceof HTMLElement){this.redactionManager.shouldUnredactElement(t)||(void 0!==e.text&&(e.text="*".repeat(e.text?.length||1)),void 0!==e.value&&(e.value="*".repeat(e.value?.length||1)));}}catch{}}}});this.recordInstance=t||null;};if(l(`π― DOM ready state: ${document.readyState}`),"complete"===document.readyState||"interactive"===document.readyState)l(`π― DOM ready (${document.readyState}), starting recording immediately`),t();else {l("π― DOM not ready, waiting for DOMContentLoaded event");const e=()=>("interactive"===document.readyState||"complete"===document.readyState)&&(l(`π― DOM ready (${document.readyState}), starting recording`),t(),true);if(e())return;document.addEventListener("DOMContentLoaded",()=>{l("π― DOMContentLoaded fired, starting recording"),t();},{once:true});const s=setInterval(()=>{e()&&clearInterval(s);},10);setTimeout(()=>clearInterval(s),5e3);}}takeFullSnapshot(){this.fullSnapshotTimeout&&clearTimeout(this.fullSnapshotTimeout),this.fullSnapshotTimeout=window.setTimeout(()=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{try{this.rrwebRecord&&"function"==typeof this.rrwebRecord.takeFullSnapshot?(this.rrwebRecord.takeFullSnapshot(),l("β
FullSnapshot taken (delayed for animations)")):a("β οΈ takeFullSnapshot not available on record function");}catch(e){o("β Failed to take FullSnapshot:",e);}});});},1e3);}async stop(){await this.ensureInitialized(),P&&(this.flushInterval&&(clearInterval(this.flushInterval),this.flushInterval=null),this.recordInstance&&(this.recordInstance(),this.recordInstance=null),this.fullSnapshotTimeout&&(clearTimeout(this.fullSnapshotTimeout),this.fullSnapshotTimeout=null),this.rrwebRecord=null,this.disableConsoleTracking(),this.cleanupNavigationTracking());}async addEvent(e){if(P&&this.checkAndRefreshSession(),e&&"object"==typeof e){if(2===e.type){const t=!!e.data,s=!(!e.data||!e.data.node);l(t&&s?`β
Valid FullSnapshot: hasData=${t}, hasNode=${s}, dataType=${e.data?.node?.type}`:`β οΈ Empty FullSnapshot detected: hasData=${t}, hasNode=${s} - continuing session`);}this.eventQueue.length>=this.MAX_QUEUE_SIZE&&(this.eventQueue.shift(),l("Queue is full, the oldest event is dropped.")),this.eventQueue.push(e),2===e.type?(l("FullSnapshot added, triggering immediate flush"),this.flushEvents()):this.eventQueue.length>=.8*this.MAX_QUEUE_SIZE&&(l(`Queue at ${this.eventQueue.length}/${this.MAX_QUEUE_SIZE}, triggering immediate flush`),this.flushEvents());}else l("β οΈ Skipping invalid event:",e);}getSessionDuration(){const e=this._sessionStartTimestamp??this.sessionStartTime;if(!e)return null;const t=this.eventQueue.filter(e=>e&&e.timestamp);if(0===t.length)return null;const s=t.reduce((e,t)=>!e||t.timestamp&&t.timestamp>e.timestamp?t:e,null);if(!s||!s.timestamp)return null;const i=s.timestamp-e;return i>=0?i:null}shouldSkipDueToMinimumDuration(){const e=this.minimumDurationMilliseconds,t=this.getSessionDuration();return !!(null!==t&&t>=0&&t<e)&&(l(`Session duration (${t}ms) below minimum (${e}ms), skipping send`),true)}async flushEvents(){if(this.isProcessing)return;if(this.monthlyLimitReached)return;if(true===this._isIdle&&0===this.eventQueue.length)return;const e=this.minimumDurationMilliseconds,t=this.getSessionDuration();if(null!==t&&t>=0&&t<e)return l(`Session duration (${t}ms) below minimum (${e}ms), buffering`),void setTimeout(()=>{this.flushEvents();},2e3);this.isProcessing=true;try{const e=this.eventQueue,t=e.filter(e=>e&&2===e.type);if(this.eventQueue=[],t.length>0&&P&&(window.__hb_pending_snapshots=t,setTimeout(()=>{delete window.__hb_pending_snapshots;},5e3)),e.length>0){l("Flushing events:",e);const t=e.filter(e=>2===e.type);t.length>0&&l(`[FIXED] Sending ${t.length} FullSnapshot(s) with valid data`);try{const t=this.propertyManager.getAutomaticProperties();await this.api.sendEventsChunked(e,this.sessionId,this.endUserId,this.windowId,t);}catch(e){if(e.message?.includes("ERROR: Session already completed"))a("Session expired, events will be lost");else if(e.message?.includes("413")||e.message?.includes("Content Too Large"))a("Payload too large, events will be lost");else {if(!(e.message?.includes("ERR_BLOCKED_BY_CLIENT")||e.message?.includes("Failed to fetch")||e.message?.includes("NetworkError")))throw e;a("Request blocked by ad blocker or network issue, events will be lost");}}}await this.flushPendingCustomEvents(),await this.flushPendingLogs(),await this.flushPendingNetworkErrors();}finally{this.isProcessing=false;}}isInteractiveEvent(e){if(3!==e.type)return false;const t=e.data?.source;return [1,2,3,4,5,6,11].includes(t)}updateIdleState(e){const t=this.isInteractiveEvent(e),s=e.timestamp||Date.now();if(t){const e=true===this._isIdle;this._lastActivityTimestamp=s,null!==this._sessionActivityTimestamp&&(this._sessionActivityTimestamp=s),e?(l("β
User activity detected, exiting idle state"),this._isIdle=false,this.rrwebRecord&&"function"==typeof this.rrwebRecord.takeFullSnapshot&&(this.rrwebRecord.takeFullSnapshot(),l("β
FullSnapshot taken after returning from idle"))):"unknown"===this._isIdle&&(this._isIdle=false);}else if(true!==this._isIdle){const e=s-this._lastActivityTimestamp;e>this.IDLE_THRESHOLD_MS&&(l(`βΈοΈ Session idle detected (${Math.round(e/1e3)}s since last activity) - stopping background event recording`),l(`βΉοΈ Session will expire after 15 minutes of inactivity (${Math.round((9e5-e)/1e3)}s remaining)`),this._isIdle=true,this.flushEvents());}}async addRecordingEvent(e){if(P&&this.checkAndRefreshSession(),e&&"object"==typeof e){if(this.updateIdleState(e),true!==this._isIdle||3!==e.type||this.isInteractiveEvent(e)){if(2===e.type){const t=!!e.data,s=!(!e.data||!e.data.node);l(t&&s?`β
Valid FullSnapshot: hasData=${t}, hasNode=${s}, dataType=${e.data?.node?.type}`:`β οΈ Empty FullSnapshot detected: hasData=${t}, hasNode=${s} - continuing session`);}this.eventQueue.length>=this.MAX_QUEUE_SIZE&&(this.eventQueue.shift(),l("Queue is full, the oldest event is dropped.")),this.eventQueue.push(e),2===e.type?(l("FullSnapshot added, triggering immediate flush"),this.flushEvents()):true!==this._isIdle&&this.eventQueue.length>=.8*this.MAX_QUEUE_SIZE&&(l(`Queue at ${this.eventQueue.length}/${this.MAX_QUEUE_SIZE}, triggering immediate flush`),this.flushEvents());}}else l("β οΈ Skipping invalid recording event:",e);}_canUseSessionStorage(){if(!P)return false;try{const e="__sessionStorage_test__";return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch{return false}}_getWindowIdFromStorage(){if(!this._canUseSessionStorage())return null;try{return sessionStorage.getItem(this._window_id_storage_key)}catch{return null}}_setWindowIdInStorage(e){if(this._canUseSessionStorage())try{sessionStorage.setItem(this._window_id_storage_key,e),l(`Stored windowId in sessionStorage: ${e}`);}catch(e){a("Failed to store windowId in sessionStorage:",e);}}_removeWindowIdFromStorage(){if(this._canUseSessionStorage())try{sessionStorage.removeItem(this._window_id_storage_key);}catch(e){a("Failed to remove windowId from sessionStorage:",e);}}_getPrimaryWindowExists(){if(!this._canUseSessionStorage())return false;try{return "true"===sessionStorage.getItem(this._primary_window_exists_storage_key)}catch{return false}}_setPrimaryWindowExists(e){if(this._canUseSessionStorage())try{e?sessionStorage.setItem(this._primary_window_exists_storage_key,"true"):sessionStorage.removeItem(this._primary_window_exists_storage_key);}catch(e){a("Failed to set primary_window_exists flag:",e);}}getOrCreateWindowId(){if(!P)return v1();const e=this._getWindowIdFromStorage(),s=this._getPrimaryWindowExists();if(e&&!s)return l(`Reusing windowId from previous page load: ${e}`),this._setWindowIdInStorage(e),this._setPrimaryWindowExists(true),e;{const e=v1();return l(`Creating new windowId: ${e} (new window/tab detected)`),this._setWindowIdInStorage(e),this._setPrimaryWindowExists(true),e}}setupWindowUnloadListener(){P&&window.addEventListener("beforeunload",()=>{this._canUseSessionStorage()&&(this._setPrimaryWindowExists(false),l("Cleared primary_window_exists flag on beforeunload"));},{capture:false});}setCookie(e,t,s){if(P)try{const i=new Date;i.setTime(i.getTime()+24*s*60*60*1e3);const n=`expires=${i.toUTCString()}`;document.cookie=`${e}=${t};${n};path=/;SameSite=Lax`,localStorage.setItem(e,t),l(`Set cookie and localStorage: ${e}`);}catch(s){try{localStorage.setItem(e,t),l(`Cookie blocked, using localStorage: ${e}`);}catch(e){o("Failed to store user ID in both cookie and localStorage:",e);}}}getCookie(e){if(!P)return null;try{const t=e+"=",s=document.cookie.split(";");for(let i=0;i<s.length;i++){let n=s[i];for(;" "===n.charAt(0);)n=n.substring(1,n.length);if(0===n.indexOf(t)){const s=n.substring(t.length,n.length);return l(`Found cookie: ${e}`),s}}const i=localStorage.getItem(e);return i?(l(`Cookie not found, using localStorage: ${e}`),i):null}catch(t){try{const t=localStorage.getItem(e);if(t)return l(`Cookie access failed, using localStorage: ${e}`),t}catch(e){o("Failed to access both cookie and localStorage:",e);}return null}}deleteCookie(e){if(P){try{document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=Lax`,l(`Deleted cookie: ${e}`);}catch(t){o(`Failed to delete cookie: ${e}`,t);}try{localStorage.removeItem(e),l(`Removed from localStorage: ${e}`);}catch(t){o(`Failed to remove from localStorage: ${e}`,t);}}}logout(){if(P)try{const e="human_behavior_end_user_id";this.deleteCookie(e);const s="human_behavior_session";localStorage.removeItem(s),this.endUserId=null,this.userProperties={},this.endUserId=v1(),this.setCookie("human_behavior_end_user_id",this.endUserId,365),this.sessionId=this.createNewSession(s),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),d("User logged out - cleared all user data and started fresh session");}catch(e){o("Error during logout:",e);}}async redact(e){await this.ensureInitialized(),P?this.redactionManager=new v(e):a("Redaction is only available in browser environments");}setRedactedFields(e){this.redactionManager.setFieldsToRedact(e),this.recordInstance&&this.restartWithNewRedaction();}setUnredactedFields(e){this.redactionManager.setFieldsToUnredact(e),this.recordInstance&&this.restartWithNewRedaction();}restartWithNewRedaction(){this.recordInstance&&(this.recordInstance(),this.start());}hasUnredactedFields(){return this.redactionManager.hasUnredactedFields()}getUnredactedFields(){return this.redactionManager.getUnredactedFields()}redactFields(e){this.redactionManager.redactFields(e),this.recordInstance&&this.restartWithNewRedaction();}clearUnredactedFields(){this.redactionManager.clearUnredactedFields(),this.recordInstance&&this.restartWithNewRedaction();}checkAndRefreshSession(){if(!P)return;const e="human_behavior_session",s=Date.now(),i=this.getStoredSession(e);if(!i||!i.sessionId)return this.createNewSession(e),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),void l(`Created new session (no stored session): ${this.sessionId}`);this.updateSessionActivity(e,s,i.sessionId,i.sessionStartTimestamp);}getOrCreateSessionId(){if(!P)return v1();const e="human_behavior_session",s=Date.now(),i=this.getStoredSession(e);if(!i||!i.sessionId){const t=this.createNewSession(e);return this.api.setTrackingContext(t,this.endUserId),t}const n=s-i.lastActivityTimestamp,r=s-i.sessionStartTimestamp;if(n>9e5||r>864e5){l(`Session expired: idle=${n}ms, age=${r}ms`);const t=this.createNewSession(e);return this.api.setTrackingContext(t,this.endUserId),t}return this.updateSessionActivity(e,s,i.sessionId,i.sessionStartTimestamp),i.sessionId}getStoredSession(e){const s=Date.now(),i=9e5,n=864e5;if(this.sessionId&&null!==this._sessionActivityTimestamp&&null!==this._sessionStartTimestamp){const r=s-this._sessionActivityTimestamp,o=s-this._sessionStartTimestamp;if(!(r>i||o>n))return {sessionId:this.sessionId,lastActivityTimestamp:this._sessionActivityTimestamp,sessionStartTimestamp:this._sessionStartTimestamp};{l("Session in memory expired: creating new session immediately");const s=this.sessionId;if(this.createNewSession(e),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),d(`π Session timeout (memory): Created new session ${this.sessionId} (previous: ${s})`),null!==this._sessionActivityTimestamp&&null!==this._sessionStartTimestamp)return {sessionId:this.sessionId,lastActivityTimestamp:this._sessionActivityTimestamp,sessionStartTimestamp:this._sessionStartTimestamp}}}try{const r=localStorage.getItem(e);if(!r)return null;const o=JSON.parse(r),a=s-o.lastActivityTimestamp,c=s-o.sessionStartTimestamp;if(a>i||c>n){l(`Session in localStorage expired: idle=${Math.round(a/1e3/60)}min, age=${Math.round(c/1e3/60/60)}hrs`);const s=o.sessionId;if(this.createNewSession(e),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),d(`π Session timeout (localStorage): Created new session ${this.sessionId} (previous: ${s})`),null!==this._sessionActivityTimestamp&&null!==this._sessionStartTimestamp)return {sessionId:this.sessionId,lastActivityTimestamp:this._sessionActivityTimestamp,sessionStartTimestamp:this._sessionStartTimestamp}}return o.sessionId&&(this.sessionId=o.sessionId,this._sessionActivityTimestamp=o.lastActivityTimestamp,this._sessionStartTimestamp=o.sessionStartTimestamp),o}catch{return null}}createNewSession(e){const s=v1(),i=Date.now();this.sessionId=s,this._sessionActivityTimestamp=i,this._sessionStartTimestamp=i,this._lastActivityTimestamp=i;const n={sessionId:s,lastActivityTimestamp:i,sessionStartTimestamp:i};try{localStorage.setItem(e,JSON.stringify(n));}catch(e){a(`Failed to save session to localStorage: ${e}`);}return l(`Created new session: ${s}`),s}updateSessionActivity(e,t,s,i){this.sessionId=s,this._sessionActivityTimestamp=t,this._sessionStartTimestamp=i;const n={sessionId:s,lastActivityTimestamp:t,sessionStartTimestamp:i};try{localStorage.setItem(e,JSON.stringify(n));}catch(e){a(`Failed to update session in localStorage: ${e}`);}}getSessionId(){return this.sessionId}getCurrentUrl(){return this.currentUrl}getSnapshotFrequencyInfo(){return {sessionDuration:Date.now()-this.sessionStartTime,currentInterval:3e5,currentThreshold:1e3,phase:"configured"}}async testConnection(){try{return await this.api.init(this.sessionId,this.endUserId),{success:!0}}catch(e){return {success:false,error:e.message||"Unknown error"}}}getConnectionStatus(){const e=[];let t=false;return this.eventQueue.length>0&&(t=true,e.push("Some requests may be blocked by ad blockers")),this._connectionBlocked&&(t=true,e.push("Initial connection test failed - ad blocker may be active")),"undefined"==typeof window&&e.push("Not running in browser environment"),void 0===navigator.sendBeacon&&e.push("sendBeacon not available, using fetch fallback"),{blocked:t,recommendations:e}}isPreexistingUser(){if(!P)return false;const e=this.getCookie("human_behavior_end_user_id");return null!==e&&e!==this.endUserId}getUserInfo(){return {endUserId:this.endUserId,sessionId:this.sessionId,isPreexistingUser:this.isPreexistingUser(),initialized:this.initialized}}setSessionProperty(e,t){this.propertyManager.setSessionProperty(e,t);}setSessionProperties(e){this.propertyManager.setSessionProperties(e);}getSessionProperty(e){return this.propertyManager.getSessionProperty(e)}removeSessionProperty(e){this.propertyManager.removeSessionProperty(e);}setUserProperty(e,t){this.propertyManager.setUserProperty(e,t);}setUserProperties(e){this.propertyManager.setUserProperties(e);}getUserProperty(e){return this.propertyManager.getUserProperty(e)}removeUserProperty(e){this.propertyManager.removeUserProperty(e);}setOnce(e,t,s="user"){this.propertyManager.setOnce(e,t,s);}clearSessionProperties(){this.propertyManager.clearSessionProperties();}clearUserProperties(){this.propertyManager.clearUserProperties();}getAllProperties(){return this.propertyManager.getAllProperties()}}function R(e){const t=globalThis.__humanBehaviorGlobalTracker;return t?.identifyUser?t.identifyUser({userProperties:e}):(console.warn("HumanBehavior tracker not found. Make sure the SDK is initialized."),null)}function D(e,t){const s=globalThis.__humanBehaviorGlobalTracker;return s?.track?s.track(e,t):(console.warn("HumanBehavior tracker not found. Make sure the SDK is initialized."),null)}function L(){const e=globalThis.__humanBehaviorGlobalTracker;return !!e?.identifyUser}P&&(window.HumanBehaviorTracker=F);
|
|
12372
|
+
var s;!function(e){e[e.NONE=0]="NONE",e[e.ERROR=1]="ERROR",e[e.WARN=2]="WARN",e[e.INFO=3]="INFO",e[e.DEBUG=4]="DEBUG";}(s||(s={}));const i=new class{constructor(e){this.config={level:s.ERROR,enableConsole:true,enableStorage:false},this.isBrowser="undefined"!=typeof window,e&&(this.config={...this.config,...e});}setConfig(e){this.config={...this.config,...e};}shouldLog(e){return e<=this.config.level}formatMessage(e,t,...s){return `[HumanBehavior ${e}] ${(new Date).toISOString()}: ${t}`}error(e,...t){if(!this.shouldLog(s.ERROR))return;const i=this.formatMessage("ERROR",e);this.config.enableConsole&&console.error(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}warn(e,...t){if(!this.shouldLog(s.WARN))return;const i=this.formatMessage("WARN",e);this.config.enableConsole&&console.warn(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}info(e,...t){if(!this.shouldLog(s.INFO))return;const i=this.formatMessage("INFO",e);this.config.enableConsole&&console.log(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}debug(e,...t){if(!this.shouldLog(s.DEBUG))return;const i=this.formatMessage("DEBUG",e);this.config.enableConsole&&console.log(i,...t),this.config.enableStorage&&this.isBrowser&&this.logToStorage(i,t);}logToStorage(e,t){try{const s=JSON.parse(localStorage.getItem("human_behavior_logs")||"[]"),i={message:e,args:t.length>0?t:void 0,timestamp:Date.now()};s.push(i),s.length>1e3&&s.splice(0,s.length-1e3),localStorage.setItem("human_behavior_logs",JSON.stringify(s));}catch(e){}}getLogs(){if(!this.isBrowser)return [];try{return JSON.parse(localStorage.getItem("human_behavior_logs")||"[]")}catch(e){return []}}clearLogs(){this.isBrowser&&localStorage.removeItem("human_behavior_logs");}};let n=false;const r=()=>n,o=(e,...t)=>{n=true;try{i.error(e,...t);}finally{n=false;}},a=(e,...t)=>{n=true;try{i.warn(e,...t);}finally{n=false;}},d=(e,...t)=>{n=true;try{i.info(e,...t);}finally{n=false;}},c=(e,...t)=>{n=true;try{i.debug(e,...t);}finally{n=false;}};class l{constructor(e){this._isPolling=false,this._pollIntervalMs=3e3,this._queue=[],this._queue=[],this._areWeOnline=true,this._sendRequest=e,"undefined"!=typeof window&&"onLine"in window.navigator&&(this._areWeOnline=window.navigator.onLine,window.addEventListener("online",()=>{this._areWeOnline=true,this._flush();}),window.addEventListener("offline",()=>{this._areWeOnline=false;}));}get length(){return this._queue.length}async retriableRequest(e){const t=e.retriesPerformedSoFar||0;if(t>0){const s=new URL(e.url);s.searchParams.set("retry_count",t.toString()),e.url=s.toString();}try{await this._sendRequest(e);}catch(s){if(this._shouldRetry(s,t)&&t<10)return void this._enqueue(e);e.callback&&e.callback({statusCode:s.status||0,text:s.message||"Request failed"});}}_shouldRetry(e,t){return e.status>=400&&e.status<500?408===e.status||429===e.status:e.status>=500||!e.status}_enqueue(e){const t=e.retriesPerformedSoFar||0;e.retriesPerformedSoFar=t+1;const s=function(e){const t=3e3*2**e,s=t/2,i=Math.min(18e5,t),n=(Math.random()-.5)*(i-s);return Math.ceil(i+n)}(t),i=Date.now()+s;this._queue.push({retryAt:i,requestOptions:e});let n=`Enqueued failed request for retry in ${Math.round(s/1e3)}s`;"undefined"==typeof navigator||navigator.onLine||(n+=" (Browser is offline)"),a(n),this._isPolling||(this._isPolling=true,this._poll());}_poll(){this._poller&&clearTimeout(this._poller),this._poller=setTimeout(()=>{this._areWeOnline&&this._queue.length>0&&this._flush(),this._poll();},this._pollIntervalMs);}_flush(){const e=Date.now(),t=[],s=this._queue.filter(s=>s.retryAt<e||(t.push(s),false));if(this._queue=t,s.length>0)for(const{requestOptions:e}of s)this.retriableRequest(e).catch(e=>{o("Failed to retry request:",e);});}unload(){this._poller&&(clearTimeout(this._poller),this._poller=void 0);for(const{requestOptions:e}of this._queue)try{this._sendBeaconRequest(e);}catch(e){o("Failed to send request via sendBeacon on unload:",e);}this._queue=[];}_sendBeaconRequest(e){if("undefined"!=typeof navigator&&navigator.sendBeacon)try{const t=new URL(e.url);t.searchParams.set("beacon","1");let s=null;e.body&&("string"==typeof e.body?s=new Blob([e.body],{type:"application/json"}):e.body instanceof Blob&&(s=e.body));navigator.sendBeacon(t.toString(),s)||a("sendBeacon returned false for unload request");}catch(e){o("Error sending beacon request:",e);}}}class h{constructor(e,t=1e3){this.storageKey="human_behavior_queue",this.maxQueueSize=t;}getQueue(){if("undefined"==typeof window||!window.localStorage)return [];try{const e=window.localStorage.getItem(this.storageKey);if(!e)return [];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){return a("Failed to read persisted queue:",e),[]}}setQueue(e){if("undefined"!=typeof window&&window.localStorage)try{const t=e.slice(-this.maxQueueSize);window.localStorage.setItem(this.storageKey,JSON.stringify(t)),c(`Persisted ${t.length} events to storage`);}catch(t){if("QuotaExceededError"===t.name||22===t.code){a("Storage quota exceeded, clearing old events");try{const t=e.slice(-Math.floor(this.maxQueueSize/2));window.localStorage.setItem(this.storageKey,JSON.stringify(t));}catch(e){a("Failed to save smaller queue, clearing storage"),this.clearQueue();}}else a("Failed to persist queue:",t);}}addToQueue(e){const t=this.getQueue();t.push(e),t.length>this.maxQueueSize&&(t.shift(),c("Queue is full, the oldest event is dropped.")),this.setQueue(t);}removeFromQueue(e){const t=this.getQueue();t.splice(0,e),this.setQueue(t);}clearQueue(){if("undefined"!=typeof window&&window.localStorage)try{window.localStorage.removeItem(this.storageKey);}catch(e){a("Failed to clear persisted queue:",e);}}getQueueLength(){return this.getQueue().length}}const u="0.7.0",m=1048576,p=52428.8;function g(e,t,s){return (new TextEncoder).encode(w({sessionId:s,events:[...e,t]})).length>m}function w(e){return JSON.stringify(e,(e,t)=>"bigint"==typeof t?t.toString():t)}function f(e,t){if(!e||"object"!=typeof e)return [];if((new TextEncoder).encode(w({sessionId:t,events:[e]})).length<=m)return [e];const s={...e},i=["screenshot","html","dom","fullText","innerHTML","outerHTML"];i.forEach(e=>{s[e]&&delete s[e];});if((new TextEncoder).encode(w({sessionId:t,events:[s]})).length<=m)return [s];return [{type:e.type,timestamp:e.timestamp,url:e.url,pathname:e.pathname,...Object.fromEntries(Object.entries(e).filter(([e,t])=>!i.includes(e)&&"object"!=typeof t&&"string"!=typeof t||"string"==typeof t&&t.length<1e3))}]}class y{constructor({apiKey:e,ingestionUrl:t}){this.monthlyLimitReached=false,this.sessionId="",this.endUserId=null,this.cspBlocked=false,this.requestTimeout=1e4,this.currentBatchSize=100,this.apiKey=e,this.baseUrl=t,this.persistence=new h(e),this.retryQueue=new l(e=>this._sendRequestInternal(e)),this._loadPersistedEvents();}setTrackingContext(e,t){this.sessionId=e,this.endUserId=t;}async _loadPersistedEvents(){const e=this.persistence.getQueue();if(0!==e.length){c(`Loading ${e.length} persisted events from storage`);for(const t of e)try{await this.sendEventsChunked(t.events,t.sessionId,t.endUserId||void 0,t.windowId,t.automaticProperties),this.persistence.removeFromQueue(1);}catch(e){a("Failed to send persisted event, will retry later:",e);}}}async _sendRequestInternal(e){const t="undefined"!=typeof AbortController?new AbortController:null;let s=null;t&&(s=setTimeout(()=>{t.abort();},this.requestTimeout));try{const i=e.estimatedSize||0,n="POST"===e.method&&i<p,r=await fetch(e.url,{method:e.method||"GET",headers:e.headers||{},body:e.body,signal:t?.signal,keepalive:n});s&&clearTimeout(s);const o=await r.text();let a=null;try{a=JSON.parse(o);}catch{}if(e.callback&&e.callback({statusCode:r.status,text:o,json:a}),!r.ok)throw {status:r.status,message:o}}catch(e){if(s&&clearTimeout(s),"AbortError"===e.name)throw {status:0,message:"Request timeout"};throw e}}unload(){this.retryQueue.unload();}checkMonthlyLimit(){return !this.monthlyLimitReached}async init(e,t){if(!this.checkMonthlyLimit())return {sessionId:e,endUserId:t};let s=null,i=null;"undefined"!=typeof window&&(s=window.location.href,i=document.referrer),d("API init called with:",{sessionId:e,userId:t,entryURL:s,referrer:i,baseUrl:this.baseUrl});try{const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/init`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Referer:i||""},body:w({sessionId:e,endUserId:t,entryURL:s,referrer:i,sdkVersion:u})});if(d("API init response status:",n.status),!n.ok){if(429===n.status)return this.monthlyLimitReached=!0,{sessionId:e,endUserId:t};const s=await n.text();throw o("API init failed:",n.status,s),new Error(`Failed to initialize ingestion: ${n.statusText} - ${s}`)}const r=await n.json();return !0===r.monthlyLimitReached&&(this.monthlyLimitReached=!0,d("Monthly limit reached detected from server response")),d("API init success:",r),{sessionId:r.sessionId,endUserId:r.endUserId}}catch(e){throw o("API init error:",e),e}}async sendEvents(e,t,s){const i=e.filter(e=>e&&"object"==typeof e),n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:t,events:i,endUserId:s,sdkVersion:u})});if(!n.ok){if(429===n.status)throw this.monthlyLimitReached=true,new Error("429: Monthly video processing limit reached");throw new Error(`Failed to send events: ${n.statusText}`)} true===(await n.json()).monthlyLimitReached&&(this.monthlyLimitReached=true,d("Monthly limit reached detected from events response"));}async sendEventsChunked(e,t,s,i,n){if(!this.checkMonthlyLimit())return [];try{const r=[];let o=[];for(const a of e)if(a&&"object"==typeof a)if(g(o,a,t)){if(o.length>0){c(`[SDK] Sending chunk with ${o.length} events`);const e=await this.trackedFetch(`${this.baseUrl}/api/ingestion/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:t,events:o,endUserId:s,windowId:i,automaticProperties:n,sdkVersion:u})});if(!e.ok){if(429===e.status)return this.monthlyLimitReached=!0,r.flat();throw new Error(`Failed to send events: ${e.statusText}`)}const a=await e.json();!0===a.monthlyLimitReached&&(this.monthlyLimitReached=!0,d("Monthly limit reached detected from chunked events response")),r.push(a),o=[];}o=f(a,t);}else o.push(a);if(o.length>0){const e=await this._sendChunkWithRetry(o,t,s,i,n||o[0]?.automaticProperties);e&&r.push(e);}return r.flat()}catch(r){throw o("Error sending events:",r),this._persistEvents(e,t,s,i,n),r}}async _sendChunkWithRetry(e,t,s,i,n){let r=Math.min(this.currentBatchSize,e.length),o=0;for(;o<e.length;){const c=w({sessionId:t,events:e.slice(o,o+r),endUserId:s,windowId:i,automaticProperties:n,sdkVersion:u}),l=(new TextEncoder).encode(c).length;try{const h=await this.trackedFetch(`${this.baseUrl}/api/ingestion/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:c},l);if(!h.ok){if(429===h.status)return this.monthlyLimitReached=!0,this._persistEvents(e.slice(o),t,s,i,n),null;if(413===h.status){a(`413 error: reducing batch size from ${r} to ${Math.max(1,Math.floor(r/2))}`),this.currentBatchSize=Math.max(1,Math.floor(r/2)),r=this.currentBatchSize;continue}return await this.retryQueue.retriableRequest({url:`${this.baseUrl}/api/ingestion/events`,method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:c,estimatedSize:l,callback:e=>{200===e.statusCode&&e.json&&!0===e.json.monthlyLimitReached&&(this.monthlyLimitReached=!0);}}),this._persistEvents(e.slice(o),t,s,i,n),null}const u=await h.json();if(!0===u.monthlyLimitReached&&(this.monthlyLimitReached=!0,d("Monthly limit reached detected from chunked events response")),o+=r,o>=e.length)return u}catch(r){return a("Network error sending chunk, adding to retry queue:",r),await this.retryQueue.retriableRequest({url:`${this.baseUrl}/api/ingestion/events`,method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:c,estimatedSize:l,callback:e=>{200===e.statusCode&&e.json&&true===e.json.monthlyLimitReached&&(this.monthlyLimitReached=true);}}),this._persistEvents(e.slice(o),t,s,i,n),null}}return null}_persistEvents(e,t,s,i,n){0!==e.length&&this.persistence.addToQueue({sessionId:t,events:e,endUserId:s,windowId:i,automaticProperties:n,timestamp:Date.now()});}async sendUserData(e,t,s){try{const i={userId:e,userAttributes:t,sessionId:s,posthogName:t.email||t.name||null};c("Sending user data to server:",i);const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/user`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w(i)});if(!n.ok)throw new Error(`Failed to send user data: ${n.statusText} with API key: ${this.apiKey}`);const r=await n.json();return c("Server response:",r),r}catch(e){throw o("Error sending user data:",e),e}}async sendUserAuth(e,t,s,i){try{const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/user/auth`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({userId:e,userAttributes:t,sessionId:s,authFields:i})});if(!n.ok)throw new Error(`Failed to authenticate user: ${n.statusText} with API key: ${this.apiKey}`);return await n.json()}catch(e){throw o("Error authenticating user:",e),e}}sendSessionEndBeacon(e,t){if("undefined"==typeof navigator||"function"!=typeof navigator.sendBeacon)return false;try{const s={sessionId:e,endUserId:t||null,apiKey:this.apiKey},i=new Blob([w(s)],{type:"application/json"});return navigator.sendBeacon(`${this.baseUrl}/api/ingestion/session-end`,i)}catch{return false}}sendHeartbeatBeacon(e,t){if("undefined"==typeof navigator||"function"!=typeof navigator.sendBeacon)return false;try{const s={sessionId:e,endUserId:t||null,apiKey:this.apiKey},i=new Blob([w(s)],{type:"application/json"});return navigator.sendBeacon(`${this.baseUrl}/api/ingestion/heartbeat`,i)}catch{return false}}sendBeaconEvents(e,t,s,i,n,r){const o={sessionId:t,events:e,endUserId:s||null,windowId:i,automaticProperties:n,sdkVersion:u,apiKey:this.apiKey},a=new Blob([w(o)],{type:"application/json"});return navigator.sendBeacon(`${this.baseUrl}/api/ingestion/events`,a)}async sendCustomEvent(e,t,s,i){d("[SDK] Sending custom event",{sessionId:e,eventName:t,eventProperties:s,endUserId:i});try{const n=await this.trackedFetch(`${this.baseUrl}/api/ingestion/customEvent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:e,eventName:t,eventProperties:s||{},endUserId:i||null})});if(d("[SDK] Custom event response",{status:n.status,statusText:n.statusText}),!n.ok){const e=await n.text();throw o("[SDK] Failed to send custom event",{status:n.status,statusText:n.statusText,errorText:e}),new Error(`Failed to send custom event: ${n.status} ${n.statusText} - ${e}`)}const r=await n.json();return c("[SDK] Custom event success",r),r}catch(i){throw o("[SDK] Error sending custom event",i,{sessionId:e,eventName:t,eventProperties:s}),i}}async sendCustomEventBatch(e,t,s){try{const i=await this.trackedFetch(`${this.baseUrl}/api/ingestion/customEvent/batch`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:e,events:t,endUserId:s||null})});if(!i.ok)throw new Error(`Failed to send custom event batch: ${i.statusText}`);return await i.json()}catch(e){throw o("Error sending custom event batch:",e),e}}sendCustomEventBatchBeacon(e,t,s){if("undefined"==typeof navigator||"function"!=typeof navigator.sendBeacon)return false;try{const i={sessionId:e,events:t,endUserId:s||null,apiKey:this.apiKey},n=new Blob([w(i)],{type:"application/json"});return navigator.sendBeacon(`${this.baseUrl}/api/ingestion/customEvent/batch`,n)}catch{return false}}async sendLog(e){try{if(c("[SDK] Sending log to server:",{level:e.level,message:e.message.substring(0,50),sessionId:e.sessionId}),!this.baseUrl)return;if(!e.sessionId)return;const t=await fetch(`${this.baseUrl}/api/ingestion/logs`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w(e)});t.ok?c("[SDK] Log sent successfully"):a("[SDK] Failed to send log to server:",t.status,t.statusText);}catch(e){a("[SDK] Failed to send log to server:",e);}}async sendNetworkError(e){try{if(c("[SDK] Sending network error to server:",{errorType:e.errorType,url:e.url.substring(0,50),sessionId:e.sessionId}),!this.baseUrl)return;if(!e.sessionId)return;const t=await fetch(`${this.baseUrl}/api/ingestion/network`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w(e)});t.ok?c("[SDK] Network error sent successfully"):a("[SDK] Failed to send network error to server:",t.status,t.statusText);}catch(e){a("[SDK] Failed to send network error to server:",e);}}async sendIpInfo(e,t){try{if(!this.baseUrl||!e||!t)return;const s=await fetch(`${this.baseUrl}/api/ingestion/ip-info`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:w({sessionId:e,endUserId:t,ipDetectionMethod:"server_header"})});s.ok||a("[SDK] Failed to send ip-info:",s.status,s.statusText);}catch(e){a("[SDK] Failed to send ip-info:",e);}}async trackedFetch(e,s,i){const n=Date.now(),r=v1(),o=this.shouldSkipNetworkTracking(e);if(this.cspBlocked&&"POST"===s.method&&"undefined"!=typeof navigator&&"function"==typeof navigator.sendBeacon)return this.trackedFetchWithBeaconFallback(e,s,o);try{const t="undefined"!=typeof AbortController?new AbortController:null;let a=null;t&&(a=setTimeout(()=>{t.abort();},this.requestTimeout));const d="POST"===s.method&&void 0!==i&&i<p,c=await fetch(e,{...s,signal:t?.signal,keepalive:d});a&&clearTimeout(a);const l=Date.now()-n;return c.ok||o||await this.sendNetworkError({requestId:r,url:e,method:s.method||"GET",status:c.status,statusText:c.statusText,duration:l,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyHttpError(c.status),errorMessage:c.statusText,startTimeMs:n,spanName:`${s.method||"GET"} ${e}`,spanStatus:"error",attributes:{"http.status_code":c.status,"http.status_text":c.statusText}}).catch(()=>{}),c}catch(t){const i=Date.now()-n;if("AbortError"===t.name){const e=new Error("Request timeout");e.name="TimeoutError",t=e;}if(this.isCSPViolation(t)&&"POST"===s.method&&"undefined"!=typeof navigator&&"function"==typeof navigator.sendBeacon)return this.cspBlocked=true,a("[SDK] CSP violation detected, falling back to sendBeacon for future requests"),this.trackedFetchWithBeaconFallback(e,s,o);throw o||await this.sendNetworkError({requestId:r,url:e,method:s.method||"GET",status:null,statusText:null,duration:i,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyNetworkError(t),errorMessage:t.message,errorName:t.name,startTimeMs:n,spanName:`${s.method||"GET"} ${e}`,spanStatus:"error",attributes:{"error.name":t.name,"error.message":t.message}}).catch(()=>{}),t}}async trackedFetchWithBeaconFallback(e,t,s){try{let s=null,i="";if(t.body)if("string"==typeof t.body)try{s=JSON.parse(t.body),i=t.body;}catch{i=t.body;}else {if(t.body instanceof Blob){a("[SDK] Cannot extract apiKey from Blob body for sendBeacon, using URL param"),e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;return navigator.sendBeacon(e,t.body)?new Response(null,{status:200,statusText:"OK",headers:new Headers}):new Response(null,{status:500,statusText:"sendBeacon failed",headers:new Headers})}i=w(t.body),s=t.body;}if(e.includes("/api/ingestion/"))if(s&&"object"==typeof s)s.apiKey=this.apiKey,i=w(s);else if(i)try{const e=JSON.parse(i);e.apiKey=this.apiKey,i=w(e);}catch{e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;}else e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;else e=`${e}${e.includes("?")?"&":"?"}apiKey=${encodeURIComponent(this.apiKey)}`;const n=i?new Blob([i],{type:"application/json"}):null;return navigator.sendBeacon(e,n)?(c("[SDK] Successfully sent request via sendBeacon (CSP fallback)"),new Response(null,{status:200,statusText:"OK",headers:new Headers})):(a("[SDK] sendBeacon returned false - browser may be throttling"),new Response(null,{status:200,statusText:"OK (sendBeacon best-effort)",headers:new Headers}))}catch(e){return o("[SDK] sendBeacon fallback failed:",e),new Response(null,{status:500,statusText:"Failed to send via sendBeacon",headers:new Headers})}}isCSPViolation(e){const t=(e?.message||"").toLowerCase();return "typeerror"===(e?.name||"").toLowerCase()&&t.includes("failed to fetch")||t.includes("content security policy")||t.includes("csp")||t.includes("violates")||t.includes("refused to connect")&&t.includes("violates")}shouldSkipNetworkTracking(e){if(!e||!this.baseUrl)return false;try{const t=new URL(e),s=new URL(this.baseUrl);return !(t.origin!==s.origin||!t.pathname.startsWith("/api/ingestion/"))||!!e.includes(this.baseUrl)}catch(t){return e.includes(this.baseUrl)}}classifyHttpError(e){return e>=400&&e<500?"client_error":e>=500?"server_error":"unknown_error"}classifyNetworkError(e){const t=e.message||"",s=e.name||"";return this.isCSPViolation(e)?"csp_violation":t.includes("ERR_BLOCKED_BY_CLIENT")||t.includes("ERR_BLOCKED_BY_RESPONSE")||t.includes("blocked:other")||t.includes("net::ERR_BLOCKED_BY_CLIENT")||t.includes("net::ERR_BLOCKED_BY_RESPONSE")||"TypeError"===s&&t.includes("Failed to fetch")&&(t.includes("blocked")||t.includes("ERR_BLOCKED"))?"blocked_by_client":t.includes("CORS")||t.includes("Access-Control")?"cors_error":t.includes("timeout")||"TimeoutError"===s?"timeout_error":t.includes("Failed to fetch")||t.includes("NetworkError")?"network_error":"unknown_error"}}class v{constructor(e){if(this.redactedText="[REDACTED]",this.unredactedFields=new Set,this.redactedFields=new Set,this.redactionMode="privacy-first",this.excludeSelectors=['[data-no-redact="true"]',".human-behavior-no-redact"],e?.redactedText&&(this.redactedText=e.redactedText),e?.excludeSelectors&&(this.excludeSelectors=[...this.excludeSelectors,...e.excludeSelectors]),e?.redactionStrategy)if(this.redactionMode=e.redactionStrategy.mode,"privacy-first"===this.redactionMode)e.redactionStrategy.unredactFields&&this.setFieldsToUnredact(e.redactionStrategy.unredactFields);else {const t=['input[type="password"]','[data-hb-redact="true"]'],s=e.redactionStrategy.redactFields&&e.redactionStrategy.redactFields.length>0?e.redactionStrategy.redactFields:t;this.setFieldsToRedact(s);}e?.legacyRedactFields&&this.setFieldsToUnredact(e.legacyRedactFields),e?.userFields&&this.setFieldsToUnredact(e.userFields);}setFieldsToRedact(e){this.redactedFields.clear();['input[type="password"]','input[type="password" i]','[type="password"]','[type="password" i]',...e].forEach(e=>{this.redactedFields.add(e);}),this.redactedFields.size>0?c(`Redaction: Active for ${this.redactedFields.size} field(s):`,Array.from(this.redactedFields)):c("Redaction: No fields to redact"),this.applyRedactionClasses();}setFieldsToUnredact(e){this.unredactedFields.clear();const t=e.filter(e=>!this.isPasswordSelector(e)||(a(`Cannot unredact password field: ${e} - Password fields are always protected`),false));t.forEach(e=>this.unredactedFields.add(e)),t.length>0?c(`Unredaction: Active for ${t.length} field(s):`,t):c("Unredaction: No valid fields to unredact"),this.applyUnredactionClasses();}redactFields(e){e.forEach(e=>{this.unredactedFields.delete(e);}),this.unredactedFields.size>0?c(`Unredaction: Removed ${e.length} field(s), ${this.unredactedFields.size} remaining:`,Array.from(this.unredactedFields)):c("Unredaction: All fields redacted"),this.applyUnredactionClasses();}clearUnredactedFields(){this.unredactedFields.clear(),c("Unredaction: All fields cleared, everything redacted"),this.removeUnredactionClasses();}hasUnredactedFields(){return this.unredactedFields.size>0}getRedactionMode(){return this.redactionMode}getUnredactedFields(){return Array.from(this.unredactedFields)}getMaskTextSelector(){return "privacy-first"===this.redactionMode?0===this.unredactedFields.size?null:Array.from(this.unredactedFields).join(","):0===this.redactedFields.size?null:Array.from(this.redactedFields).join(",")}applyRedactionClasses(){0!==this.redactedFields.size&&("undefined"!=typeof document&&"loading"!==document.readyState?this.redactedFields.forEach(e=>{try{const t=document.querySelectorAll(e);t.forEach(e=>{e&&e.classList&&e.classList.add("rr-mask");}),c(`Added rr-mask class to ${t.length} element(s) for selector: ${e}`);}catch(t){a(`Invalid selector: ${e}`);}}):c("DOM not ready, deferring redaction class application"));}applyUnredactionClasses(){0!==this.unredactedFields.size&&("undefined"!=typeof document&&"loading"!==document.readyState?this.unredactedFields.forEach(e=>{try{const t=document.querySelectorAll(e);t.forEach(e=>{e&&e.classList&&e.classList.remove("rr-mask");}),c(`Removed rr-mask class from ${t.length} element(s) for selector: ${e}`);}catch(t){a(`Invalid selector: ${e}`);}}):c("DOM not ready, deferring unredaction class application"));}removeUnredactionClasses(){c("Unredaction classes removed");}isPasswordSelector(e){return ['input[type="password"]','input[type="password" i]','[type="password"]','[type="password" i]'].some(t=>e.toLowerCase().includes(t.toLowerCase().replace(/[\[\]]/g,"")))}getOriginalValue(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)return e.value}isElementUnredacted(e){return this.shouldUnredactElement(e)}shouldUnredactElement(e){if("privacy-first"===this.redactionMode){if(0===this.unredactedFields.size)return false;for(const t of this.unredactedFields)try{if(e.matches(t))return !0}catch(e){a(`Invalid selector: ${t}`);}return false}if(0===this.redactedFields.size)return true;for(const t of this.redactedFields)try{if(e.matches(t))return !1}catch(e){a(`Invalid selector: ${t}`);}return true}}new v;const _="undefined"!=typeof window;function S(){if(!_)return "unknown";const e=navigator.userAgent.toLowerCase(),t=window.screen.width,s=window.screen.height;return /mobile|android|iphone|ipad|ipod|blackberry|windows phone/i.test(e)?/ipad/i.test(e)||t>=768&&s>=1024?"tablet":"mobile":/windows|macintosh|linux/i.test(e)?"desktop":"unknown"}function k(e){try{return new URL(e).hostname}catch{return ""}}function T(){if(!_)return {device_type:"unknown",browser:"unknown",browser_version:"unknown",os:"unknown",os_version:"unknown",screen_resolution:"unknown",viewport_size:"unknown",color_depth:0,timezone:"unknown",language:"unknown",languages:[]};const{browser:e,browser_version:t}=function(){if(!_)return {browser:"unknown",browser_version:"unknown"};const e=navigator.userAgent;if(/chrome/i.test(e)&&!/edge/i.test(e)){const t=e.match(/chrome\/(\d+)/i);return {browser:"chrome",browser_version:t?t[1]:"unknown"}}if(/firefox/i.test(e)){const t=e.match(/firefox\/(\d+)/i);return {browser:"firefox",browser_version:t?t[1]:"unknown"}}if(/safari/i.test(e)&&!/chrome/i.test(e)){const t=e.match(/version\/(\d+)/i);return {browser:"safari",browser_version:t?t[1]:"unknown"}}if(/edge/i.test(e)){const t=e.match(/edge\/(\d+)/i);return {browser:"edge",browser_version:t?t[1]:"unknown"}}if(/msie|trident/i.test(e)){const t=e.match(/msie (\d+)/i)||e.match(/rv:(\d+)/i);return {browser:"ie",browser_version:t?t[1]:"unknown"}}return {browser:"unknown",browser_version:"unknown"}}(),{os:s,os_version:i}=function(){if(!_)return {os:"unknown",os_version:"unknown"};const e=navigator.userAgent;if(/windows/i.test(e)){const t=e.match(/windows nt (\d+\.\d+)/i);let s="unknown";if(t){const e=parseFloat(t[1]);s=10===e?"10":6.3===e?"8.1":6.2===e?"8":6.1===e?"7":t[1];}return {os:"windows",os_version:s}}if(/macintosh|mac os x/i.test(e)){const t=e.match(/mac os x (\d+[._]\d+)/i);return {os:"macos",os_version:t?t[1].replace("_","."):"unknown"}}if(/iphone|ipad|ipod/i.test(e)){const t=e.match(/os (\d+[._]\d+)/i);return {os:"ios",os_version:t?t[1].replace("_","."):"unknown"}}if(/android/i.test(e)){const t=e.match(/android (\d+\.\d+)/i);return {os:"android",os_version:t?t[1]:"unknown"}}return /linux/i.test(e)?{os:"linux",os_version:"unknown"}:{os:"unknown",os_version:"unknown"}}();return {device_type:S(),browser:e,browser_version:t,os:s,os_version:i,screen_resolution:`${window.screen.width}x${window.screen.height}`,viewport_size:`${window.innerWidth}x${window.innerHeight}`,color_depth:window.screen.colorDepth,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,language:navigator.language,languages:[...navigator.languages||[navigator.language]],raw_user_agent:navigator.userAgent}}function E(){if(!_)return {current_url:"",pathname:"",search:"",hash:"",title:"",referrer:"",referrer_domain:"",initial_referrer:"",initial_referrer_domain:""};const e=window.location.href,t=document.referrer,s=function(e){const t=new URL(e),s={};return ["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(e=>{const i=t.searchParams.get(e);i&&(s[e]=i);}),s}(e);return {current_url:e,pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,title:document.title,referrer:t,referrer_domain:k(t),initial_referrer:t,initial_referrer_domain:k(t),initial_host:window.location.hostname,...s}}function I(){return {...T(),...E()}}function b(){if(!_)return {};const e=E();return {initial_referrer:e.initial_referrer,initial_referrer_domain:e.initial_referrer_domain,initial_url:e.current_url,initial_pathname:e.pathname,initial_utm_source:e.utm_source,initial_utm_medium:e.utm_medium,initial_utm_campaign:e.utm_campaign,initial_utm_term:e.utm_term,initial_utm_content:e.utm_content}}function C(){if(!_)return {};const e=E();return {current_url:e.current_url,pathname:e.pathname,search:e.search,hash:e.hash,title:e.title,referrer:e.referrer,referrer_domain:e.referrer_domain,utm_source:e.utm_source,utm_medium:e.utm_medium,utm_campaign:e.utm_campaign,utm_term:e.utm_term,utm_content:e.utm_content}}class U{constructor(e={}){this.sessionProperties={},this.userProperties={},this.initialProperties={},this.isInitialized=false,this.config={enableAutomaticProperties:true,enableSessionProperties:true,enableUserProperties:true,propertyDenylist:[],...e},this.automaticProperties=I(),this.initialize();}initialize(){this.isInitialized||(this.initialProperties=b(),this.loadSessionProperties(),this.isInitialized=true);}getEventProperties(e={}){const t={};return this.config.enableAutomaticProperties&&(Object.assign(t,this.getAutomaticProperties()),this.config.enableSessionProperties&&Object.assign(t,this.sessionProperties),this.config.enableUserProperties&&Object.assign(t,this.userProperties),this.sessionProperties.$initial_properties_captured||(Object.assign(t,this.initialProperties),this.setSessionProperty("$initial_properties_captured",true))),Object.assign(t,e),this.applyDenylist(t),t}getAutomaticProperties(){return {...this.automaticProperties,...C()}}getAutomaticPropertiesWithGeoIP(e={}){return {...this.automaticProperties,...C(),...e}}setSessionProperty(e,t){this.sessionProperties[e]=t,this.saveSessionProperties();}setSessionProperties(e){Object.assign(this.sessionProperties,e),this.saveSessionProperties();}getSessionProperty(e){return this.sessionProperties[e]}removeSessionProperty(e){delete this.sessionProperties[e],this.saveSessionProperties();}setUserProperty(e,t){this.userProperties[e]=t;}setUserProperties(e){Object.assign(this.userProperties,e);}getUserProperty(e){return this.userProperties[e]}removeUserProperty(e){delete this.userProperties[e];}setOnce(e,t,s="user"){"session"===s?e in this.sessionProperties||this.setSessionProperty(e,t):e in this.userProperties||this.setUserProperty(e,t);}clearSessionProperties(){this.sessionProperties={},this.saveSessionProperties();}clearUserProperties(){this.userProperties={};}reset(){this.clearSessionProperties(),this.clearUserProperties(),this.initialProperties={},this.isInitialized=false,this.initialize();}loadSessionProperties(){if("undefined"!=typeof sessionStorage)try{const e=sessionStorage.getItem("hb_session_properties");e&&(this.sessionProperties=JSON.parse(e));}catch(e){console.warn("Failed to load session properties:",e);}}saveSessionProperties(){if("undefined"!=typeof sessionStorage)try{sessionStorage.setItem("hb_session_properties",JSON.stringify(this.sessionProperties));}catch(e){console.warn("Failed to save session properties:",e);}}applyDenylist(e){this.config.propertyDenylist&&0!==this.config.propertyDenylist.length&&this.config.propertyDenylist.forEach(t=>{delete e[t];});}updateAutomaticProperties(){this.automaticProperties=I();}getAllProperties(){return {automatic:this.getAutomaticProperties(),session:{...this.sessionProperties},user:{...this.userProperties},initial:{...this.initialProperties}}}}const D="undefined"!=typeof window;class P{get isTrackerStarted(){return this.isStarted}setupDomReadyHandler(){if(D)if("complete"===document.readyState||"interactive"===document.readyState)this.onDomReady();else if(document.addEventListener){document.addEventListener("DOMContentLoaded",()=>this.onDomReady(),{capture:false});const e=setInterval(()=>{"interactive"!==document.readyState&&"complete"!==document.readyState||(clearInterval(e),this.onDomReady());},10);setTimeout(()=>clearInterval(e),5e3);}else this.onDomReady();else this.onDomReady();}onDomReady(){this.isDomReady||(this.isDomReady=true,c("π― DOM is ready, processing queued requests"),this.requestQueue.forEach(e=>{this.processRequest(e);}),this.requestQueue=[],this.domReadyHandlers.forEach(e=>e()),this.domReadyHandlers=[]);}queueRequest(e){this.isDomReady?this.processRequest(e):this.requestQueue.push(e);}async processRequest(e){switch(c("Processing queued request:",e),e.type){case "addEvent":await this.addEvent(e.event);break;case "identifyUser":await this.identifyUser(e.userProperties);break;case "trackPageView":this.trackPageView();break;default:a("Unknown request type:",e.type);}}registerDomReadyHandler(e){this.isDomReady?e():this.domReadyHandlers.push(e);}static init(e,t){if(D&&false!==t?.suppressConsoleErrors){const e=console.error;console.error=(...t)=>{const s=t.join(" ");s.includes("SecurityError: Failed to execute 'toDataURL'")||s.includes("Tainted canvases may not be exported")||s.includes("Cannot inline img src=")||s.includes("Cross-Origin")||s.includes("CORS")||s.includes("Access-Control-Allow-Origin")||s.includes("Failed to load resource")||s.includes("net::ERR_BLOCKED_BY_CLIENT")||s.includes("NetworkError when attempting to fetch resource")||s.includes("Failed to fetch")||s.includes("TypeError: NetworkError")||s.includes("HumanBehavior ERROR")||s.includes("Failed to track custom event")||s.includes("Error sending custom event")||e.apply(console,t);};const t=console.warn;console.warn=(...e)=>{const s=e.join(" ");s.includes("Cannot inline img src=")||s.includes("Cross-Origin")||s.includes("CORS")||s.includes("Access-Control-Allow-Origin")||s.includes("Failed to load resource")||s.includes("net::ERR_BLOCKED_BY_CLIENT")||s.includes("NetworkError when attempting to fetch resource")||s.includes("Failed to fetch")||s.includes("Custom event network error")||s.includes("Request blocked by ad blocker")||t.apply(console,e);},window.addEventListener("error",e=>{const t=e.message||"";if(t.includes("SecurityError")||t.includes("Tainted canvases")||t.includes("toDataURL")||t.includes("Cross-Origin")||t.includes("CORS")||t.includes("NetworkError")||t.includes("Failed to fetch"))return e.preventDefault(),false});}if(D&&window.__humanBehaviorGlobalTracker)return c("Tracker already initialized, returning existing instance"),window.__humanBehaviorGlobalTracker;t?.logLevel&&this.configureLogging({level:t.logLevel});const s=new P(e,t?.ingestionUrl,{enableAutomaticProperties:t?.enableAutomaticProperties,propertyDenylist:t?.propertyDenylist,redactionStrategy:t?.redactionStrategy,redactFields:t?.redactFields,maxQueueSize:t?.maxQueueSize,enableConsoleTracking:t?.enableConsoleTracking,enableNetworkTracking:t?.enableNetworkTracking});return s.recordCanvas=t?.recordCanvas??false,t?.redactFields&&s.setUnredactedFields(t.redactFields),false!==t?.enableAutomaticTracking&&s.setupAutomaticTracking(t?.automaticTrackingOptions),s.start(),s}constructor(e,s,i){if(this.eventQueue=[],this.pendingCustomEvents=[],this.pendingLogs=[],this.pendingNetworkErrors=[],this.customEventBatch=[],this.customEventBatchTimer=null,this.CUSTOM_EVENT_FLUSH_MS=100,this.CUSTOM_EVENT_BATCH_MAX=50,this._sessionActivityTimestamp=null,this._sessionStartTimestamp=null,this.userProperties={},this.isProcessing=false,this.flushInterval=null,this.FLUSH_INTERVAL_MS=3e3,this.heartbeatInterval=null,this.HEARTBEAT_INTERVAL_MS=3e4,this.SESSION_IDLE_TIMEOUT_MS=18e5,this.SESSION_MAX_LENGTH_MS=864e5,this.focusBlurGraceTimeout=null,this.FOCUS_BLUR_GRACE_MS=2e3,this.lastEmittedFocusState=null,this.endUserId=null,this.initialized=false,this.initializationPromise=null,this.monthlyLimitReached=false,this.isDomReady=false,this.requestQueue=[],this.domReadyHandlers=[],this.originalConsole=null,this.consoleTrackingEnabled=false,this.originalFetch=null,this.networkTrackingEnabled=false,this.enableConsoleTrackingFlag=true,this.enableNetworkTrackingFlag=true,this.navigationTrackingEnabled=false,this.currentUrl="",this.previousUrl="",this.originalPushState=null,this.originalReplaceState=null,this.navigationListeners=[],this.lastPushStateAt=0,this.NAVIGATION_DEDUPE_MS=100,this._connectionBlocked=false,this.recordInstance=null,this.sessionStartTime=Date.now(),this.rrwebRecord=null,this.fullSnapshotTimeout=null,this.recordCanvas=false,this.isStarted=false,this.minimumDurationMilliseconds=5e3,this._isIdle="unknown",this._lastActivityTimestamp=Date.now(),this.IDLE_THRESHOLD_MS=3e5,this.rageClickTracker={clicks:[]},this.RAGE_CLICK_THRESHOLD_PX=30,this.RAGE_CLICK_TIMEOUT_MS=1e3,this.RAGE_CLICK_CLICK_COUNT=3,this.rageJustFiredAt=0,this.deadClickTracker={pendingClicks:new Map},this.DEAD_CLICK_SCROLL_THRESHOLD_MS=100,this.DEAD_CLICK_SELECTION_THRESHOLD_MS=2500,this.DEAD_CLICK_MUTATION_THRESHOLD_MS=100,this.DEAD_CLICK_ABSOLUTE_TIMEOUT_MS=2750,!e)throw new Error("Human Behavior API Key is required");const n=s||"https://ingest.humanbehavior.co";if(this.api=new y({apiKey:e,ingestionUrl:n}),this.apiKey=e,this.ingestionUrl=n,this.MAX_QUEUE_SIZE=i?.maxQueueSize??1e3,this.enableConsoleTrackingFlag=false!==i?.enableConsoleTracking,this.enableNetworkTrackingFlag=false!==i?.enableNetworkTracking,this.redactionManager=new v({redactionStrategy:i?.redactionStrategy,legacyRedactFields:i?.redactFields}),this.propertyManager=new U({enableAutomaticProperties:false!==i?.enableAutomaticProperties,propertyDenylist:i?.propertyDenylist||[]}),D){const e="human_behavior_end_user_id",s=this.getCookie(e);this.endUserId=s||v1(),s?c(`Reusing existing endUserId: ${this.endUserId}`):(this.setCookie(e,this.endUserId,365),c(`Generated new endUserId: ${this.endUserId}`));}else this.endUserId=v1();if(D){const e=this.apiKey||"default";this._window_id_storage_key=`human_behavior_${e}_window_id`,this._primary_window_exists_storage_key=`human_behavior_${e}_primary_window_exists`,this.sessionId=this.getOrCreateSessionId(),this.windowId=this.getOrCreateWindowId(),this.currentUrl=window.location.href,window.__humanBehaviorGlobalTracker=this,this.setupWindowUnloadListener();}else this._window_id_storage_key="",this._primary_window_exists_storage_key="",this.sessionId=v1(),this.windowId=v1();this.api.setTrackingContext(this.sessionId,this.endUserId),this.initializationPromise=this.init().catch(e=>{o("Initialization failed:",e);});}async init(){try{this.initialized=!0,D?(this.setupPageUnloadHandler(),this.setupNavigationTracking()):d("HumanBehaviorTracker initialized in server environment. Session tracking is disabled."),d(`HumanBehaviorTracker initialized with sessionId: ${this.sessionId}, endUserId: ${this.endUserId}`);}catch(e){o("Failed to initialize HumanBehaviorTracker:",e),this.initialized=true;}}async ensureInitialized(){this.initializationPromise&&await this.initializationPromise;}setupNavigationTracking(){if(!D||this.navigationTrackingEnabled)return;this.navigationTrackingEnabled=true,c("Setting up navigation tracking"),this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState,history.pushState=(...e)=>{this.previousUrl=this.currentUrl,this.originalPushState.apply(history,e),this.currentUrl=window.location.href,this.lastPushStateAt=Date.now(),this.trackNavigationEvent("pushState",this.previousUrl,this.currentUrl),this.takeFullSnapshot();},history.replaceState=(...e)=>{this.previousUrl=this.currentUrl,this.originalReplaceState.apply(history,e),this.currentUrl=window.location.href,this.lastPushStateAt=Date.now(),this.trackNavigationEvent("replaceState",this.previousUrl,this.currentUrl),this.takeFullSnapshot();};const e=()=>{this.previousUrl=this.currentUrl,this.currentUrl=window.location.href,this.trackNavigationEvent("popstate",this.previousUrl,this.currentUrl),this.takeFullSnapshot();};window.addEventListener("popstate",e),this.navigationListeners.push(()=>{window.removeEventListener("popstate",e);});const t=()=>{if(Date.now()-this.lastPushStateAt<this.NAVIGATION_DEDUPE_MS)return this.previousUrl=this.currentUrl,void(this.currentUrl=window.location.href);this.previousUrl=this.currentUrl,this.currentUrl=window.location.href,this.trackNavigationEvent("hashchange",this.previousUrl,this.currentUrl);};window.addEventListener("hashchange",t),this.navigationListeners.push(()=>{window.removeEventListener("hashchange",t);}),this.trackNavigationEvent("pageLoad","",this.currentUrl);}async trackNavigationEvent(e,t,s){if(this.initialized)if("pageLoad"===e||t!==s)try{if("pageLoad"===e||"pushState"===e||"replaceState"===e||"popstate"===e||"hashchange"===e){const s={url:window.location.href,fromUrl:t,$navigation_type:e,navigationType:e,pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,referrer:document.referrer,timestamp:Date.now()};await this.customEvent("$pageview",s);}c(`Navigation tracked: ${e} from ${t} to ${s}`);}catch(e){o("Failed to track navigation event:",e);}else c(`Navigation dedupe: ${e} same URL (${s})`);}async trackPageView(e){if(this.initialized){this.propertyManager.updateAutomaticProperties();try{const t={url:e||window.location.href,pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,referrer:document.referrer,timestamp:(new Date).toISOString()},s=this.propertyManager.getEventProperties(t);await this.addEvent({type:5,data:{payload:{eventType:"pageview",...s}},timestamp:Date.now()}),c(`Pageview tracked: ${t.url}`);}catch(e){o("Failed to track pageview event:",e);}}}async customEvent(e,s){if(null==e||"string"!=typeof e||""===e.trim())return void a("customEvent() called with empty or invalid name; skipping");this.endUserId||(a(`endUserId not available, using anonymous ID for event: ${e}`),this.endUserId=v1()),D&&this.checkAndRefreshSession();const i=this.propertyManager.getEventProperties(s);if(this.shouldSkipDueToMinimumDuration())return c(`Custom event '${e}' queued due to session duration below minimum`),void this.pendingCustomEvents.push({eventName:e,properties:i,timestamp:Date.now()});await this.flushPendingCustomEvents(),this.queueCustomEvent(e,i),c(`Custom event queued: ${e}`,i);}queueCustomEvent(e,t){this.customEventBatch.push({eventName:e,eventProperties:t}),this.customEventBatch.length>=this.CUSTOM_EVENT_BATCH_MAX?this.flushCustomEventBatch():null==this.customEventBatchTimer&&(this.customEventBatchTimer=setTimeout(()=>{this.customEventBatchTimer=null,this.flushCustomEventBatch();},this.CUSTOM_EVENT_FLUSH_MS));}async flushCustomEventBatch(){if(null!=this.customEventBatchTimer&&(clearTimeout(this.customEventBatchTimer),this.customEventBatchTimer=null),0===this.customEventBatch.length)return;const e=this.customEventBatch;this.customEventBatch=[];try{return await this.api.sendCustomEventBatch(this.sessionId,e,this.endUserId),void c(`Custom event batch flushed: ${e.length} event(s)`)}catch(e){o("Failed to flush custom event batch, falling back per-event:",e);}for(const t of e)try{await this.api.sendCustomEvent(this.sessionId,t.eventName,t.eventProperties,this.endUserId);}catch(e){o("Per-event fallback also failed:",e);try{await this.addEvent({type:5,data:{payload:{eventType:"custom",eventName:t.eventName,properties:t.eventProperties||{},timestamp:(new Date).toISOString(),url:D?window.location.href:"",pathname:D?window.location.pathname:""}},timestamp:Date.now()});}catch(e){o("Failed to add custom event to event stream as fallback:",e);}}}setupAutomaticTracking(e){if(!D)return;const t={trackButtons:false!==e?.trackButtons,trackLinks:false,trackForms:false!==e?.trackForms,includeText:false!==e?.includeText,includeClasses:e?.includeClasses||false};c("Setting up automatic tracking with config:",t),this.setupAutocapture(t),t.trackForms&&this.setupAutomaticFormTracking(t),this.setupRageClickDetection(),this.setupDeadClickDetection();}setupAutocapture(e){document.addEventListener("click",async t=>{const s=t.target;if(!s||1!==s.nodeType||"function"!=typeof s.closest)return;const i=s.closest('button, a, input, select, textarea, label, [role="button"], [role="link"], [role="tab"], [role="menuitem"]')||s,n=(i.tagName||"").toLowerCase(),r={tag:n,x:t.clientX,y:t.clientY,page:window.location.pathname,path:this.buildDomPath(i),timestamp:Date.now()};i.id&&(r.id=i.id,r.elementId=i.id);const o=i.getAttribute&&i.getAttribute("role");o&&(r.role=o);const a=i.type;!a||"input"!==n&&"button"!==n||(r.type=a);const d=i.href;if(d&&(r.href=d),false!==e.includeText){const e=(i.textContent||"").replace(/\s+/g," ").trim();e&&(r.text=e.substring(0,200),r.elementText=e.substring(0,100));}const c=i.className;e.includeClasses&&"string"==typeof c&&c&&(r.class=c,r.elementClass=c),await this.customEvent("$click",r);});}buildDomPath(e){const t=[];let s=e,i=0;for(;s&&1===s.nodeType&&i<8;){const e=(s.tagName||"").toLowerCase();if(!e)break;let n=e;if(s.id)n+="#"+s.id;else if("string"==typeof s.className&&s.className){const e=s.className.trim().split(/\s+/)[0];e&&(n+="."+e);}if(t.unshift(n),"body"===e||"html"===e)break;s=s.parentElement,i++;}return t.join(" > ")}setupRageClickDetection(){D&&document.addEventListener("click",async e=>{const t=e.target;if(!t||1!==t.nodeType)return;const s=e.clientX,i=e.clientY,n=Date.now();if(this.isRageClick(s,i,n,t)){const e=("function"==typeof t.closest?t.closest('button, a, [role="button"], [role="link"]'):null)||t,r=(e.tagName||"").toLowerCase(),o={x:s,y:i,page:window.location.pathname,element:r,clickCount:this.rageClickTracker.clicks.length,timestamp:n};e.id&&(o.elementId=e.id);const a=e.className;"string"==typeof a&&a&&(o.elementClass=a),e.textContent&&(o.elementText=e.textContent.trim().substring(0,100)),Object.keys(o).forEach(e=>{null!==o[e]&&void 0!==o[e]||delete o[e];}),await this.customEvent("$rageclick",o),this.rageJustFiredAt=n;}});}isRageClick(e,t,s,i){if(this.rageJustFiredAt>0&&s-this.rageJustFiredAt<this.RAGE_CLICK_TIMEOUT_MS)return false;if(this.rageJustFiredAt>0&&s-this.rageJustFiredAt>=this.RAGE_CLICK_TIMEOUT_MS)return this.rageJustFiredAt=0,this.rageClickTracker.clicks=[{x:e,y:t,timestamp:s,element:i}],false;const n=this.rageClickTracker.clicks,r=n[n.length-1],o=n[0];if(o&&r&&s-r.timestamp<this.RAGE_CLICK_TIMEOUT_MS&&Math.hypot(e-o.x,t-o.y)<this.RAGE_CLICK_THRESHOLD_PX){if(n.push({x:e,y:t,timestamp:s,element:i}),n.length===this.RAGE_CLICK_CLICK_COUNT)return true}else this.rageClickTracker.clicks=[{x:e,y:t,timestamp:s,element:i}];return false}setupDeadClickDetection(){D&&(this.setupDeadClickMutationObserver(),this.setupDeadClickScrollObserver(),this.setupDeadClickSelectionObserver(),this.setupDeadClickNavigationTracking(),document.addEventListener("click",e=>{const t=e.target;if(!t||1!==t.nodeType)return;if(!this.isInteractiveElement(t))return;if(this.ignoreClickForDeadDetection(t))return;const s=Date.now()+Math.random(),i=Date.now(),n=this.deadClickTracker.lastMutationTime,r=this.DEAD_CLICK_ABSOLUTE_TIMEOUT_MS,o=window.setTimeout(()=>{this.handleDeadClickTimeout(s);},r);this.deadClickTracker.pendingClicks.set(s,{element:t,originalEvent:e,timestamp:i,timer:o,cancelled:false,lastMutationTimeAtClick:n});}));}setupDeadClickMutationObserver(){D&&(this.deadClickTracker.mutationObserver||(this.deadClickTracker.mutationObserver=new MutationObserver(()=>{const e=Date.now();this.deadClickTracker.lastMutationTime=e,this.deadClickTracker.pendingClicks.forEach((t,s)=>{if(t.cancelled)return;const i=e-t.timestamp,n=t.lastMutationTimeAtClick||0,r=e>n,o=i>=0&&i<this.DEAD_CLICK_MUTATION_THRESHOLD_MS,a=i<0&&Math.abs(i)<50;(o&&r||a)&&this.cancelPendingClick(s);});}),this.deadClickTracker.mutationObserver.observe(document,{attributes:true,characterData:true,childList:true,subtree:true})));}setupDeadClickScrollObserver(){D&&window.addEventListener("scroll",()=>{const e=Date.now();this.deadClickTracker.pendingClicks.forEach((t,s)=>{e-t.timestamp<this.DEAD_CLICK_SCROLL_THRESHOLD_MS&&this.cancelPendingClick(s);});},{capture:true,passive:true});}setupDeadClickSelectionObserver(){D&&document.addEventListener("selectionchange",()=>{const e=Date.now();this.deadClickTracker.lastSelectionChangedTime=e,this.deadClickTracker.pendingClicks.forEach((t,s)=>{e-t.timestamp<this.DEAD_CLICK_SELECTION_THRESHOLD_MS&&this.cancelPendingClick(s);});});}setupDeadClickNavigationTracking(){if(!D)return;let e=window.location.href;const t=this.trackNavigationEvent.bind(this);this.trackNavigationEvent=async(s,i,n)=>(this.cancelAllPendingClicks(),e=window.location.href,t(s,i,n));const s=()=>{const t=window.location.href;t!==e&&(this.cancelAllPendingClicks(),e=t);};window.addEventListener("popstate",s),window.addEventListener("hashchange",s),window.addEventListener("beforeunload",()=>{this.cancelAllPendingClicks();}),setInterval(()=>{s();},100);}isInteractiveElement(e){if(!e||1!==e.nodeType||!e.tagName)return false;const t=e.tagName.toLowerCase();if("button"===t||"a"===t)return true;if("input"===t)return false;if(["select","textarea"].includes(t))return true;const s=e.getAttribute("role");if(s&&["button","link","tab","menuitem","checkbox","radio"].includes(s))return true;if(e.onclick||e.getAttribute("onclick"))return true;try{if("pointer"===window.getComputedStyle(e).cursor)return !0}catch(e){}return !!e.closest('button, a, [role="button"], [role="link"], [role="tab"], [role="menuitem"]')}ignoreClickForDeadDetection(e){if(!e||!e.tagName)return true;if("html"===e.tagName.toLowerCase())return true;const t=Date.now();for(const s of this.deadClickTracker.pendingClicks.values())if(s.element===e&&Math.abs(t-s.timestamp)<1e3)return true;return false}cancelPendingClick(e){const t=this.deadClickTracker.pendingClicks.get(e);t&&!t.cancelled&&(clearTimeout(t.timer),t.cancelled=true,this.deadClickTracker.pendingClicks.delete(e));}cancelAllPendingClicks(){this.deadClickTracker.pendingClicks.forEach((e,t)=>{e.cancelled||(clearTimeout(e.timer),this.deadClickTracker.pendingClicks.delete(t));});}async handleDeadClickTimeout(e){const t=this.deadClickTracker.pendingClicks.get(e);if(!t||t.cancelled)return;const s=Date.now()-t.timestamp;let i;const n=t.lastMutationTimeAtClick||0,r=this.deadClickTracker.lastMutationTime||0,o=r>n&&r>=t.timestamp,a=n>0&&n<t.timestamp&&t.timestamp-n<50;let d;o?i=r-t.timestamp:a&&(i=0),this.deadClickTracker.lastSelectionChangedTime&&t.timestamp<=this.deadClickTracker.lastSelectionChangedTime&&(d=this.deadClickTracker.lastSelectionChangedTime-t.timestamp);const c=void 0!==i&&i<this.DEAD_CLICK_MUTATION_THRESHOLD_MS,l=void 0!==d&&d<this.DEAD_CLICK_SELECTION_THRESHOLD_MS;c||l||await this.fireDeadClickEvent(t,s,i,d),this.deadClickTracker.pendingClicks.delete(e);}async fireDeadClickEvent(e,t,s,i){const n=e.element.closest('button, a, [role="button"], [role="link"]')||e.element,r={x:e.originalEvent.clientX,y:e.originalEvent.clientY,page:window.location.pathname,element:n.tagName.toLowerCase(),absoluteDelayMs:t,timestamp:e.timestamp};void 0!==s&&(r.mutationDelayMs=s),void 0!==i&&(r.selectionChangedDelayMs=i),n.id&&(r.elementId=n.id),n.className&&(r.elementClass=n.className),n.textContent&&(r.elementText=n.textContent.trim().substring(0,100)),Object.keys(r).forEach(e=>{null!==r[e]&&void 0!==r[e]||delete r[e];}),await this.customEvent("$deadclick",r);}setupAutomaticLinkTracking(e){}setupAutomaticFormTracking(e){document.addEventListener("submit",async t=>{const s=t.target,i=new FormData(s),n={formId:s.id||null,formAction:s.action||null,formMethod:s.method||"get",fields:Array.from(i.keys()),page:window.location.pathname,timestamp:Date.now()};e.includeClasses&&(n.formClass=s.className||null),Object.keys(n).forEach(e=>{null===n[e]&&delete n[e];}),await this.customEvent("$form_submitted",n);});}cleanupNavigationTracking(){this.navigationTrackingEnabled&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.navigationListeners.forEach(e=>e()),this.navigationListeners=[],this.navigationTrackingEnabled=false,c("Navigation tracking cleaned up"));}static logToStorage(e){d(e);}static configureLogging(e){i.setConfig({level:{none:0,error:1,warn:2,info:3,debug:4}[e.level||"error"],enableConsole:false!==e.enableConsole,enableStorage:e.enableStorage||false});}enableConsoleTracking(){D&&!this.consoleTrackingEnabled&&(this.originalConsole={log:console.log,warn:console.warn,error:console.error},console.log=(...e)=>{this.trackConsoleEvent("log",e),this.originalConsole.log(...e);},console.warn=(...e)=>{this.trackConsoleEvent("warn",e),this.originalConsole.warn(...e);},console.error=(...e)=>{this.trackConsoleEvent("error",e),this.originalConsole.error(...e);},this.consoleTrackingEnabled=true,c("Console tracking enabled"));}enableNetworkTracking(){D&&!this.networkTrackingEnabled&&"undefined"!=typeof fetch&&(this.originalFetch=window.fetch.bind(window),window.fetch=async(e,s)=>{const i=Date.now(),n=v1(),r="string"==typeof e?e:e instanceof URL?e.toString():e.url,o=(s?.method||("object"==typeof e&&"method"in e?e.method:void 0)||"GET").toUpperCase(),a=this.shouldSkipNetworkTracking(r),d=1e4;let l=null,h=false;a||(l=setTimeout(()=>{const e=Date.now()-i;if(!h){h=true;const t={requestId:n,url:r,method:o,status:null,statusText:null,duration:e,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:"long_loading",errorMessage:`Request took longer than 10000ms (${e}ms elapsed)`,startTimeMs:i,spanName:`${o} ${r}`,spanStatus:"slow",attributes:{"http.method":o,"http.url":r,"request.duration_ms":e,"request.long_loading_threshold_ms":d},automaticProperties:this.propertyManager.getAutomaticProperties()};return this.shouldSkipDueToMinimumDuration()?(c("Long-loading network error queued due to session duration below minimum"),void this.pendingNetworkErrors.push({errorData:t,timestamp:Date.now()})):(this.flushPendingNetworkErrors(),void this.api.sendNetworkError(t).catch(()=>{}))}},d));try{const t=await this.originalFetch(e,s),d=Date.now()-i;if(l&&clearTimeout(l),!t.ok&&!a){const e={requestId:n,url:r,method:o,status:t.status,statusText:t.statusText,duration:d,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyHttpError(t.status),errorMessage:t.statusText,startTimeMs:i,spanName:`${o} ${r}`,spanStatus:"error",attributes:{"http.status_code":t.status,"http.status_text":t.statusText},automaticProperties:this.propertyManager.getAutomaticProperties()};if(this.shouldSkipDueToMinimumDuration())return c("Failed request network error queued due to session duration below minimum"),this.pendingNetworkErrors.push({errorData:e,timestamp:Date.now()}),t;this.flushPendingNetworkErrors(),this.api.sendNetworkError(e).catch(()=>{});}return t}catch(e){const t=Date.now()-i;if(l&&clearTimeout(l),!a){const s={requestId:n,url:r,method:o,status:null,statusText:null,duration:t,timestampMs:Date.now(),sessionId:this.sessionId,endUserId:this.endUserId,errorType:this.classifyNetworkError(e),errorMessage:e.message,errorName:e.name,startTimeMs:i,spanName:`${o} ${r}`,spanStatus:"error",attributes:{"error.name":e.name,"error.message":e.message},automaticProperties:this.propertyManager.getAutomaticProperties()};if(this.shouldSkipDueToMinimumDuration())throw c("Network error queued due to session duration below minimum"),this.pendingNetworkErrors.push({errorData:s,timestamp:Date.now()}),e;this.flushPendingNetworkErrors(),this.api.sendNetworkError(s).catch(()=>{});}throw e}},this.networkTrackingEnabled=true,c("Network tracking enabled"));}async flushPendingCustomEvents(){if(0===this.pendingCustomEvents.length)return;const e=[...this.pendingCustomEvents];this.pendingCustomEvents=[],c(`Flushing ${e.length} pending custom events`);for(const{eventName:t,properties:s}of e)this.queueCustomEvent(t,s);}async flushPendingLogs(){if(0===this.pendingLogs.length)return;const e=[...this.pendingLogs];this.pendingLogs=[],c(`Flushing ${e.length} pending logs`);for(const{logData:t}of e)try{await this.api.sendLog(t);}catch(e){o("Failed to flush pending log:",e);}}async flushPendingNetworkErrors(){if(0===this.pendingNetworkErrors.length)return;const e=[...this.pendingNetworkErrors];this.pendingNetworkErrors=[],c(`Flushing ${e.length} pending network errors`);for(const{errorData:t}of e)try{await this.api.sendNetworkError(t);}catch(e){o("Failed to flush pending network error:",e);}}enablePageLoadTracking(){D&&"undefined"!=typeof window&&("complete"===document.readyState?this.trackPageLoad():window.addEventListener("load",()=>{this.trackPageLoad();}),c("Page load tracking enabled"));}trackPageLoad(){if(D&&"undefined"!=typeof performance)try{const e=performance.getEntriesByType("navigation")[0];if(!e)return;const s=e.loadEventEnd-e.fetchStart;if(s>3e3){const i=v1(),n=e.domContentLoadedEventEnd-e.fetchStart,r=e.domComplete-e.fetchStart,o={requestId:i,url:window.location.href,method:"GET",status:200,statusText:"OK",duration:s,timestampMs:e.loadEventEnd+performance.timeOrigin,sessionId:this.sessionId,endUserId:this.endUserId,errorType:"slow_page_load",errorMessage:`Page load took ${s}ms`,startTimeMs:e.fetchStart+performance.timeOrigin,spanName:"page_load",spanStatus:"slow",attributes:{"page.url":window.location.href,"page.load_time":s,"page.dom_content_loaded":n,"page.dom_complete":r}};if(this.shouldSkipDueToMinimumDuration())return c("Slow page load network error queued due to session duration below minimum"),void this.pendingNetworkErrors.push({errorData:o,timestamp:Date.now()});this.flushPendingNetworkErrors(),this.api.sendNetworkError(o).catch(()=>{});}}catch(e){a("Failed to track page load:",e);}}shouldSkipNetworkTracking(e){if(!e||!this.ingestionUrl)return false;try{const t=new URL(e),s=new URL(this.ingestionUrl);return !(t.origin!==s.origin||!t.pathname.startsWith("/api/ingestion/"))||!!e.includes(this.ingestionUrl)}catch(t){return e.includes(this.ingestionUrl)}}classifyHttpError(e){return e>=400&&e<500?"client_error":e>=500?"server_error":"unknown_error"}classifyNetworkError(e){const t=e.message||"",s=e.name||"";return t.includes("blocked")||t.includes("ERR_BLOCKED_BY_CLIENT")||t.includes("net::ERR_BLOCKED_BY_CLIENT")||"TypeError"===s&&t.includes("Failed to fetch")?"blocked_by_client":t.includes("CORS")||t.includes("Cross-Origin")||t.includes("Access-Control-Allow-Origin")||"TypeError"===s&&t.includes("CORS")?"cors_error":t.includes("timeout")||t.includes("TIMEOUT")||t.includes("NetworkError")||"NetworkError"===s?"network_error":t.includes("abort")||"AbortError"===s?"aborted":"unknown_error"}disableConsoleTracking(){D&&this.consoleTrackingEnabled&&(this.originalConsole&&(console.log=this.originalConsole.log,console.warn=this.originalConsole.warn,console.error=this.originalConsole.error),this.consoleTrackingEnabled=false,c("Console tracking disabled"));}trackConsoleEvent(e,t){if(this.initialized)if("log"!==e)try{if(r())return void(this.originalConsole&&this.originalConsole[e](...t));const s=(new Error).stack||"";if(this.isSDKStackFrame(s))return void(this.originalConsole&&this.originalConsole[e](...t));const i={level:e,message:t.map(e=>"object"==typeof e?JSON.stringify(e):String(e)).join(" "),timestampMs:Date.now(),url:D?window.location.href:"",userAgent:D?navigator.userAgent:"",stack:s,sessionId:this.sessionId,endUserId:this.endUserId,automaticProperties:this.propertyManager.getAutomaticProperties()};if(this.shouldSkipDueToMinimumDuration())return c(`Console ${e} queued due to session duration below minimum`),void this.pendingLogs.push({logData:i,timestamp:Date.now()});this.flushPendingLogs(),this.api.sendLog(i).catch(e=>{this.addEvent({type:5,data:{payload:{eventType:"console",...i}},timestamp:Date.now()}).catch(()=>{});});}catch(e){o("Error in trackConsoleEvent:",e);}else this.originalConsole&&this.originalConsole.log(...t);}isSDKStackFrame(e){if(!e)return false;const t=["humanbehavior-js","@humanbehavior/core","@humanbehavior/browser","tracker.ts","api.ts","logger.ts","utils/logger","packages/core","packages/browser","index.mjs","index.js"],s=e.split("\n");e.toLowerCase();let i=false;for(let e=0;e<s.length;e++){const n=s[e].trim().toLowerCase();if(!n||"error"===n||n.startsWith("error:"))continue;if(!t.some(e=>n.includes(e.toLowerCase()))){i=true;break}}return !i}setupPageUnloadHandler(){if(!D)return;const e="__humanBehaviorUnloadAttached";if(window[e])return c("Page unload handlers already attached on window β skipping re-attach"),void(window.__humanBehaviorActiveTracker=this);window[e]=true,window.__humanBehaviorActiveTracker=this,c("Setting up page unload handler"),window.addEventListener("visibilitychange",()=>{const e="hidden"===document.visibilityState?"hidden":"visible";this.emitVisibilityMarker(e),"hidden"===document.visibilityState?(c("Page hidden - sending pending events"),this.flushEvents()):"visible"===document.visibilityState&&(c("Page visible - taking full snapshot for multi-window replay"),this.takeFullSnapshot());}),this.setupWindowFocusTracking();const t="onpagehide"in window?"pagehide":"beforeunload";window.addEventListener(t,()=>{c("Page unloading - sending final events via sendBeacon");let e=false;const t=()=>{if(!e){e=true;try{this.api?.sendSessionEndBeacon(this.sessionId,this.endUserId);}catch{}}};try{if(this.customEventBatch.length>0){null!=this.customEventBatchTimer&&(clearTimeout(this.customEventBatchTimer),this.customEventBatchTimer=null);const e=this.customEventBatch;this.customEventBatch=[];const t=this.api?.sendCustomEventBatchBeacon(this.sessionId,e,this.endUserId);t||this.api?.sendCustomEventBatch(this.sessionId,e,this.endUserId).catch(()=>{});}}catch{}const s=this.minimumDurationMilliseconds,i=this.getSessionDuration();if(null!==i&&i>=0&&i<s)return c(`Session duration (${i}ms) below minimum (${s}ms), not sending on unload`),void t();const n=[...this.eventQueue];if(D&&window.__hb_pending_snapshots){const e=window.__hb_pending_snapshots;Array.isArray(e)&&e.length>0&&(c("Including pending FullSnapshot(s) in sendBeacon for short session"),n.unshift(...e),delete window.__hb_pending_snapshots);}if(n.length>0&&this.api)try{const e=this.propertyManager.getAutomaticProperties();this.api.sendBeaconEvents(n,this.sessionId,this.endUserId||void 0,this.windowId,e),this.eventQueue=[];}catch(e){a("Failed to send events via sendBeacon on unload:",e);}this.api&&this.api.unload(),t();});const s=()=>{localStorage.setItem("human_behavior_last_activity",Date.now().toString());};window.addEventListener("click",s),window.addEventListener("keydown",s),window.addEventListener("scroll",s),window.addEventListener("mousemove",s);}viewLogs(){try{const e=i.getLogs();d("HumanBehavior Logs:",e),i.clearLogs();}catch(e){o("Failed to read logs:",e);}}async identifyUser(e){const t=e?.userProperties&&"object"==typeof e.userProperties?e.userProperties:e||{},s=this.endUserId;this.userProperties={...this.userProperties,...t};try{this.propertyManager?.setUserProperties(t);}catch{}c("Identifying user:",{userProperties:t,originalEndUserId:s,sessionId:this.sessionId}),!D||this.propertyManager.getAutomaticProperties();const i=await this.api.sendUserData(s||"",t,this.sessionId);if(i.actualUserId||i.wasExistingUser){const e=i.actualUserId||s;if(e&&e!==s){const t="human_behavior_end_user_id";if(this.setCookie(t,e,365),D)try{localStorage.setItem(t,e);}catch(e){c("Failed to set canonical endUserId in localStorage:",e);}c(`π Preexisting user detected. Future sessions will use canonical ID: ${e} (current session stays: ${s})`);}}return s||""}getUserAttributes(){return {...(()=>{try{return this.propertyManager?.getAllProperties().user||{}}catch{return {}}})(),...this.userProperties}}async start(){if(!D)return;if(this.isStarted)return void c("HumanBehaviorTracker already started, skipping start() call.");this.isStarted=true,this._lastActivityTimestamp=null!==this._sessionActivityTimestamp?this._sessionActivityTimestamp:Date.now(),this._isIdle="unknown",this.flushInterval=window.setInterval(()=>{this.flushEvents();},this.FLUSH_INTERVAL_MS),this.heartbeatInterval=window.setInterval(()=>{try{if("undefined"!=typeof document&&"visible"!==document.visibilityState)return;if(!this.sessionId||!this.api)return;this.api.sendHeartbeatBeacon(this.sessionId,this.endUserId);}catch{}},this.HEARTBEAT_INTERVAL_MS),this.enableConsoleTrackingFlag&&this.enableConsoleTracking(),this.enableNetworkTrackingFlag&&this.enableNetworkTracking(),this.enablePageLoadTracking(),this.api.sendIpInfo(this.sessionId,this.endUserId);const t=()=>{if(this.recordInstance)return void c("π― Recording already started, skipping duplicate start");c("π― DOM ready, starting session recording"),this.rrwebRecord=record;const t=record({emit:e=>{this.addRecordingEvent(e),2===e.type&&c(`π― FullSnapshot generated at ${(new Date).toISOString()}`);},maskTextSelector:this.redactionManager.getMaskTextSelector()||void 0,maskTextFn:void 0,maskAllInputs:"privacy-first"===this.redactionManager.getRedactionMode(),maskInputOptions:{password:true,text:true,textarea:true,email:true,number:true,tel:true,url:true,search:true,date:true,time:true,month:true,week:true},maskInputFn:(e,t)=>{try{const s=this.redactionManager.getRedactionMode();if(!(t instanceof HTMLElement))return e;if("privacy-first"===s)return "*".repeat(e.length||1);const i=this.redactionManager.shouldUnredactElement(t);t.id,t.name,t.type;return i?e:"*".repeat(e.length||1)}catch{return e}},slimDOMOptions:{},collectFonts:false,inlineStylesheet:true,recordCrossOriginIframes:false,recordCanvas:this.recordCanvas,sampling:this.recordCanvas?{canvas:4}:void 0,dataURLOptions:this.recordCanvas?{type:"image/webp",quality:.4}:void 0,hooks:{input:e=>{try{if("privacy-first"===this.redactionManager.getRedactionMode())return;const t="undefined"!=typeof document?document.querySelector(`[data-rrweb-id="${e.id}"]`):null;if(t&&t instanceof HTMLElement){this.redactionManager.shouldUnredactElement(t)||(void 0!==e.text&&(e.text="*".repeat(e.text?.length||1)),void 0!==e.value&&(e.value="*".repeat(e.value?.length||1)));}}catch{}}}});this.recordInstance=t||null;};if(c(`π― DOM ready state: ${document.readyState}`),"complete"===document.readyState||"interactive"===document.readyState)c(`π― DOM ready (${document.readyState}), starting recording immediately`),t();else {c("π― DOM not ready, waiting for DOMContentLoaded event");const e=()=>("interactive"===document.readyState||"complete"===document.readyState)&&(c(`π― DOM ready (${document.readyState}), starting recording`),t(),true);if(e())return;document.addEventListener("DOMContentLoaded",()=>{c("π― DOMContentLoaded fired, starting recording"),t();},{once:true});const s=setInterval(()=>{e()&&clearInterval(s);},10);setTimeout(()=>clearInterval(s),5e3);}}emitVisibilityMarker(e){try{const t={type:5,data:{tag:"$visibility",payload:{state:e}},timestamp:Date.now()};this.eventQueue.push(t);}catch{}}emitFocusMarker(e){try{const t={type:5,data:{tag:"$focus",payload:{state:e}},timestamp:Date.now()};this.eventQueue.push(t);}catch{}}setupWindowFocusTracking(){if(D){try{"function"!=typeof document.hasFocus||document.hasFocus()||(this.emitFocusMarker("blurred"),this.lastEmittedFocusState="blurred");}catch{}window.addEventListener("blur",()=>this.onWindowBlur(),false),window.addEventListener("focus",()=>this.onWindowFocus(),false);}}onWindowBlur(){D&&(null!==this.focusBlurGraceTimeout&&clearTimeout(this.focusBlurGraceTimeout),this.focusBlurGraceTimeout=window.setTimeout(()=>{this.focusBlurGraceTimeout=null;try{if("function"==typeof document.hasFocus&&document.hasFocus())return;if("blurred"===this.lastEmittedFocusState)return;this.emitFocusMarker("blurred"),this.lastEmittedFocusState="blurred";}catch{}},this.FOCUS_BLUR_GRACE_MS));}onWindowFocus(){if(D&&(null!==this.focusBlurGraceTimeout&&(clearTimeout(this.focusBlurGraceTimeout),this.focusBlurGraceTimeout=null),"blurred"===this.lastEmittedFocusState))try{this.emitFocusMarker("focused"),this.lastEmittedFocusState="focused";}catch{}}takeFullSnapshot(){this.fullSnapshotTimeout&&clearTimeout(this.fullSnapshotTimeout),this.fullSnapshotTimeout=window.setTimeout(()=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{try{this.rrwebRecord&&"function"==typeof this.rrwebRecord.takeFullSnapshot?(this.rrwebRecord.takeFullSnapshot(),c("β
FullSnapshot taken (delayed for animations)")):a("β οΈ takeFullSnapshot not available on record function");}catch(e){o("β Failed to take FullSnapshot:",e);}});});},1e3);}async stop(){await this.ensureInitialized(),D&&(this.flushInterval&&(clearInterval(this.flushInterval),this.flushInterval=null),this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null),this.recordInstance&&(this.recordInstance(),this.recordInstance=null),this.fullSnapshotTimeout&&(clearTimeout(this.fullSnapshotTimeout),this.fullSnapshotTimeout=null),null!==this.focusBlurGraceTimeout&&(clearTimeout(this.focusBlurGraceTimeout),this.focusBlurGraceTimeout=null),this.rrwebRecord=null,this.disableConsoleTracking(),this.cleanupNavigationTracking(),this.deadClickTracker.mutationObserver&&(this.deadClickTracker.mutationObserver.disconnect(),this.deadClickTracker.mutationObserver=void 0),this.deadClickTracker.pendingClicks.forEach((e,t)=>{e.cancelled||clearTimeout(e.timer);}),this.deadClickTracker.pendingClicks.clear());}async addEvent(e){if(D&&this.checkAndRefreshSession(),e&&"object"==typeof e){if(2===e.type){const t=!!e.data,s=!(!e.data||!e.data.node);c(t&&s?`β
Valid FullSnapshot: hasData=${t}, hasNode=${s}, dataType=${e.data?.node?.type}`:`β οΈ Empty FullSnapshot detected: hasData=${t}, hasNode=${s} - continuing session`);}this.eventQueue.length>=this.MAX_QUEUE_SIZE&&(this.eventQueue.shift(),c("Queue is full, the oldest event is dropped.")),this.eventQueue.push(e),2===e.type?(c("FullSnapshot added, triggering immediate flush"),this.flushEvents()):this.eventQueue.length>=.8*this.MAX_QUEUE_SIZE&&(c(`Queue at ${this.eventQueue.length}/${this.MAX_QUEUE_SIZE}, triggering immediate flush`),this.flushEvents());}else c("β οΈ Skipping invalid event:",e);}getSessionDuration(){const e=this._sessionStartTimestamp??this.sessionStartTime;if(!e)return null;const t=this.eventQueue.filter(e=>e&&e.timestamp);if(0===t.length)return null;const s=t.reduce((e,t)=>!e||t.timestamp&&t.timestamp>e.timestamp?t:e,null);if(!s||!s.timestamp)return null;const i=s.timestamp-e;return i>=0?i:null}shouldSkipDueToMinimumDuration(){const e=this.minimumDurationMilliseconds,t=this.getSessionDuration();return !!(null!==t&&t>=0&&t<e)&&(c(`Session duration (${t}ms) below minimum (${e}ms), skipping send`),true)}async flushEvents(){if(this.isProcessing)return;if(this.monthlyLimitReached)return;if(true===this._isIdle&&0===this.eventQueue.length)return;const e=this.minimumDurationMilliseconds,t=this.getSessionDuration();if(null!==t&&t>=0&&t<e)return c(`Session duration (${t}ms) below minimum (${e}ms), buffering`),void setTimeout(()=>{this.flushEvents();},2e3);this.isProcessing=true;try{const e=this.eventQueue,t=e.filter(e=>e&&2===e.type);if(this.eventQueue=[],t.length>0&&D&&(window.__hb_pending_snapshots=t,setTimeout(()=>{delete window.__hb_pending_snapshots;},5e3)),e.length>0){c("Flushing events:",e);const t=e.filter(e=>2===e.type);t.length>0&&c(`[FIXED] Sending ${t.length} FullSnapshot(s) with valid data`);try{const t=this.propertyManager.getAutomaticProperties();await this.api.sendEventsChunked(e,this.sessionId,this.endUserId,this.windowId,t);}catch(e){if(e.message?.includes("ERROR: Session already completed"))a("Session expired, events will be lost");else if(e.message?.includes("413")||e.message?.includes("Content Too Large"))a("Payload too large, events will be lost");else {if(!(e.message?.includes("ERR_BLOCKED_BY_CLIENT")||e.message?.includes("Failed to fetch")||e.message?.includes("NetworkError")))throw e;a("Request blocked by ad blocker or network issue, events will be lost");}}}await this.flushPendingCustomEvents(),await this.flushPendingLogs(),await this.flushPendingNetworkErrors();}finally{this.isProcessing=false;}}isInteractiveEvent(e){if(3!==e.type)return false;const t=e.data?.source;return [1,2,3,4,5,6,11].includes(t)}updateIdleState(e){const t=this.isInteractiveEvent(e),s=e.timestamp||Date.now();if(t){const e=true===this._isIdle;this._lastActivityTimestamp=s,null!==this._sessionActivityTimestamp&&(this._sessionActivityTimestamp=s),e?(c("β
User activity detected, exiting idle state"),this._isIdle=false,this.rrwebRecord&&"function"==typeof this.rrwebRecord.takeFullSnapshot&&(this.rrwebRecord.takeFullSnapshot(),c("β
FullSnapshot taken after returning from idle"))):"unknown"===this._isIdle&&(this._isIdle=false);}else if(true!==this._isIdle){const e=s-this._lastActivityTimestamp;e>this.IDLE_THRESHOLD_MS&&(c(`βΈοΈ Session idle detected (${Math.round(e/1e3)}s since last activity) - stopping background event recording`),c(`βΉοΈ Session will expire after ${Math.round(this.SESSION_IDLE_TIMEOUT_MS/6e4)} minutes of inactivity (${Math.round((this.SESSION_IDLE_TIMEOUT_MS-e)/1e3)}s remaining)`),this._isIdle=true,this.flushEvents());}}async addRecordingEvent(e){if(D&&this.checkAndRefreshSession(),e&&"object"==typeof e){if(this.updateIdleState(e),true!==this._isIdle||3!==e.type||this.isInteractiveEvent(e)){if(2===e.type){const t=!!e.data,s=!(!e.data||!e.data.node);c(t&&s?`β
Valid FullSnapshot: hasData=${t}, hasNode=${s}, dataType=${e.data?.node?.type}`:`β οΈ Empty FullSnapshot detected: hasData=${t}, hasNode=${s} - continuing session`);}this.eventQueue.length>=this.MAX_QUEUE_SIZE&&(this.eventQueue.shift(),c("Queue is full, the oldest event is dropped.")),this.eventQueue.push(e),2===e.type?(c("FullSnapshot added, triggering immediate flush"),this.flushEvents()):true!==this._isIdle&&this.eventQueue.length>=.8*this.MAX_QUEUE_SIZE&&(c(`Queue at ${this.eventQueue.length}/${this.MAX_QUEUE_SIZE}, triggering immediate flush`),this.flushEvents());}}else c("β οΈ Skipping invalid recording event:",e);}_canUseSessionStorage(){if(!D)return false;try{const e="__sessionStorage_test__";return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch{return false}}_getWindowIdFromStorage(){if(!this._canUseSessionStorage())return null;try{return sessionStorage.getItem(this._window_id_storage_key)}catch{return null}}_setWindowIdInStorage(e){if(this._canUseSessionStorage())try{sessionStorage.setItem(this._window_id_storage_key,e),c(`Stored windowId in sessionStorage: ${e}`);}catch(e){a("Failed to store windowId in sessionStorage:",e);}}_removeWindowIdFromStorage(){if(this._canUseSessionStorage())try{sessionStorage.removeItem(this._window_id_storage_key);}catch(e){a("Failed to remove windowId from sessionStorage:",e);}}_getPrimaryWindowExists(){if(!this._canUseSessionStorage())return false;try{return "true"===sessionStorage.getItem(this._primary_window_exists_storage_key)}catch{return false}}_setPrimaryWindowExists(e){if(this._canUseSessionStorage())try{e?sessionStorage.setItem(this._primary_window_exists_storage_key,"true"):sessionStorage.removeItem(this._primary_window_exists_storage_key);}catch(e){a("Failed to set primary_window_exists flag:",e);}}getOrCreateWindowId(){if(!D)return v1();const e=this._getWindowIdFromStorage(),s=this._getPrimaryWindowExists();if(e&&!s)return c(`Reusing windowId from previous page load: ${e}`),this._setWindowIdInStorage(e),this._setPrimaryWindowExists(true),e;{const e=v1();return c(`Creating new windowId: ${e} (new window/tab detected)`),this._setWindowIdInStorage(e),this._setPrimaryWindowExists(true),e}}setupWindowUnloadListener(){D&&window.addEventListener("beforeunload",()=>{this._canUseSessionStorage()&&(this._setPrimaryWindowExists(false),c("Cleared primary_window_exists flag on beforeunload"));},{capture:false});}setCookie(e,t,s){if(D)try{const i=new Date;i.setTime(i.getTime()+24*s*60*60*1e3);const n=`expires=${i.toUTCString()}`;document.cookie=`${e}=${t};${n};path=/;SameSite=Lax`,localStorage.setItem(e,t),c(`Set cookie and localStorage: ${e}`);}catch(s){try{localStorage.setItem(e,t),c(`Cookie blocked, using localStorage: ${e}`);}catch(e){o("Failed to store user ID in both cookie and localStorage:",e);}}}getCookie(e){if(!D)return null;try{const t=e+"=",s=document.cookie.split(";");for(let i=0;i<s.length;i++){let n=s[i];for(;" "===n.charAt(0);)n=n.substring(1,n.length);if(0===n.indexOf(t)){const s=n.substring(t.length,n.length);return c(`Found cookie: ${e}`),s}}const i=localStorage.getItem(e);return i?(c(`Cookie not found, using localStorage: ${e}`),i):null}catch(t){try{const t=localStorage.getItem(e);if(t)return c(`Cookie access failed, using localStorage: ${e}`),t}catch(e){o("Failed to access both cookie and localStorage:",e);}return null}}deleteCookie(e){if(D){try{document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=Lax`,c(`Deleted cookie: ${e}`);}catch(t){o(`Failed to delete cookie: ${e}`,t);}try{localStorage.removeItem(e),c(`Removed from localStorage: ${e}`);}catch(t){o(`Failed to remove from localStorage: ${e}`,t);}}}logout(){if(D)try{const e="human_behavior_end_user_id";this.deleteCookie(e);const s="human_behavior_session";localStorage.removeItem(s),this.endUserId=null,this.userProperties={},this.endUserId=v1(),this.setCookie("human_behavior_end_user_id",this.endUserId,365),this.sessionId=this.createNewSession(s),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),d("User logged out - cleared all user data and started fresh session");}catch(e){o("Error during logout:",e);}}async redact(e){await this.ensureInitialized(),D?this.redactionManager=new v(e):a("Redaction is only available in browser environments");}setRedactedFields(e){this.redactionManager.setFieldsToRedact(e),this.recordInstance&&this.restartWithNewRedaction();}setUnredactedFields(e){this.redactionManager.setFieldsToUnredact(e),this.recordInstance&&this.restartWithNewRedaction();}restartWithNewRedaction(){this.recordInstance&&(this.recordInstance(),this.start());}hasUnredactedFields(){return this.redactionManager.hasUnredactedFields()}getUnredactedFields(){return this.redactionManager.getUnredactedFields()}redactFields(e){this.redactionManager.redactFields(e),this.recordInstance&&this.restartWithNewRedaction();}clearUnredactedFields(){this.redactionManager.clearUnredactedFields(),this.recordInstance&&this.restartWithNewRedaction();}checkAndRefreshSession(){if(!D)return;const e="human_behavior_session",s=Date.now(),i=this.getStoredSession(e);if(!i||!i.sessionId)return this.createNewSession(e),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),void c(`Created new session (no stored session): ${this.sessionId}`);this.updateSessionActivity(e,s,i.sessionId,i.sessionStartTimestamp);}getOrCreateSessionId(){if(!D)return v1();const e="human_behavior_session",s=Date.now(),i=this.getStoredSession(e);if(!i||!i.sessionId){const t=this.createNewSession(e);return this.api.setTrackingContext(t,this.endUserId),t}const n=s-i.lastActivityTimestamp,r=s-i.sessionStartTimestamp;if(n>this.SESSION_IDLE_TIMEOUT_MS||r>this.SESSION_MAX_LENGTH_MS){c(`Session expired: idle=${n}ms, age=${r}ms`);const t=this.createNewSession(e);return this.api.setTrackingContext(t,this.endUserId),t}return this.updateSessionActivity(e,s,i.sessionId,i.sessionStartTimestamp),i.sessionId}getStoredSession(e){const s=Date.now(),i=this.SESSION_IDLE_TIMEOUT_MS,n=this.SESSION_MAX_LENGTH_MS;if(this.sessionId&&null!==this._sessionActivityTimestamp&&null!==this._sessionStartTimestamp){const r=s-this._sessionActivityTimestamp,o=s-this._sessionStartTimestamp;if(!(r>i||o>n))return {sessionId:this.sessionId,lastActivityTimestamp:this._sessionActivityTimestamp,sessionStartTimestamp:this._sessionStartTimestamp};{c("Session in memory expired: creating new session immediately");const s=this.sessionId;if(this.createNewSession(e),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),d(`π Session timeout (memory): Created new session ${this.sessionId} (previous: ${s})`),null!==this._sessionActivityTimestamp&&null!==this._sessionStartTimestamp)return {sessionId:this.sessionId,lastActivityTimestamp:this._sessionActivityTimestamp,sessionStartTimestamp:this._sessionStartTimestamp}}}try{const r=localStorage.getItem(e);if(!r)return null;const o=JSON.parse(r),a=s-o.lastActivityTimestamp,l=s-o.sessionStartTimestamp;if(a>i||l>n){c(`Session in localStorage expired: idle=${Math.round(a/1e3/60)}min, age=${Math.round(l/1e3/60/60)}hrs`);const s=o.sessionId;if(this.createNewSession(e),this.windowId=v1(),this._setWindowIdInStorage(this.windowId),this.api.setTrackingContext(this.sessionId,this.endUserId),this.takeFullSnapshot(),d(`π Session timeout (localStorage): Created new session ${this.sessionId} (previous: ${s})`),null!==this._sessionActivityTimestamp&&null!==this._sessionStartTimestamp)return {sessionId:this.sessionId,lastActivityTimestamp:this._sessionActivityTimestamp,sessionStartTimestamp:this._sessionStartTimestamp}}return o.sessionId&&(this.sessionId=o.sessionId,this._sessionActivityTimestamp=o.lastActivityTimestamp,this._sessionStartTimestamp=o.sessionStartTimestamp),o}catch{return null}}createNewSession(e){const s=v1(),i=Date.now();this.sessionId=s,this._sessionActivityTimestamp=i,this._sessionStartTimestamp=i,this._lastActivityTimestamp=i;const n={sessionId:s,lastActivityTimestamp:i,sessionStartTimestamp:i};try{localStorage.setItem(e,JSON.stringify(n));}catch(e){a(`Failed to save session to localStorage: ${e}`);}return c(`Created new session: ${s}`),s}updateSessionActivity(e,t,s,i){this.sessionId=s,this._sessionActivityTimestamp=t,this._sessionStartTimestamp=i;const n={sessionId:s,lastActivityTimestamp:t,sessionStartTimestamp:i};try{localStorage.setItem(e,JSON.stringify(n));}catch(e){a(`Failed to update session in localStorage: ${e}`);}}getSessionId(){return this.sessionId}getCurrentUrl(){return D&&"undefined"!=typeof window&&window.location?window.location.href:this.currentUrl}getSnapshotFrequencyInfo(){return {sessionDuration:Date.now()-this.sessionStartTime,currentInterval:3e5,currentThreshold:1e3,phase:"configured"}}async testConnection(){try{return await this.api.init(this.sessionId,this.endUserId),{success:!0}}catch(e){return {success:false,error:e.message||"Unknown error"}}}getConnectionStatus(){const e=[];let t=false;return this.eventQueue.length>0&&(t=true,e.push("Some requests may be blocked by ad blockers")),this._connectionBlocked&&(t=true,e.push("Initial connection test failed - ad blocker may be active")),"undefined"==typeof window&&e.push("Not running in browser environment"),void 0===navigator.sendBeacon&&e.push("sendBeacon not available, using fetch fallback"),{blocked:t,recommendations:e}}isPreexistingUser(){if(!D)return false;const e=this.getCookie("human_behavior_end_user_id");return null!==e&&e!==this.endUserId}getUserInfo(){return {endUserId:this.endUserId,sessionId:this.sessionId,isPreexistingUser:this.isPreexistingUser(),initialized:this.initialized}}setSessionProperty(e,t){this.propertyManager.setSessionProperty(e,t);}setSessionProperties(e){this.propertyManager.setSessionProperties(e);}getSessionProperty(e){return this.propertyManager.getSessionProperty(e)}removeSessionProperty(e){this.propertyManager.removeSessionProperty(e);}setUserProperty(e,t){this.propertyManager.setUserProperty(e,t);}setUserProperties(e){this.propertyManager.setUserProperties(e);}getUserProperty(e){return this.propertyManager.getUserProperty(e)}removeUserProperty(e){this.propertyManager.removeUserProperty(e);}setOnce(e,t,s="user"){this.propertyManager.setOnce(e,t,s);}clearSessionProperties(){this.propertyManager.clearSessionProperties();}clearUserProperties(){this.propertyManager.clearUserProperties();}getAllProperties(){return this.propertyManager.getAllProperties()}}function F(e){const t=globalThis.__humanBehaviorGlobalTracker;return t?.identifyUser?t.identifyUser({userProperties:e}):(console.warn("HumanBehavior tracker not found. Make sure the SDK is initialized."),null)}function L(e,t){const s=("undefined"!=typeof window?window:globalThis).__humanBehaviorGlobalTracker;return s?.customEvent?s.customEvent(e,t):s?.track?s.track(e,t):(console.warn("HumanBehavior tracker not found. Make sure the SDK is initialized."),null)}function R(){const e=globalThis.__humanBehaviorGlobalTracker;return !!e?.identifyUser}D&&(window.HumanBehaviorTracker=P);
|
|
12175
12373
|
|
|
12176
12374
|
/**
|
|
12177
12375
|
* Main entry point for the HumanBehavior SDK
|
|
@@ -12179,13 +12377,13 @@ var s;!function(e){e[e.NONE=0]="NONE",e[e.ERROR=1]="ERROR",e[e.WARN=2]="WARN",e[
|
|
|
12179
12377
|
// Import the main tracker first
|
|
12180
12378
|
// Create an initialization function
|
|
12181
12379
|
const init = (apiKey, ingestionUrl, options) => {
|
|
12182
|
-
return new
|
|
12380
|
+
return new P(apiKey, ingestionUrl, options);
|
|
12183
12381
|
};
|
|
12184
12382
|
// For UMD builds, expose the class and init function globally
|
|
12185
12383
|
if (typeof window !== 'undefined') {
|
|
12186
|
-
window.HumanBehaviorTracker =
|
|
12384
|
+
window.HumanBehaviorTracker = P;
|
|
12187
12385
|
window.humanbehavior = { init };
|
|
12188
12386
|
}
|
|
12189
12387
|
|
|
12190
|
-
export { y as HumanBehaviorAPI,
|
|
12388
|
+
export { y as HumanBehaviorAPI, P as HumanBehaviorTracker, s as LogLevel, U as PropertyManager, v as RedactionManager, I as getAutomaticProperties, C as getCurrentPageProperties, T as getDeviceInfo, b as getInitialProperties, E as getLocationInfo, F as identifyUserGlobally, init, R as isGlobalTrackerAvailable, r as isSDKLogging, c as logDebug, o as logError, d as logInfo, a as logWarn, i as logger, L as sendEventGlobally };
|
|
12191
12389
|
//# sourceMappingURL=index.js.map
|