humanbehavior-js 0.5.71 β†’ 0.6.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.
@@ -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$2 = /* @__PURE__ */ ((NodeType2) => {
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$2 || {});
16
+ })(NodeType$3 || {});
17
17
  const testableAccessors$1 = {
18
- Node: ["childNodes", "parentNode", "parentElement", "textContent"],
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, s2.href)
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" && (tagName === "table" || tagName === "td" || tagName === "th")) {
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 (tagName === "video" || tagName === "audio") && name === "autoplay";
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$2.Document,
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$2.Document,
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$2.DocumentType,
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$2.CDATA,
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$2.Comment,
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
- var _a2;
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 text = index$1.textContent(n2);
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
- text = "SCRIPT_PLACEHOLDER";
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 && text && needsMask) {
772
- text = maskTextFn ? maskTextFn(text, index$1.parentElement(n2)) : text.replace(/[\S]/g, "*");
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$2.Text,
776
- textContent: text || "",
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 && // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element
826
- !(n2.innerText || index$1.textContent(n2) || "").trim().length) {
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 (tagName === "input" || tagName === "textarea" || tagName === "select") {
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 (tagName === "audio" || tagName === "video") {
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$2.Element,
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$2.Comment) {
1142
+ if (slimDOMOptions.comment && sn.type === NodeType$3.Comment) {
979
1143
  return true;
980
- } else if (sn.type === NodeType$2.Element) {
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" || sn.attributes.rel === "modulepreload") && sn.attributes.as === "script" || // prefetch link
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$2.Text && !_serializedNode.isStyle && !_serializedNode.textContent.replace(/^\s+|\s+$/gm, "").length) {
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$2.Element) {
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$2.Document || serializedNode.type === NodeType$2.Element) && recordChild) {
1090
- if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType$2.Element && serializedNode.tagName === "head") {
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$2.Element && serializedNode.tagName === "textarea" && serializedNode.attributes.value !== void 0) ;
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$2.Element && serializedNode.tagName === "iframe") {
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$2.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")) {
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 === true || slimDOM === "all" ? (
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: ["childNodes", "parentNode", "parentElement", "textContent"],
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 = n2.ownerDocument;
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 = n2.ownerDocument;
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) || parent.tagName === "TEXTAREA") {
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.removes, n2, this.mirror) && !this.movedSet.has(index.parentNode(n2))) {
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.removes, n2, this.mirror)) {
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
- item.attributes.value = Array.from(
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 isParentRemoved(removes, n2, mirror2) {
9470
- if (removes.length === 0) return false;
9471
- return _isParentRemoved(removes, n2, mirror2);
9472
- }
9473
- function _isParentRemoved(removes, n2, mirror2) {
9474
- let node2 = index.parentNode(n2);
9475
- while (node2) {
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 false;
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$2.Document && !node2.rootId) node2.rootId = rootId;
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 === true || _slimDOMOptions === "all" ? {
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 (document.readyState === "interactive" || document.readyState === "complete") {
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((h) => h());
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;}},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.71",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 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,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 k="undefined"!=typeof window;function _(){if(!k)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 S(e){try{return new URL(e).hostname}catch{return ""}}function T(){if(!k)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(!k)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(!k)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:_(),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 I(){if(!k)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:S(t),initial_referrer:t,initial_referrer_domain:S(t),initial_host:window.location.hostname,...s}}function b(){return {...T(),...I()}}function E(){if(!k)return {};const e=I();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(!k)return {};const e=I();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=b(),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=b();}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,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(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 l("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._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||[]}),D){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(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{D?(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(!D||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()),D&&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(!D)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),this.setupClickTracking(t),t.trackButtons&&this.setupAutomaticButtonTracking(t),t.trackForms&&this.setupAutomaticFormTracking(t),this.setupRageClickDetection(),this.setupDeadClickDetection();}setupClickTracking(e){document.addEventListener("click",async t=>{const s=t.target;if(!s||!s.tagName)return;const i=s.closest('button, a, [role="button"], [role="link"], [role="tab"], [role="menuitem"]')||s,n={tag:i.tagName.toLowerCase(),x:t.clientX,y:t.clientY,page:window.location.pathname,timestamp:Date.now()};if(i.id&&(n.elementId=i.id),i.href&&(n.href=i.href),e.includeText){const e=i.textContent?.trim();e&&(n.elementText=e.substring(0,100));}e.includeClasses&&i.className&&(n.elementClass=i.className),await this.customEvent("$click",n);});}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(){D&&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}setupDeadClickDetection(){D&&(this.setupDeadClickMutationObserver(),this.setupDeadClickScrollObserver(),this.setupDeadClickSelectionObserver(),this.setupDeadClickNavigationTracking(),document.addEventListener("click",e=>{const t=e.target;if(!t)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){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"]')}ignoreClickForDeadDetection(e){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 l=void 0!==i&&i<this.DEAD_CLICK_MUTATION_THRESHOLD_MS,c=void 0!==d&&d<this.DEAD_CLICK_SELECTION_THRESHOLD_MS;l||c||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,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(){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,l("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 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},automaticProperties:this.propertyManager.getAutomaticProperties()};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},automaticProperties:this.propertyManager.getAutomaticProperties()};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},automaticProperties:this.propertyManager.getAutomaticProperties()};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(){D&&"undefined"!=typeof window&&("complete"===document.readyState?this.trackPageLoad():window.addEventListener("load",()=>{this.trackPageLoad();}),l("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 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(){D&&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:D?window.location.href:"",userAgent:D?navigator.userAgent:"",stack:s,sessionId:this.sessionId,endUserId:this.endUserId,automaticProperties:this.propertyManager.getAutomaticProperties()};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(!D)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(D&&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}),!D||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),D)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(!D)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(),this.api.sendIpInfo(this.sessionId,this.endUserId);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(),D&&(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(),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);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&&D&&(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(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);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(!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),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(!D)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(){D&&window.addEventListener("beforeunload",()=>{this._canUseSessionStorage()&&(this._setPrimaryWindowExists(false),l("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),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(!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 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(D){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(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 l(`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>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(!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 R(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}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 F(apiKey, ingestionUrl, options);
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 = F;
12384
+ window.HumanBehaviorTracker = P;
12187
12385
  window.humanbehavior = { init };
12188
12386
  }
12189
12387
 
12190
- export { y as HumanBehaviorAPI, F as HumanBehaviorTracker, s as LogLevel, U as PropertyManager, v as RedactionManager, T as getAutomaticProperties, C as getCurrentPageProperties, I as getDeviceInfo, E as getInitialProperties, b as getLocationInfo, R as identifyUserGlobally, init, L as isGlobalTrackerAvailable, r as isSDKLogging, l as logDebug, o as logError, d as logInfo, a as logWarn, i as logger, D as sendEventGlobally };
12388
+ export { y as HumanBehaviorAPI, P as HumanBehaviorTracker, s as LogLevel, U as PropertyManager, v as RedactionManager, b as getAutomaticProperties, C as getCurrentPageProperties, T as getDeviceInfo, E as getInitialProperties, I as getLocationInfo, F as identifyUserGlobally, init, L as isGlobalTrackerAvailable, r as isSDKLogging, l as logDebug, o as logError, d as logInfo, a as logWarn, i as logger, R as sendEventGlobally };
12191
12389
  //# sourceMappingURL=index.js.map