@tracelog/lib 0.5.5 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/README.md +157 -180
  2. package/dist/browser/tracelog.esm.js +1124 -1377
  3. package/dist/browser/tracelog.esm.js.map +1 -0
  4. package/dist/browser/tracelog.js +2 -2
  5. package/dist/browser/tracelog.js.map +1 -0
  6. package/dist/cjs/api.d.ts +12 -2
  7. package/dist/cjs/api.js +74 -29
  8. package/dist/cjs/app.d.ts +2 -2
  9. package/dist/cjs/app.js +26 -32
  10. package/dist/cjs/constants/config.constants.d.ts +7 -2
  11. package/dist/cjs/constants/config.constants.js +9 -18
  12. package/dist/cjs/constants/index.d.ts +0 -1
  13. package/dist/cjs/constants/index.js +0 -1
  14. package/dist/cjs/constants/storage.constants.d.ts +3 -2
  15. package/dist/cjs/constants/storage.constants.js +4 -4
  16. package/dist/cjs/handlers/click.handler.js +3 -6
  17. package/dist/cjs/handlers/error.handler.js +1 -11
  18. package/dist/cjs/handlers/page-view.handler.js +0 -4
  19. package/dist/cjs/handlers/performance.handler.js +14 -29
  20. package/dist/cjs/handlers/scroll.handler.js +7 -6
  21. package/dist/cjs/handlers/session.handler.js +7 -6
  22. package/dist/cjs/integrations/google-analytics.integration.js +2 -6
  23. package/dist/cjs/listeners/activity-listener-manager.js +3 -3
  24. package/dist/cjs/listeners/input-listener-managers.js +3 -3
  25. package/dist/cjs/listeners/touch-listener-manager.js +3 -3
  26. package/dist/cjs/listeners/unload-listener-manager.js +3 -3
  27. package/dist/cjs/listeners/visibility-listener-manager.js +3 -3
  28. package/dist/cjs/managers/event.manager.d.ts +5 -1
  29. package/dist/cjs/managers/event.manager.js +103 -40
  30. package/dist/cjs/managers/sender.manager.js +29 -36
  31. package/dist/cjs/managers/session.manager.js +5 -13
  32. package/dist/cjs/managers/state.manager.d.ts +0 -3
  33. package/dist/cjs/managers/state.manager.js +1 -43
  34. package/dist/cjs/managers/storage.manager.d.ts +21 -2
  35. package/dist/cjs/managers/storage.manager.js +164 -21
  36. package/dist/cjs/managers/user.manager.d.ts +1 -1
  37. package/dist/cjs/managers/user.manager.js +2 -2
  38. package/dist/cjs/public-api.d.ts +3 -3
  39. package/dist/cjs/public-api.js +1 -1
  40. package/dist/cjs/test-bridge.d.ts +1 -0
  41. package/dist/cjs/test-bridge.js +37 -2
  42. package/dist/cjs/types/config.types.d.ts +17 -20
  43. package/dist/cjs/types/config.types.js +6 -0
  44. package/dist/cjs/types/event.types.d.ts +1 -13
  45. package/dist/cjs/types/index.d.ts +0 -2
  46. package/dist/cjs/types/index.js +0 -2
  47. package/dist/cjs/types/mode.types.d.ts +1 -2
  48. package/dist/cjs/types/mode.types.js +0 -1
  49. package/dist/cjs/types/queue.types.d.ts +0 -6
  50. package/dist/cjs/types/state.types.d.ts +2 -0
  51. package/dist/cjs/types/test-bridge.types.d.ts +2 -2
  52. package/dist/cjs/types/validation-error.types.d.ts +0 -6
  53. package/dist/cjs/types/validation-error.types.js +1 -10
  54. package/dist/cjs/utils/browser/device-detector.utils.js +2 -24
  55. package/dist/cjs/utils/browser/index.d.ts +1 -0
  56. package/dist/cjs/utils/browser/index.js +1 -0
  57. package/dist/cjs/utils/browser/qa-mode.utils.d.ts +13 -0
  58. package/dist/cjs/utils/browser/qa-mode.utils.js +43 -0
  59. package/dist/cjs/utils/browser/utm-params.utils.js +0 -15
  60. package/dist/cjs/utils/data/uuid.utils.d.ts +13 -0
  61. package/dist/cjs/utils/data/uuid.utils.js +37 -1
  62. package/dist/cjs/utils/index.d.ts +1 -1
  63. package/dist/cjs/utils/index.js +1 -1
  64. package/dist/cjs/utils/logging.utils.d.ts +21 -0
  65. package/dist/cjs/utils/logging.utils.js +86 -0
  66. package/dist/cjs/utils/network/index.d.ts +0 -1
  67. package/dist/cjs/utils/network/index.js +0 -1
  68. package/dist/cjs/utils/network/url.utils.d.ts +2 -8
  69. package/dist/cjs/utils/network/url.utils.js +45 -90
  70. package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -13
  71. package/dist/cjs/utils/security/sanitize.utils.js +15 -178
  72. package/dist/cjs/utils/validations/config-validations.utils.d.ts +3 -9
  73. package/dist/cjs/utils/validations/config-validations.utils.js +56 -93
  74. package/dist/cjs/utils/validations/event-validations.utils.js +11 -5
  75. package/dist/cjs/utils/validations/index.d.ts +0 -1
  76. package/dist/cjs/utils/validations/index.js +0 -1
  77. package/dist/cjs/utils/validations/metadata-validations.utils.js +0 -1
  78. package/dist/cjs/utils/validations/type-guards.utils.d.ts +2 -2
  79. package/dist/cjs/utils/validations/type-guards.utils.js +50 -4
  80. package/dist/esm/api.d.ts +12 -2
  81. package/dist/esm/api.js +73 -29
  82. package/dist/esm/app.d.ts +2 -2
  83. package/dist/esm/app.js +28 -34
  84. package/dist/esm/constants/config.constants.d.ts +7 -2
  85. package/dist/esm/constants/config.constants.js +7 -16
  86. package/dist/esm/constants/index.d.ts +0 -1
  87. package/dist/esm/constants/index.js +0 -1
  88. package/dist/esm/constants/storage.constants.d.ts +3 -2
  89. package/dist/esm/constants/storage.constants.js +3 -2
  90. package/dist/esm/handlers/click.handler.js +3 -6
  91. package/dist/esm/handlers/error.handler.js +1 -11
  92. package/dist/esm/handlers/page-view.handler.js +0 -4
  93. package/dist/esm/handlers/performance.handler.js +14 -29
  94. package/dist/esm/handlers/scroll.handler.js +7 -6
  95. package/dist/esm/handlers/session.handler.js +7 -6
  96. package/dist/esm/integrations/google-analytics.integration.js +3 -7
  97. package/dist/esm/listeners/activity-listener-manager.js +3 -3
  98. package/dist/esm/listeners/input-listener-managers.js +3 -3
  99. package/dist/esm/listeners/touch-listener-manager.js +3 -3
  100. package/dist/esm/listeners/unload-listener-manager.js +3 -3
  101. package/dist/esm/listeners/visibility-listener-manager.js +3 -3
  102. package/dist/esm/managers/event.manager.d.ts +5 -1
  103. package/dist/esm/managers/event.manager.js +106 -43
  104. package/dist/esm/managers/sender.manager.js +31 -38
  105. package/dist/esm/managers/session.manager.js +5 -13
  106. package/dist/esm/managers/state.manager.d.ts +0 -3
  107. package/dist/esm/managers/state.manager.js +1 -43
  108. package/dist/esm/managers/storage.manager.d.ts +21 -2
  109. package/dist/esm/managers/storage.manager.js +164 -21
  110. package/dist/esm/managers/user.manager.d.ts +1 -1
  111. package/dist/esm/managers/user.manager.js +2 -2
  112. package/dist/esm/public-api.d.ts +3 -3
  113. package/dist/esm/public-api.js +1 -1
  114. package/dist/esm/test-bridge.d.ts +1 -0
  115. package/dist/esm/test-bridge.js +37 -2
  116. package/dist/esm/types/config.types.d.ts +17 -20
  117. package/dist/esm/types/config.types.js +5 -1
  118. package/dist/esm/types/event.types.d.ts +1 -13
  119. package/dist/esm/types/index.d.ts +0 -2
  120. package/dist/esm/types/index.js +0 -2
  121. package/dist/esm/types/mode.types.d.ts +1 -2
  122. package/dist/esm/types/mode.types.js +0 -1
  123. package/dist/esm/types/queue.types.d.ts +0 -6
  124. package/dist/esm/types/state.types.d.ts +2 -0
  125. package/dist/esm/types/test-bridge.types.d.ts +2 -2
  126. package/dist/esm/types/validation-error.types.d.ts +0 -6
  127. package/dist/esm/types/validation-error.types.js +0 -8
  128. package/dist/esm/utils/browser/device-detector.utils.js +2 -24
  129. package/dist/esm/utils/browser/index.d.ts +1 -0
  130. package/dist/esm/utils/browser/index.js +1 -0
  131. package/dist/esm/utils/browser/qa-mode.utils.d.ts +13 -0
  132. package/dist/esm/utils/browser/qa-mode.utils.js +39 -0
  133. package/dist/esm/utils/browser/utm-params.utils.js +0 -15
  134. package/dist/esm/utils/data/uuid.utils.d.ts +13 -0
  135. package/dist/esm/utils/data/uuid.utils.js +35 -0
  136. package/dist/esm/utils/index.d.ts +1 -1
  137. package/dist/esm/utils/index.js +1 -1
  138. package/dist/esm/utils/logging.utils.d.ts +21 -0
  139. package/dist/esm/utils/logging.utils.js +81 -0
  140. package/dist/esm/utils/network/index.d.ts +0 -1
  141. package/dist/esm/utils/network/index.js +0 -1
  142. package/dist/esm/utils/network/url.utils.d.ts +2 -8
  143. package/dist/esm/utils/network/url.utils.js +44 -88
  144. package/dist/esm/utils/security/sanitize.utils.d.ts +1 -13
  145. package/dist/esm/utils/security/sanitize.utils.js +15 -176
  146. package/dist/esm/utils/validations/config-validations.utils.d.ts +3 -9
  147. package/dist/esm/utils/validations/config-validations.utils.js +57 -93
  148. package/dist/esm/utils/validations/event-validations.utils.js +11 -5
  149. package/dist/esm/utils/validations/index.d.ts +0 -1
  150. package/dist/esm/utils/validations/index.js +0 -1
  151. package/dist/esm/utils/validations/metadata-validations.utils.js +0 -1
  152. package/dist/esm/utils/validations/type-guards.utils.d.ts +2 -2
  153. package/dist/esm/utils/validations/type-guards.utils.js +50 -4
  154. package/package.json +3 -2
  155. package/dist/cjs/app.types.d.ts +0 -2
  156. package/dist/cjs/app.types.js +0 -12
  157. package/dist/cjs/constants/api.constants.d.ts +0 -6
  158. package/dist/cjs/constants/api.constants.js +0 -14
  159. package/dist/cjs/managers/api.manager.d.ts +0 -13
  160. package/dist/cjs/managers/api.manager.js +0 -44
  161. package/dist/cjs/managers/config.builder.d.ts +0 -33
  162. package/dist/cjs/managers/config.builder.js +0 -116
  163. package/dist/cjs/managers/config.manager.d.ts +0 -56
  164. package/dist/cjs/managers/config.manager.js +0 -157
  165. package/dist/cjs/managers/tags.manager.d.ts +0 -36
  166. package/dist/cjs/managers/tags.manager.js +0 -171
  167. package/dist/cjs/types/api.types.d.ts +0 -52
  168. package/dist/cjs/types/api.types.js +0 -56
  169. package/dist/cjs/types/tag.types.d.ts +0 -43
  170. package/dist/cjs/types/tag.types.js +0 -31
  171. package/dist/cjs/utils/logging/debug-logger.utils.d.ts +0 -14
  172. package/dist/cjs/utils/logging/debug-logger.utils.js +0 -47
  173. package/dist/cjs/utils/logging/index.d.ts +0 -1
  174. package/dist/cjs/utils/logging/index.js +0 -5
  175. package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +0 -4
  176. package/dist/cjs/utils/network/fetch-with-timeout.utils.js +0 -25
  177. package/dist/cjs/utils/validations/url-validations.utils.d.ts +0 -15
  178. package/dist/cjs/utils/validations/url-validations.utils.js +0 -47
  179. package/dist/esm/app.types.d.ts +0 -2
  180. package/dist/esm/app.types.js +0 -1
  181. package/dist/esm/constants/api.constants.d.ts +0 -6
  182. package/dist/esm/constants/api.constants.js +0 -11
  183. package/dist/esm/managers/api.manager.d.ts +0 -13
  184. package/dist/esm/managers/api.manager.js +0 -41
  185. package/dist/esm/managers/config.builder.d.ts +0 -33
  186. package/dist/esm/managers/config.builder.js +0 -112
  187. package/dist/esm/managers/config.manager.d.ts +0 -56
  188. package/dist/esm/managers/config.manager.js +0 -153
  189. package/dist/esm/managers/tags.manager.d.ts +0 -36
  190. package/dist/esm/managers/tags.manager.js +0 -167
  191. package/dist/esm/types/api.types.d.ts +0 -52
  192. package/dist/esm/types/api.types.js +0 -53
  193. package/dist/esm/types/tag.types.d.ts +0 -43
  194. package/dist/esm/types/tag.types.js +0 -28
  195. package/dist/esm/utils/logging/debug-logger.utils.d.ts +0 -14
  196. package/dist/esm/utils/logging/debug-logger.utils.js +0 -44
  197. package/dist/esm/utils/logging/index.d.ts +0 -1
  198. package/dist/esm/utils/logging/index.js +0 -1
  199. package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +0 -4
  200. package/dist/esm/utils/network/fetch-with-timeout.utils.js +0 -22
  201. package/dist/esm/utils/validations/url-validations.utils.d.ts +0 -15
  202. package/dist/esm/utils/validations/url-validations.utils.js +0 -42
@@ -1,5 +1,4 @@
1
- var I = /* @__PURE__ */ ((r) => (r.Mobile = "mobile", r.Tablet = "tablet", r.Desktop = "desktop", r.Unknown = "unknown", r))(I || {});
2
- const P = 15 * 60 * 1e3, Je = 500, Ze = 1e4, xe = 250, et = 24, pe = 100, Se = 3, tt = 5e3, Ue = 1e4, rt = 10, Ee = 5, ve = 500, ye = 120, M = 1, nt = 0, st = 1, k = 3e4, x = 864e5, Ie = 120, Te = 8 * 1024, _e = 10, we = 10, X = 255, T = 1e3, q = 100, Ae = 3, w = 2, F = "data-tl", it = [
1
+ const O = "data-tlog", Ce = [
3
2
  "button",
4
3
  "a",
5
4
  'input[type="button"]',
@@ -31,47 +30,102 @@ const P = 15 * 60 * 1e3, Je = 500, Ze = 1e4, xe = 250, et = 24, pe = 100, Se = 3
31
30
  ".menu-item",
32
31
  "[data-testid]",
33
32
  '[tabindex="0"]'
34
- ], at = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"], ot = 2, lt = /* @__PURE__ */ new Set([
35
- "mode",
36
- "tags",
37
- "samplingRate",
38
- "excludedUrlPaths",
39
- "ipExcluded"
40
- ]), y = {
41
- // Project ID validation - consistent message across all layers
42
- MISSING_PROJECT_ID: "Project ID is required",
43
- PROJECT_ID_EMPTY_AFTER_TRIM: "Project ID is required",
44
- // Session timeout validation
45
- INVALID_SESSION_TIMEOUT: `Session timeout must be between ${k}ms (30 seconds) and ${x}ms (24 hours)`,
33
+ ], be = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
34
+ const m = {
35
+ INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",
36
+ INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1",
46
37
  INVALID_ERROR_SAMPLING_RATE: "Error sampling must be between 0 and 1",
47
- // Integration validation
38
+ INVALID_TRACELOG_PROJECT_ID: "TraceLog project ID is required when integration is enabled",
39
+ INVALID_CUSTOM_API_URL: "Custom API URL is required when integration is enabled",
48
40
  INVALID_GOOGLE_ANALYTICS_ID: "Google Analytics measurement ID is required when integration is enabled",
49
- // UI validation
50
41
  INVALID_SCROLL_CONTAINER_SELECTORS: "Scroll container selectors must be valid CSS selectors",
51
- // Global metadata validation
52
42
  INVALID_GLOBAL_METADATA: "Global metadata must be an object",
53
- // Array validation
54
43
  INVALID_SENSITIVE_QUERY_PARAMS: "Sensitive query params must be an array of strings"
55
- }, He = [
44
+ }, Oe = [
56
45
  /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
57
46
  /javascript:/gi,
58
47
  /on\w+\s*=/gi,
59
48
  /<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
60
49
  /<embed\b[^>]*>/gi,
61
50
  /<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi
62
- ], N = {
63
- samplingRate: M,
64
- excludedUrlPaths: [],
65
- tags: [],
66
- ipExcluded: !1
67
- }, _ = "tl", ct = (r) => r ? `${_}:${r}:uid` : `${_}:uid`, ut = (r) => r ? `${_}:${r}:queue` : `${_}:queue`, dt = (r) => r ? `${_}:${r}:session` : `${_}:session`, ht = (r) => r ? `${_}:${r}:broadcast` : `${_}:broadcast`, Ve = {
51
+ ];
52
+ var j = /* @__PURE__ */ ((s) => (s.Localhost = "localhost:8080", s.Fail = "localhost:9999", s))(j || {}), _ = /* @__PURE__ */ ((s) => (s.Mobile = "mobile", s.Tablet = "tablet", s.Desktop = "desktop", s.Unknown = "unknown", s))(_ || {}), X = /* @__PURE__ */ ((s) => (s.EVENT = "event", s.QUEUE = "queue", s))(X || {}), d = /* @__PURE__ */ ((s) => (s.PAGE_VIEW = "page_view", s.CLICK = "click", s.SCROLL = "scroll", s.SESSION_START = "session_start", s.SESSION_END = "session_end", s.CUSTOM = "custom", s.WEB_VITALS = "web_vitals", s.ERROR = "error", s))(d || {}), D = /* @__PURE__ */ ((s) => (s.UP = "up", s.DOWN = "down", s))(D || {}), L = /* @__PURE__ */ ((s) => (s.JS_ERROR = "js_error", s.PROMISE_REJECTION = "promise_rejection", s))(L || {}), R = /* @__PURE__ */ ((s) => (s.QA = "qa", s))(R || {});
53
+ class C extends Error {
54
+ constructor(e, t, r) {
55
+ super(e), this.errorCode = t, this.layer = r, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
56
+ }
57
+ }
58
+ class y extends C {
59
+ constructor(e, t = "config") {
60
+ super(e, "APP_CONFIG_INVALID", t);
61
+ }
62
+ }
63
+ class Pe extends C {
64
+ constructor(e, t = "config") {
65
+ super(e, "SESSION_TIMEOUT_INVALID", t);
66
+ }
67
+ }
68
+ class oe extends C {
69
+ constructor(e, t = "config") {
70
+ super(e, "SAMPLING_RATE_INVALID", t);
71
+ }
72
+ }
73
+ class v extends C {
74
+ constructor(e, t = "config") {
75
+ super(e, "INTEGRATION_INVALID", t);
76
+ }
77
+ }
78
+ class xt extends C {
79
+ constructor(e, t, r = "runtime") {
80
+ super(e, "INITIALIZATION_TIMEOUT", r), this.timeoutMs = t;
81
+ }
82
+ }
83
+ const De = (s, e) => {
84
+ if (e) {
85
+ if (e instanceof Error) {
86
+ const t = e.message.replace(/\s+at\s+.*$/gm, "").replace(/\(.*?:\d+:\d+\)/g, "");
87
+ return `[TraceLog] ${s}: ${t}`;
88
+ }
89
+ return `[TraceLog] ${s}: ${e instanceof Error ? e.message : "Unknown error"}`;
90
+ }
91
+ return `[TraceLog] ${s}`;
92
+ }, o = (s, e, t) => {
93
+ const { error: r, data: n, showToClient: i = !1 } = t ?? {}, a = r ? De(e, r) : `[TraceLog] ${e}`, c = s === "error" ? "error" : s === "warn" ? "warn" : "log";
94
+ if (!(s === "debug" || s === "info" && !i))
95
+ if (n !== void 0) {
96
+ const l = ke(n);
97
+ console[c](a, l);
98
+ } else n !== void 0 ? console[c](a, n) : console[c](a);
99
+ }, ke = (s) => {
100
+ const e = {}, t = ["token", "password", "secret", "key", "apikey", "api_key", "sessionid", "session_id"];
101
+ for (const [r, n] of Object.entries(s)) {
102
+ const i = r.toLowerCase();
103
+ t.some((a) => i.includes(a)) ? e[r] = "[REDACTED]" : e[r] = n;
104
+ }
105
+ return e;
106
+ };
107
+ let W, pe;
108
+ const Ue = () => {
109
+ typeof window < "u" && !W && (W = window.matchMedia("(pointer: coarse)"), pe = window.matchMedia("(hover: none)"));
110
+ }, He = () => {
111
+ try {
112
+ const s = navigator;
113
+ if (s.userAgentData && typeof s.userAgentData.mobile == "boolean")
114
+ return s.userAgentData.platform && /ipad|tablet/i.test(s.userAgentData.platform) ? _.Tablet : s.userAgentData.mobile ? _.Mobile : _.Desktop;
115
+ Ue();
116
+ const e = window.innerWidth, t = W?.matches ?? !1, r = pe?.matches ?? !1, n = "ontouchstart" in window || navigator.maxTouchPoints > 0, i = navigator.userAgent.toLowerCase(), a = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i), c = /tablet|ipad|android(?!.*mobile)/.test(i);
117
+ return e <= 767 || a && n ? _.Mobile : e >= 768 && e <= 1024 || c || t && r && n ? _.Tablet : _.Desktop;
118
+ } catch (s) {
119
+ return o("warn", "Device detection failed, defaulting to desktop", { error: s }), _.Desktop;
120
+ }
121
+ }, T = "tlog", ce = `${T}:qa_mode`, xe = `${T}:uid`, Ve = (s) => s ? `${T}:${s}:queue` : `${T}:queue`, Fe = (s) => s ? `${T}:${s}:session` : `${T}:session`, Ge = (s) => s ? `${T}:${s}:broadcast` : `${T}:broadcast`, _e = {
68
122
  LCP: 4e3,
69
123
  FCP: 1800,
70
124
  CLS: 0.25,
71
125
  INP: 200,
72
126
  TTFB: 800,
73
127
  LONG_TASK: 50
74
- }, gt = 1e3, Fe = [
128
+ }, ze = 1e3, Te = [
75
129
  // Email addresses
76
130
  /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,
77
131
  // US Phone numbers (various formats)
@@ -86,400 +140,252 @@ const P = 15 * 60 * 1e3, Je = 500, Ze = 1e4, xe = 250, et = 24, pe = 100, Se = 3
86
140
  /Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,
87
141
  // Passwords in connection strings (protocol://user:password@host)
88
142
  /:\/\/[^:/]+:([^@]+)@/gi
89
- ], be = 500, Me = 5e3, G = 50, Re = G * 2, p = {};
90
- function ft() {
91
- return p;
92
- }
93
- class m {
94
- get(e) {
95
- return p[e];
96
- }
97
- set(e, t) {
98
- const n = p[e];
99
- if (e === "config" && t) {
100
- const s = t;
101
- if (s) {
102
- const i = s.samplingRate ?? M, o = i < 0 || i > 1 ? M : i;
103
- if (o !== i) {
104
- const l = { ...s, samplingRate: o };
105
- p[e] = l;
106
- } else
107
- p[e] = s;
108
- } else
109
- p[e] = t;
110
- } else
111
- p[e] = t;
112
- this.isCriticalStateKey(e) && this.shouldLog(n, p[e]) && a.debug("StateManager", "State updated", {
113
- key: e,
114
- oldValue: this.formatLogValue(e, n),
115
- newValue: this.formatLogValue(e, p[e])
116
- });
117
- }
118
- getState() {
119
- return { ...p };
120
- }
121
- isCriticalStateKey(e) {
122
- return e === "sessionId" || e === "config" || e === "hasStartSession";
123
- }
124
- shouldLog(e, t) {
125
- return e !== t;
126
- }
127
- formatLogValue(e, t) {
128
- return e === "config" ? t ? "(configured)" : "(not configured)" : t;
129
- }
130
- }
131
- class mt {
132
- clientError = (e, t, n) => this.log("CLIENT_ERROR", e, t, n);
133
- clientWarn = (e, t, n) => this.log("CLIENT_WARN", e, t, n);
134
- info = (e, t, n) => this.log("INFO", e, t, n);
135
- error = (e, t, n) => this.log("ERROR", e, t, n);
136
- warn = (e, t, n) => this.log("WARN", e, t, n);
137
- debug = (e, t, n) => this.log("DEBUG", e, t, n);
138
- verbose = (e, t, n) => this.log("VERBOSE", e, t, n);
139
- log(e, t, n, s) {
140
- const i = ft()?.config?.mode;
141
- if (!this.shouldShow(e, i)) return;
142
- const o = `[TraceLog:${t}] ${n}`, c = this.getMethod(e);
143
- s !== void 0 ? console[c](o, s) : console[c](o);
144
- }
145
- shouldShow(e, t) {
146
- return ["CLIENT_ERROR", "ERROR"].includes(e) ? !0 : t ? t === "qa" ? ["INFO", "CLIENT_ERROR", "CLIENT_WARN"].includes(e) : t === "debug" : e === "CLIENT_WARN";
147
- }
148
- getMethod(e) {
149
- return ["CLIENT_ERROR", "ERROR"].includes(e) ? "error" : ["CLIENT_WARN", "WARN"].includes(e) ? "warn" : "log";
143
+ ], le = 500, ue = 5e3, k = 50, $e = k * 2, de = "tlog_mode", Qe = "qa", Be = () => {
144
+ if (sessionStorage.getItem(ce) === "true")
145
+ return !0;
146
+ const e = new URLSearchParams(window.location.search), r = e.get(de) === Qe;
147
+ if (r) {
148
+ sessionStorage.setItem(ce, "true"), e.delete(de);
149
+ const n = e.toString(), i = `${window.location.pathname}${n ? "?" + n : ""}${window.location.hash}`;
150
+ try {
151
+ window.history.replaceState({}, "", i);
152
+ } catch (a) {
153
+ o("warn", "History API not available, cannot replace URL", { error: a });
154
+ }
155
+ console.log(
156
+ "%c[TraceLog] QA Mode ACTIVE",
157
+ "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;"
158
+ );
150
159
  }
151
- }
152
- const a = new mt();
153
- let te, ze;
154
- const pt = () => {
155
- typeof window < "u" && !te && (te = window.matchMedia("(pointer: coarse)"), ze = window.matchMedia("(hover: none)"));
156
- }, St = () => {
157
- try {
158
- a.debug("DeviceDetector", "Starting device detection");
159
- const r = navigator;
160
- if (r.userAgentData && typeof r.userAgentData.mobile == "boolean") {
161
- if (a.debug("DeviceDetector", "Using modern User-Agent Client Hints API", {
162
- mobile: r.userAgentData.mobile,
163
- platform: r.userAgentData.platform
164
- }), r.userAgentData.platform && /ipad|tablet/i.test(r.userAgentData.platform))
165
- return a.debug("DeviceDetector", "Device detected as tablet via platform hint"), I.Tablet;
166
- const u = r.userAgentData.mobile ? I.Mobile : I.Desktop;
167
- return a.debug("DeviceDetector", "Device detected via User-Agent hints", { result: u }), u;
168
- }
169
- a.debug("DeviceDetector", "Using fallback detection methods"), pt();
170
- const e = window.innerWidth, t = te?.matches ?? !1, n = ze?.matches ?? !1, s = "ontouchstart" in window || navigator.maxTouchPoints > 0, i = navigator.userAgent.toLowerCase(), o = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i), c = /tablet|ipad|android(?!.*mobile)/.test(i), l = {
171
- width: e,
172
- hasCoarsePointer: t,
173
- hasNoHover: n,
174
- hasTouchSupport: s,
175
- isMobileUA: o,
176
- isTabletUA: c,
177
- maxTouchPoints: navigator.maxTouchPoints
178
- };
179
- return e <= 767 || o && s ? (a.debug("DeviceDetector", "Device detected as mobile", l), I.Mobile) : e >= 768 && e <= 1024 || c || t && n && s ? (a.debug("DeviceDetector", "Device detected as tablet", l), I.Tablet) : (a.debug("DeviceDetector", "Device detected as desktop", l), I.Desktop);
180
- } catch (r) {
181
- return a.warn("DeviceDetector", "Device detection failed, defaulting to desktop", {
182
- error: r instanceof Error ? r.message : r
183
- }), I.Desktop;
184
- }
185
- }, Le = () => {
186
- a.debug("UTMParams", "Extracting UTM parameters from URL", {
187
- url: window.location.href,
188
- search: window.location.search
189
- });
190
- const r = new URLSearchParams(window.location.search), e = {};
191
- at.forEach((n) => {
192
- const s = r.get(n);
193
- if (s) {
194
- const i = n.split("utm_")[1];
195
- e[i] = s, a.debug("UTMParams", "Found UTM parameter", { param: n, key: i, value: s });
160
+ return r;
161
+ }, he = () => {
162
+ const s = new URLSearchParams(window.location.search), e = {};
163
+ return be.forEach((r) => {
164
+ const n = s.get(r);
165
+ if (n) {
166
+ const i = r.split("utm_")[1];
167
+ e[i] = n;
196
168
  }
197
- });
198
- const t = Object.keys(e).length ? e : void 0;
199
- return t ? a.debug("UTMParams", "UTM parameters extracted successfully", {
200
- parameterCount: Object.keys(t).length,
201
- parameters: Object.keys(t)
202
- }) : a.debug("UTMParams", "No UTM parameters found in URL"), t;
203
- }, Et = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (r) => {
169
+ }), Object.keys(e).length ? e : void 0;
170
+ }, je = () => typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (s) => {
204
171
  const e = Math.random() * 16 | 0;
205
- return (r === "x" ? e : e & 3 | 8).toString(16);
206
- });
207
- var f = /* @__PURE__ */ ((r) => (r.Skip = "skip", r.Localhost = "localhost:8080", r.Fail = "localhost:9999", r))(f || {}), re = /* @__PURE__ */ ((r) => (r.EVENT = "event", r.QUEUE = "queue", r))(re || {}), d = /* @__PURE__ */ ((r) => (r.PAGE_VIEW = "page_view", r.CLICK = "click", r.SCROLL = "scroll", r.SESSION_START = "session_start", r.SESSION_END = "session_end", r.CUSTOM = "custom", r.WEB_VITALS = "web_vitals", r.ERROR = "error", r))(d || {}), j = /* @__PURE__ */ ((r) => (r.UP = "up", r.DOWN = "down", r))(j || {}), C = /* @__PURE__ */ ((r) => (r.JS_ERROR = "js_error", r.PROMISE_REJECTION = "promise_rejection", r))(C || {}), O = /* @__PURE__ */ ((r) => (r.QA = "qa", r.DEBUG = "debug", r))(O || {}), vt = /* @__PURE__ */ ((r) => (r.AND = "AND", r.OR = "OR", r))(vt || {}), yt = /* @__PURE__ */ ((r) => (r.URL_MATCHES = "url_matches", r.ELEMENT_MATCHES = "element_matches", r.DEVICE_TYPE = "device_type", r.ELEMENT_TEXT = "element_text", r.ELEMENT_ATTRIBUTE = "element_attribute", r.UTM_SOURCE = "utm_source", r.UTM_MEDIUM = "utm_medium", r.UTM_CAMPAIGN = "utm_campaign", r))(yt || {}), It = /* @__PURE__ */ ((r) => (r.EQUALS = "equals", r.CONTAINS = "contains", r.STARTS_WITH = "starts_with", r.ENDS_WITH = "ends_with", r.REGEX = "regex", r.GREATER_THAN = "greater_than", r.LESS_THAN = "less_than", r.EXISTS = "exists", r.NOT_EXISTS = "not_exists", r))(It || {});
208
- class H extends Error {
209
- constructor(e, t, n) {
210
- super(e), this.errorCode = t, this.layer = n, this.name = this.constructor.name, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
211
- }
212
- }
213
- class ne extends H {
214
- constructor(e = "Project ID is required", t = "config") {
215
- super(e, "PROJECT_ID_INVALID", t);
172
+ return (s === "x" ? e : e & 3 | 8).toString(16);
173
+ }), Xe = () => {
174
+ const s = Date.now();
175
+ let e = "";
176
+ try {
177
+ if (typeof crypto < "u" && crypto.getRandomValues) {
178
+ const t = crypto.getRandomValues(new Uint8Array(4));
179
+ t && (e = Array.from(t, (r) => r.toString(16).padStart(2, "0")).join(""));
180
+ }
181
+ } catch {
216
182
  }
217
- }
218
- class A extends H {
219
- constructor(e, t = "config") {
220
- super(e, "APP_CONFIG_INVALID", t);
183
+ return e || (e = Math.floor(Math.random() * 4294967295).toString(16).padStart(8, "0")), `${s}-${e}`;
184
+ }, fe = (s, e = !1) => {
185
+ try {
186
+ const t = new URL(s), r = t.protocol === "https:", n = t.protocol === "http:";
187
+ return r || e && n;
188
+ } catch {
189
+ return !1;
221
190
  }
222
- }
223
- class Tt extends H {
224
- constructor(e, t = "config") {
225
- super(e, "SESSION_TIMEOUT_INVALID", t);
191
+ }, We = (s) => {
192
+ if (s.integrations?.tracelog?.projectId) {
193
+ const r = new URL(window.location.href).hostname.split(".");
194
+ if (r.length === 0)
195
+ throw new Error("Invalid URL");
196
+ const n = s.integrations.tracelog.projectId, i = r.slice(-2).join("."), a = `https://${n}.${i}`;
197
+ if (!fe(a))
198
+ throw new Error("Invalid URL");
199
+ return a;
200
+ }
201
+ if (s.integrations?.custom?.apiUrl) {
202
+ const e = s.integrations.custom.apiUrl, t = s.integrations?.custom?.allowHttp ?? !1;
203
+ if (!fe(e, t))
204
+ throw new Error("Invalid URL");
205
+ return e;
226
206
  }
227
- }
228
- class _t extends H {
229
- constructor(e, t = "config") {
230
- super(e, "SAMPLING_RATE_INVALID", t);
207
+ return "";
208
+ }, Y = (s, e = []) => {
209
+ try {
210
+ const t = new URL(s), r = t.searchParams;
211
+ let n = !1;
212
+ const i = [];
213
+ return e.forEach((c) => {
214
+ r.has(c) && (r.delete(c), n = !0, i.push(c));
215
+ }), !n && s.includes("?") ? s : (t.search = r.toString(), t.toString());
216
+ } catch (t) {
217
+ return o("warn", "URL normalization failed, returning original", { error: t, data: { url: s.slice(0, 100) } }), s;
231
218
  }
232
- }
233
- class Ne extends H {
234
- constructor(e, t = "config") {
235
- super(e, "INTEGRATION_INVALID", t);
219
+ }, ge = (s) => {
220
+ if (!s || typeof s != "string" || s.trim().length === 0)
221
+ return "";
222
+ let e = s;
223
+ s.length > 1e3 && (e = s.slice(0, Math.max(0, 1e3)));
224
+ let t = 0;
225
+ for (const n of Oe) {
226
+ const i = e;
227
+ e = e.replace(n, ""), i !== e && t++;
228
+ }
229
+ return t > 0 && o("warn", "XSS patterns detected and removed", {
230
+ data: {
231
+ patternMatches: t,
232
+ originalValue: s.slice(0, 100)
233
+ }
234
+ }), e = e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#x27;").replaceAll("/", "&#x2F;"), e.trim();
235
+ }, K = (s, e = 0) => {
236
+ if (e > 3 || s == null)
237
+ return null;
238
+ if (typeof s == "string")
239
+ return ge(s);
240
+ if (typeof s == "number")
241
+ return !Number.isFinite(s) || s < -Number.MAX_SAFE_INTEGER || s > Number.MAX_SAFE_INTEGER ? 0 : s;
242
+ if (typeof s == "boolean")
243
+ return s;
244
+ if (Array.isArray(s))
245
+ return s.slice(0, 100).map((n) => K(n, e + 1)).filter((n) => n !== null);
246
+ if (typeof s == "object") {
247
+ const t = {}, n = Object.entries(s).slice(0, 20);
248
+ for (const [i, a] of n) {
249
+ const c = ge(i);
250
+ if (c) {
251
+ const l = K(a, e + 1);
252
+ l !== null && (t[c] = l);
253
+ }
254
+ }
255
+ return t;
236
256
  }
237
- }
238
- const wt = (r) => {
239
- if (!r || typeof r != "object")
240
- throw a.clientError("ConfigValidation", "Configuration must be an object", { config: r }), new A("Configuration must be an object", "config");
241
- if (!("id" in r))
242
- throw a.clientError("ConfigValidation", "Project ID is missing from configuration"), new ne(y.MISSING_PROJECT_ID, "config");
243
- if (r.id === null || r.id === void 0 || typeof r.id != "string")
244
- throw a.clientError("ConfigValidation", "Project ID must be a non-empty string", {
245
- providedId: r.id,
246
- type: typeof r.id
247
- }), new ne(y.MISSING_PROJECT_ID, "config");
248
- if (r.sessionTimeout !== void 0 && (typeof r.sessionTimeout != "number" || r.sessionTimeout < k || r.sessionTimeout > x))
249
- throw a.clientError("ConfigValidation", "Invalid session timeout", {
250
- provided: r.sessionTimeout,
251
- min: k,
252
- max: x
253
- }), new Tt(y.INVALID_SESSION_TIMEOUT, "config");
254
- if (r.globalMetadata !== void 0 && (typeof r.globalMetadata != "object" || r.globalMetadata === null))
255
- throw a.clientError("ConfigValidation", "Global metadata must be an object", {
256
- provided: r.globalMetadata,
257
- type: typeof r.globalMetadata
258
- }), new A(y.INVALID_GLOBAL_METADATA, "config");
259
- if (r.scrollContainerSelectors !== void 0 && bt(r.scrollContainerSelectors), r.integrations && Mt(r.integrations), r.sensitiveQueryParams !== void 0) {
260
- if (!Array.isArray(r.sensitiveQueryParams))
261
- throw a.clientError("ConfigValidation", "Sensitive query params must be an array", {
262
- provided: r.sensitiveQueryParams,
263
- type: typeof r.sensitiveQueryParams
264
- }), new A(y.INVALID_SENSITIVE_QUERY_PARAMS, "config");
265
- for (const e of r.sensitiveQueryParams)
257
+ return null;
258
+ }, Ye = (s) => {
259
+ if (typeof s != "object" || s === null)
260
+ return {};
261
+ try {
262
+ const e = K(s);
263
+ return typeof e == "object" && e !== null ? e : {};
264
+ } catch (e) {
265
+ const t = e instanceof Error ? e.message : String(e);
266
+ throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`);
267
+ }
268
+ }, Ke = (s) => {
269
+ if (!s || typeof s != "object")
270
+ throw new y("Configuration must be an object", "config");
271
+ if (s.sessionTimeout !== void 0 && (typeof s.sessionTimeout != "number" || s.sessionTimeout < 3e4 || s.sessionTimeout > 864e5))
272
+ throw new Pe(m.INVALID_SESSION_TIMEOUT, "config");
273
+ if (s.globalMetadata !== void 0 && (typeof s.globalMetadata != "object" || s.globalMetadata === null))
274
+ throw new y(m.INVALID_GLOBAL_METADATA, "config");
275
+ if (s.scrollContainerSelectors !== void 0 && Ze(s.scrollContainerSelectors), s.integrations && Je(s.integrations), s.sensitiveQueryParams !== void 0) {
276
+ if (!Array.isArray(s.sensitiveQueryParams))
277
+ throw new y(m.INVALID_SENSITIVE_QUERY_PARAMS, "config");
278
+ for (const e of s.sensitiveQueryParams)
266
279
  if (typeof e != "string")
267
- throw a.clientError("ConfigValidation", "All sensitive query params must be strings", {
268
- param: e,
269
- type: typeof e
270
- }), new A("All sensitive query params must be strings", "config");
271
- }
272
- if (r.errorSampling !== void 0 && (typeof r.errorSampling != "number" || r.errorSampling < 0 || r.errorSampling > 1))
273
- throw a.clientError("ConfigValidation", "Invalid error sampling rate", {
274
- provided: r.errorSampling,
275
- expected: "0-1"
276
- }), new _t(y.INVALID_ERROR_SAMPLING_RATE, "config");
277
- }, At = (r) => {
278
- if (r.includes("<") || r.includes(">") || /on\w+\s*=/i.test(r) || !/^[a-zA-Z0-9\-_#.[\]="':, >+~*()]+$/.test(r))
280
+ throw new y("All sensitive query params must be strings", "config");
281
+ }
282
+ if (s.errorSampling !== void 0 && (typeof s.errorSampling != "number" || s.errorSampling < 0 || s.errorSampling > 1))
283
+ throw new oe(m.INVALID_ERROR_SAMPLING_RATE, "config");
284
+ if (s.samplingRate !== void 0 && (typeof s.samplingRate != "number" || s.samplingRate < 0 || s.samplingRate > 1))
285
+ throw new oe(m.INVALID_SAMPLING_RATE, "config");
286
+ }, qe = (s) => {
287
+ if (s.includes("<") || s.includes(">") || /on\w+\s*=/i.test(s) || !/^[a-zA-Z0-9\-_#.[\]="':, >+~*()]+$/.test(s))
279
288
  return !1;
280
289
  let t = 0;
281
- for (const s of r)
282
- if (s === "(" && t++, s === ")" && t--, t < 0) return !1;
290
+ for (const n of s)
291
+ if (n === "(" && t++, n === ")" && t--, t < 0) return !1;
283
292
  if (t !== 0) return !1;
284
- let n = 0;
285
- for (const s of r)
286
- if (s === "[" && n++, s === "]" && n--, n < 0) return !1;
287
- return n === 0;
288
- }, bt = (r) => {
289
- const e = Array.isArray(r) ? r : [r];
293
+ let r = 0;
294
+ for (const n of s)
295
+ if (n === "[" && r++, n === "]" && r--, r < 0) return !1;
296
+ return r === 0;
297
+ }, Ze = (s) => {
298
+ const e = Array.isArray(s) ? s : [s];
290
299
  for (const t of e) {
291
300
  if (typeof t != "string" || t.trim() === "")
292
- throw a.clientError("ConfigValidation", "Invalid scroll container selector", {
293
- selector: t,
294
- type: typeof t,
295
- isEmpty: t === "" || typeof t == "string" && t.trim() === ""
296
- }), new A(y.INVALID_SCROLL_CONTAINER_SELECTORS, "config");
297
- if (!At(t))
298
- throw a.clientError("ConfigValidation", "Invalid or potentially unsafe CSS selector", {
299
- selector: t,
300
- reason: "Failed security validation"
301
- }), new A("Invalid or potentially unsafe CSS selector", "config");
302
- }
303
- }, Mt = (r) => {
304
- if (r && r.googleAnalytics) {
305
- if (!r.googleAnalytics.measurementId || typeof r.googleAnalytics.measurementId != "string" || r.googleAnalytics.measurementId.trim() === "")
306
- throw a.clientError("ConfigValidation", "Invalid Google Analytics measurement ID", {
307
- provided: r.googleAnalytics.measurementId,
308
- type: typeof r.googleAnalytics.measurementId
309
- }), new Ne(y.INVALID_GOOGLE_ANALYTICS_ID, "config");
310
- const e = r.googleAnalytics.measurementId.trim();
311
- if (!e.match(/^(G-|UA-)/))
312
- throw a.clientError("ConfigValidation", 'Google Analytics measurement ID must start with "G-" or "UA-"', {
313
- provided: e
314
- }), new Ne('Google Analytics measurement ID must start with "G-" or "UA-"', "config");
315
- }
316
- }, Rt = (r) => {
317
- wt(r);
318
- const e = {
319
- ...r,
320
- id: r.id.trim(),
321
- globalMetadata: r.globalMetadata ?? {},
322
- sensitiveQueryParams: r.sensitiveQueryParams ?? []
323
- };
324
- if (!e.id)
325
- throw a.clientError("ConfigValidation", "Project ID is empty after trimming whitespace", {
326
- originalId: r.id,
327
- normalizedId: e.id
328
- }), new ne(y.PROJECT_ID_EMPTY_AFTER_TRIM, "config");
329
- return e;
330
- }, Ce = (r) => {
331
- if (!r || typeof r != "string" || r.trim().length === 0)
332
- return a.debug("Sanitize", "String sanitization skipped - empty or invalid input", { value: r, type: typeof r }), "";
333
- const e = r.length;
334
- let t = r;
335
- r.length > T && (t = r.slice(0, Math.max(0, T)), a.warn("Sanitize", "String truncated due to length limit", {
336
- originalLength: e,
337
- maxLength: T,
338
- truncatedLength: t.length
339
- }));
340
- let n = 0;
341
- for (const i of He) {
342
- const o = t;
343
- t = t.replace(i, ""), o !== t && n++;
344
- }
345
- n > 0 && a.warn("Sanitize", "XSS patterns detected and removed", {
346
- patternMatches: n,
347
- originalValue: r.slice(0, 100)
348
- // Log first 100 chars for debugging
349
- }), t = t.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#x27;").replaceAll("/", "&#x2F;");
350
- const s = t.trim();
351
- return (e > 50 || n > 0) && a.debug("Sanitize", "String sanitization completed", {
352
- originalLength: e,
353
- sanitizedLength: s.length,
354
- xssPatternMatches: n,
355
- wasTruncated: e > T
356
- }), s;
357
- }, Lt = (r) => {
358
- if (typeof r != "string")
359
- return "";
360
- r.length > T && (r = r.slice(0, Math.max(0, T)));
361
- let e = r;
362
- for (const t of He)
363
- e = e.replace(t, "");
364
- return e = e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#x27;"), e.trim();
365
- }, U = (r, e = 0) => {
366
- if (e > Ae)
367
- return a.warn("Sanitize", "Maximum object depth exceeded during sanitization", {
368
- depth: e,
369
- maxDepth: Ae
370
- }), null;
371
- if (r == null)
372
- return null;
373
- if (typeof r == "string")
374
- return Ce(r);
375
- if (typeof r == "number")
376
- return !Number.isFinite(r) || r < -Number.MAX_SAFE_INTEGER || r > Number.MAX_SAFE_INTEGER ? (a.warn("Sanitize", "Invalid number sanitized to 0", { value: r, isFinite: Number.isFinite(r) }), 0) : r;
377
- if (typeof r == "boolean")
378
- return r;
379
- if (Array.isArray(r)) {
380
- const t = r.length, n = r.slice(0, q);
381
- t > q && a.warn("Sanitize", "Array truncated due to length limit", {
382
- originalLength: t,
383
- maxLength: q,
384
- depth: e
385
- });
386
- const s = n.map((i) => U(i, e + 1)).filter((i) => i !== null);
387
- return t > 0 && s.length === 0 && a.warn("Sanitize", "All array items were filtered out during sanitization", { originalLength: t, depth: e }), s;
388
- }
389
- if (typeof r == "object") {
390
- const t = {}, n = Object.entries(r), s = n.length, i = n.slice(0, 20);
391
- s > 20 && a.warn("Sanitize", "Object keys truncated due to limit", {
392
- originalKeys: s,
393
- maxKeys: 20,
394
- depth: e
395
- });
396
- let o = 0;
397
- for (const [c, l] of i) {
398
- const u = Ce(c);
399
- if (u) {
400
- const h = U(l, e + 1);
401
- h !== null ? t[u] = h : o++;
402
- } else
403
- o++;
404
- }
405
- return o > 0 && a.debug("Sanitize", "Object properties filtered during sanitization", {
406
- filteredKeysCount: o,
407
- remainingKeys: Object.keys(t).length,
408
- depth: e
409
- }), t;
410
- }
411
- return a.debug("Sanitize", "Unknown value type sanitized to null", { type: typeof r, depth: e }), null;
412
- }, Nt = (r) => {
413
- a.debug("Sanitize", "Starting API config sanitization");
414
- const e = {};
415
- if (typeof r != "object" || r === null)
416
- return a.warn("Sanitize", "API config data is not an object", { data: r, type: typeof r }), e;
417
- try {
418
- const t = Object.keys(r);
419
- let n = 0, s = 0;
420
- for (const i of t)
421
- if (lt.has(i)) {
422
- const o = r[i];
423
- if (i === "excludedUrlPaths") {
424
- const c = Array.isArray(o) ? o : typeof o == "string" ? [o] : [], l = c.length;
425
- e.excludedUrlPaths = c.map((h) => Lt(String(h))).filter(Boolean);
426
- const u = l - e.excludedUrlPaths.length;
427
- u > 0 && a.warn("Sanitize", "Some excluded URL paths were filtered during sanitization", {
428
- originalCount: l,
429
- filteredCount: u
430
- });
431
- } else if (i === "tags")
432
- Array.isArray(o) ? (e.tags = o, a.debug("Sanitize", "Tags processed", { count: o.length })) : a.warn("Sanitize", "Tags value is not an array", { value: o, type: typeof o });
433
- else if (i === "samplingRate") {
434
- const c = U(o);
435
- typeof c == "number" && (e.samplingRate = c);
436
- } else {
437
- const c = U(o);
438
- c !== null ? e[i] = c : a.warn("Sanitize", "API config value sanitized to null", { key: i, originalValue: o });
301
+ throw o("error", "Invalid scroll container selector", {
302
+ showToClient: !0,
303
+ data: {
304
+ selector: t,
305
+ type: typeof t,
306
+ isEmpty: t === "" || typeof t == "string" && t.trim() === ""
439
307
  }
440
- n++;
441
- } else
442
- s++, a.debug("Sanitize", "API config key not allowed", { key: i });
443
- a.info("Sanitize", "API config sanitization completed", {
444
- originalKeys: t.length,
445
- processedKeys: n,
446
- filteredKeys: s,
447
- finalKeys: Object.keys(e).length
448
- });
449
- } catch (t) {
450
- throw a.error("Sanitize", "API config sanitization failed", {
451
- error: t instanceof Error ? t.message : t
452
- }), new Error(`API config sanitization failed: ${t instanceof Error ? t.message : "Unknown error"}`);
308
+ }), new y(m.INVALID_SCROLL_CONTAINER_SELECTORS, "config");
309
+ if (!qe(t))
310
+ throw o("error", "Invalid or potentially unsafe CSS selector", {
311
+ showToClient: !0,
312
+ data: {
313
+ selector: t,
314
+ reason: "Failed security validation"
315
+ }
316
+ }), new y("Invalid or potentially unsafe CSS selector", "config");
317
+ }
318
+ }, Je = (s) => {
319
+ if (s) {
320
+ if (s.tracelog && (!s.tracelog.projectId || typeof s.tracelog.projectId != "string" || s.tracelog.projectId.trim() === ""))
321
+ throw new v(m.INVALID_TRACELOG_PROJECT_ID, "config");
322
+ if (s.custom) {
323
+ if (!s.custom.apiUrl || typeof s.custom.apiUrl != "string" || s.custom.apiUrl.trim() === "")
324
+ throw new v(m.INVALID_CUSTOM_API_URL, "config");
325
+ if (s.custom.allowHttp !== void 0 && typeof s.custom.allowHttp != "boolean")
326
+ throw new v("allowHttp must be a boolean", "config");
327
+ const e = s.custom.apiUrl.trim();
328
+ if (!e.startsWith("http://") && !e.startsWith("https://"))
329
+ throw new v('Custom API URL must start with "http://" or "https://"', "config");
330
+ if (!(s.custom.allowHttp ?? !1) && e.startsWith("http://"))
331
+ throw new v(
332
+ "Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)",
333
+ "config"
334
+ );
335
+ }
336
+ if (s.googleAnalytics) {
337
+ if (!s.googleAnalytics.measurementId || typeof s.googleAnalytics.measurementId != "string" || s.googleAnalytics.measurementId.trim() === "")
338
+ throw new v(m.INVALID_GOOGLE_ANALYTICS_ID, "config");
339
+ if (!s.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))
340
+ throw new v('Google Analytics measurement ID must start with "G-" or "UA-"', "config");
341
+ }
453
342
  }
454
- return e;
455
- }, Ct = (r) => {
456
- if (a.debug("Sanitize", "Starting metadata sanitization", { hasMetadata: r != null }), typeof r != "object" || r === null)
457
- return a.debug("Sanitize", "Metadata is not an object, returning empty object", {
458
- metadata: r,
459
- type: typeof r
460
- }), {};
461
- try {
462
- const e = Object.keys(r).length, t = U(r), n = typeof t == "object" && t !== null ? t : {}, s = Object.keys(n).length;
463
- return a.debug("Sanitize", "Metadata sanitization completed", {
464
- originalKeys: e,
465
- finalKeys: s,
466
- keysFiltered: e - s
467
- }), n;
468
- } catch (e) {
469
- throw a.error("Sanitize", "Metadata sanitization failed", {
470
- error: e instanceof Error ? e.message : e
471
- }), new Error(`Metadata sanitization failed: ${e instanceof Error ? e.message : "Unknown error"}`);
343
+ }, et = (s) => {
344
+ Ke(s);
345
+ const e = {
346
+ ...s,
347
+ sessionTimeout: s.sessionTimeout ?? 9e5,
348
+ globalMetadata: s.globalMetadata ?? {},
349
+ sensitiveQueryParams: s.sensitiveQueryParams ?? [],
350
+ errorSampling: s.errorSampling ?? 1,
351
+ samplingRate: s.samplingRate ?? 1
352
+ };
353
+ return e.integrations?.custom && (e.integrations.custom = {
354
+ ...e.integrations.custom,
355
+ allowHttp: e.integrations.custom.allowHttp ?? !1
356
+ }), e;
357
+ }, tt = (s) => {
358
+ if (typeof s == "string")
359
+ return !0;
360
+ if (typeof s == "object" && s !== null && !Array.isArray(s)) {
361
+ const e = Object.entries(s);
362
+ if (e.length > 20)
363
+ return !1;
364
+ for (const [, t] of e) {
365
+ if (t == null)
366
+ continue;
367
+ const r = typeof t;
368
+ if (r !== "string" && r !== "number" && r !== "boolean")
369
+ return !1;
370
+ }
371
+ return !0;
472
372
  }
473
- }, Pt = (r) => {
474
- if (typeof r != "object" || r === null)
373
+ return !1;
374
+ }, rt = (s) => {
375
+ if (typeof s != "object" || s === null)
475
376
  return !1;
476
- for (const e of Object.values(r)) {
377
+ for (const e of Object.values(s)) {
477
378
  if (e == null)
478
379
  continue;
479
380
  const t = typeof e;
480
381
  if (!(t === "string" || t === "number" || t === "boolean")) {
481
382
  if (Array.isArray(e)) {
482
- if (!e.every((n) => typeof n == "string"))
383
+ if (e.length === 0)
384
+ continue;
385
+ if (typeof e[0] == "string") {
386
+ if (!e.every((i) => typeof i == "string"))
387
+ return !1;
388
+ } else if (!e.every((i) => tt(i)))
483
389
  return !1;
484
390
  continue;
485
391
  }
@@ -487,407 +393,146 @@ const wt = (r) => {
487
393
  }
488
394
  }
489
395
  return !0;
490
- }, Ot = (r) => typeof r != "string" ? {
396
+ }, st = (s) => typeof s != "string" ? {
491
397
  valid: !1,
492
398
  error: "Event name must be a string"
493
- } : r.length === 0 ? {
399
+ } : s.length === 0 ? {
494
400
  valid: !1,
495
401
  error: "Event name cannot be empty"
496
- } : r.length > Ie ? {
402
+ } : s.length > 120 ? {
497
403
  valid: !1,
498
- error: `Event name is too long (max ${Ie} characters)`
499
- } : r.includes("<") || r.includes(">") || r.includes("&") ? {
404
+ error: "Event name is too long (max 120 characters)"
405
+ } : s.includes("<") || s.includes(">") || s.includes("&") ? {
500
406
  valid: !1,
501
407
  error: "Event name contains invalid characters"
502
- } : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(r.toLowerCase()) ? {
408
+ } : ["constructor", "prototype", "__proto__", "eval", "function", "var", "let", "const"].includes(s.toLowerCase()) ? {
503
409
  valid: !1,
504
410
  error: "Event name cannot be a reserved word"
505
- } : { valid: !0 }, Pe = (r, e, t) => {
506
- const n = Ct(e), s = `${t} "${r}" metadata error`;
507
- if (!Pt(n))
411
+ } : { valid: !0 }, Se = (s, e, t) => {
412
+ const r = Ye(e), n = `${t} "${s}" metadata error`;
413
+ if (!rt(r))
508
414
  return {
509
415
  valid: !1,
510
- error: `${s}: object has invalid types. Valid types are string, number, boolean or string arrays.`
416
+ error: `${n}: object has invalid types. Valid types are string, number, boolean or string arrays.`
511
417
  };
512
418
  let i;
513
419
  try {
514
- i = JSON.stringify(n);
420
+ i = JSON.stringify(r);
515
421
  } catch {
516
422
  return {
517
423
  valid: !1,
518
- error: `${s}: object contains circular references or cannot be serialized.`
424
+ error: `${n}: object contains circular references or cannot be serialized.`
519
425
  };
520
426
  }
521
- if (i.length > Te)
427
+ if (i.length > 8192)
522
428
  return {
523
429
  valid: !1,
524
- error: `${s}: object is too large (max ${Te / 1024} KB).`
430
+ error: `${n}: object is too large (max ${8192 / 1024} KB).`
525
431
  };
526
- if (Object.keys(n).length > _e)
432
+ if (Object.keys(r).length > 10)
527
433
  return {
528
434
  valid: !1,
529
- error: `${s}: object has too many keys (max ${_e} keys).`
435
+ error: `${n}: object has too many keys (max 10 keys).`
530
436
  };
531
- for (const [c, l] of Object.entries(n)) {
437
+ for (const [c, l] of Object.entries(r)) {
532
438
  if (Array.isArray(l)) {
533
- if (l.length > we)
439
+ if (l.length > 10)
534
440
  return {
535
441
  valid: !1,
536
- error: `${s}: array property "${c}" is too large (max ${we} items).`
442
+ error: `${n}: array property "${c}" is too large (max 10 items).`
537
443
  };
538
444
  for (const u of l)
539
445
  if (typeof u == "string" && u.length > 500)
540
446
  return {
541
447
  valid: !1,
542
- error: `${s}: array property "${c}" contains strings that are too long (max 500 characters).`
448
+ error: `${n}: array property "${c}" contains strings that are too long (max 500 characters).`
543
449
  };
544
450
  }
545
- if (typeof l == "string" && l.length > T)
451
+ if (typeof l == "string" && l.length > 1e3)
546
452
  return {
547
453
  valid: !1,
548
- error: `${s}: property "${c}" is too long (max ${T} characters).`
454
+ error: `${n}: property "${c}" is too long (max 1000 characters).`
549
455
  };
550
456
  }
551
457
  return {
552
458
  valid: !0,
553
- sanitizedMetadata: n
459
+ sanitizedMetadata: r
554
460
  };
555
- }, Dt = (r, e, t) => {
461
+ }, nt = (s, e, t) => {
556
462
  if (Array.isArray(e)) {
557
- const n = [], s = `${t} "${r}" metadata error`;
463
+ const r = [], n = `${t} "${s}" metadata error`;
558
464
  for (let i = 0; i < e.length; i++) {
559
- const o = e[i];
560
- if (typeof o != "object" || o === null || Array.isArray(o))
465
+ const a = e[i];
466
+ if (typeof a != "object" || a === null || Array.isArray(a))
561
467
  return {
562
468
  valid: !1,
563
- error: `${s}: array item at index ${i} must be an object.`
469
+ error: `${n}: array item at index ${i} must be an object.`
564
470
  };
565
- const c = Pe(r, o, t);
471
+ const c = Se(s, a, t);
566
472
  if (!c.valid)
567
473
  return {
568
474
  valid: !1,
569
- error: `${s}: array item at index ${i} is invalid: ${c.error}`
475
+ error: `${n}: array item at index ${i} is invalid: ${c.error}`
570
476
  };
571
- c.sanitizedMetadata && n.push(c.sanitizedMetadata);
477
+ c.sanitizedMetadata && r.push(c.sanitizedMetadata);
572
478
  }
573
479
  return {
574
480
  valid: !0,
575
- sanitizedMetadata: n
481
+ sanitizedMetadata: r
576
482
  };
577
483
  }
578
- return Pe(r, e, t);
579
- }, kt = (r, e) => {
580
- const t = Ot(r);
484
+ return Se(s, e, t);
485
+ }, it = (s, e) => {
486
+ const t = st(s);
581
487
  if (!t.valid)
582
- return a.clientError("EventValidation", "Event name validation failed", { eventName: r, error: t.error }), t;
488
+ return o("error", "Event name validation failed", {
489
+ showToClient: !0,
490
+ data: { eventName: s, error: t.error }
491
+ }), t;
583
492
  if (!e)
584
493
  return { valid: !0 };
585
- const n = Dt(r, e, "customEvent");
586
- return n.valid || a.clientError("EventValidation", "Event metadata validation failed", {
587
- eventName: r,
588
- error: n.error
589
- }), n;
590
- }, se = (r, e = !1) => {
591
- try {
592
- const t = new URL(r), n = t.protocol === "https:", s = t.protocol === "http:";
593
- return n || e && s;
594
- } catch {
595
- return !1;
596
- }
597
- }, xt = (r, e = !1) => {
598
- const t = new URL(window.location.href), n = t.hostname, s = n.split(".");
599
- if (s.length === 0)
600
- throw a.clientError("URLUtils", "Invalid hostname - no domain parts found", { hostname: n }), new Error("Invalid URL");
601
- const i = s.slice(-2).join("."), c = `${e && t.protocol === "http:" ? "http" : "https"}://${r}.${i}`;
602
- if (!se(c, e))
603
- throw a.clientError("URLUtils", "Generated API URL failed validation", {
604
- apiUrl: c,
605
- allowHttp: e
606
- }), new Error("Invalid URL");
607
- return c;
608
- }, ie = (r, e = []) => {
609
- try {
610
- const t = new URL(r), n = t.searchParams, s = Array.from(n.keys()).length;
611
- let i = !1;
612
- const o = [];
613
- return e.forEach((l) => {
614
- n.has(l) && (n.delete(l), i = !0, o.push(l));
615
- }), i && a.debug("URLUtils", "Sensitive parameters removed from URL", {
616
- removedParams: o,
617
- originalParamCount: s,
618
- finalParamCount: Array.from(n.keys()).length
619
- }), !i && r.includes("?") ? r : (t.search = n.toString(), t.toString());
620
- } catch (t) {
621
- return a.warn("URLUtils", "URL normalization failed, returning original", {
622
- url: r.slice(0, 100),
623
- error: t instanceof Error ? t.message : t
624
- }), r;
625
- }
626
- }, Ut = (r, e = []) => {
627
- if (e.length === 0)
628
- return !1;
629
- let t;
630
- try {
631
- const l = new URL(r, window.location.origin);
632
- t = l.pathname + (l.hash ?? "");
633
- } catch (l) {
634
- return a.warn("URLUtils", "Failed to parse URL for path exclusion check", {
635
- url: r.slice(0, 100),
636
- error: l instanceof Error ? l.message : l
637
- }), !1;
638
- }
639
- const n = (l) => typeof l == "object" && l !== void 0 && typeof l.test == "function", s = (l) => l.replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&"), i = (l) => new RegExp(
640
- "^" + l.split("*").map((u) => s(u)).join(".+") + "$"
641
- );
642
- return !!e.find((l) => {
643
- try {
644
- return n(l) ? l.test(t) : l.includes("*") ? i(l).test(t) : l === t;
645
- } catch (u) {
646
- return a.warn("URLUtils", "Error testing exclusion pattern", {
647
- pattern: l,
648
- path: t,
649
- error: u instanceof Error ? u.message : u
650
- }), !1;
494
+ const r = nt(s, e, "customEvent");
495
+ return r.valid || o("error", "Event metadata validation failed", {
496
+ showToClient: !0,
497
+ data: {
498
+ eventName: s,
499
+ error: r.error
651
500
  }
652
- });
501
+ }), r;
653
502
  };
654
- async function Ht(r, e = {}) {
655
- const { timeout: t = 1e4, ...n } = e, s = new AbortController(), i = setTimeout(() => {
656
- s.abort();
657
- }, t);
658
- try {
659
- const o = await fetch(r, {
660
- ...n,
661
- signal: s.signal
662
- });
663
- return clearTimeout(i), o;
664
- } catch (o) {
665
- throw clearTimeout(i), o instanceof Error && o.name === "AbortError" ? new Error(`Request timeout after ${t}ms`) : o;
666
- }
667
- }
668
- class Vt {
503
+ class at {
669
504
  listeners = /* @__PURE__ */ new Map();
670
505
  on(e, t) {
671
506
  this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(t);
672
507
  }
673
508
  off(e, t) {
674
- const n = this.listeners.get(e);
675
- if (n) {
676
- const s = n.indexOf(t);
677
- s > -1 && n.splice(s, 1);
509
+ const r = this.listeners.get(e);
510
+ if (r) {
511
+ const n = r.indexOf(t);
512
+ n > -1 && r.splice(n, 1);
678
513
  }
679
514
  }
680
515
  emit(e, t) {
681
- const n = this.listeners.get(e);
682
- n && n.forEach((s) => s(t));
516
+ const r = this.listeners.get(e);
517
+ r && r.forEach((n) => n(t));
683
518
  }
684
519
  removeAllListeners() {
685
520
  this.listeners.clear();
686
521
  }
687
522
  }
688
- function Ft(r, e = !1) {
689
- try {
690
- if (r === f.Localhost || r === f.Fail) {
691
- const n = `http://${r}`;
692
- if (!se(n, !0))
693
- throw new Error(`Invalid localhost URL format: ${r}`);
694
- return n;
695
- }
696
- const t = xt(r, e);
697
- if (!se(t, e))
698
- throw new Error(`Generated API URL failed validation: ${t}`);
699
- return t;
700
- } catch (t) {
701
- throw a.error("ApiManager", "API URL generation failed", {
702
- projectId: r,
703
- allowHttp: e,
704
- error: t instanceof Error ? t.message : t
705
- }), t;
706
- }
707
- }
708
- class Oe {
709
- /**
710
- * Builds final configuration from app config and API config
711
- * Applies clear precedence: API overrides client, with defaults as fallback
712
- */
713
- static build(e, t = {}) {
714
- const n = this.resolveMode(e, t.mode), s = {
715
- // Core identifiers
716
- id: e.id,
717
- // Session configuration
718
- sessionTimeout: this.resolveSessionTimeout(e.sessionTimeout),
719
- // Mode configuration (resolved first)
720
- mode: n,
721
- // Sampling configuration (depends on mode)
722
- samplingRate: this.resolveSamplingRate(t.samplingRate, e.samplingRate),
723
- errorSampling: this.resolveErrorSampling(e.errorSampling, n),
724
- // Filtering configuration
725
- excludedUrlPaths: t.excludedUrlPaths ?? e.excludedUrlPaths ?? [],
726
- tags: t.tags ?? [],
727
- ipExcluded: t.ipExcluded ?? !1,
728
- // Client-only configuration
729
- globalMetadata: e.globalMetadata ?? {},
730
- scrollContainerSelectors: e.scrollContainerSelectors,
731
- sensitiveQueryParams: e.sensitiveQueryParams ?? [],
732
- integrations: e.integrations,
733
- // Security configuration
734
- allowHttp: e.allowHttp ?? !1
735
- };
736
- return a.debug("ConfigBuilder", "Configuration built", {
737
- projectId: s.id,
738
- mode: s.mode,
739
- samplingRate: s.samplingRate,
740
- errorSampling: s.errorSampling,
741
- hasTags: !!s.tags?.length,
742
- hasExclusions: !!s.excludedUrlPaths?.length
743
- }), s;
744
- }
745
- /**
746
- * Resolves session timeout with validation
747
- * Returns default if undefined or out of valid range
748
- */
749
- static resolveSessionTimeout(e) {
750
- return e === void 0 ? P : e < k || e > x ? (a.warn("ConfigBuilder", "Invalid session timeout, using default", {
751
- provided: e,
752
- min: k,
753
- max: x,
754
- default: P
755
- }), P) : e;
756
- }
757
- /**
758
- * Resolves sampling rate with validation
759
- * Priority: API config > app config > default
760
- */
761
- static resolveSamplingRate(e, t) {
762
- const n = e ?? t;
763
- return n === void 0 ? M : n < nt || n > st ? (a.warn("ConfigBuilder", "Invalid sampling rate, using default", {
764
- provided: n,
765
- default: M
766
- }), M) : n;
767
- }
768
- /**
769
- * Resolves error sampling rate based on mode
770
- * In debug/qa modes: uses provided value or defaults to full sampling (1.0)
771
- * In production: uses provided value or defaults to 10% sampling (0.1)
772
- */
773
- static resolveErrorSampling(e, t) {
774
- return t === O.DEBUG || t === O.QA ? e ?? 1 : e ?? 0.1;
775
- }
776
- /**
777
- * Resolves mode with special project ID handling
778
- * Priority: Special project ID > API mode > app mode
779
- */
780
- static resolveMode(e, t) {
781
- return e.id === f.Skip || e.id === f.Fail || e.id.toLowerCase().startsWith("skip-") ? O.DEBUG : t ?? e.mode;
782
- }
783
- }
784
- class zt {
785
- static PRODUCTION_DOMAINS = [/^https:\/\/.*\.tracelog\.app$/, /^https:\/\/.*\.tracelog\.dev$/];
786
- /**
787
- * Gets complete configuration by loading API config and building final config.
788
- *
789
- * @param apiUrl - Base URL for the configuration API
790
- * @param appConfig - Client-side configuration from init()
791
- * @returns Promise<Config> - Merged configuration object
792
- */
793
- async get(e, t) {
794
- if (t.id === f.Skip || t.id === f.Fail || t.id.toLowerCase().startsWith("skip-"))
795
- return this.createDefaultConfig(t);
796
- const n = await this.loadFromApi(e, t), s = this.applyQaModeIfEnabled(n), i = Oe.build(t, s);
797
- return a.info("ConfigManager", "Configuration loaded", {
798
- projectId: i.id,
799
- mode: i.mode,
800
- hasTags: !!i.tags?.length,
801
- hasExclusions: !!i.excludedUrlPaths?.length
802
- }), i;
803
- }
804
- /**
805
- * Loads configuration from API and returns sanitized API config.
806
- * Only returns values explicitly provided by the API.
807
- */
808
- async loadFromApi(e, t) {
809
- try {
810
- const n = this.buildConfigUrl(e, t), s = this.buildHeaders(t), i = await Ht(n, {
811
- method: "GET",
812
- headers: s,
813
- timeout: Ue
814
- });
815
- if (!i.ok)
816
- throw new Error(`HTTP ${i.status}: ${i.statusText}`);
817
- const o = await this.parseJsonResponse(i), c = Nt(o);
818
- return {
819
- ...c,
820
- excludedUrlPaths: c.excludedUrlPaths ?? N.excludedUrlPaths,
821
- tags: c.tags ?? N.tags
822
- };
823
- } catch (n) {
824
- const s = n instanceof Error ? n.message : "Unknown error";
825
- throw a.error("ConfigManager", "Failed to load configuration", {
826
- error: s,
827
- apiUrl: e,
828
- projectId: t.id
829
- }), new Error(`Configuration load failed: ${s}`);
830
- }
831
- }
832
- /**
833
- * Builds the configuration URL based on project type and QA mode.
834
- */
835
- buildConfigUrl(e, t) {
836
- if (t.id === f.Localhost || t.id === f.Fail)
837
- return `http://${t.id}/config`;
838
- const s = `${e}/config`;
839
- return this.isQaModeEnabled() ? `${s}?qaMode=true` : s;
840
- }
841
- /**
842
- * Builds request headers based on project configuration.
843
- * Always includes X-TraceLog-Project header for consistent identification.
844
- */
845
- buildHeaders(e) {
846
- return {
847
- "Content-Type": "application/json",
848
- "X-TraceLog-Project": e.id
849
- };
850
- }
851
- /**
852
- * Parses and validates JSON response from config API.
853
- */
854
- async parseJsonResponse(e) {
855
- if (!e.headers.get("content-type")?.includes("application/json"))
856
- throw new Error("Invalid response content-type, expected JSON");
857
- const n = await e.json();
858
- if (!n || typeof n != "object" || Array.isArray(n))
859
- throw new Error("Invalid response format, expected object");
860
- return n;
861
- }
862
- /**
863
- * Checks if QA mode is enabled via URL parameter.
864
- */
865
- isQaModeEnabled() {
866
- return new URLSearchParams(window.location.search).get("qaMode") === "true";
523
+ const $ = {};
524
+ class f {
525
+ get(e) {
526
+ return $[e];
867
527
  }
868
- /**
869
- * Applies QA mode to API config if enabled via URL parameter.
870
- */
871
- applyQaModeIfEnabled(e) {
872
- return this.isQaModeEnabled() && !e.mode ? (a.info("ConfigManager", "QA mode enabled via URL parameter"), { ...e, mode: O.QA }) : e;
528
+ set(e, t) {
529
+ $[e] = t;
873
530
  }
874
- /**
875
- * Creates default configuration for skip mode and fallback scenarios.
876
- * Only uses API defaults for fields not provided by the app config.
877
- */
878
- createDefaultConfig(e) {
879
- const t = {
880
- // Only use defaults if app config doesn't provide these values
881
- tags: N.tags,
882
- ipExcluded: N.ipExcluded,
883
- ...e.samplingRate === void 0 && { samplingRate: N.samplingRate }
884
- // Don't override excludedUrlPaths if provided by app config
885
- // ConfigBuilder will handle the fallback to [] if both are undefined
886
- };
887
- return Oe.build(e, t);
531
+ getState() {
532
+ return { ...$ };
888
533
  }
889
534
  }
890
- class Gt extends m {
535
+ class ot extends f {
891
536
  storeManager;
892
537
  retryTimeoutId = null;
893
538
  retryCount = 0;
@@ -896,23 +541,23 @@ class Gt extends m {
896
541
  super(), this.storeManager = e;
897
542
  }
898
543
  getQueueStorageKey() {
899
- const e = this.get("config")?.id || "default", t = this.get("userId") || "anonymous";
900
- return `${ut(e)}:${t}`;
544
+ const e = this.get("userId") || "anonymous";
545
+ return Ve(e);
901
546
  }
902
547
  sendEventsQueueSync(e) {
903
548
  if (this.shouldSkipSend())
904
549
  return this.resetRetryState(), !0;
905
- if (this.get("config")?.id === f.Fail)
906
- return a.warn("SenderManager", "Fail mode: simulating network failure (sync)", {
907
- events: e.events.length
550
+ if (this.get("config")?.integrations?.custom?.apiUrl === j.Fail)
551
+ return o("warn", "Fail mode: simulating network failure (sync)", {
552
+ data: { events: e.events.length }
908
553
  }), !1;
909
- const n = this.sendQueueSyncInternal(e);
910
- return n && this.resetRetryState(), n;
554
+ const r = this.sendQueueSyncInternal(e);
555
+ return r && this.resetRetryState(), r;
911
556
  }
912
557
  async sendEventsQueue(e, t) {
913
- !this.persistEvents(e) && !this.shouldSkipSend() && a.warn("SenderManager", "Failed to persist events, attempting immediate send");
914
- const s = await this.send(e);
915
- return s ? (this.clearPersistedEvents(), this.resetRetryState(), t?.onSuccess?.(e.events.length, e.events, e)) : (this.scheduleRetry(e, t), t?.onFailure?.()), s;
558
+ this.shouldSkipSend() || this.persistEvents(e) || o("warn", "Failed to persist events, attempting immediate send");
559
+ const r = await this.send(e);
560
+ return r ? (this.clearPersistedEvents(), this.resetRetryState(), t?.onSuccess?.(e.events.length, e.events, e)) : (this.scheduleRetry(e, t), t?.onFailure?.()), r;
916
561
  }
917
562
  async recoverPersistedEvents(e) {
918
563
  try {
@@ -921,10 +566,10 @@ class Gt extends m {
921
566
  this.clearPersistedEvents();
922
567
  return;
923
568
  }
924
- const n = this.createRecoveryBody(t);
925
- await this.send(n) ? (this.clearPersistedEvents(), this.resetRetryState(), e?.onSuccess?.(t.events.length, t.events, n)) : (this.scheduleRetry(n, e), e?.onFailure?.());
569
+ const r = this.createRecoveryBody(t);
570
+ await this.send(r) ? (this.clearPersistedEvents(), this.resetRetryState(), e?.onSuccess?.(t.events.length, t.events, r)) : (this.scheduleRetry(r, e), e?.onFailure?.());
926
571
  } catch (t) {
927
- a.error("SenderManager", "Failed to recover persisted events", { error: t }), this.clearPersistedEvents();
572
+ o("error", "Failed to recover persisted events", { error: t }), this.clearPersistedEvents();
928
573
  }
929
574
  }
930
575
  persistEventsForRecovery(e) {
@@ -939,55 +584,55 @@ class Gt extends m {
939
584
  async send(e) {
940
585
  if (this.shouldSkipSend())
941
586
  return this.simulateSuccessfulSend();
942
- if (this.get("config")?.id === f.Fail)
943
- return a.warn("SenderManager", "Fail mode: simulating network failure", {
944
- events: e.events.length
587
+ if (this.get("config")?.integrations?.custom?.apiUrl === j.Fail)
588
+ return o("warn", "Fail mode: simulating network failure", {
589
+ data: { events: e.events.length }
945
590
  }), !1;
946
- const { url: n, payload: s } = this.prepareRequest(e);
591
+ const { url: r, payload: n } = this.prepareRequest(e);
947
592
  try {
948
- return (await this.sendWithTimeout(n, s)).ok;
593
+ return (await this.sendWithTimeout(r, n)).ok;
949
594
  } catch (i) {
950
- const o = i instanceof Error ? i.message : String(i);
951
- return a.error("SenderManager", "Send request failed", {
952
- error: o,
953
- events: e.events.length,
954
- url: n.replace(/\/\/[^/]+/, "//[DOMAIN]")
595
+ return o("error", "Send request failed", {
596
+ error: i,
597
+ data: {
598
+ events: e.events.length,
599
+ url: r.replace(/\/\/[^/]+/, "//[DOMAIN]")
600
+ }
955
601
  }), !1;
956
602
  }
957
603
  }
958
604
  async sendWithTimeout(e, t) {
959
- const n = new AbortController(), s = setTimeout(() => n.abort(), Ue), i = this.get("config");
605
+ const r = new AbortController(), n = setTimeout(() => r.abort(), 1e4);
960
606
  try {
961
- const o = await fetch(e, {
607
+ const i = await fetch(e, {
962
608
  method: "POST",
963
- headers: {
964
- "Content-Type": "application/json",
965
- "X-TraceLog-Project": i?.id || "unknown"
966
- },
967
609
  body: t,
968
610
  keepalive: !0,
969
611
  credentials: "include",
970
- signal: n.signal
612
+ signal: r.signal,
613
+ headers: {
614
+ "Content-Type": "application/json"
615
+ }
971
616
  });
972
- if (!o.ok)
973
- throw new Error(`HTTP ${o.status}: ${o.statusText}`);
974
- return o;
617
+ if (!i.ok)
618
+ throw new Error(`HTTP ${i.status}: ${i.statusText}`);
619
+ return i;
975
620
  } finally {
976
- clearTimeout(s);
621
+ clearTimeout(n);
977
622
  }
978
623
  }
979
624
  sendQueueSyncInternal(e) {
980
- const { url: t, payload: n } = this.prepareRequest(e), s = new Blob([n], { type: "application/json" });
625
+ const { url: t, payload: r } = this.prepareRequest(e), n = new Blob([r], { type: "application/json" });
981
626
  if (this.isSendBeaconAvailable()) {
982
- if (navigator.sendBeacon(t, s))
627
+ if (navigator.sendBeacon(t, n))
983
628
  return !0;
984
- a.warn("SenderManager", "sendBeacon failed, persisting events for recovery");
629
+ o("warn", "sendBeacon failed, persisting events for recovery");
985
630
  } else
986
- a.warn("SenderManager", "sendBeacon not available, persisting events for recovery");
631
+ o("warn", "sendBeacon not available, persisting events for recovery");
987
632
  return this.persistEventsForRecovery(e), !1;
988
633
  }
989
634
  prepareRequest(e) {
990
- const t = `${this.get("apiUrl")}/collect`, n = {
635
+ const t = `${this.get("apiUrl")}/collect`, r = {
991
636
  ...e,
992
637
  _metadata: {
993
638
  referer: typeof window < "u" ? window.location.href : void 0,
@@ -996,7 +641,7 @@ class Gt extends m {
996
641
  };
997
642
  return {
998
643
  url: t,
999
- payload: JSON.stringify(n)
644
+ payload: JSON.stringify(r)
1000
645
  };
1001
646
  }
1002
647
  getPersistedData() {
@@ -1005,12 +650,12 @@ class Gt extends m {
1005
650
  if (t)
1006
651
  return JSON.parse(t);
1007
652
  } catch (e) {
1008
- a.warn("SenderManager", "Failed to parse persisted data", { error: e }), this.clearPersistedEvents();
653
+ o("warn", "Failed to parse persisted data", { error: e }), this.clearPersistedEvents();
1009
654
  }
1010
655
  return null;
1011
656
  }
1012
657
  isDataRecent(e) {
1013
- return !e.timestamp || typeof e.timestamp != "number" ? !1 : (Date.now() - e.timestamp) / (1e3 * 60 * 60) < et;
658
+ return !e.timestamp || typeof e.timestamp != "number" ? !1 : (Date.now() - e.timestamp) / (1e3 * 60 * 60) < 24;
1014
659
  }
1015
660
  createRecoveryBody(e) {
1016
661
  return {
@@ -1030,10 +675,10 @@ class Gt extends m {
1030
675
  events: e.events,
1031
676
  timestamp: Date.now(),
1032
677
  ...e.global_metadata && { global_metadata: e.global_metadata }
1033
- }, n = this.getQueueStorageKey();
1034
- return this.storeManager.setItem(n, JSON.stringify(t)), !!this.storeManager.getItem(n);
678
+ }, r = this.getQueueStorageKey();
679
+ return this.storeManager.setItem(r, JSON.stringify(t)), !!this.storeManager.getItem(r);
1035
680
  } catch (t) {
1036
- return a.warn("SenderManager", "Failed to persist events", { error: t }), !1;
681
+ return o("warn", "Failed to persist events", { error: t }), !1;
1037
682
  }
1038
683
  }
1039
684
  clearPersistedEvents() {
@@ -1041,7 +686,7 @@ class Gt extends m {
1041
686
  const e = this.getQueueStorageKey();
1042
687
  this.storeManager.removeItem(e);
1043
688
  } catch (e) {
1044
- a.warn("SenderManager", "Failed to clear persisted events", { error: e });
689
+ o("warn", "Failed to clear persisted events", { error: e });
1045
690
  }
1046
691
  }
1047
692
  resetRetryState() {
@@ -1050,27 +695,22 @@ class Gt extends m {
1050
695
  scheduleRetry(e, t) {
1051
696
  if (this.retryTimeoutId !== null || this.isRetrying)
1052
697
  return;
1053
- if (this.retryCount >= Se) {
1054
- a.warn("SenderManager", "Max retries reached, giving up", { retryCount: this.retryCount }), this.clearPersistedEvents(), this.resetRetryState(), t?.onFailure?.();
698
+ if (this.retryCount >= 3) {
699
+ o("warn", "Max retries reached, giving up", { data: { retryCount: this.retryCount } }), this.clearPersistedEvents(), this.resetRetryState(), t?.onFailure?.();
1055
700
  return;
1056
701
  }
1057
- const n = tt * Math.pow(2, this.retryCount);
702
+ const r = 5e3 * Math.pow(2, this.retryCount);
1058
703
  this.isRetrying = !0, this.retryTimeoutId = window.setTimeout(async () => {
1059
704
  this.retryTimeoutId = null, this.retryCount++;
1060
705
  try {
1061
- await this.send(e) ? (this.clearPersistedEvents(), this.resetRetryState(), t?.onSuccess?.(e.events.length)) : this.retryCount >= Se ? (this.clearPersistedEvents(), this.resetRetryState(), t?.onFailure?.()) : this.scheduleRetry(e, t);
706
+ await this.send(e) ? (this.clearPersistedEvents(), this.resetRetryState(), t?.onSuccess?.(e.events.length)) : this.retryCount >= 3 ? (this.clearPersistedEvents(), this.resetRetryState(), t?.onFailure?.()) : this.scheduleRetry(e, t);
1062
707
  } finally {
1063
708
  this.isRetrying = !1;
1064
709
  }
1065
- }, n), a.debug("SenderManager", "Retry scheduled", {
1066
- attempt: this.retryCount + 1,
1067
- delay: n,
1068
- events: e.events.length
1069
- });
710
+ }, r);
1070
711
  }
1071
712
  shouldSkipSend() {
1072
- const e = this.get("config"), { id: t } = e || {};
1073
- return t === f.Skip;
713
+ return !this.get("apiUrl");
1074
714
  }
1075
715
  async simulateSuccessfulSend() {
1076
716
  const e = Math.random() * 400 + 100;
@@ -1083,76 +723,107 @@ class Gt extends m {
1083
723
  this.retryTimeoutId !== null && (clearTimeout(this.retryTimeoutId), this.retryTimeoutId = null);
1084
724
  }
1085
725
  }
1086
- class jt extends m {
726
+ class ct extends f {
1087
727
  googleAnalytics;
1088
728
  dataSender;
1089
729
  emitter;
1090
730
  eventsQueue = [];
731
+ pendingEventsBuffer = [];
1091
732
  lastEventFingerprint = null;
1092
733
  lastEventTime = 0;
1093
734
  sendIntervalId = null;
1094
- constructor(e, t = null, n = null) {
1095
- super(), this.googleAnalytics = t, this.dataSender = new Gt(e), this.emitter = n;
735
+ rateLimitCounter = 0;
736
+ rateLimitWindowStart = 0;
737
+ constructor(e, t = null, r = null) {
738
+ super(), this.googleAnalytics = t, this.dataSender = new ot(e), this.emitter = r;
1096
739
  }
1097
740
  async recoverPersistedEvents() {
1098
741
  await this.dataSender.recoverPersistedEvents({
1099
- onSuccess: (e, t, n) => {
742
+ onSuccess: (e, t, r) => {
1100
743
  if (t && t.length > 0) {
1101
- const s = t.map((i) => i.timestamp + "_" + i.type);
1102
- this.removeProcessedEvents(s), n && this.emitEventsQueue(n);
744
+ const n = t.map((i) => i.id);
745
+ this.removeProcessedEvents(n), r && this.emitEventsQueue(r);
1103
746
  }
1104
747
  },
1105
748
  onFailure: async () => {
1106
- a.warn("EventManager", "Failed to recover persisted events");
749
+ o("warn", "Failed to recover persisted events");
1107
750
  }
1108
751
  });
1109
752
  }
1110
753
  track({
1111
754
  type: e,
1112
755
  page_url: t,
1113
- from_page_url: n,
1114
- scroll_data: s,
756
+ from_page_url: r,
757
+ scroll_data: n,
1115
758
  click_data: i,
1116
- custom_event: o,
759
+ custom_event: a,
1117
760
  web_vitals: c,
1118
761
  error_data: l,
1119
762
  session_end_reason: u
1120
763
  }) {
1121
764
  if (!e) {
1122
- a.warn("EventManager", "Event type is required");
765
+ o("error", "Event type is required - event will be ignored");
1123
766
  return;
1124
767
  }
1125
- const h = e, L = h === d.SESSION_START, Ke = h === d.SESSION_END, Xe = L || Ke, qe = t || this.get("pageUrl"), K = this.buildEventPayload({
1126
- type: h,
1127
- page_url: qe,
1128
- from_page_url: n,
1129
- scroll_data: s,
768
+ if (!this.get("sessionId")) {
769
+ this.pendingEventsBuffer.length >= 100 && (this.pendingEventsBuffer.shift(), o("warn", "Pending events buffer full - dropping oldest event", {
770
+ data: { maxBufferSize: 100 }
771
+ })), this.pendingEventsBuffer.push({
772
+ type: e,
773
+ page_url: t,
774
+ from_page_url: r,
775
+ scroll_data: n,
776
+ click_data: i,
777
+ custom_event: a,
778
+ web_vitals: c,
779
+ error_data: l,
780
+ session_end_reason: u
781
+ });
782
+ return;
783
+ }
784
+ const p = e === d.SESSION_START || e === d.SESSION_END;
785
+ if (!p && !this.checkRateLimit())
786
+ return;
787
+ const N = e, Le = N === d.SESSION_START, Re = t || this.get("pageUrl"), z = this.buildEventPayload({
788
+ type: N,
789
+ page_url: Re,
790
+ from_page_url: r,
791
+ scroll_data: n,
1130
792
  click_data: i,
1131
- custom_event: o,
793
+ custom_event: a,
1132
794
  web_vitals: c,
1133
795
  error_data: l,
1134
796
  session_end_reason: u
1135
797
  });
1136
- if (!this.isEventExcluded(K) && !(!Xe && !this.shouldSample())) {
1137
- if (L) {
1138
- const me = this.get("sessionId");
1139
- if (!me) {
1140
- a.warn("EventManager", "Session start event ignored: missing sessionId");
798
+ if (!(!p && !this.shouldSample())) {
799
+ if (Le) {
800
+ const ae = this.get("sessionId");
801
+ if (!ae) {
802
+ o("error", "Session start event requires sessionId - event will be ignored");
1141
803
  return;
1142
804
  }
1143
805
  if (this.get("hasStartSession")) {
1144
- a.warn("EventManager", "Duplicate session_start detected", {
1145
- sessionId: me
806
+ o("warn", "Duplicate session_start detected", {
807
+ data: { sessionId: ae }
1146
808
  });
1147
809
  return;
1148
810
  }
1149
811
  this.set("hasStartSession", !0);
1150
812
  }
1151
- this.isDuplicateEvent(K) || this.addToQueue(K);
813
+ if (!this.isDuplicateEvent(z)) {
814
+ if (this.get("mode") === R.QA && N === d.CUSTOM && a) {
815
+ console.log("[TraceLog] Event", {
816
+ name: a.name,
817
+ ...a.metadata && { metadata: a.metadata }
818
+ }), this.emitEvent(z);
819
+ return;
820
+ }
821
+ this.addToQueue(z);
822
+ }
1152
823
  }
1153
824
  }
1154
825
  stop() {
1155
- this.sendIntervalId && (clearInterval(this.sendIntervalId), this.sendIntervalId = null), this.eventsQueue = [], this.lastEventFingerprint = null, this.lastEventTime = 0, this.dataSender.stop();
826
+ this.sendIntervalId && (clearInterval(this.sendIntervalId), this.sendIntervalId = null), this.eventsQueue = [], this.pendingEventsBuffer = [], this.lastEventFingerprint = null, this.lastEventTime = 0, this.rateLimitCounter = 0, this.rateLimitWindowStart = 0, this.dataSender.stop();
1156
827
  }
1157
828
  async flushImmediately() {
1158
829
  return this.flushEvents(!1);
@@ -1163,24 +834,38 @@ class jt extends m {
1163
834
  getQueueLength() {
1164
835
  return this.eventsQueue.length;
1165
836
  }
837
+ flushPendingEvents() {
838
+ if (this.pendingEventsBuffer.length === 0)
839
+ return;
840
+ if (!this.get("sessionId")) {
841
+ o("warn", "Cannot flush pending events: session not initialized - keeping in buffer", {
842
+ data: { bufferedEventCount: this.pendingEventsBuffer.length }
843
+ });
844
+ return;
845
+ }
846
+ const t = [...this.pendingEventsBuffer];
847
+ this.pendingEventsBuffer = [], t.forEach((r) => {
848
+ this.track(r);
849
+ });
850
+ }
1166
851
  clearSendInterval() {
1167
852
  this.sendIntervalId && (clearInterval(this.sendIntervalId), this.sendIntervalId = null);
1168
853
  }
1169
854
  flushEvents(e) {
1170
855
  if (this.eventsQueue.length === 0)
1171
856
  return e ? !0 : Promise.resolve(!0);
1172
- const t = this.buildEventsPayload(), n = [...this.eventsQueue], s = n.map((i) => `${i.timestamp}_${i.type}`);
857
+ const t = this.buildEventsPayload(), r = [...this.eventsQueue], n = r.map((i) => i.id);
1173
858
  if (e) {
1174
859
  const i = this.dataSender.sendEventsQueueSync(t);
1175
- return i && (this.removeProcessedEvents(s), this.clearSendInterval(), this.emitEventsQueue(t)), i;
860
+ return i && (this.removeProcessedEvents(n), this.clearSendInterval(), this.emitEventsQueue(t)), i;
1176
861
  } else
1177
862
  return this.dataSender.sendEventsQueue(t, {
1178
863
  onSuccess: () => {
1179
- this.removeProcessedEvents(s), this.clearSendInterval(), this.emitEventsQueue(t);
864
+ this.removeProcessedEvents(n), this.clearSendInterval(), this.emitEventsQueue(t);
1180
865
  },
1181
866
  onFailure: () => {
1182
- a.warn("EventManager", "Async flush failed", {
1183
- eventCount: n.length
867
+ o("warn", "Async flush failed", {
868
+ data: { eventCount: r.length }
1184
869
  });
1185
870
  }
1186
871
  });
@@ -1188,37 +873,39 @@ class jt extends m {
1188
873
  async sendEventsQueue() {
1189
874
  if (!this.get("sessionId") || this.eventsQueue.length === 0)
1190
875
  return;
1191
- const e = this.buildEventsPayload(), t = [...this.eventsQueue], n = t.map((s) => `${s.timestamp}_${s.type}`);
876
+ const e = this.buildEventsPayload(), t = [...this.eventsQueue], r = t.map((n) => n.id);
1192
877
  await this.dataSender.sendEventsQueue(e, {
1193
878
  onSuccess: () => {
1194
- this.removeProcessedEvents(n), this.emitEventsQueue(e);
879
+ this.removeProcessedEvents(r), this.emitEventsQueue(e);
1195
880
  },
1196
881
  onFailure: async () => {
1197
- a.warn("EventManager", "Events send failed, keeping in queue", {
1198
- eventCount: t.length
882
+ o("warn", "Events send failed, keeping in queue", {
883
+ data: { eventCount: t.length }
1199
884
  });
1200
885
  }
1201
886
  });
1202
887
  }
1203
888
  buildEventsPayload() {
1204
889
  const e = /* @__PURE__ */ new Map(), t = [];
1205
- for (const s of this.eventsQueue) {
1206
- const i = this.createEventSignature(s);
1207
- e.has(i) || t.push(i), e.set(i, s);
890
+ for (const n of this.eventsQueue) {
891
+ const i = this.createEventSignature(n);
892
+ e.has(i) || t.push(i), e.set(i, n);
1208
893
  }
1209
- const n = t.map((s) => e.get(s)).filter((s) => !!s).sort((s, i) => s.timestamp - i.timestamp);
894
+ const r = t.map((n) => e.get(n)).filter((n) => !!n).sort((n, i) => n.timestamp - i.timestamp);
1210
895
  return {
1211
896
  user_id: this.get("userId"),
1212
897
  session_id: this.get("sessionId"),
1213
898
  device: this.get("device"),
1214
- events: n,
899
+ events: r,
1215
900
  ...this.get("config")?.globalMetadata && { global_metadata: this.get("config")?.globalMetadata }
1216
901
  };
1217
902
  }
1218
903
  buildEventPayload(e) {
1219
- const t = e.type === d.SESSION_START, n = e.page_url ?? this.get("pageUrl"), s = {
904
+ const t = e.type === d.SESSION_START, r = e.page_url ?? this.get("pageUrl");
905
+ return {
906
+ id: Xe(),
1220
907
  type: e.type,
1221
- page_url: n,
908
+ page_url: r,
1222
909
  timestamp: Date.now(),
1223
910
  ...t && { referrer: document.referrer || "Direct" },
1224
911
  ...e.from_page_url && { from_page_url: e.from_page_url },
@@ -1228,23 +915,18 @@ class jt extends m {
1228
915
  ...e.web_vitals && { web_vitals: e.web_vitals },
1229
916
  ...e.error_data && { error_data: e.error_data },
1230
917
  ...e.session_end_reason && { session_end_reason: e.session_end_reason },
1231
- ...t && Le() && { utm: Le() }
1232
- }, i = this.get("config")?.tags;
1233
- return i?.length && (s.tags = i), s;
1234
- }
1235
- isEventExcluded(e) {
1236
- const t = this.get("config"), n = Ut(e.page_url, t?.excludedUrlPaths ?? []), s = this.get("hasStartSession"), i = e.type === d.SESSION_END, o = e.type === d.SESSION_START;
1237
- return n && !o && !(i && s) ? !0 : t?.ipExcluded === !0;
918
+ ...t && he() && { utm: he() }
919
+ };
1238
920
  }
1239
921
  isDuplicateEvent(e) {
1240
- const t = Date.now(), n = this.createEventFingerprint(e);
1241
- return this.lastEventFingerprint === n && t - this.lastEventTime < Je ? !0 : (this.lastEventFingerprint = n, this.lastEventTime = t, !1);
922
+ const t = Date.now(), r = this.createEventFingerprint(e);
923
+ return this.lastEventFingerprint === r && t - this.lastEventTime < 500 ? !0 : (this.lastEventFingerprint = r, this.lastEventTime = t, !1);
1242
924
  }
1243
925
  createEventFingerprint(e) {
1244
926
  let t = `${e.type}_${e.page_url}`;
1245
927
  if (e.click_data) {
1246
- const n = Math.round((e.click_data.x || 0) / 10) * 10, s = Math.round((e.click_data.y || 0) / 10) * 10;
1247
- t += `_click_${n}_${s}`;
928
+ const r = Math.round((e.click_data.x || 0) / 10) * 10, n = Math.round((e.click_data.y || 0) / 10) * 10;
929
+ t += `_click_${r}_${n}`;
1248
930
  }
1249
931
  return e.scroll_data && (t += `_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`), e.custom_event && (t += `_custom_${e.custom_event.name}`), e.web_vitals && (t += `_vitals_${e.web_vitals.type}`), e.error_data && (t += `_error_${e.error_data.type}_${e.error_data.message}`), t;
1250
932
  }
@@ -1252,15 +934,17 @@ class jt extends m {
1252
934
  return this.createEventFingerprint(e);
1253
935
  }
1254
936
  addToQueue(e) {
1255
- if (this.eventsQueue.push(e), this.emitEvent(e), this.eventsQueue.length > pe) {
937
+ if (this.eventsQueue.push(e), this.emitEvent(e), this.eventsQueue.length > 100) {
1256
938
  const t = this.eventsQueue.findIndex(
1257
- (s) => s.type !== d.SESSION_START && s.type !== d.SESSION_END
1258
- ), n = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
1259
- a.warn("EventManager", "Event queue overflow, oldest non-critical event removed", {
1260
- maxLength: pe,
1261
- currentLength: this.eventsQueue.length,
1262
- removedEventType: n?.type,
1263
- wasCritical: n?.type === d.SESSION_START || n?.type === d.SESSION_END
939
+ (n) => n.type !== d.SESSION_START && n.type !== d.SESSION_END
940
+ ), r = t >= 0 ? this.eventsQueue.splice(t, 1)[0] : this.eventsQueue.shift();
941
+ o("warn", "Event queue overflow, oldest non-critical event removed", {
942
+ data: {
943
+ maxLength: 100,
944
+ currentLength: this.eventsQueue.length,
945
+ removedEventType: r?.type,
946
+ wasCritical: r?.type === d.SESSION_START || r?.type === d.SESSION_END
947
+ }
1264
948
  });
1265
949
  }
1266
950
  this.sendIntervalId || this.startSendInterval(), this.handleGoogleAnalyticsIntegration(e);
@@ -1268,11 +952,11 @@ class jt extends m {
1268
952
  startSendInterval() {
1269
953
  this.sendIntervalId = window.setInterval(() => {
1270
954
  this.eventsQueue.length > 0 && this.sendEventsQueue();
1271
- }, Ze);
955
+ }, 1e4);
1272
956
  }
1273
957
  handleGoogleAnalyticsIntegration(e) {
1274
958
  if (this.googleAnalytics && e.type === d.CUSTOM && e.custom_event) {
1275
- if (this.get("config")?.mode === "qa" || this.get("config")?.mode === "debug")
959
+ if (this.get("mode") === R.QA)
1276
960
  return;
1277
961
  this.googleAnalytics.trackEvent(e.custom_event.name, e.custom_event.metadata ?? {});
1278
962
  }
@@ -1281,21 +965,22 @@ class jt extends m {
1281
965
  const e = this.get("config")?.samplingRate ?? 1;
1282
966
  return Math.random() < e;
1283
967
  }
968
+ checkRateLimit() {
969
+ const e = Date.now();
970
+ return e - this.rateLimitWindowStart > 1e3 && (this.rateLimitCounter = 0, this.rateLimitWindowStart = e), this.rateLimitCounter >= 200 ? !1 : (this.rateLimitCounter++, !0);
971
+ }
1284
972
  removeProcessedEvents(e) {
1285
973
  const t = new Set(e);
1286
- this.eventsQueue = this.eventsQueue.filter((n) => {
1287
- const s = `${n.timestamp}_${n.type}`;
1288
- return !t.has(s);
1289
- });
974
+ this.eventsQueue = this.eventsQueue.filter((r) => !t.has(r.id));
1290
975
  }
1291
976
  emitEvent(e) {
1292
- this.emitter && this.emitter.emit(re.EVENT, e);
977
+ this.emitter && this.emitter.emit(X.EVENT, e);
1293
978
  }
1294
979
  emitEventsQueue(e) {
1295
- this.emitter && this.emitter.emit(re.QUEUE, e);
980
+ this.emitter && this.emitter.emit(X.QUEUE, e);
1296
981
  }
1297
982
  }
1298
- class $t {
983
+ class lt {
1299
984
  /**
1300
985
  * Gets or creates a unique user ID for the given project.
1301
986
  * The user ID is persisted in localStorage and reused across sessions.
@@ -1304,15 +989,15 @@ class $t {
1304
989
  * @param projectId - Project identifier for namespacing
1305
990
  * @returns Persistent unique user ID
1306
991
  */
1307
- static getId(e, t) {
1308
- const n = ct(t ?? ""), s = e.getItem(n);
1309
- if (s)
1310
- return s;
1311
- const i = Et();
1312
- return e.setItem(n, i), i;
992
+ static getId(e) {
993
+ const t = xe, r = e.getItem(t);
994
+ if (r)
995
+ return r;
996
+ const n = je();
997
+ return e.setItem(t, n), n;
1313
998
  }
1314
999
  }
1315
- class Qt extends m {
1000
+ class ut extends f {
1316
1001
  storageManager;
1317
1002
  eventManager;
1318
1003
  projectId;
@@ -1322,23 +1007,23 @@ class Qt extends m {
1322
1007
  visibilityChangeHandler = null;
1323
1008
  beforeUnloadHandler = null;
1324
1009
  isTracking = !1;
1325
- constructor(e, t, n) {
1326
- super(), this.storageManager = e, this.eventManager = t, this.projectId = n;
1010
+ constructor(e, t, r) {
1011
+ super(), this.storageManager = e, this.eventManager = t, this.projectId = r;
1327
1012
  }
1328
1013
  initCrossTabSync() {
1329
1014
  if (typeof BroadcastChannel > "u") {
1330
- a.warn("SessionManager", "BroadcastChannel not supported");
1015
+ o("warn", "BroadcastChannel not supported");
1331
1016
  return;
1332
1017
  }
1333
1018
  const e = this.getProjectId();
1334
- this.broadcastChannel = new BroadcastChannel(ht(e)), this.broadcastChannel.onmessage = (t) => {
1335
- const { action: n, sessionId: s, timestamp: i, projectId: o } = t.data ?? {};
1336
- if (o === e) {
1337
- if (n === "session_end") {
1338
- a.debug("SessionManager", "Session end synced from another tab"), this.resetSessionState();
1019
+ this.broadcastChannel = new BroadcastChannel(Ge(e)), this.broadcastChannel.onmessage = (t) => {
1020
+ const { action: r, sessionId: n, timestamp: i, projectId: a } = t.data ?? {};
1021
+ if (a === e) {
1022
+ if (r === "session_end") {
1023
+ this.resetSessionState();
1339
1024
  return;
1340
1025
  }
1341
- s && typeof i == "number" && i > Date.now() - 5e3 && (this.set("sessionId", s), this.set("hasStartSession", !0), this.persistSession(s, i), this.isTracking && this.setupSessionTimeout(), a.debug("SessionManager", "Session synced from another tab", { sessionId: s }));
1026
+ n && typeof i == "number" && i > Date.now() - 5e3 && (this.set("sessionId", n), this.set("hasStartSession", !0), this.persistSession(n, i), this.isTracking && this.setupSessionTimeout());
1342
1027
  }
1343
1028
  };
1344
1029
  }
@@ -1366,8 +1051,8 @@ class Qt extends m {
1366
1051
  const e = this.loadStoredSession();
1367
1052
  if (!e)
1368
1053
  return null;
1369
- const t = this.get("config")?.sessionTimeout ?? P;
1370
- return Date.now() - e.lastActivity > t ? (a.debug("SessionManager", "Stored session expired"), this.clearStoredSession(), null) : (a.info("SessionManager", "Session recovered from storage", { sessionId: e.id }), e.id);
1054
+ const t = this.get("config")?.sessionTimeout ?? 9e5;
1055
+ return Date.now() - e.lastActivity > t ? (this.clearStoredSession(), null) : e.id;
1371
1056
  }
1372
1057
  persistSession(e, t = Date.now()) {
1373
1058
  this.saveStoredSession({
@@ -1384,8 +1069,8 @@ class Qt extends m {
1384
1069
  if (!t)
1385
1070
  return null;
1386
1071
  try {
1387
- const n = JSON.parse(t);
1388
- return !n.id || typeof n.lastActivity != "number" ? null : n;
1072
+ const r = JSON.parse(t);
1073
+ return !r.id || typeof r.lastActivity != "number" ? null : r;
1389
1074
  } catch {
1390
1075
  return this.storageManager.removeItem(e), null;
1391
1076
  }
@@ -1395,24 +1080,24 @@ class Qt extends m {
1395
1080
  this.storageManager.setItem(t, JSON.stringify(e));
1396
1081
  }
1397
1082
  getSessionStorageKey() {
1398
- return dt(this.getProjectId());
1083
+ return Fe(this.getProjectId());
1399
1084
  }
1400
1085
  getProjectId() {
1401
1086
  return this.projectId;
1402
1087
  }
1403
1088
  async startTracking() {
1404
1089
  if (this.isTracking) {
1405
- a.warn("SessionManager", "Session tracking already active");
1090
+ o("warn", "Session tracking already active");
1406
1091
  return;
1407
1092
  }
1408
- const e = this.recoverSession(), t = e ?? this.generateSessionId(), n = !!e;
1093
+ const e = this.recoverSession(), t = e ?? this.generateSessionId(), r = !!e;
1409
1094
  this.isTracking = !0;
1410
1095
  try {
1411
- this.set("sessionId", t), this.persistSession(t), n || this.eventManager.track({
1096
+ this.set("sessionId", t), this.persistSession(t), r || this.eventManager.track({
1412
1097
  type: d.SESSION_START
1413
- }), this.initCrossTabSync(), this.shareSession(t), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners(), a.info("SessionManager", "Session tracking started", { sessionId: t, recovered: n });
1414
- } catch (s) {
1415
- throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null), s;
1098
+ }), this.initCrossTabSync(), this.shareSession(t), this.setupSessionTimeout(), this.setupActivityListeners(), this.setupLifecycleListeners();
1099
+ } catch (n) {
1100
+ throw this.isTracking = !1, this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupLifecycleListeners(), this.cleanupCrossTabSync(), this.set("sessionId", null), n;
1416
1101
  }
1417
1102
  }
1418
1103
  generateSessionId() {
@@ -1420,7 +1105,7 @@ class Qt extends m {
1420
1105
  }
1421
1106
  setupSessionTimeout() {
1422
1107
  this.clearSessionTimeout();
1423
- const e = this.get("config")?.sessionTimeout ?? P;
1108
+ const e = this.get("config")?.sessionTimeout ?? 9e5;
1424
1109
  this.sessionTimeoutId = setTimeout(() => {
1425
1110
  this.endSession("inactivity");
1426
1111
  }, e);
@@ -1452,26 +1137,24 @@ class Qt extends m {
1452
1137
  async endSession(e) {
1453
1138
  const t = this.get("sessionId");
1454
1139
  if (!t) {
1455
- a.warn("SessionManager", "endSession called without active session", { reason: e }), this.resetSessionState(e);
1140
+ o("warn", "endSession called without active session", { data: { reason: e } }), this.resetSessionState(e);
1456
1141
  return;
1457
1142
  }
1458
- a.info("SessionManager", "Ending session", { sessionId: t, reason: e }), this.eventManager.track({
1143
+ this.eventManager.track({
1459
1144
  type: d.SESSION_END,
1460
1145
  session_end_reason: e
1461
1146
  });
1462
- const n = () => {
1147
+ const r = () => {
1463
1148
  this.broadcastSessionEnd(t, e), this.resetSessionState(e);
1464
1149
  };
1465
1150
  if (this.eventManager.flushImmediatelySync()) {
1466
- n();
1151
+ r();
1467
1152
  return;
1468
1153
  }
1469
1154
  try {
1470
- await this.eventManager.flushImmediately(), n();
1155
+ await this.eventManager.flushImmediately(), r();
1471
1156
  } catch (i) {
1472
- a.warn("SessionManager", "Async flush failed during session end", {
1473
- error: i instanceof Error ? i.message : "Unknown error"
1474
- }), n();
1157
+ o("warn", "Async flush failed during session end", { error: i }), r();
1475
1158
  }
1476
1159
  }
1477
1160
  resetSessionState(e) {
@@ -1484,7 +1167,7 @@ class Qt extends m {
1484
1167
  this.clearSessionTimeout(), this.cleanupActivityListeners(), this.cleanupCrossTabSync(), this.cleanupLifecycleListeners(), this.isTracking = !1, this.set("hasStartSession", !1);
1485
1168
  }
1486
1169
  }
1487
- class Bt extends m {
1170
+ class dt extends f {
1488
1171
  eventManager;
1489
1172
  storageManager;
1490
1173
  sessionManager = null;
@@ -1496,15 +1179,15 @@ class Bt extends m {
1496
1179
  if (this.isActive())
1497
1180
  return;
1498
1181
  if (this.destroyed) {
1499
- a.warn("SessionHandler", "Cannot start tracking on destroyed handler");
1182
+ o("warn", "Cannot start tracking on destroyed handler");
1500
1183
  return;
1501
1184
  }
1502
- const e = this.get("config")?.id;
1503
- if (!e)
1185
+ const e = this.get("config"), t = e?.integrations?.tracelog?.projectId ?? e?.integrations?.custom?.apiUrl ?? "default";
1186
+ if (!t)
1504
1187
  throw new Error("Cannot start session tracking: config not available");
1505
1188
  try {
1506
- this.sessionManager = new Qt(this.storageManager, this.eventManager, e), await this.sessionManager.startTracking();
1507
- } catch (t) {
1189
+ this.sessionManager = new ut(this.storageManager, this.eventManager, t), await this.sessionManager.startTracking(), this.eventManager.flushPendingEvents();
1190
+ } catch (r) {
1508
1191
  if (this.sessionManager) {
1509
1192
  try {
1510
1193
  this.sessionManager.destroy();
@@ -1512,9 +1195,7 @@ class Bt extends m {
1512
1195
  }
1513
1196
  this.sessionManager = null;
1514
1197
  }
1515
- throw a.error("SessionHandler", "Failed to start session tracking", {
1516
- error: t instanceof Error ? t.message : "Unknown error"
1517
- }), t;
1198
+ throw o("error", "Failed to start session tracking", { error: r }), r;
1518
1199
  }
1519
1200
  }
1520
1201
  isActive() {
@@ -1530,7 +1211,7 @@ class Bt extends m {
1530
1211
  this.destroyed || (this.sessionManager && (this.sessionManager.destroy(), this.sessionManager = null), this.destroyed = !0, this.set("hasStartSession", !1));
1531
1212
  }
1532
1213
  }
1533
- class Wt extends m {
1214
+ class ht extends f {
1534
1215
  eventManager;
1535
1216
  onTrack;
1536
1217
  originalPushState;
@@ -1539,34 +1220,34 @@ class Wt extends m {
1539
1220
  super(), this.eventManager = e, this.onTrack = t;
1540
1221
  }
1541
1222
  startTracking() {
1542
- a.debug("PageViewHandler", "Starting page view tracking"), this.trackInitialPageView(), window.addEventListener("popstate", this.trackCurrentPage, !0), window.addEventListener("hashchange", this.trackCurrentPage, !0), this.patchHistory("pushState"), this.patchHistory("replaceState");
1223
+ this.trackInitialPageView(), window.addEventListener("popstate", this.trackCurrentPage, !0), window.addEventListener("hashchange", this.trackCurrentPage, !0), this.patchHistory("pushState"), this.patchHistory("replaceState");
1543
1224
  }
1544
1225
  stopTracking() {
1545
- a.debug("PageViewHandler", "Stopping page view tracking"), window.removeEventListener("popstate", this.trackCurrentPage, !0), window.removeEventListener("hashchange", this.trackCurrentPage, !0), this.originalPushState && (window.history.pushState = this.originalPushState), this.originalReplaceState && (window.history.replaceState = this.originalReplaceState);
1226
+ window.removeEventListener("popstate", this.trackCurrentPage, !0), window.removeEventListener("hashchange", this.trackCurrentPage, !0), this.originalPushState && (window.history.pushState = this.originalPushState), this.originalReplaceState && (window.history.replaceState = this.originalReplaceState);
1546
1227
  }
1547
1228
  patchHistory(e) {
1548
1229
  const t = window.history[e];
1549
- e === "pushState" && !this.originalPushState ? this.originalPushState = t : e === "replaceState" && !this.originalReplaceState && (this.originalReplaceState = t), window.history[e] = (...n) => {
1550
- t.apply(window.history, n), this.trackCurrentPage();
1230
+ e === "pushState" && !this.originalPushState ? this.originalPushState = t : e === "replaceState" && !this.originalReplaceState && (this.originalReplaceState = t), window.history[e] = (...r) => {
1231
+ t.apply(window.history, r), this.trackCurrentPage();
1551
1232
  };
1552
1233
  }
1553
1234
  trackCurrentPage = async () => {
1554
- const e = window.location.href, t = ie(e, this.get("config").sensitiveQueryParams);
1235
+ const e = window.location.href, t = Y(e, this.get("config").sensitiveQueryParams);
1555
1236
  if (this.get("pageUrl") === t)
1556
1237
  return;
1557
1238
  this.onTrack();
1558
- const n = this.get("pageUrl");
1559
- a.debug("PageViewHandler", "Page navigation detected", { from: n, to: t }), this.set("pageUrl", t);
1560
- const s = this.extractPageViewData();
1239
+ const r = this.get("pageUrl");
1240
+ this.set("pageUrl", t);
1241
+ const n = this.extractPageViewData();
1561
1242
  this.eventManager.track({
1562
1243
  type: d.PAGE_VIEW,
1563
1244
  page_url: this.get("pageUrl"),
1564
- from_page_url: n,
1565
- ...s && { page_view: s }
1245
+ from_page_url: r,
1246
+ ...n && { page_view: n }
1566
1247
  });
1567
1248
  };
1568
1249
  trackInitialPageView() {
1569
- const e = ie(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
1250
+ const e = Y(window.location.href, this.get("config").sensitiveQueryParams), t = this.extractPageViewData();
1570
1251
  this.eventManager.track({
1571
1252
  type: d.PAGE_VIEW,
1572
1253
  page_url: e,
@@ -1574,17 +1255,17 @@ class Wt extends m {
1574
1255
  }), this.onTrack();
1575
1256
  }
1576
1257
  extractPageViewData() {
1577
- const { pathname: e, search: t, hash: n } = window.location, { referrer: s } = document, { title: i } = document;
1578
- return !s && !i && !e && !t && !n ? void 0 : {
1579
- ...s && { referrer: s },
1258
+ const { pathname: e, search: t, hash: r } = window.location, { referrer: n } = document, { title: i } = document;
1259
+ return !n && !i && !e && !t && !r ? void 0 : {
1260
+ ...n && { referrer: n },
1580
1261
  ...i && { title: i },
1581
1262
  ...e && { pathname: e },
1582
1263
  ...t && { search: t },
1583
- ...n && { hash: n }
1264
+ ...r && { hash: r }
1584
1265
  };
1585
1266
  }
1586
1267
  }
1587
- class Yt extends m {
1268
+ class ft extends f {
1588
1269
  eventManager;
1589
1270
  clickHandler;
1590
1271
  constructor(e) {
@@ -1592,26 +1273,26 @@ class Yt extends m {
1592
1273
  }
1593
1274
  startTracking() {
1594
1275
  this.clickHandler || (this.clickHandler = (e) => {
1595
- const t = e, n = t.target, s = n instanceof HTMLElement ? n : n instanceof Node && n.parentElement instanceof HTMLElement ? n.parentElement : null;
1596
- if (!s) {
1597
- a.warn("ClickHandler", "Click target not found or not an element");
1276
+ const t = e, r = t.target, n = r instanceof HTMLElement ? r : r instanceof Node && r.parentElement instanceof HTMLElement ? r.parentElement : null;
1277
+ if (!n) {
1278
+ o("warn", "Click target not found or not an element");
1598
1279
  return;
1599
1280
  }
1600
- const i = this.findTrackingElement(s), o = this.getRelevantClickElement(s), c = this.calculateClickCoordinates(t, s);
1281
+ const i = this.findTrackingElement(n), a = this.getRelevantClickElement(n), c = this.calculateClickCoordinates(t, n);
1601
1282
  if (i) {
1602
1283
  const u = this.extractTrackingData(i);
1603
1284
  if (u) {
1604
- const h = this.createCustomEventData(u);
1285
+ const p = this.createCustomEventData(u);
1605
1286
  this.eventManager.track({
1606
1287
  type: d.CUSTOM,
1607
1288
  custom_event: {
1608
- name: h.name,
1609
- ...h.value && { metadata: { value: h.value } }
1289
+ name: p.name,
1290
+ ...p.value && { metadata: { value: p.value } }
1610
1291
  }
1611
1292
  });
1612
1293
  }
1613
1294
  }
1614
- const l = this.generateClickData(s, o, c);
1295
+ const l = this.generateClickData(n, a, c);
1615
1296
  this.eventManager.track({
1616
1297
  type: d.CLICK,
1617
1298
  click_data: l
@@ -1622,21 +1303,18 @@ class Yt extends m {
1622
1303
  this.clickHandler && (window.removeEventListener("click", this.clickHandler, !0), this.clickHandler = void 0);
1623
1304
  }
1624
1305
  findTrackingElement(e) {
1625
- return e.hasAttribute(`${F}-name`) ? e : e.closest(`[${F}-name]`) || void 0;
1306
+ return e.hasAttribute(`${O}-name`) ? e : e.closest(`[${O}-name]`) || void 0;
1626
1307
  }
1627
1308
  getRelevantClickElement(e) {
1628
- for (const t of it)
1309
+ for (const t of Ce)
1629
1310
  try {
1630
1311
  if (e.matches(t))
1631
1312
  return e;
1632
- const n = e.closest(t);
1633
- if (n)
1634
- return n;
1635
- } catch (n) {
1636
- a.warn("ClickHandler", "Invalid selector in element search", {
1637
- selector: t,
1638
- error: n instanceof Error ? n.message : "Unknown error"
1639
- });
1313
+ const r = e.closest(t);
1314
+ if (r)
1315
+ return r;
1316
+ } catch (r) {
1317
+ o("warn", "Invalid selector in element search", { error: r, data: { selector: t } });
1640
1318
  continue;
1641
1319
  }
1642
1320
  return e;
@@ -1645,24 +1323,24 @@ class Yt extends m {
1645
1323
  return Math.max(0, Math.min(1, Number(e.toFixed(3))));
1646
1324
  }
1647
1325
  calculateClickCoordinates(e, t) {
1648
- const n = t.getBoundingClientRect(), s = e.clientX, i = e.clientY, o = n.width > 0 ? this.clamp((s - n.left) / n.width) : 0, c = n.height > 0 ? this.clamp((i - n.top) / n.height) : 0;
1649
- return { x: s, y: i, relativeX: o, relativeY: c };
1326
+ const r = t.getBoundingClientRect(), n = e.clientX, i = e.clientY, a = r.width > 0 ? this.clamp((n - r.left) / r.width) : 0, c = r.height > 0 ? this.clamp((i - r.top) / r.height) : 0;
1327
+ return { x: n, y: i, relativeX: a, relativeY: c };
1650
1328
  }
1651
1329
  extractTrackingData(e) {
1652
- const t = e.getAttribute(`${F}-name`), n = e.getAttribute(`${F}-value`);
1330
+ const t = e.getAttribute(`${O}-name`), r = e.getAttribute(`${O}-value`);
1653
1331
  if (t)
1654
1332
  return {
1655
1333
  element: e,
1656
1334
  name: t,
1657
- ...n && { value: n }
1335
+ ...r && { value: r }
1658
1336
  };
1659
1337
  }
1660
- generateClickData(e, t, n) {
1661
- const { x: s, y: i, relativeX: o, relativeY: c } = n, l = this.getRelevantText(e, t), u = this.extractElementAttributes(t);
1338
+ generateClickData(e, t, r) {
1339
+ const { x: n, y: i, relativeX: a, relativeY: c } = r, l = this.getRelevantText(e, t), u = this.extractElementAttributes(t);
1662
1340
  return {
1663
- x: s,
1341
+ x: n,
1664
1342
  y: i,
1665
- relativeX: o,
1343
+ relativeX: a,
1666
1344
  relativeY: c,
1667
1345
  tag: t.tagName.toLowerCase(),
1668
1346
  ...t.id && { id: t.id },
@@ -1677,8 +1355,8 @@ class Yt extends m {
1677
1355
  };
1678
1356
  }
1679
1357
  getRelevantText(e, t) {
1680
- const n = e.textContent?.trim() ?? "", s = t.textContent?.trim() ?? "";
1681
- return !n && !s ? "" : n && n.length <= X ? n : s.length <= X ? s : s.slice(0, X - 3) + "...";
1358
+ const r = e.textContent?.trim() ?? "", n = t.textContent?.trim() ?? "";
1359
+ return !r && !n ? "" : r && r.length <= 255 ? r : n.length <= 255 ? n : n.slice(0, 252) + "...";
1682
1360
  }
1683
1361
  extractElementAttributes(e) {
1684
1362
  const t = [
@@ -1692,12 +1370,12 @@ class Yt extends m {
1692
1370
  "name",
1693
1371
  "alt",
1694
1372
  "role"
1695
- ], n = {};
1696
- for (const s of t) {
1697
- const i = e.getAttribute(s);
1698
- i && (n[s] = i);
1373
+ ], r = {};
1374
+ for (const n of t) {
1375
+ const i = e.getAttribute(n);
1376
+ i && (r[n] = i);
1699
1377
  }
1700
- return n;
1378
+ return r;
1701
1379
  }
1702
1380
  createCustomEventData(e) {
1703
1381
  return {
@@ -1706,13 +1384,13 @@ class Yt extends m {
1706
1384
  };
1707
1385
  }
1708
1386
  }
1709
- class Kt extends m {
1387
+ class gt extends f {
1710
1388
  eventManager;
1711
1389
  containers = [];
1712
1390
  limitWarningLogged = !1;
1713
- minDepthChange = Ee;
1714
- minIntervalMs = ve;
1715
- maxEventsPerSession = ye;
1391
+ minDepthChange = 5;
1392
+ minIntervalMs = 500;
1393
+ maxEventsPerSession = 120;
1716
1394
  constructor(e) {
1717
1395
  super(), this.eventManager = e;
1718
1396
  }
@@ -1727,10 +1405,10 @@ class Kt extends m {
1727
1405
  this.containers.length = 0, this.set("scrollEventCount", 0), this.limitWarningLogged = !1;
1728
1406
  }
1729
1407
  trySetupContainers(e, t) {
1730
- const n = e.map((s) => this.safeQuerySelector(s)).filter((s) => s instanceof HTMLElement);
1731
- if (n.length > 0) {
1732
- for (const s of n)
1733
- this.containers.some((o) => o.element === s) || this.setupScrollContainer(s);
1408
+ const r = e.map((n) => this.safeQuerySelector(n)).filter((n) => n instanceof HTMLElement);
1409
+ if (r.length > 0) {
1410
+ for (const n of r)
1411
+ this.containers.some((a) => a.element === n) || this.setupScrollContainer(n);
1734
1412
  return;
1735
1413
  }
1736
1414
  if (t < 5) {
@@ -1743,41 +1421,41 @@ class Kt extends m {
1743
1421
  if (e !== window && !this.isElementScrollable(e))
1744
1422
  return;
1745
1423
  const t = () => {
1746
- this.get("suppressNextScroll") || (this.clearContainerTimer(s), s.debounceTimer = window.setTimeout(() => {
1747
- const i = this.calculateScrollData(s);
1424
+ this.get("suppressNextScroll") || (this.clearContainerTimer(n), n.debounceTimer = window.setTimeout(() => {
1425
+ const i = this.calculateScrollData(n);
1748
1426
  if (i) {
1749
- const o = Date.now();
1750
- this.processScrollEvent(s, i, o);
1427
+ const a = Date.now();
1428
+ this.processScrollEvent(n, i, a);
1751
1429
  }
1752
- s.debounceTimer = null;
1753
- }, xe));
1754
- }, n = this.getScrollTop(e), s = {
1430
+ n.debounceTimer = null;
1431
+ }, 250));
1432
+ }, r = this.getScrollTop(e), n = {
1755
1433
  element: e,
1756
- lastScrollPos: n,
1434
+ lastScrollPos: r,
1757
1435
  lastDepth: this.calculateScrollDepth(
1758
- n,
1436
+ r,
1759
1437
  this.getScrollHeight(e),
1760
1438
  this.getViewportHeight(e)
1761
1439
  ),
1762
- lastDirection: j.DOWN,
1440
+ lastDirection: D.DOWN,
1763
1441
  lastEventTime: 0,
1764
1442
  debounceTimer: null,
1765
1443
  listener: t
1766
1444
  };
1767
- this.containers.push(s), e instanceof Window ? window.addEventListener("scroll", t, { passive: !0 }) : e.addEventListener("scroll", t, { passive: !0 });
1445
+ this.containers.push(n), e instanceof Window ? window.addEventListener("scroll", t, { passive: !0 }) : e.addEventListener("scroll", t, { passive: !0 });
1768
1446
  }
1769
- processScrollEvent(e, t, n) {
1770
- if (!this.shouldEmitScrollEvent(e, t, n))
1447
+ processScrollEvent(e, t, r) {
1448
+ if (!this.shouldEmitScrollEvent(e, t, r))
1771
1449
  return;
1772
- e.lastEventTime = n, e.lastDepth = t.depth, e.lastDirection = t.direction;
1773
- const s = this.get("scrollEventCount") ?? 0;
1774
- this.set("scrollEventCount", s + 1), this.eventManager.track({
1450
+ e.lastEventTime = r, e.lastDepth = t.depth, e.lastDirection = t.direction;
1451
+ const n = this.get("scrollEventCount") ?? 0;
1452
+ this.set("scrollEventCount", n + 1), this.eventManager.track({
1775
1453
  type: d.SCROLL,
1776
1454
  scroll_data: t
1777
1455
  });
1778
1456
  }
1779
- shouldEmitScrollEvent(e, t, n) {
1780
- return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e, n) || !this.hasSignificantDepthChange(e, t.depth));
1457
+ shouldEmitScrollEvent(e, t, r) {
1458
+ return this.hasReachedSessionLimit() ? (this.logLimitOnce(), !1) : !(!this.hasElapsedMinimumInterval(e, r) || !this.hasSignificantDepthChange(e, t.depth));
1781
1459
  }
1782
1460
  hasReachedSessionLimit() {
1783
1461
  return (this.get("scrollEventCount") ?? 0) >= this.maxEventsPerSession;
@@ -1789,12 +1467,12 @@ class Kt extends m {
1789
1467
  return Math.abs(t - e.lastDepth) >= this.minDepthChange;
1790
1468
  }
1791
1469
  logLimitOnce() {
1792
- this.limitWarningLogged || (this.limitWarningLogged = !0, a.warn("ScrollHandler", "Max scroll events per session reached", {
1793
- limit: this.maxEventsPerSession
1470
+ this.limitWarningLogged || (this.limitWarningLogged = !0, o("warn", "Max scroll events per session reached", {
1471
+ data: { limit: this.maxEventsPerSession }
1794
1472
  }));
1795
1473
  }
1796
1474
  applyConfigOverrides() {
1797
- this.minDepthChange = Ee, this.minIntervalMs = ve, this.maxEventsPerSession = ye;
1475
+ this.minDepthChange = 5, this.minIntervalMs = 500, this.maxEventsPerSession = 120;
1798
1476
  }
1799
1477
  isWindowScrollable() {
1800
1478
  return document.documentElement.scrollHeight > window.innerHeight;
@@ -1803,20 +1481,20 @@ class Kt extends m {
1803
1481
  e.debounceTimer !== null && (clearTimeout(e.debounceTimer), e.debounceTimer = null);
1804
1482
  }
1805
1483
  getScrollDirection(e, t) {
1806
- return e > t ? j.DOWN : j.UP;
1484
+ return e > t ? D.DOWN : D.UP;
1807
1485
  }
1808
- calculateScrollDepth(e, t, n) {
1809
- if (t <= n)
1486
+ calculateScrollDepth(e, t, r) {
1487
+ if (t <= r)
1810
1488
  return 0;
1811
- const s = t - n;
1812
- return Math.min(100, Math.max(0, Math.floor(e / s * 100)));
1489
+ const n = t - r;
1490
+ return Math.min(100, Math.max(0, Math.floor(e / n * 100)));
1813
1491
  }
1814
1492
  calculateScrollData(e) {
1815
- const { element: t, lastScrollPos: n } = e, s = this.getScrollTop(t);
1816
- if (Math.abs(s - n) < rt || t === window && !this.isWindowScrollable())
1493
+ const { element: t, lastScrollPos: r } = e, n = this.getScrollTop(t);
1494
+ if (Math.abs(n - r) < 10 || t === window && !this.isWindowScrollable())
1817
1495
  return null;
1818
- const o = this.getViewportHeight(t), c = this.getScrollHeight(t), l = this.getScrollDirection(s, n), u = this.calculateScrollDepth(s, c, o);
1819
- return e.lastScrollPos = s, { depth: u, direction: l };
1496
+ const a = this.getViewportHeight(t), c = this.getScrollHeight(t), l = this.getScrollDirection(n, r), u = this.calculateScrollDepth(n, c, a);
1497
+ return e.lastScrollPos = n, { depth: u, direction: l };
1820
1498
  }
1821
1499
  getScrollTop(e) {
1822
1500
  return e instanceof Window ? window.scrollY : e.scrollTop;
@@ -1828,21 +1506,22 @@ class Kt extends m {
1828
1506
  return e instanceof Window ? document.documentElement.scrollHeight : e.scrollHeight;
1829
1507
  }
1830
1508
  isElementScrollable(e) {
1831
- const t = getComputedStyle(e), n = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflowX === "auto" || t.overflowX === "scroll" || t.overflow === "auto" || t.overflow === "scroll", s = e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth;
1832
- return n && s;
1509
+ const t = getComputedStyle(e), r = t.overflowY === "auto" || t.overflowY === "scroll" || t.overflowX === "auto" || t.overflowX === "scroll" || t.overflow === "auto" || t.overflow === "scroll", n = e.scrollHeight > e.clientHeight || e.scrollWidth > e.clientWidth;
1510
+ return r && n;
1833
1511
  }
1834
1512
  safeQuerySelector(e) {
1835
1513
  try {
1836
1514
  return document.querySelector(e);
1837
1515
  } catch (t) {
1838
- return a.clientWarn("ScrollHandler", "Invalid CSS selector", {
1839
- selector: e,
1840
- error: t instanceof Error ? t.message : "Unknown error"
1516
+ return o("warn", "Invalid CSS selector", {
1517
+ error: t,
1518
+ data: { selector: e },
1519
+ showToClient: !0
1841
1520
  }), null;
1842
1521
  }
1843
1522
  }
1844
1523
  }
1845
- class Xt extends m {
1524
+ class St extends f {
1846
1525
  isInitialized = !1;
1847
1526
  async initialize() {
1848
1527
  if (this.isInitialized)
@@ -1855,21 +1534,17 @@ class Xt extends m {
1855
1534
  return;
1856
1535
  }
1857
1536
  await this.loadScript(e), this.configureGtag(e, t), this.isInitialized = !0;
1858
- } catch (n) {
1859
- a.error("GoogleAnalyticsIntegration", "Initialization failed", {
1860
- error: n instanceof Error ? n.message : "Unknown error"
1861
- });
1537
+ } catch (r) {
1538
+ o("error", "Google Analytics initialization failed", { error: r });
1862
1539
  }
1863
1540
  }
1864
1541
  trackEvent(e, t) {
1865
1542
  if (!(!e?.trim() || !this.isInitialized || typeof window.gtag != "function"))
1866
1543
  try {
1867
- const n = Array.isArray(t) ? { items: t } : t;
1868
- window.gtag("event", e, n);
1869
- } catch (n) {
1870
- a.error("GoogleAnalyticsIntegration", "Event tracking failed", {
1871
- error: n instanceof Error ? n.message : "Unknown error"
1872
- });
1544
+ const r = Array.isArray(t) ? { items: t } : t;
1545
+ window.gtag("event", e, r);
1546
+ } catch (r) {
1547
+ o("error", "Google Analytics event tracking failed", { error: r });
1873
1548
  }
1874
1549
  }
1875
1550
  cleanup() {
@@ -1881,29 +1556,31 @@ class Xt extends m {
1881
1556
  return document.getElementById("tracelog-ga-script") ? !0 : !!document.querySelector('script[src*="googletagmanager.com/gtag/js"]');
1882
1557
  }
1883
1558
  async loadScript(e) {
1884
- return new Promise((t, n) => {
1885
- const s = document.createElement("script");
1886
- s.id = "tracelog-ga-script", s.async = !0, s.src = `https://www.googletagmanager.com/gtag/js?id=${e}`, s.onload = () => t(), s.onerror = () => n(new Error("Failed to load Google Analytics script")), document.head.appendChild(s);
1559
+ return new Promise((t, r) => {
1560
+ const n = document.createElement("script");
1561
+ n.id = "tracelog-ga-script", n.async = !0, n.src = `https://www.googletagmanager.com/gtag/js?id=${e}`, n.onload = () => t(), n.onerror = () => r(new Error("Failed to load Google Analytics script")), document.head.appendChild(n);
1887
1562
  });
1888
1563
  }
1889
1564
  configureGtag(e, t) {
1890
- const n = document.createElement("script");
1891
- n.innerHTML = `
1565
+ const r = document.createElement("script");
1566
+ r.innerHTML = `
1892
1567
  window.dataLayer = window.dataLayer || [];
1893
1568
  function gtag(){dataLayer.push(arguments);}
1894
1569
  gtag('js', new Date());
1895
1570
  gtag('config', '${e}', {
1896
1571
  'user_id': '${t}'
1897
1572
  });
1898
- `, document.head.appendChild(n);
1573
+ `, document.head.appendChild(r);
1899
1574
  }
1900
1575
  }
1901
- class qt {
1576
+ class Et {
1902
1577
  storage;
1578
+ sessionStorageRef;
1903
1579
  fallbackStorage = /* @__PURE__ */ new Map();
1580
+ fallbackSessionStorage = /* @__PURE__ */ new Map();
1904
1581
  hasQuotaExceededError = !1;
1905
1582
  constructor() {
1906
- this.storage = this.initializeStorage(), this.storage || a.warn("StorageManager", "localStorage not available, using memory fallback");
1583
+ this.storage = this.initializeStorage("localStorage"), this.sessionStorageRef = this.initializeStorage("sessionStorage"), this.storage || o("warn", "localStorage not available, using memory fallback"), this.sessionStorageRef || o("warn", "sessionStorage not available, using memory fallback");
1907
1584
  }
1908
1585
  /**
1909
1586
  * Retrieves an item from storage
@@ -1911,26 +1588,42 @@ class qt {
1911
1588
  getItem(e) {
1912
1589
  try {
1913
1590
  return this.storage ? this.storage.getItem(e) : this.fallbackStorage.get(e) ?? null;
1914
- } catch (t) {
1915
- return a.warn("StorageManager", "Failed to get item, using fallback", { key: e, error: t }), this.fallbackStorage.get(e) ?? null;
1591
+ } catch {
1592
+ return this.fallbackStorage.get(e) ?? null;
1916
1593
  }
1917
1594
  }
1918
1595
  /**
1919
1596
  * Stores an item in storage
1920
1597
  */
1921
1598
  setItem(e, t) {
1599
+ this.fallbackStorage.set(e, t);
1922
1600
  try {
1923
1601
  if (this.storage) {
1924
1602
  this.storage.setItem(e, t);
1925
1603
  return;
1926
1604
  }
1927
- } catch (n) {
1928
- n instanceof DOMException && n.name === "QuotaExceededError" ? (this.hasQuotaExceededError = !0, a.error("StorageManager", "localStorage quota exceeded - data will not persist after reload", {
1929
- key: e,
1930
- valueSize: t.length
1931
- })) : a.warn("StorageManager", "Failed to set item, using fallback", { key: e, error: n });
1605
+ } catch (r) {
1606
+ if (r instanceof DOMException && r.name === "QuotaExceededError")
1607
+ if (this.hasQuotaExceededError = !0, o("warn", "localStorage quota exceeded, attempting cleanup", {
1608
+ data: { key: e, valueSize: t.length }
1609
+ }), this.cleanupOldData())
1610
+ try {
1611
+ if (this.storage) {
1612
+ this.storage.setItem(e, t);
1613
+ return;
1614
+ }
1615
+ } catch (i) {
1616
+ o("error", "localStorage quota exceeded even after cleanup - data will not persist", {
1617
+ error: i,
1618
+ data: { key: e, valueSize: t.length }
1619
+ });
1620
+ }
1621
+ else
1622
+ o("error", "localStorage quota exceeded and no data to cleanup - data will not persist", {
1623
+ error: r,
1624
+ data: { key: e, valueSize: t.length }
1625
+ });
1932
1626
  }
1933
- this.fallbackStorage.set(e, t);
1934
1627
  }
1935
1628
  /**
1936
1629
  * Removes an item from storage
@@ -1938,8 +1631,7 @@ class qt {
1938
1631
  removeItem(e) {
1939
1632
  try {
1940
1633
  this.storage && this.storage.removeItem(e);
1941
- } catch (t) {
1942
- a.warn("StorageManager", "Failed to remove item", { key: e, error: t });
1634
+ } catch {
1943
1635
  }
1944
1636
  this.fallbackStorage.delete(e);
1945
1637
  }
@@ -1954,12 +1646,12 @@ class qt {
1954
1646
  try {
1955
1647
  const e = [];
1956
1648
  for (let t = 0; t < this.storage.length; t++) {
1957
- const n = this.storage.key(t);
1958
- n?.startsWith("tracelog_") && e.push(n);
1649
+ const r = this.storage.key(t);
1650
+ r?.startsWith("tracelog_") && e.push(r);
1959
1651
  }
1960
- e.forEach((t) => this.storage.removeItem(t)), this.fallbackStorage.clear(), a.debug("StorageManager", "Cleared storage", { itemsRemoved: e.length });
1652
+ e.forEach((t) => this.storage.removeItem(t)), this.fallbackStorage.clear();
1961
1653
  } catch (e) {
1962
- a.error("StorageManager", "Failed to clear storage", { error: e }), this.fallbackStorage.clear();
1654
+ o("error", "Failed to clear storage", { error: e }), this.fallbackStorage.clear();
1963
1655
  }
1964
1656
  }
1965
1657
  /**
@@ -1976,25 +1668,93 @@ class qt {
1976
1668
  return this.hasQuotaExceededError;
1977
1669
  }
1978
1670
  /**
1979
- * Initialize localStorage with feature detection
1671
+ * Attempts to cleanup old TraceLog data from storage to free up space
1672
+ * Returns true if any data was removed, false otherwise
1980
1673
  */
1981
- initializeStorage() {
1674
+ cleanupOldData() {
1675
+ if (!this.storage)
1676
+ return !1;
1677
+ try {
1678
+ const e = [], t = [];
1679
+ for (let i = 0; i < this.storage.length; i++) {
1680
+ const a = this.storage.key(i);
1681
+ a?.startsWith("tracelog_") && (e.push(a), a.startsWith("tracelog_persisted_events_") && t.push(a));
1682
+ }
1683
+ if (t.length > 0)
1684
+ return t.forEach((i) => {
1685
+ try {
1686
+ this.storage.removeItem(i);
1687
+ } catch {
1688
+ }
1689
+ }), !0;
1690
+ const r = ["tracelog_session_", "tracelog_user_id", "tracelog_device_id", "tracelog_config"], n = e.filter((i) => !r.some((a) => i.startsWith(a)));
1691
+ return n.length > 0 ? (n.slice(0, 5).forEach((a) => {
1692
+ try {
1693
+ this.storage.removeItem(a);
1694
+ } catch {
1695
+ }
1696
+ }), !0) : !1;
1697
+ } catch (e) {
1698
+ return o("error", "Failed to cleanup old data", { error: e }), !1;
1699
+ }
1700
+ }
1701
+ /**
1702
+ * Initialize storage (localStorage or sessionStorage) with feature detection
1703
+ */
1704
+ initializeStorage(e) {
1982
1705
  if (typeof window > "u")
1983
1706
  return null;
1984
1707
  try {
1985
- const e = window.localStorage, t = "__tracelog_test__";
1986
- return e.setItem(t, "test"), e.removeItem(t), e;
1708
+ const t = e === "localStorage" ? window.localStorage : window.sessionStorage, r = "__tracelog_test__";
1709
+ return t.setItem(r, "test"), t.removeItem(r), t;
1987
1710
  } catch {
1988
1711
  return null;
1989
1712
  }
1990
1713
  }
1714
+ /**
1715
+ * Retrieves an item from sessionStorage
1716
+ */
1717
+ getSessionItem(e) {
1718
+ try {
1719
+ return this.sessionStorageRef ? this.sessionStorageRef.getItem(e) : this.fallbackSessionStorage.get(e) ?? null;
1720
+ } catch {
1721
+ return this.fallbackSessionStorage.get(e) ?? null;
1722
+ }
1723
+ }
1724
+ /**
1725
+ * Stores an item in sessionStorage
1726
+ */
1727
+ setSessionItem(e, t) {
1728
+ this.fallbackSessionStorage.set(e, t);
1729
+ try {
1730
+ if (this.sessionStorageRef) {
1731
+ this.sessionStorageRef.setItem(e, t);
1732
+ return;
1733
+ }
1734
+ } catch (r) {
1735
+ r instanceof DOMException && r.name === "QuotaExceededError" && o("error", "sessionStorage quota exceeded - data will not persist", {
1736
+ error: r,
1737
+ data: { key: e, valueSize: t.length }
1738
+ });
1739
+ }
1740
+ }
1741
+ /**
1742
+ * Removes an item from sessionStorage
1743
+ */
1744
+ removeSessionItem(e) {
1745
+ try {
1746
+ this.sessionStorageRef && this.sessionStorageRef.removeItem(e);
1747
+ } catch {
1748
+ }
1749
+ this.fallbackSessionStorage.delete(e);
1750
+ }
1991
1751
  }
1992
- class Jt extends m {
1752
+ class mt extends f {
1993
1753
  eventManager;
1994
1754
  reportedByNav = /* @__PURE__ */ new Map();
1995
1755
  observers = [];
1996
1756
  lastLongTaskSentAt = 0;
1997
- vitalThresholds = Ve;
1757
+ vitalThresholds = _e;
1998
1758
  constructor(e) {
1999
1759
  super(), this.eventManager = e;
2000
1760
  }
@@ -2005,20 +1765,17 @@ class Jt extends m {
2005
1765
  this.observers.forEach((e, t) => {
2006
1766
  try {
2007
1767
  e.disconnect();
2008
- } catch (n) {
2009
- a.warn("PerformanceHandler", "Failed to disconnect performance observer", {
2010
- error: n instanceof Error ? n.message : "Unknown error",
2011
- observerIndex: t
2012
- });
1768
+ } catch (r) {
1769
+ o("warn", "Failed to disconnect performance observer", { error: r, data: { observerIndex: t } });
2013
1770
  }
2014
1771
  }), this.observers.length = 0, this.reportedByNav.clear();
2015
1772
  }
2016
1773
  observeWebVitalsFallback() {
2017
1774
  this.reportTTFB(), this.safeObserve(
2018
1775
  "largest-contentful-paint",
2019
- (n) => {
2020
- const s = n.getEntries(), i = s[s.length - 1];
2021
- i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(w)) });
1776
+ (r) => {
1777
+ const n = r.getEntries(), i = n[n.length - 1];
1778
+ i && this.sendVital({ type: "LCP", value: Number(i.startTime.toFixed(2)) });
2022
1779
  },
2023
1780
  { type: "largest-contentful-paint", buffered: !0 },
2024
1781
  !0
@@ -2026,52 +1783,50 @@ class Jt extends m {
2026
1783
  let e = 0, t = this.getNavigationId();
2027
1784
  this.safeObserve(
2028
1785
  "layout-shift",
2029
- (n) => {
2030
- const s = this.getNavigationId();
2031
- s !== t && (e = 0, t = s);
2032
- const i = n.getEntries();
2033
- for (const o of i) {
2034
- if (o.hadRecentInput === !0)
1786
+ (r) => {
1787
+ const n = this.getNavigationId();
1788
+ n !== t && (e = 0, t = n);
1789
+ const i = r.getEntries();
1790
+ for (const a of i) {
1791
+ if (a.hadRecentInput === !0)
2035
1792
  continue;
2036
- const c = typeof o.value == "number" ? o.value : 0;
1793
+ const c = typeof a.value == "number" ? a.value : 0;
2037
1794
  e += c;
2038
1795
  }
2039
- this.sendVital({ type: "CLS", value: Number(e.toFixed(w)) });
1796
+ this.sendVital({ type: "CLS", value: Number(e.toFixed(2)) });
2040
1797
  },
2041
1798
  { type: "layout-shift", buffered: !0 }
2042
1799
  ), this.safeObserve(
2043
1800
  "paint",
2044
- (n) => {
2045
- for (const s of n.getEntries())
2046
- s.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(s.startTime.toFixed(w)) });
1801
+ (r) => {
1802
+ for (const n of r.getEntries())
1803
+ n.name === "first-contentful-paint" && this.sendVital({ type: "FCP", value: Number(n.startTime.toFixed(2)) });
2047
1804
  },
2048
1805
  { type: "paint", buffered: !0 },
2049
1806
  !0
2050
1807
  ), this.safeObserve(
2051
1808
  "event",
2052
- (n) => {
2053
- let s = 0;
2054
- const i = n.getEntries();
2055
- for (const o of i) {
2056
- const c = (o.processingEnd ?? 0) - (o.startTime ?? 0);
2057
- s = Math.max(s, c);
1809
+ (r) => {
1810
+ let n = 0;
1811
+ const i = r.getEntries();
1812
+ for (const a of i) {
1813
+ const c = (a.processingEnd ?? 0) - (a.startTime ?? 0);
1814
+ n = Math.max(n, c);
2058
1815
  }
2059
- s > 0 && this.sendVital({ type: "INP", value: Number(s.toFixed(w)) });
1816
+ n > 0 && this.sendVital({ type: "INP", value: Number(n.toFixed(2)) });
2060
1817
  },
2061
1818
  { type: "event", buffered: !0 }
2062
1819
  );
2063
1820
  }
2064
1821
  async initWebVitals() {
2065
1822
  try {
2066
- const { onLCP: e, onCLS: t, onFCP: n, onTTFB: s, onINP: i } = await Promise.resolve().then(() => Er), o = (c) => (l) => {
2067
- const u = Number(l.value.toFixed(w));
1823
+ const { onLCP: e, onCLS: t, onFCP: r, onTTFB: n, onINP: i } = await Promise.resolve().then(() => Ht), a = (c) => (l) => {
1824
+ const u = Number(l.value.toFixed(2));
2068
1825
  this.sendVital({ type: c, value: u });
2069
1826
  };
2070
- e(o("LCP")), t(o("CLS")), n(o("FCP")), s(o("TTFB")), i(o("INP"));
1827
+ e(a("LCP")), t(a("CLS")), r(a("FCP")), n(a("TTFB")), i(a("INP"));
2071
1828
  } catch (e) {
2072
- a.warn("PerformanceHandler", "Failed to load web-vitals library, using fallback", {
2073
- error: e instanceof Error ? e.message : "Unknown error"
2074
- }), this.observeWebVitalsFallback();
1829
+ o("warn", "Failed to load web-vitals library, using fallback", { error: e }), this.observeWebVitalsFallback();
2075
1830
  }
2076
1831
  }
2077
1832
  reportTTFB() {
@@ -2080,11 +1835,9 @@ class Jt extends m {
2080
1835
  if (!e)
2081
1836
  return;
2082
1837
  const t = e.responseStart;
2083
- typeof t == "number" && Number.isFinite(t) && this.sendVital({ type: "TTFB", value: Number(t.toFixed(w)) });
1838
+ typeof t == "number" && Number.isFinite(t) && this.sendVital({ type: "TTFB", value: Number(t.toFixed(2)) });
2084
1839
  } catch (e) {
2085
- a.warn("PerformanceHandler", "Failed to report TTFB", {
2086
- error: e instanceof Error ? e.message : "Unknown error"
2087
- });
1840
+ o("warn", "Failed to report TTFB", { error: e });
2088
1841
  }
2089
1842
  }
2090
1843
  observeLongTasks() {
@@ -2092,9 +1845,9 @@ class Jt extends m {
2092
1845
  "longtask",
2093
1846
  (e) => {
2094
1847
  const t = e.getEntries();
2095
- for (const n of t) {
2096
- const s = Number(n.duration.toFixed(w)), i = Date.now();
2097
- i - this.lastLongTaskSentAt >= gt && (this.shouldSendVital("LONG_TASK", s) && this.trackWebVital("LONG_TASK", s), this.lastLongTaskSentAt = i);
1848
+ for (const r of t) {
1849
+ const n = Number(r.duration.toFixed(2)), i = Date.now();
1850
+ i - this.lastLongTaskSentAt >= ze && (this.shouldSendVital("LONG_TASK", n) && this.trackWebVital("LONG_TASK", n), this.lastLongTaskSentAt = i);
2098
1851
  }
2099
1852
  },
2100
1853
  { type: "longtask", buffered: !0 }
@@ -2105,16 +1858,16 @@ class Jt extends m {
2105
1858
  return;
2106
1859
  const t = this.getNavigationId();
2107
1860
  if (t) {
2108
- const n = this.reportedByNav.get(t);
2109
- if (n?.has(e.type))
1861
+ const r = this.reportedByNav.get(t);
1862
+ if (r?.has(e.type))
2110
1863
  return;
2111
- n ? n.add(e.type) : this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type]));
1864
+ r ? r.add(e.type) : this.reportedByNav.set(t, /* @__PURE__ */ new Set([e.type]));
2112
1865
  }
2113
1866
  this.trackWebVital(e.type, e.value);
2114
1867
  }
2115
1868
  trackWebVital(e, t) {
2116
1869
  if (!Number.isFinite(t)) {
2117
- a.warn("PerformanceHandler", "Invalid web vital value", { type: e, value: t });
1870
+ o("warn", "Invalid web vital value", { data: { type: e, value: t } });
2118
1871
  return;
2119
1872
  }
2120
1873
  this.eventManager.track({
@@ -2130,12 +1883,10 @@ class Jt extends m {
2130
1883
  const e = performance.getEntriesByType("navigation")[0];
2131
1884
  if (!e)
2132
1885
  return null;
2133
- const t = e.startTime || performance.now(), n = Math.random().toString(36).substr(2, 5);
2134
- return `${t.toFixed(2)}_${window.location.pathname}_${n}`;
1886
+ const t = e.startTime || performance.now(), r = Math.random().toString(36).substr(2, 5);
1887
+ return `${t.toFixed(2)}_${window.location.pathname}_${r}`;
2135
1888
  } catch (e) {
2136
- return a.warn("PerformanceHandler", "Failed to get navigation ID", {
2137
- error: e instanceof Error ? e.message : "Unknown error"
2138
- }), null;
1889
+ return o("warn", "Failed to get navigation ID", { error: e }), null;
2139
1890
  }
2140
1891
  }
2141
1892
  isObserverSupported(e) {
@@ -2143,45 +1894,41 @@ class Jt extends m {
2143
1894
  const t = PerformanceObserver.supportedEntryTypes;
2144
1895
  return !t || t.includes(e);
2145
1896
  }
2146
- safeObserve(e, t, n, s = !1) {
1897
+ safeObserve(e, t, r, n = !1) {
2147
1898
  try {
2148
1899
  if (!this.isObserverSupported(e))
2149
1900
  return !1;
2150
- const i = new PerformanceObserver((o, c) => {
1901
+ const i = new PerformanceObserver((a, c) => {
2151
1902
  try {
2152
- t(o, c);
1903
+ t(a, c);
2153
1904
  } catch (l) {
2154
- a.warn("PerformanceHandler", "Observer callback failed", {
2155
- type: e,
2156
- error: l instanceof Error ? l.message : "Unknown error"
1905
+ o("warn", "Observer callback failed", {
1906
+ error: l,
1907
+ data: { type: e }
2157
1908
  });
2158
1909
  }
2159
- if (s)
1910
+ if (n)
2160
1911
  try {
2161
1912
  c.disconnect();
2162
1913
  } catch {
2163
1914
  }
2164
1915
  });
2165
- return i.observe(n ?? { type: e, buffered: !0 }), s || this.observers.push(i), !0;
1916
+ return i.observe(r ?? { type: e, buffered: !0 }), n || this.observers.push(i), !0;
2166
1917
  } catch (i) {
2167
- return a.warn("PerformanceHandler", "Failed to create performance observer", {
2168
- type: e,
2169
- error: i instanceof Error ? i.message : "Unknown error"
1918
+ return o("warn", "Failed to create performance observer", {
1919
+ error: i,
1920
+ data: { type: e }
2170
1921
  }), !1;
2171
1922
  }
2172
1923
  }
2173
1924
  shouldSendVital(e, t) {
2174
1925
  if (typeof t != "number" || !Number.isFinite(t))
2175
- return a.warn("PerformanceHandler", "Invalid web vital value", { type: e, value: t }), !1;
2176
- const n = this.vitalThresholds[e];
2177
- return typeof n == "number" && t <= n ? (a.debug("PerformanceHandler", "Web vital below threshold, skipping", {
2178
- type: e,
2179
- value: t,
2180
- threshold: n
2181
- }), !1) : !0;
1926
+ return o("warn", "Invalid web vital value", { data: { type: e, value: t } }), !1;
1927
+ const r = this.vitalThresholds[e];
1928
+ return !(typeof r == "number" && t <= r);
2182
1929
  }
2183
1930
  }
2184
- class Zt extends m {
1931
+ class pt extends f {
2185
1932
  eventManager;
2186
1933
  recentErrors = /* @__PURE__ */ new Map();
2187
1934
  constructor(e) {
@@ -2201,32 +1948,28 @@ class Zt extends m {
2201
1948
  if (!this.shouldSample())
2202
1949
  return;
2203
1950
  const t = this.sanitize(e.message || "Unknown error");
2204
- this.shouldSuppressError(C.JS_ERROR, t) || (a.warn("ErrorHandler", "JS error captured", {
2205
- message: t,
2206
- filename: e.filename,
2207
- line: e.lineno
2208
- }), this.eventManager.track({
1951
+ this.shouldSuppressError(L.JS_ERROR, t) || this.eventManager.track({
2209
1952
  type: d.ERROR,
2210
1953
  error_data: {
2211
- type: C.JS_ERROR,
1954
+ type: L.JS_ERROR,
2212
1955
  message: t,
2213
1956
  ...e.filename && { filename: e.filename },
2214
1957
  ...e.lineno && { line: e.lineno },
2215
1958
  ...e.colno && { column: e.colno }
2216
1959
  }
2217
- }));
1960
+ });
2218
1961
  };
2219
1962
  handleRejection = (e) => {
2220
1963
  if (!this.shouldSample())
2221
1964
  return;
2222
- const t = this.extractRejectionMessage(e.reason), n = this.sanitize(t);
2223
- this.shouldSuppressError(C.PROMISE_REJECTION, n) || (a.warn("ErrorHandler", "Promise rejection captured", { message: n }), this.eventManager.track({
1965
+ const t = this.extractRejectionMessage(e.reason), r = this.sanitize(t);
1966
+ this.shouldSuppressError(L.PROMISE_REJECTION, r) || this.eventManager.track({
2224
1967
  type: d.ERROR,
2225
1968
  error_data: {
2226
- type: C.PROMISE_REJECTION,
2227
- message: n
1969
+ type: L.PROMISE_REJECTION,
1970
+ message: r
2228
1971
  }
2229
- }));
1972
+ });
2230
1973
  };
2231
1974
  extractRejectionMessage(e) {
2232
1975
  if (!e) return "Unknown rejection";
@@ -2242,37 +1985,34 @@ class Zt extends m {
2242
1985
  }
2243
1986
  }
2244
1987
  sanitize(e) {
2245
- let t = e.length > be ? e.slice(0, be) + "..." : e;
2246
- for (const n of Fe) {
2247
- const s = new RegExp(n.source, n.flags);
2248
- t = t.replace(s, "[REDACTED]");
1988
+ let t = e.length > le ? e.slice(0, le) + "..." : e;
1989
+ for (const r of Te) {
1990
+ const n = new RegExp(r.source, r.flags);
1991
+ t = t.replace(n, "[REDACTED]");
2249
1992
  }
2250
1993
  return t;
2251
1994
  }
2252
1995
  shouldSuppressError(e, t) {
2253
- const n = Date.now(), s = `${e}:${t}`, i = this.recentErrors.get(s);
2254
- return i && n - i < Me ? (this.recentErrors.set(s, n), !0) : (this.recentErrors.set(s, n), this.recentErrors.size > Re ? (a.warn("ErrorHandler", "Hard limit exceeded, clearing all tracked errors", {
2255
- size: this.recentErrors.size,
2256
- limit: Re
2257
- }), this.recentErrors.clear(), this.recentErrors.set(s, n), !1) : (this.recentErrors.size > G && this.pruneOldErrors(), !1));
1996
+ const r = Date.now(), n = `${e}:${t}`, i = this.recentErrors.get(n);
1997
+ return i && r - i < ue ? (this.recentErrors.set(n, r), !0) : (this.recentErrors.set(n, r), this.recentErrors.size > $e ? (this.recentErrors.clear(), this.recentErrors.set(n, r), !1) : (this.recentErrors.size > k && this.pruneOldErrors(), !1));
2258
1998
  }
2259
1999
  pruneOldErrors() {
2260
2000
  const e = Date.now();
2261
- for (const [s, i] of this.recentErrors.entries())
2262
- e - i > Me && this.recentErrors.delete(s);
2263
- if (this.recentErrors.size <= G)
2001
+ for (const [n, i] of this.recentErrors.entries())
2002
+ e - i > ue && this.recentErrors.delete(n);
2003
+ if (this.recentErrors.size <= k)
2264
2004
  return;
2265
- const t = Array.from(this.recentErrors.entries()).sort((s, i) => s[1] - i[1]), n = this.recentErrors.size - G;
2266
- for (let s = 0; s < n; s += 1) {
2267
- const i = t[s];
2005
+ const t = Array.from(this.recentErrors.entries()).sort((n, i) => n[1] - i[1]), r = this.recentErrors.size - k;
2006
+ for (let n = 0; n < r; n += 1) {
2007
+ const i = t[n];
2268
2008
  i && this.recentErrors.delete(i[0]);
2269
2009
  }
2270
2010
  }
2271
2011
  }
2272
- class er extends m {
2012
+ class _t extends f {
2273
2013
  isInitialized = !1;
2274
2014
  suppressNextScrollTimer = null;
2275
- emitter = new Vt();
2015
+ emitter = new at();
2276
2016
  managers = {};
2277
2017
  handlers = {};
2278
2018
  integrations = {};
@@ -2281,26 +2021,25 @@ class er extends m {
2281
2021
  }
2282
2022
  async init(e) {
2283
2023
  if (!this.isInitialized) {
2284
- if (!e.id?.trim())
2285
- throw new Error("Project ID is required");
2286
- this.managers.storage = new qt();
2024
+ this.managers.storage = new Et();
2287
2025
  try {
2288
- await this.setupState(e), await this.setupIntegrations(), this.managers.event = new jt(this.managers.storage, this.integrations.googleAnalytics, this.emitter), this.initializeHandlers(), await this.managers.event.recoverPersistedEvents().catch(() => {
2289
- a.warn("App", "Failed to recover persisted events");
2026
+ this.setupState(e), await this.setupIntegrations(), this.managers.event = new ct(this.managers.storage, this.integrations.googleAnalytics, this.emitter), await this.initializeHandlers(), await this.managers.event.recoverPersistedEvents().catch((t) => {
2027
+ o("warn", "Failed to recover persisted events", { error: t });
2290
2028
  }), this.isInitialized = !0;
2291
2029
  } catch (t) {
2292
- throw await this.destroy(!0), new Error(`TraceLog initialization failed: ${t}`);
2030
+ await this.destroy(!0);
2031
+ const r = t instanceof Error ? t.message : String(t);
2032
+ throw new Error(`[TraceLog] TraceLog initialization failed: ${r}`);
2293
2033
  }
2294
2034
  }
2295
2035
  }
2296
2036
  sendCustomEvent(e, t) {
2297
2037
  if (!this.managers.event)
2298
2038
  return;
2299
- const { valid: n, error: s, sanitizedMetadata: i } = kt(e, t);
2300
- if (!n) {
2301
- const o = this.get("config");
2302
- if (o?.mode === "qa" || o?.mode === "debug")
2303
- throw new Error(`Custom event "${e}" validation failed: ${s}`);
2039
+ const { valid: r, error: n, sanitizedMetadata: i } = it(e, t);
2040
+ if (!r) {
2041
+ if (this.get("mode") === R.QA)
2042
+ throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${n}`);
2304
2043
  return;
2305
2044
  }
2306
2045
  this.managers.event.track({
@@ -2321,120 +2060,123 @@ class er extends m {
2321
2060
  if (!this.isInitialized && !e)
2322
2061
  return;
2323
2062
  this.integrations.googleAnalytics?.cleanup();
2324
- const t = Object.values(this.handlers).filter(Boolean).map(async (n) => {
2063
+ const t = Object.values(this.handlers).filter(Boolean).map(async (r) => {
2325
2064
  try {
2326
- await n.stopTracking();
2327
- } catch {
2328
- a.warn("App", "Failed to stop tracking");
2065
+ await r.stopTracking();
2066
+ } catch (n) {
2067
+ o("warn", "Failed to stop tracking", { error: n });
2329
2068
  }
2330
2069
  });
2331
2070
  await Promise.allSettled(t), this.suppressNextScrollTimer && (clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = null), this.managers.event?.flushImmediatelySync(), this.managers.event?.stop(), this.emitter.removeAllListeners(), this.set("hasStartSession", !1), this.set("suppressNextScroll", !1), this.set("sessionId", null), this.isInitialized = !1, this.handlers = {};
2332
2071
  }
2333
- async setupState(e) {
2334
- const t = Ft(e.id, e.allowHttp);
2335
- this.set("apiUrl", t);
2336
- const s = await new zt().get(t, e);
2337
- this.set("config", s);
2338
- const i = $t.getId(this.managers.storage, s.id);
2339
- this.set("userId", i), this.set("device", St());
2340
- const o = ie(window.location.href, s.sensitiveQueryParams);
2341
- this.set("pageUrl", o);
2072
+ setupState(e) {
2073
+ this.set("config", e);
2074
+ const t = lt.getId(this.managers.storage);
2075
+ this.set("userId", t);
2076
+ const r = We(e);
2077
+ this.set("apiUrl", r);
2078
+ const n = He();
2079
+ this.set("device", n);
2080
+ const i = Y(window.location.href, e.sensitiveQueryParams);
2081
+ this.set("pageUrl", i);
2082
+ const a = Be() ? R.QA : void 0;
2083
+ a && this.set("mode", a);
2342
2084
  }
2343
2085
  async setupIntegrations() {
2344
- const e = this.get("config"), t = e.integrations?.googleAnalytics?.measurementId;
2345
- if (!e.ipExcluded && t?.trim())
2086
+ if (this.get("config").integrations?.googleAnalytics?.measurementId?.trim())
2346
2087
  try {
2347
- this.integrations.googleAnalytics = new Xt(), await this.integrations.googleAnalytics.initialize();
2088
+ this.integrations.googleAnalytics = new St(), await this.integrations.googleAnalytics.initialize();
2348
2089
  } catch {
2349
2090
  this.integrations.googleAnalytics = void 0;
2350
2091
  }
2351
2092
  }
2352
- initializeHandlers() {
2353
- this.handlers.session = new Bt(
2093
+ async initializeHandlers() {
2094
+ this.handlers.session = new dt(
2354
2095
  this.managers.storage,
2355
2096
  this.managers.event
2356
- ), this.handlers.session.startTracking().catch((t) => {
2357
- a.error("App", "Session handler failed to start", {
2358
- message: t instanceof Error ? t.message : "Unknown error"
2359
- });
2360
- });
2097
+ ), await this.handlers.session.startTracking();
2361
2098
  const e = () => {
2362
2099
  this.set("suppressNextScroll", !0), this.suppressNextScrollTimer && clearTimeout(this.suppressNextScrollTimer), this.suppressNextScrollTimer = window.setTimeout(() => {
2363
2100
  this.set("suppressNextScroll", !1);
2364
- }, xe * ot);
2101
+ }, 250 * 2);
2365
2102
  };
2366
- this.handlers.pageView = new Wt(this.managers.event, e), this.handlers.pageView.startTracking(), this.handlers.click = new Yt(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new Kt(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new Jt(this.managers.event), this.handlers.performance.startTracking().catch(() => {
2367
- a.warn("App", "Failed to start performance tracking");
2368
- }), this.handlers.error = new Zt(this.managers.event), this.handlers.error.startTracking();
2103
+ this.handlers.pageView = new ht(this.managers.event, e), this.handlers.pageView.startTracking(), this.handlers.click = new ft(this.managers.event), this.handlers.click.startTracking(), this.handlers.scroll = new gt(this.managers.event), this.handlers.scroll.startTracking(), this.handlers.performance = new mt(this.managers.event), this.handlers.performance.startTracking().catch((t) => {
2104
+ o("warn", "Failed to start performance tracking", { error: t });
2105
+ }), this.handlers.error = new pt(this.managers.event), this.handlers.error.startTracking();
2369
2106
  }
2370
2107
  }
2371
- let g = null, D = !1, J = !1;
2372
- const tr = async (r) => {
2108
+ const I = [];
2109
+ let h = null, w = !1, U = !1;
2110
+ const Tt = async (s) => {
2373
2111
  if (typeof window > "u" || typeof document > "u")
2374
- throw new Error("This library can only be used in a browser environment");
2375
- if (!window.__traceLogDisabled) {
2376
- if (g) {
2377
- a.debug("API", "Library already initialized, skipping duplicate initialization");
2378
- return;
2379
- }
2380
- if (D)
2381
- throw a.warn("API", "Initialization already in progress"), new Error("Initialization already in progress");
2382
- D = !0;
2112
+ throw new Error("[TraceLog] This library can only be used in a browser environment");
2113
+ if (!window.__traceLogDisabled && !h && !w) {
2114
+ w = !0;
2383
2115
  try {
2384
- a.info("API", "Initializing TraceLog", { projectId: r.id });
2385
- const e = Rt(r), t = new er();
2116
+ const e = et(s), t = new _t();
2386
2117
  try {
2387
- await t.init(e), g = t, a.info("API", "TraceLog initialized successfully", { projectId: e.id });
2388
- } catch (n) {
2118
+ I.forEach(({ event: i, callback: a }) => {
2119
+ t.on(i, a);
2120
+ }), I.length = 0;
2121
+ const r = t.init(e), n = new Promise((i, a) => {
2122
+ setTimeout(() => {
2123
+ a(new Error("[TraceLog] Initialization timeout after 10000ms"));
2124
+ }, 1e4);
2125
+ });
2126
+ await Promise.race([r, n]), h = t;
2127
+ } catch (r) {
2389
2128
  try {
2390
2129
  await t.destroy(!0);
2391
- } catch (s) {
2392
- a.warn("API", "Failed to cleanup partially initialized app", { cleanupError: s });
2130
+ } catch (n) {
2131
+ o("error", "Failed to cleanup partially initialized app", { error: n });
2393
2132
  }
2394
- throw n;
2133
+ throw r;
2395
2134
  }
2396
2135
  } catch (e) {
2397
- throw g = null, a.error("API", "Initialization failed", { error: e }), e;
2136
+ throw h = null, e;
2398
2137
  } finally {
2399
- D = !1;
2138
+ w = !1;
2400
2139
  }
2401
2140
  }
2402
- }, rr = (r, e) => {
2403
- if (!g)
2404
- throw new Error("TraceLog not initialized. Please call init() first.");
2405
- try {
2406
- g.sendCustomEvent(r, e);
2407
- } catch (t) {
2408
- throw a.error("API", "Failed to send custom event", { eventName: r, error: t }), t;
2409
- }
2410
- }, nr = (r, e) => {
2411
- if (!g)
2412
- throw new Error("TraceLog not initialized. Please call init() first.");
2413
- g.on(r, e);
2414
- }, sr = (r, e) => {
2415
- if (!g)
2416
- throw new Error("TraceLog not initialized. Please call init() first.");
2417
- g.off(r, e);
2418
- }, ir = () => g !== null, ar = async () => {
2419
- if (!g)
2420
- throw new Error("App not initialized");
2421
- if (J)
2422
- throw new Error("Destroy operation already in progress");
2423
- J = !0;
2141
+ }, vt = (s, e) => {
2142
+ if (!h)
2143
+ throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");
2144
+ if (U)
2145
+ throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");
2146
+ h.sendCustomEvent(s, e);
2147
+ }, It = (s, e) => {
2148
+ if (!h || w) {
2149
+ I.push({ event: s, callback: e });
2150
+ return;
2151
+ }
2152
+ h.on(s, e);
2153
+ }, yt = (s, e) => {
2154
+ if (!h) {
2155
+ const t = I.findIndex((r) => r.event === s && r.callback === e);
2156
+ t !== -1 && I.splice(t, 1);
2157
+ return;
2158
+ }
2159
+ h.off(s, e);
2160
+ }, At = () => h !== null, wt = async () => {
2161
+ if (!h)
2162
+ throw new Error("[TraceLog] App not initialized");
2163
+ if (U)
2164
+ throw new Error("[TraceLog] Destroy operation already in progress");
2165
+ U = !0;
2424
2166
  try {
2425
- a.info("API", "Destroying TraceLog instance"), await g.destroy(), g = null, D = !1, a.info("API", "TraceLog destroyed successfully");
2426
- } catch (r) {
2427
- throw g = null, D = !1, a.error("API", "Error during destroy, forced cleanup", { error: r }), r;
2167
+ await h.destroy(), h = null, w = !1, I.length = 0;
2168
+ } catch (s) {
2169
+ h = null, w = !1, I.length = 0, o("warn", "Error during destroy, forced cleanup completed", { error: s });
2428
2170
  } finally {
2429
- J = !1;
2171
+ U = !1;
2430
2172
  }
2431
- }, vr = {
2432
- WEB_VITALS_THRESHOLDS: Ve
2173
+ }, Vt = {
2174
+ WEB_VITALS_THRESHOLDS: _e
2433
2175
  // Business thresholds for performance analysis
2434
- }, yr = {
2435
- PII_PATTERNS: Fe
2176
+ }, Ft = {
2177
+ PII_PATTERNS: Te
2436
2178
  // Patterns for sensitive data protection
2437
- }, Ir = {
2179
+ }, Gt = {
2438
2180
  LOW_ACTIVITY_EVENT_COUNT: 50,
2439
2181
  HIGH_ACTIVITY_EVENT_COUNT: 1e3,
2440
2182
  MIN_EVENTS_FOR_DYNAMIC_CALCULATION: 100,
@@ -2444,7 +2186,7 @@ const tr = async (r) => {
2444
2186
  MIN_ENGAGED_SESSION_DURATION_MS: 30 * 1e3,
2445
2187
  MIN_SCROLL_DEPTH_ENGAGEMENT: 25
2446
2188
  // 25% scroll depth for engagement
2447
- }, Tr = {
2189
+ }, zt = {
2448
2190
  INACTIVITY_TIMEOUT_MS: 30 * 60 * 1e3,
2449
2191
  // 30min for analytics (vs 15min client)
2450
2192
  SHORT_SESSION_THRESHOLD_MS: 30 * 1e3,
@@ -2452,20 +2194,20 @@ const tr = async (r) => {
2452
2194
  LONG_SESSION_THRESHOLD_MS: 30 * 60 * 1e3,
2453
2195
  MAX_REALISTIC_SESSION_DURATION_MS: 8 * 60 * 60 * 1e3
2454
2196
  // Filter outliers
2455
- }, _r = {
2197
+ }, $t = {
2456
2198
  MOBILE_MAX_WIDTH: 768,
2457
2199
  TABLET_MAX_WIDTH: 1024,
2458
2200
  MOBILE_PERFORMANCE_FACTOR: 1.5,
2459
2201
  // Mobile typically 1.5x slower
2460
2202
  TABLET_PERFORMANCE_FACTOR: 1.2
2461
- }, wr = {
2203
+ }, Qt = {
2462
2204
  MIN_TEXT_LENGTH_FOR_ANALYSIS: 10,
2463
2205
  MIN_CLICKS_FOR_HOT_ELEMENT: 10,
2464
2206
  // Popular element threshold
2465
2207
  MIN_SCROLL_COMPLETION_PERCENT: 80,
2466
2208
  // Page consumption threshold
2467
2209
  MIN_TIME_ON_PAGE_FOR_READ_MS: 15 * 1e3
2468
- }, Ar = {
2210
+ }, Bt = {
2469
2211
  SIGNIFICANT_CHANGE_PERCENT: 20,
2470
2212
  MAJOR_CHANGE_PERCENT: 50,
2471
2213
  MIN_EVENTS_FOR_INSIGHT: 100,
@@ -2475,19 +2217,19 @@ const tr = async (r) => {
2475
2217
  LOW_ERROR_RATE_PERCENT: 1,
2476
2218
  HIGH_ERROR_RATE_PERCENT: 5,
2477
2219
  CRITICAL_ERROR_RATE_PERCENT: 10
2478
- }, br = {
2220
+ }, jt = {
2479
2221
  SHORT_TERM_TREND_HOURS: 24,
2480
2222
  MEDIUM_TERM_TREND_DAYS: 7,
2481
2223
  LONG_TERM_TREND_DAYS: 30,
2482
2224
  MIN_DATA_POINTS_FOR_TREND: 5,
2483
2225
  WEEKLY_PATTERN_MIN_WEEKS: 4,
2484
2226
  DAILY_PATTERN_MIN_DAYS: 14
2485
- }, Mr = {
2227
+ }, Xt = {
2486
2228
  MIN_SEGMENT_SIZE: 10,
2487
2229
  MIN_COHORT_SIZE: 5,
2488
2230
  COHORT_ANALYSIS_DAYS: [1, 3, 7, 14, 30],
2489
2231
  MIN_FUNNEL_EVENTS: 20
2490
- }, Rr = {
2232
+ }, Wt = {
2491
2233
  DEFAULT_EVENTS_LIMIT: 5,
2492
2234
  DEFAULT_SESSIONS_LIMIT: 5,
2493
2235
  DEFAULT_PAGES_LIMIT: 5,
@@ -2495,243 +2237,248 @@ const tr = async (r) => {
2495
2237
  MAX_TIME_RANGE_DAYS: 365,
2496
2238
  ANALYTICS_BATCH_SIZE: 1e3
2497
2239
  // For historical analysis
2498
- }, Lr = {
2240
+ }, Yt = {
2499
2241
  ANOMALY_THRESHOLD_SIGMA: 2.5,
2500
2242
  STRONG_ANOMALY_THRESHOLD_SIGMA: 3,
2501
2243
  TRAFFIC_DROP_ALERT_PERCENT: -30,
2502
2244
  TRAFFIC_SPIKE_ALERT_PERCENT: 200,
2503
2245
  MIN_BASELINE_DAYS: 7,
2504
2246
  MIN_EVENTS_FOR_ANOMALY_DETECTION: 50
2505
- }, Nr = {
2247
+ }, Kt = {
2506
2248
  PAGE_URL_EXCLUDED: "excluded",
2507
2249
  PAGE_URL_UNKNOWN: "unknown"
2508
- }, Cr = {
2509
- init: tr,
2510
- event: rr,
2511
- on: nr,
2512
- off: sr,
2513
- isInitialized: ir,
2514
- destroy: ar
2250
+ }, qt = {
2251
+ init: Tt,
2252
+ event: vt,
2253
+ on: It,
2254
+ off: yt,
2255
+ isInitialized: At,
2256
+ destroy: wt
2515
2257
  };
2516
- var ae, Ge = -1, R = function(r) {
2258
+ var q, ve = -1, M = function(s) {
2517
2259
  addEventListener("pageshow", function(e) {
2518
- e.persisted && (Ge = e.timeStamp, r(e));
2260
+ e.persisted && (ve = e.timeStamp, s(e));
2519
2261
  }, !0);
2520
- }, he = function() {
2521
- var r = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
2522
- if (r && r.responseStart > 0 && r.responseStart < performance.now()) return r;
2523
- }, B = function() {
2524
- var r = he();
2525
- return r && r.activationStart || 0;
2526
- }, E = function(r, e) {
2527
- var t = he(), n = "navigate";
2528
- return Ge >= 0 ? n = "back-forward-cache" : t && (document.prerendering || B() > 0 ? n = "prerender" : document.wasDiscarded ? n = "restore" : t.type && (n = t.type.replace(/_/g, "-"))), { name: r, value: e === void 0 ? -1 : e, rating: "good", delta: 0, entries: [], id: "v4-".concat(Date.now(), "-").concat(Math.floor(8999999999999 * Math.random()) + 1e12), navigationType: n };
2529
- }, V = function(r, e, t) {
2262
+ }, se = function() {
2263
+ var s = self.performance && performance.getEntriesByType && performance.getEntriesByType("navigation")[0];
2264
+ if (s && s.responseStart > 0 && s.responseStart < performance.now()) return s;
2265
+ }, V = function() {
2266
+ var s = se();
2267
+ return s && s.activationStart || 0;
2268
+ }, S = function(s, e) {
2269
+ var t = se(), r = "navigate";
2270
+ return ve >= 0 ? r = "back-forward-cache" : t && (document.prerendering || V() > 0 ? r = "prerender" : document.wasDiscarded ? r = "restore" : t.type && (r = t.type.replace(/_/g, "-"))), { name: s, value: e === void 0 ? -1 : e, rating: "good", delta: 0, entries: [], id: "v4-".concat(Date.now(), "-").concat(Math.floor(8999999999999 * Math.random()) + 1e12), navigationType: r };
2271
+ }, b = function(s, e, t) {
2530
2272
  try {
2531
- if (PerformanceObserver.supportedEntryTypes.includes(r)) {
2532
- var n = new PerformanceObserver(function(s) {
2273
+ if (PerformanceObserver.supportedEntryTypes.includes(s)) {
2274
+ var r = new PerformanceObserver(function(n) {
2533
2275
  Promise.resolve().then(function() {
2534
- e(s.getEntries());
2276
+ e(n.getEntries());
2535
2277
  });
2536
2278
  });
2537
- return n.observe(Object.assign({ type: r, buffered: !0 }, t || {})), n;
2279
+ return r.observe(Object.assign({ type: s, buffered: !0 }, t || {})), r;
2538
2280
  }
2539
2281
  } catch {
2540
2282
  }
2541
- }, v = function(r, e, t, n) {
2542
- var s, i;
2543
- return function(o) {
2544
- e.value >= 0 && (o || n) && ((i = e.value - (s || 0)) || s === void 0) && (s = e.value, e.delta = i, e.rating = function(c, l) {
2283
+ }, E = function(s, e, t, r) {
2284
+ var n, i;
2285
+ return function(a) {
2286
+ e.value >= 0 && (a || r) && ((i = e.value - (n || 0)) || n === void 0) && (n = e.value, e.delta = i, e.rating = function(c, l) {
2545
2287
  return c > l[1] ? "poor" : c > l[0] ? "needs-improvement" : "good";
2546
- }(e.value, t), r(e));
2288
+ }(e.value, t), s(e));
2547
2289
  };
2548
- }, ge = function(r) {
2290
+ }, ne = function(s) {
2549
2291
  requestAnimationFrame(function() {
2550
2292
  return requestAnimationFrame(function() {
2551
- return r();
2293
+ return s();
2552
2294
  });
2553
2295
  });
2554
- }, W = function(r) {
2296
+ }, F = function(s) {
2555
2297
  document.addEventListener("visibilitychange", function() {
2556
- document.visibilityState === "hidden" && r();
2298
+ document.visibilityState === "hidden" && s();
2557
2299
  });
2558
- }, fe = function(r) {
2300
+ }, ie = function(s) {
2559
2301
  var e = !1;
2560
2302
  return function() {
2561
- e || (r(), e = !0);
2303
+ e || (s(), e = !0);
2562
2304
  };
2563
- }, b = -1, De = function() {
2305
+ }, A = -1, Ee = function() {
2564
2306
  return document.visibilityState !== "hidden" || document.prerendering ? 1 / 0 : 0;
2565
- }, Q = function(r) {
2566
- document.visibilityState === "hidden" && b > -1 && (b = r.type === "visibilitychange" ? r.timeStamp : 0, or());
2567
- }, ke = function() {
2568
- addEventListener("visibilitychange", Q, !0), addEventListener("prerenderingchange", Q, !0);
2569
- }, or = function() {
2570
- removeEventListener("visibilitychange", Q, !0), removeEventListener("prerenderingchange", Q, !0);
2571
- }, je = function() {
2572
- return b < 0 && (b = De(), ke(), R(function() {
2307
+ }, x = function(s) {
2308
+ document.visibilityState === "hidden" && A > -1 && (A = s.type === "visibilitychange" ? s.timeStamp : 0, Mt());
2309
+ }, me = function() {
2310
+ addEventListener("visibilitychange", x, !0), addEventListener("prerenderingchange", x, !0);
2311
+ }, Mt = function() {
2312
+ removeEventListener("visibilitychange", x, !0), removeEventListener("prerenderingchange", x, !0);
2313
+ }, Ie = function() {
2314
+ return A < 0 && (A = Ee(), me(), M(function() {
2573
2315
  setTimeout(function() {
2574
- b = De(), ke();
2316
+ A = Ee(), me();
2575
2317
  }, 0);
2576
2318
  })), { get firstHiddenTime() {
2577
- return b;
2319
+ return A;
2578
2320
  } };
2579
- }, Y = function(r) {
2321
+ }, G = function(s) {
2580
2322
  document.prerendering ? addEventListener("prerenderingchange", function() {
2581
- return r();
2582
- }, !0) : r();
2583
- }, oe = [1800, 3e3], $e = function(r, e) {
2584
- e = e || {}, Y(function() {
2585
- var t, n = je(), s = E("FCP"), i = V("paint", function(o) {
2586
- o.forEach(function(c) {
2587
- c.name === "first-contentful-paint" && (i.disconnect(), c.startTime < n.firstHiddenTime && (s.value = Math.max(c.startTime - B(), 0), s.entries.push(c), t(!0)));
2323
+ return s();
2324
+ }, !0) : s();
2325
+ }, Z = [1800, 3e3], ye = function(s, e) {
2326
+ e = e || {}, G(function() {
2327
+ var t, r = Ie(), n = S("FCP"), i = b("paint", function(a) {
2328
+ a.forEach(function(c) {
2329
+ c.name === "first-contentful-paint" && (i.disconnect(), c.startTime < r.firstHiddenTime && (n.value = Math.max(c.startTime - V(), 0), n.entries.push(c), t(!0)));
2588
2330
  });
2589
2331
  });
2590
- i && (t = v(r, s, oe, e.reportAllChanges), R(function(o) {
2591
- s = E("FCP"), t = v(r, s, oe, e.reportAllChanges), ge(function() {
2592
- s.value = performance.now() - o.timeStamp, t(!0);
2332
+ i && (t = E(s, n, Z, e.reportAllChanges), M(function(a) {
2333
+ n = S("FCP"), t = E(s, n, Z, e.reportAllChanges), ne(function() {
2334
+ n.value = performance.now() - a.timeStamp, t(!0);
2593
2335
  });
2594
2336
  }));
2595
2337
  });
2596
- }, le = [0.1, 0.25], lr = function(r, e) {
2597
- e = e || {}, $e(fe(function() {
2598
- var t, n = E("CLS", 0), s = 0, i = [], o = function(l) {
2338
+ }, J = [0.1, 0.25], Nt = function(s, e) {
2339
+ e = e || {}, ye(ie(function() {
2340
+ var t, r = S("CLS", 0), n = 0, i = [], a = function(l) {
2599
2341
  l.forEach(function(u) {
2600
2342
  if (!u.hadRecentInput) {
2601
- var h = i[0], L = i[i.length - 1];
2602
- s && u.startTime - L.startTime < 1e3 && u.startTime - h.startTime < 5e3 ? (s += u.value, i.push(u)) : (s = u.value, i = [u]);
2343
+ var p = i[0], N = i[i.length - 1];
2344
+ n && u.startTime - N.startTime < 1e3 && u.startTime - p.startTime < 5e3 ? (n += u.value, i.push(u)) : (n = u.value, i = [u]);
2603
2345
  }
2604
- }), s > n.value && (n.value = s, n.entries = i, t());
2605
- }, c = V("layout-shift", o);
2606
- c && (t = v(r, n, le, e.reportAllChanges), W(function() {
2607
- o(c.takeRecords()), t(!0);
2608
- }), R(function() {
2609
- s = 0, n = E("CLS", 0), t = v(r, n, le, e.reportAllChanges), ge(function() {
2346
+ }), n > r.value && (r.value = n, r.entries = i, t());
2347
+ }, c = b("layout-shift", a);
2348
+ c && (t = E(s, r, J, e.reportAllChanges), F(function() {
2349
+ a(c.takeRecords()), t(!0);
2350
+ }), M(function() {
2351
+ n = 0, r = S("CLS", 0), t = E(s, r, J, e.reportAllChanges), ne(function() {
2610
2352
  return t();
2611
2353
  });
2612
2354
  }), setTimeout(t, 0));
2613
2355
  }));
2614
- }, Qe = 0, Z = 1 / 0, z = 0, cr = function(r) {
2615
- r.forEach(function(e) {
2616
- e.interactionId && (Z = Math.min(Z, e.interactionId), z = Math.max(z, e.interactionId), Qe = z ? (z - Z) / 7 + 1 : 0);
2356
+ }, Ae = 0, Q = 1 / 0, P = 0, Lt = function(s) {
2357
+ s.forEach(function(e) {
2358
+ e.interactionId && (Q = Math.min(Q, e.interactionId), P = Math.max(P, e.interactionId), Ae = P ? (P - Q) / 7 + 1 : 0);
2617
2359
  });
2618
- }, Be = function() {
2619
- return ae ? Qe : performance.interactionCount || 0;
2620
- }, ur = function() {
2621
- "interactionCount" in performance || ae || (ae = V("event", cr, { type: "event", buffered: !0, durationThreshold: 0 }));
2622
- }, S = [], $ = /* @__PURE__ */ new Map(), We = 0, dr = function() {
2623
- var r = Math.min(S.length - 1, Math.floor((Be() - We) / 50));
2624
- return S[r];
2625
- }, hr = [], gr = function(r) {
2626
- if (hr.forEach(function(s) {
2627
- return s(r);
2628
- }), r.interactionId || r.entryType === "first-input") {
2629
- var e = S[S.length - 1], t = $.get(r.interactionId);
2630
- if (t || S.length < 10 || r.duration > e.latency) {
2631
- if (t) r.duration > t.latency ? (t.entries = [r], t.latency = r.duration) : r.duration === t.latency && r.startTime === t.entries[0].startTime && t.entries.push(r);
2360
+ }, we = function() {
2361
+ return q ? Ae : performance.interactionCount || 0;
2362
+ }, Rt = function() {
2363
+ "interactionCount" in performance || q || (q = b("event", Lt, { type: "event", buffered: !0, durationThreshold: 0 }));
2364
+ }, g = [], H = /* @__PURE__ */ new Map(), Me = 0, Ct = function() {
2365
+ var s = Math.min(g.length - 1, Math.floor((we() - Me) / 50));
2366
+ return g[s];
2367
+ }, bt = [], Ot = function(s) {
2368
+ if (bt.forEach(function(n) {
2369
+ return n(s);
2370
+ }), s.interactionId || s.entryType === "first-input") {
2371
+ var e = g[g.length - 1], t = H.get(s.interactionId);
2372
+ if (t || g.length < 10 || s.duration > e.latency) {
2373
+ if (t) s.duration > t.latency ? (t.entries = [s], t.latency = s.duration) : s.duration === t.latency && s.startTime === t.entries[0].startTime && t.entries.push(s);
2632
2374
  else {
2633
- var n = { id: r.interactionId, latency: r.duration, entries: [r] };
2634
- $.set(n.id, n), S.push(n);
2375
+ var r = { id: s.interactionId, latency: s.duration, entries: [s] };
2376
+ H.set(r.id, r), g.push(r);
2635
2377
  }
2636
- S.sort(function(s, i) {
2637
- return i.latency - s.latency;
2638
- }), S.length > 10 && S.splice(10).forEach(function(s) {
2639
- return $.delete(s.id);
2378
+ g.sort(function(n, i) {
2379
+ return i.latency - n.latency;
2380
+ }), g.length > 10 && g.splice(10).forEach(function(n) {
2381
+ return H.delete(n.id);
2640
2382
  });
2641
2383
  }
2642
2384
  }
2643
- }, Ye = function(r) {
2385
+ }, Ne = function(s) {
2644
2386
  var e = self.requestIdleCallback || self.setTimeout, t = -1;
2645
- return r = fe(r), document.visibilityState === "hidden" ? r() : (t = e(r), W(r)), t;
2646
- }, ce = [200, 500], fr = function(r, e) {
2647
- "PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, Y(function() {
2387
+ return s = ie(s), document.visibilityState === "hidden" ? s() : (t = e(s), F(s)), t;
2388
+ }, ee = [200, 500], Pt = function(s, e) {
2389
+ "PerformanceEventTiming" in self && "interactionId" in PerformanceEventTiming.prototype && (e = e || {}, G(function() {
2648
2390
  var t;
2649
- ur();
2650
- var n, s = E("INP"), i = function(c) {
2651
- Ye(function() {
2652
- c.forEach(gr);
2653
- var l = dr();
2654
- l && l.latency !== s.value && (s.value = l.latency, s.entries = l.entries, n());
2391
+ Rt();
2392
+ var r, n = S("INP"), i = function(c) {
2393
+ Ne(function() {
2394
+ c.forEach(Ot);
2395
+ var l = Ct();
2396
+ l && l.latency !== n.value && (n.value = l.latency, n.entries = l.entries, r());
2655
2397
  });
2656
- }, o = V("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
2657
- n = v(r, s, ce, e.reportAllChanges), o && (o.observe({ type: "first-input", buffered: !0 }), W(function() {
2658
- i(o.takeRecords()), n(!0);
2659
- }), R(function() {
2660
- We = Be(), S.length = 0, $.clear(), s = E("INP"), n = v(r, s, ce, e.reportAllChanges);
2398
+ }, a = b("event", i, { durationThreshold: (t = e.durationThreshold) !== null && t !== void 0 ? t : 40 });
2399
+ r = E(s, n, ee, e.reportAllChanges), a && (a.observe({ type: "first-input", buffered: !0 }), F(function() {
2400
+ i(a.takeRecords()), r(!0);
2401
+ }), M(function() {
2402
+ Me = we(), g.length = 0, H.clear(), n = S("INP"), r = E(s, n, ee, e.reportAllChanges);
2661
2403
  }));
2662
2404
  }));
2663
- }, ue = [2500, 4e3], ee = {}, mr = function(r, e) {
2664
- e = e || {}, Y(function() {
2665
- var t, n = je(), s = E("LCP"), i = function(l) {
2405
+ }, te = [2500, 4e3], B = {}, Dt = function(s, e) {
2406
+ e = e || {}, G(function() {
2407
+ var t, r = Ie(), n = S("LCP"), i = function(l) {
2666
2408
  e.reportAllChanges || (l = l.slice(-1)), l.forEach(function(u) {
2667
- u.startTime < n.firstHiddenTime && (s.value = Math.max(u.startTime - B(), 0), s.entries = [u], t());
2409
+ u.startTime < r.firstHiddenTime && (n.value = Math.max(u.startTime - V(), 0), n.entries = [u], t());
2668
2410
  });
2669
- }, o = V("largest-contentful-paint", i);
2670
- if (o) {
2671
- t = v(r, s, ue, e.reportAllChanges);
2672
- var c = fe(function() {
2673
- ee[s.id] || (i(o.takeRecords()), o.disconnect(), ee[s.id] = !0, t(!0));
2411
+ }, a = b("largest-contentful-paint", i);
2412
+ if (a) {
2413
+ t = E(s, n, te, e.reportAllChanges);
2414
+ var c = ie(function() {
2415
+ B[n.id] || (i(a.takeRecords()), a.disconnect(), B[n.id] = !0, t(!0));
2674
2416
  });
2675
2417
  ["keydown", "click"].forEach(function(l) {
2676
2418
  addEventListener(l, function() {
2677
- return Ye(c);
2419
+ return Ne(c);
2678
2420
  }, { once: !0, capture: !0 });
2679
- }), W(c), R(function(l) {
2680
- s = E("LCP"), t = v(r, s, ue, e.reportAllChanges), ge(function() {
2681
- s.value = performance.now() - l.timeStamp, ee[s.id] = !0, t(!0);
2421
+ }), F(c), M(function(l) {
2422
+ n = S("LCP"), t = E(s, n, te, e.reportAllChanges), ne(function() {
2423
+ n.value = performance.now() - l.timeStamp, B[n.id] = !0, t(!0);
2682
2424
  });
2683
2425
  });
2684
2426
  }
2685
2427
  });
2686
- }, de = [800, 1800], pr = function r(e) {
2687
- document.prerendering ? Y(function() {
2688
- return r(e);
2428
+ }, re = [800, 1800], kt = function s(e) {
2429
+ document.prerendering ? G(function() {
2430
+ return s(e);
2689
2431
  }) : document.readyState !== "complete" ? addEventListener("load", function() {
2690
- return r(e);
2432
+ return s(e);
2691
2433
  }, !0) : setTimeout(e, 0);
2692
- }, Sr = function(r, e) {
2434
+ }, Ut = function(s, e) {
2693
2435
  e = e || {};
2694
- var t = E("TTFB"), n = v(r, t, de, e.reportAllChanges);
2695
- pr(function() {
2696
- var s = he();
2697
- s && (t.value = Math.max(s.responseStart - B(), 0), t.entries = [s], n(!0), R(function() {
2698
- t = E("TTFB", 0), (n = v(r, t, de, e.reportAllChanges))(!0);
2436
+ var t = S("TTFB"), r = E(s, t, re, e.reportAllChanges);
2437
+ kt(function() {
2438
+ var n = se();
2439
+ n && (t.value = Math.max(n.responseStart - V(), 0), t.entries = [n], r(!0), M(function() {
2440
+ t = S("TTFB", 0), (r = E(s, t, re, e.reportAllChanges))(!0);
2699
2441
  }));
2700
2442
  });
2701
2443
  };
2702
- const Er = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2444
+ const Ht = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2703
2445
  __proto__: null,
2704
- CLSThresholds: le,
2705
- FCPThresholds: oe,
2706
- INPThresholds: ce,
2707
- LCPThresholds: ue,
2708
- TTFBThresholds: de,
2709
- onCLS: lr,
2710
- onFCP: $e,
2711
- onINP: fr,
2712
- onLCP: mr,
2713
- onTTFB: Sr
2446
+ CLSThresholds: J,
2447
+ FCPThresholds: Z,
2448
+ INPThresholds: ee,
2449
+ LCPThresholds: te,
2450
+ TTFBThresholds: re,
2451
+ onCLS: Nt,
2452
+ onFCP: ye,
2453
+ onINP: Pt,
2454
+ onLCP: Dt,
2455
+ onTTFB: Ut
2714
2456
  }, Symbol.toStringTag, { value: "Module" }));
2715
2457
  export {
2716
- Rr as ANALYTICS_QUERY_LIMITS,
2717
- Lr as ANOMALY_DETECTION,
2718
- wr as CONTENT_ANALYTICS,
2719
- yr as DATA_PROTECTION,
2720
- _r as DEVICE_ANALYTICS,
2721
- I as DeviceType,
2722
- Ir as ENGAGEMENT_THRESHOLDS,
2723
- C as ErrorType,
2458
+ Wt as ANALYTICS_QUERY_LIMITS,
2459
+ Yt as ANOMALY_DETECTION,
2460
+ y as AppConfigValidationError,
2461
+ Qt as CONTENT_ANALYTICS,
2462
+ Ft as DATA_PROTECTION,
2463
+ $t as DEVICE_ANALYTICS,
2464
+ _ as DeviceType,
2465
+ Gt as ENGAGEMENT_THRESHOLDS,
2466
+ X as EmitterEvent,
2467
+ L as ErrorType,
2724
2468
  d as EventType,
2725
- Ar as INSIGHT_THRESHOLDS,
2726
- O as Mode,
2727
- vr as PERFORMANCE_CONFIG,
2728
- Mr as SEGMENTATION_ANALYTICS,
2729
- Tr as SESSION_ANALYTICS,
2730
- Nr as SPECIAL_PAGE_URLS,
2731
- j as ScrollDirection,
2732
- br as TEMPORAL_ANALYSIS,
2733
- It as TagConditionOperator,
2734
- yt as TagConditionType,
2735
- vt as TagLogicalOperator,
2736
- Cr as tracelog
2469
+ Bt as INSIGHT_THRESHOLDS,
2470
+ xt as InitializationTimeoutError,
2471
+ v as IntegrationValidationError,
2472
+ R as Mode,
2473
+ Vt as PERFORMANCE_CONFIG,
2474
+ Xt as SEGMENTATION_ANALYTICS,
2475
+ zt as SESSION_ANALYTICS,
2476
+ Kt as SPECIAL_PAGE_URLS,
2477
+ oe as SamplingRateValidationError,
2478
+ D as ScrollDirection,
2479
+ Pe as SessionTimeoutValidationError,
2480
+ j as SpecialApiUrl,
2481
+ jt as TEMPORAL_ANALYSIS,
2482
+ C as TraceLogValidationError,
2483
+ qt as tracelog
2737
2484
  };