@sourav732/error-tracker-js 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +228 -2
  2. package/dist/index.cjs +2 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.mjs +2 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/dist/types/collectors/breadcrumbCollector.d.ts +45 -0
  7. package/dist/types/collectors/collector.d.ts +22 -0
  8. package/dist/types/collectors/cspCollector.d.ts +63 -0
  9. package/dist/types/collectors/errorCollector.d.ts +26 -0
  10. package/dist/types/collectors/httpErrorCollector.d.ts +34 -0
  11. package/dist/types/collectors/jsonResponseCollector.d.ts +24 -0
  12. package/dist/types/collectors/memoryCollector.d.ts +38 -0
  13. package/dist/types/collectors/networkInterceptor.d.ts +54 -0
  14. package/dist/types/collectors/performanceCollector.d.ts +50 -0
  15. package/dist/types/collectors/resourceCollector.d.ts +45 -0
  16. package/dist/types/collectors/responsivenessCollector.d.ts +45 -0
  17. package/dist/types/collectors/screenshotCollector.d.ts +52 -0
  18. package/dist/types/collectors/workerCollector.d.ts +22 -0
  19. package/dist/types/constants.d.ts +99 -0
  20. package/dist/types/core/circularBuffer.d.ts +15 -0
  21. package/dist/types/core/client.d.ts +71 -0
  22. package/dist/types/core/config.d.ts +28 -0
  23. package/dist/types/core/device.d.ts +23 -0
  24. package/dist/types/core/env.d.ts +21 -0
  25. package/dist/types/core/eventFilters.d.ts +32 -0
  26. package/dist/types/core/eventQueue.d.ts +52 -0
  27. package/dist/types/core/logger.d.ts +19 -0
  28. package/dist/types/core/payloadBuilder.d.ts +32 -0
  29. package/dist/types/core/reportedErrors.d.ts +18 -0
  30. package/dist/types/core/retryManager.d.ts +18 -0
  31. package/dist/types/core/safe.d.ts +10 -0
  32. package/dist/types/core/serialize.d.ts +13 -0
  33. package/dist/types/core/stackParser.d.ts +5 -0
  34. package/dist/types/index.d.ts +55 -0
  35. package/dist/types/transport/httpTransport.d.ts +24 -0
  36. package/dist/types/transport/offlineStore.d.ts +33 -0
  37. package/dist/types/types.d.ts +161 -0
  38. package/package.json +62 -4
package/README.md CHANGED
@@ -1,3 +1,229 @@
1
- # Temporary Holding Version
1
+ # Error Tracker — JavaScript SDK
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Client-side error, performance and memory monitoring for browser apps (vanilla JS, React, Vue, …).
4
+ The SDK captures problems in the page and POSTs structured JSON events to your ingestion endpoint.
5
+
6
+ - **Zero runtime dependencies.** ES5 output, ESM and CommonJS builds, TypeScript types included.
7
+ - **Never breaks the host app.** Every hook is guarded. SDK failures are swallowed and logged only when `debug: true`.
8
+ - **Silent by default.** Nothing is written to the console unless `debug: true`.
9
+ - **Supported environments:** Chrome 60+, Safari 12+, Firefox 60+, and Node.js 14+ (manual capture only; Node needs a global `fetch`, i.e. 18+, to deliver events).
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install @sourav732/error-tracker-js
15
+ ```
16
+
17
+ ## Quick start
18
+
19
+ Initialise as early as possible, before the rest of your app code runs:
20
+
21
+ ```ts
22
+ import ErrorTracker from '@sourav732/error-tracker-js';
23
+
24
+ ErrorTracker.init({
25
+ apiKey: 'pk_live_xxx',
26
+ endpoint: 'https://api.yourcompany.com/v1/events',
27
+ environment: 'production',
28
+ appVersion: '2.1.4',
29
+ sampleRate: 1.0,
30
+ maxBreadcrumbs: 30,
31
+ maskSelectors: ['.credit-card', '[data-private]', '#ssn'],
32
+ debug: false,
33
+ });
34
+ ```
35
+
36
+ Uncaught errors, unhandled promise rejections, failed resource loads, slow page loads, slow API calls and suspected memory leaks are all reported automatically. You can also report things yourself:
37
+
38
+ ```ts
39
+ try {
40
+ await submitPayment(cart);
41
+ } catch (err) {
42
+ ErrorTracker.captureError(err, { cartId: cart.id, step: 'payment' });
43
+ }
44
+
45
+ ErrorTracker.captureMessage('Checkout started', 'info'); // 'info' | 'warning' | 'error'
46
+
47
+ ErrorTracker.setUser({ id: 'usr_8821', email: 'jane@example.com', name: 'Jane' });
48
+ ErrorTracker.setUser(null); // on logout
49
+
50
+ ErrorTracker.addBreadcrumb({ type: 'cart', message: 'Applied coupon', data: { code: 'SPRING' } });
51
+ ```
52
+
53
+ You can call any method before `init()`. Up to 100 calls are buffered and replayed once the SDK starts.
54
+
55
+ ### React
56
+
57
+ ```tsx
58
+ import ErrorTracker from '@sourav732/error-tracker-js';
59
+
60
+ class ErrorBoundary extends React.Component<{ children: React.ReactNode }, { failed: boolean }> {
61
+ state = { failed: false };
62
+ static getDerivedStateFromError() {
63
+ return { failed: true };
64
+ }
65
+ componentDidCatch(error: Error, info: React.ErrorInfo) {
66
+ ErrorTracker.captureError(error, { componentStack: info.componentStack });
67
+ }
68
+ render() {
69
+ return this.state.failed ? <p>Something went wrong.</p> : this.props.children;
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### Vue 3
75
+
76
+ ```ts
77
+ app.config.errorHandler = (err, instance, info) => {
78
+ ErrorTracker.captureError(err, { info, component: instance?.$options.name });
79
+ };
80
+ ```
81
+
82
+ ### Script tag (no bundler)
83
+
84
+ ```html
85
+ <script type="module">
86
+ import ErrorTracker from '/vendor/error-tracker/index.mjs';
87
+ ErrorTracker.init({ apiKey: 'pk_live_xxx', endpoint: 'https://api.yourcompany.com/v1/events' });
88
+ </script>
89
+ ```
90
+
91
+ ## Configuration
92
+
93
+ | Option | Type | Default | Description |
94
+ | --- | --- | --- | --- |
95
+ | `apiKey` | `string` | required | Sent in the `X-API-Key` header. Kept in memory only, never written to storage. |
96
+ | `endpoint` | `string` | required | Ingestion URL. Batches are POSTed here. |
97
+ | `environment` | `string` | `'production'` | Free-form, e.g. `staging`. |
98
+ | `appVersion` | `string` | `null` | Your app's version. |
99
+ | `sampleRate` | `number` | `1.0` | 0–1. Each event is dropped when `Math.random() > sampleRate`. |
100
+ | `maxBreadcrumbs` | `number` | `30` | Size of the breadcrumb ring buffer (max 100). |
101
+ | `maskSelectors` | `string[]` | `[]` | Elements to black out in screenshots and hide in click breadcrumbs. `input[type="password"]` is always masked. |
102
+ | `debug` | `boolean` | `false` | Log SDK diagnostics to the console. |
103
+ | `captureHttpErrors` | `boolean` | `true` | Report every fetch/XHR response with a 4xx or 5xx status as an `HttpError` event. |
104
+ | `captureNetworkErrors` | `boolean` | `true` | Report fetch/XHR requests that got no response (offline, timeout, refused, DNS/SSL, CORS) as `NetworkError`. Requests the app aborts are never reported. |
105
+ | `captureConsoleErrors` | `boolean` | `false` | Report each `console.error(...)` call as an event. Off by default because libraries log a lot of noise there. |
106
+ | `captureScreenshots` | `boolean` | `true` | Attach a viewport screenshot to error events. |
107
+ | `html2canvasUrl` | `string` | cdnjs html2canvas 1.4.1 | Where the screenshot library is loaded from. |
108
+ | `html2canvasIntegrity` | `string` | SRI hash of the default URL | SRI hash for `html2canvasUrl`. Defaults to `''` (no check) when you set a custom URL. |
109
+ | `beforeSend` | `(event) => event \| null` | — | Scrub or drop events before they are queued. If the hook throws, the original event is sent. |
110
+
111
+ An invalid `apiKey` or `endpoint` leaves the SDK disabled. It never throws.
112
+
113
+ Other public methods: `flush(): Promise<void>` sends everything now (and never rejects). `close(): Promise<void>` flushes, removes every hook and persists anything unsent. `isInitialized(): boolean`.
114
+
115
+ ## What is collected
116
+
117
+ | Collector | Captures |
118
+ | --- | --- |
119
+ | **Errors** | `error` events (capture phase) and `unhandledrejection`. Stack traces are parsed from V8, Firefox and Safari formats into `{ filename, lineno, colno, function }` (max 50 frames, no source maps applied). Errors from other-origin scripts loaded without CORS are labelled `CrossOriginScriptError` (see below). |
120
+ | **Network** | `HttpError` for fetch/XHR responses with a 4xx/5xx status (e.g. `GET https://app.example.com/api/cart → 500`). `NetworkError` for requests that got no response: offline, timeout, connection refused, DNS/SSL failure, CORS (`context.failure` says which, as far as the browser reveals). Requests the app aborts itself are not reported. `InvalidJsonResponse` when `response.json()` fails, even if the app catches it. The stack trace of all three points at the app code that made the request. |
121
+ | **Resources** | `ResourceError` for failed `<img>`/`<script>`/`<link>` loads, web fonts (`document.fonts`), and CSS background images / `@import`s with a 4xx/5xx status. Failures that happened while the HTML was still loading, before the SDK started, are picked up from Resource Timing. Failed `<link rel="preload">` hints are skipped, since the element using the file reports it. CSS-image and pre-start checks are Chromium 109+ only, and same-origin (or `Timing-Allow-Origin`) only. |
122
+ | **Security & workers** | `CspViolation` for Content-Security-Policy violations, both enforced and report-only. In Chromium a buffered `ReportingObserver` also catches violations from before the SDK started. Violations caused by the SDK's own screenshot library are ignored. `WorkerError` for uncaught errors inside dedicated Web Workers, and workers that fail to start. |
123
+ | **Console** | Opt-in (`captureConsoleErrors: true`): each `console.error(...)` becomes a `ConsoleError` event, or the passed Error's own type. Errors the SDK has already reported are skipped. |
124
+ | **Breadcrumbs** | Clicks (tag, visible text, CSS path; form values are never read), `pushState`/`replaceState`/`popstate` navigation, page visibility changes, `console.warn`/`console.error`, and every `fetch`/XHR call (URL, method, status or failure, duration). |
125
+ | **Performance** | Page load, TTFB (Navigation Timing L2, with an L1 fallback), FCP, LCP and CLS (via `PerformanceObserver`), plus the last 20 API calls. A page load over 3000 ms or an API call over 2000 ms is flagged and also sent as its own `performance` event. |
126
+ | **Responsiveness** | `MainThreadBlocked` when one task freezes the page for more than 1 s (Long Tasks API, Chromium only; at most one report per 30 s). The frame rate is sampled for 1 s, 5 s after start and then every 30 s while the page is visible. It fills `performance.frame_rate_fps`, and a sample under 20 fps is reported as `LowFrameRate`. |
127
+ | **Memory** | `performance.memory` (Chromium only), polled every 30 s. Sets `leak_suspected` and sends a `performance` event when the heap grows by more than 20% across 3 consecutive rising readings with no navigation in between. |
128
+ | **Screenshots** | The visible viewport as a JPEG (quality 0.6), only when the page is visible. At most one every 10 s, with a 3 s time budget and a ~750 KB size cap. |
129
+
130
+ Query strings and fragments are stripped from every recorded URL, because they often carry tokens.
131
+
132
+ **One failure, one event.** Error objects the SDK has reported are remembered. For example, a failed `fetch` reported as `NetworkError` is not reported again when the app leaves the rejected promise uncaught, or when a framework logs it with `console.error`.
133
+
134
+ ### Start the SDK as early as possible
135
+
136
+ Errors that happen before `init()` runs are not captured, apart from the resource and CSP failures recovered from browser buffers (see above). In particular, calling `init()` inside a React `useEffect` misses errors during the first render and hydration. In Next.js 15.3+, put `init()` in `instrumentation-client.js`, which runs before React starts. Otherwise, import and initialise the SDK at the very top of your entry file.
137
+
138
+ ### Cross-origin scripts ("Script error.")
139
+
140
+ Browsers hide the message and stack of errors thrown by scripts from another origin, such as a CDN or third-party widget. All that arrives is `Script error.`, which the SDK reports as `CrossOriginScriptError`, with a hint in `context`. To get the real error, load the script with `crossorigin="anonymous"` and serve it with an `Access-Control-Allow-Origin` header.
141
+
142
+ ### Not covered
143
+
144
+ - Errors the app catches and swallows (`catch {}` without `captureError`).
145
+ - Service Worker internals, and iframes from other origins.
146
+ - Memory data in Firefox and Safari: they expose no API, so the memory fields are `null` there.
147
+ - Tab crashes and out-of-memory kills: the page dies without any signal, so `oom_kill` is always `null`.
148
+ - A page stuck in an infinite loop: the task never ends, so it can't be reported from inside the page.
149
+ - Layout bugs that never throw.
150
+
151
+ ### Screenshots and Content Security Policy
152
+
153
+ html2canvas is **not bundled**. It is loaded on demand the first time a screenshot is needed, with Subresource Integrity checking. If your site uses a CSP, allow the script origin (`script-src https://cdnjs.cloudflare.com`). Alternatively, self-host the file and set `html2canvasUrl` (and `html2canvasIntegrity`). If the library can't load, error events are sent without a screenshot. html2canvas also draws `data:` images, so a policy that restricts `img-src` needs `data:` for screenshots to render. The SDK does not report the violations its own library causes.
154
+
155
+ Masking works in two layers. Masked elements are painted black in html2canvas's cloned DOM (form values are blanked and their children hidden). Then, after rendering, black rectangles are drawn over their on-screen bounds. If the canvas can't be drawn on, the screenshot is discarded rather than sent unmasked.
156
+
157
+ ## Delivery
158
+
159
+ - Events are batched (up to 10 per request) and sent 2 s after the first event, or immediately once 10 are waiting.
160
+ - The request is `POST <endpoint>`, with headers `Content-Type: application/json` and `X-API-Key: <apiKey>`, and the body `{ "events": [ ... ] }`.
161
+ - **Retries:** network errors, 5xx, 408 and 429 are retried 3 times, after 1 s, 2 s and 4 s. Other 4xx responses (bad payload, invalid key) are dropped without retrying, since resending can't succeed.
162
+ - **Offline:** when `navigator.onLine === false`, or once retries are exhausted, events are stored in `localStorage["_et_queue"]` (newest 50, with the API key removed). The stored queue is flushed on the `online` event, when the tab becomes visible again, and on the next `init()`. If storage is full, screenshots are dropped first, then the oldest events.
163
+ - **Error storms:** identical events (same type, message and top frame) are deduplicated within 5 s. After that, at most 100 events per rolling minute are accepted. When the limit drops events, one `EventsDropped` summary (`context.dropped_count`) is sent 10 s later, so a storm is never silent.
164
+
165
+ ## Payload
166
+
167
+ Every event follows the shared cross-platform schema. Every field is always present, and values the browser can't provide are `null`:
168
+
169
+ ```json
170
+ {
171
+ "sdk": { "name": "error-tracker-js", "version": "1.0.0" },
172
+ "api_key": "pk_live_xxx",
173
+ "event_type": "error",
174
+ "level": "error",
175
+ "timestamp": "2026-10-17T10:42:15.000Z",
176
+ "environment": "production",
177
+ "app_version": "2.1.4",
178
+ "user": { "id": "usr_8821", "email": null, "name": null },
179
+ "error": { "message": "Cannot read properties of undefined (reading 'price')", "type": "TypeError", "handled": false },
180
+ "stacktrace": [{ "filename": "https://app.example.com/static/cart.js", "lineno": 142, "colno": 12, "function": "handlePayment" }],
181
+ "breadcrumbs": [{ "timestamp": "2026-10-17T10:42:14.100Z", "type": "click", "message": "Clicked Pay Now", "data": { "tag": "button", "text": "Pay Now", "selector": "form#checkout > button.primary" } }],
182
+ "screenshot": "data:image/jpeg;base64,...",
183
+ "performance": {
184
+ "page_load_ms": 4200, "ttfb_ms": 320, "fcp_ms": 1800, "lcp_ms": 2400, "cls": 0.02,
185
+ "startup_ms": null, "frame_rate_fps": null, "slow_screen": true,
186
+ "api_calls": [{ "url": "https://app.example.com/api/cart", "method": "POST", "status": 200, "duration_ms": 230 }],
187
+ "slow_api_calls": []
188
+ },
189
+ "memory": { "used_mb": 142.3, "total_mb": 256, "leak_suspected": false, "oom_kill": null },
190
+ "device": {
191
+ "platform": "js", "os": "Windows 11", "os_version": "15.0.0", "manufacturer": null, "model": null,
192
+ "browser": "Chrome", "browser_version": "124.0", "screen_width": 1920, "screen_height": 1080,
193
+ "url": "https://app.example.com/checkout", "referrer": null, "locale": "en-IN"
194
+ },
195
+ "context": null
196
+ }
197
+ ```
198
+
199
+ **JS-specific fields** that are not part of the shared schema: `level` (severity of `captureMessage`), `context` (the second argument to `captureError`), `performance.cls`, and `device.referrer`.
200
+
201
+ **Event types:**
202
+ - `error` covers uncaught and captured errors, plus `HttpError`, `NetworkError`, `InvalidJsonResponse`, `ResourceError`, `CspViolation`, `WorkerError`, `ConsoleError` and `CrossOriginScriptError` in `error.type`.
203
+ - `message` comes from `captureMessage`, and also carries the `EventsDropped` summary.
204
+ - `performance` carries `SlowPageLoad`, `SlowApiCall`, `MemoryLeakSuspected`, `MainThreadBlocked` and `LowFrameRate` in `error.type`.
205
+ - `crash` is unused on the web.
206
+
207
+ **`handled`:** `false` when something broke without app code getting a chance to react (uncaught exceptions and rejections, failed resources, CSP blocks, worker errors). `true` when the problem was handed back to the app: an HTTP error status, a rejected request, a JSON parse error thrown to the caller, `console.error`, performance issues, and `captureError`. Most events built by the SDK put extra detail in `context`.
208
+
209
+ ## Development
210
+
211
+ ```bash
212
+ npm install
213
+ npm run typecheck # strict TypeScript over src + tests
214
+ npm test # Vitest (jsdom)
215
+ npm run build # dist/index.mjs, dist/index.cjs, dist/types
216
+ ```
217
+
218
+ All thresholds, timeouts and limits live in [`src/constants.ts`](src/constants.ts).
219
+
220
+ ### Releasing
221
+
222
+ ```bash
223
+ npm version patch # or minor / major; bumps package.json and creates a git tag
224
+ # then set SDK_VERSION in src/constants.ts to the same version (a test fails if they differ)
225
+ npm publish # runs typecheck, tests and build first (prepublishOnly), then uploads
226
+ git push --follow-tags
227
+ ```
228
+
229
+ The package is public (`publishConfig.access`). Check what will be uploaded with `npm publish --dry-run`.
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="0.1.0",t=[1e3,2e3,4e3],n=2e3,r="<anonymous>",i="image/jpeg",o=1e6,s="#000000",l=['input[type="password"]'];function a(){return"undefined"!=typeof window?window:null}function u(){return"undefined"!=typeof document?document:null}function c(){return"undefined"!=typeof navigator?navigator:null}function h(){return"undefined"!=typeof performance?performance:null}function f(){try{return"undefined"!=typeof localStorage?localStorage:null}catch(e){return null}}function p(){var e=c();return null===e||!1!==e.onLine}function d(){var e=u();return null!==e&&"hidden"!==e.visibilityState}function m(){return(new Date).toISOString()}function v(){var e=h();return null!==e&&"function"==typeof e.now?e.now():Date.now()}function g(e){var t=e.search(/[?#]/);return-1===t?e:e.slice(0,t)}function y(e){var t=u();try{return null!==t?new URL(e,t.baseURI).href:e}catch(t){return e}}function b(e){return null==e||!isFinite(e)||e<0?null:Math.round(e)}var w="[ErrorTracker]",k=function(){function e(e){this.enabled=e}return e.prototype.setEnabled=function(e){this.enabled=e},e.prototype.isEnabled=function(){return this.enabled},e.prototype.info=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];this.write("log",e,t)},e.prototype.warn=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];this.write("warn",e,t)},e.prototype.error=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];this.write("error",e,t)},e.prototype.write=function(e,t,n){if(this.enabled&&"undefined"!=typeof console)try{var r=console[e];"function"==typeof r&&r.apply(console,[w+" "+t].concat(n))}catch(e){}},e}(),S=new k(!1),E="undefined"!=typeof WeakSet?new WeakSet:null;function _(e){return null!==e&&("object"==typeof e||"function"==typeof e)}function L(e){null!==E&&_(e)&&E.add(e)}function x(e){return null!==E&&_(e)&&E.has(e)}var P={};function O(e,t,n){return e+"|"+String(t)+"|"+String(n)}function T(e,t,n,r){try{return n()}catch(n){return e.warn(t+" failed",n),r}}function R(e,t,n){T(e,t,n,void 0)}function C(e,t,n){return function(){for(var r=[],i=0;i<arguments.length;i++)r[i]=arguments[i];R(e,t,function(){n.apply(null,r)})}}function F(e,t){return e.length>t?e.slice(0,t)+"…":e}function M(e,t){return void 0===t&&(t=5),j(e,t,[])}function A(e){var t=M(e);return null===t||"object"!=typeof t||N(t)?{}:t}function N(e){return"[object Array]"===Object.prototype.toString.call(e)}function j(e,t,n){if(null==e)return null;switch(typeof e){case"string":return F(e,1e3);case"number":return isFinite(e)?e:String(e);case"boolean":return e;case"bigint":case"symbol":return e.toString();case"function":return"[Function "+(e.name||"anonymous")+"]"}if(e instanceof Error)return{name:e.name,message:F(e.message,1e3)};if(e instanceof Date)return isNaN(e.getTime())?"Invalid Date":e.toISOString();if("undefined"!=typeof Node&&e instanceof Node)return"["+e.nodeName+"]";if(-1!==n.indexOf(e))return"[Circular]";if(t<=0)return"[MaxDepth]";n.push(e);try{if(N(e)){for(var r=[],i=Math.min(e.length,50),o=0;o<i;o++)r.push(j(e[o],t-1,n));return r}var s={},l=e,a=Object.keys(l).slice(0,50);for(o=0;o<a.length;o++){var u=void 0;try{u=l[a[o]]}catch(e){continue}void 0!==u&&(s[a[o]]=j(u,t-1,n))}return s}finally{n.pop()}}function q(e){if("string"==typeof e)return e;if(e instanceof Error)return e.message;try{var t=JSON.stringify(M(e));return void 0===t?String(e):t}catch(t){return Object.prototype.toString.call(e)}}var U=/^\s*at (?:(.+?) \()?(.+?):(\d+):(\d+)\)?\s*$/,I=/^\s*at (?:(.+?) \()?(native|<anonymous>|unknown location)\)?\s*$/,V=/\(eval at [^()]*\((.+?):(\d+):(\d+)\)/,D=/^\s*at /,B=/^\s*(.*?)@(.+?):(\d+):(\d+)\s*$/,H=/^\s*(.*?)@(.+?) line (\d+) > (?:eval|Function)/,z=/^\s*(.*?)@\[native code\]\s*$/;function W(e){if("string"!=typeof e||0===e.length)return[];for(var t=e.split("\n"),n=t.some(function(e){return D.test(e)}),r=[],i=0;i<t.length&&r.length<50;i++){var o=n?X(t[i]):J(t[i]);null!==o&&r.push(o)}return r}function K(e){if(null!==e&&"object"==typeof e&&"stack"in e){var t=e.stack;return"string"==typeof t?W(t):[]}return[]}function X(e){if(!D.test(e))return null;var t=V.exec(e);if(null!==t){var n=/^\s*at (.+?) \(/.exec(e);return $(null!==n?n[1]:"",t[1],t[2],t[3])}var r=U.exec(e);if(null!==r)return $(r[1]||"",r[2],r[3],r[4]);var i=I.exec(e);return null!==i?$(i[1]||"",null,null,null):null}function J(e){var t=H.exec(e);if(null!==t)return $(t[1],t[2],t[3],null);var n=B.exec(e);if(null!==n)return $(n[1],n[2],n[3],n[4]);var r=z.exec(e);return null!==r?$(r[1],null,null,null):null}function $(e,t,n,r){return{filename:null!==t&&t.length>0?t:null,lineno:Z(n),colno:Z(r),function:Y(e)}}function Y(e){var t=e.trim();return 0===t.indexOf("async ")&&(t=t.slice(6)),(t=t.replace(/\/<+$/,"").replace(/<$/,"")).length>0?t:r}function Z(e){if(null===e)return null;var t=parseInt(e,10);return isNaN(t)?null:t}var G="Error",Q=["preload","prefetch","modulepreload"],ee=/^Script error\.?$/;function te(e,t,r){void 0===r&&(r=G);var i=null!==e&&"object"==typeof e&&"string"==typeof e.message,o=r;if(i){var s=e.name;if("string"==typeof s&&s.length>0)o=s;else{var l=e.constructor;void 0!==l&&"string"==typeof l.name&&l.name.length>0&&(o=l.name)}}return L(e),{error:{message:F(i?e.message:q(e),n),type:o,handled:t},stacktrace:K(e)}}var ne=function(){function e(e,t){this.sink=e,this.installed=!1;var n=this;this.handleError=C(t,"error handler",function(e){if(re(e)){if(x(e.error))return;var t=e.filename?g(e.filename):null;if(function(e,t){void 0===t&&(t=Date.now());var n=P[e];return void 0!==n&&t-n<=2e3}(O(e.message,t,e.lineno||null)))return}var r=n.fromErrorEvent(e);null!==r&&n.sink.onError(r)}),this.handleRejection=C(t,"rejection handler",function(e){x(e.reason)||n.sink.onError(te(e.reason,!1,"UnhandledRejection"))})}return e.prototype.install=function(){var e=a();this.installed||null===e||(e.addEventListener("error",this.handleError,!0),e.addEventListener("unhandledrejection",this.handleRejection),this.installed=!0)},e.prototype.uninstall=function(){var e=a();this.installed&&null!==e&&(e.removeEventListener("error",this.handleError,!0),e.removeEventListener("unhandledrejection",this.handleRejection),this.installed=!1)},e.prototype.fromErrorEvent=function(e){if(re(e)){var t=void 0;return 0===(t=null!==e.error&&void 0!==e.error?te(e.error,!1):ee.test(e.message||"")?{error:{message:e.message,type:"CrossOriginScriptError",handled:!1},stacktrace:[],context:{hint:'Error details are hidden by the browser because the script came from another origin. Load it with crossorigin="anonymous" and serve it with an Access-Control-Allow-Origin header to get the real message and stack.'}}:{error:{message:F(e.message||"Unknown error",n),type:G,handled:!1},stacktrace:[]}).stacktrace.length&&e.filename&&(t.stacktrace=[{filename:e.filename,lineno:e.lineno||null,colno:e.colno||null,function:r}]),t}var i,o,s=e.target;if(null!==s&&s!==a()&&function(e){return"undefined"!=typeof Element&&e instanceof Element}(s)){if(function(e){if("LINK"!==e.tagName)return!1;for(var t=(e.getAttribute("rel")||"").toLowerCase().split(/\s+/),n=0;n<t.length;n++)if(-1!==Q.indexOf(t[n]))return!0;return!1}(s))return null;var l=null!==(o=(i=s).getAttribute("src")||i.getAttribute("href"))&&o.length>0?g(o):null;return{error:{message:F("Failed to load <"+s.tagName.toLowerCase()+">"+(null!==l?" "+l:""),n),type:"ResourceError",handled:!1},stacktrace:[]}}return null},e}();function re(e){return"undefined"!=typeof ErrorEvent&&e instanceof ErrorEvent}var ie=["warn","error"],oe=["INPUT","TEXTAREA","SELECT"];function se(e){for(var t=[],n=e;null!==n&&t.length<5;){var r=n.tagName.toLowerCase();if(n.id){t.unshift(r+"#"+n.id);break}var i="string"==typeof n.className?n.className.trim():"";if(i.length>0&&(r+="."+i.split(/\s+/).slice(0,2).join(".")),t.unshift(r),"BODY"===n.tagName)break;n=n.parentElement}return t.join(" > ")}var le=function(){function e(e,t,n,r,i){void 0===i&&(i=!1),this.sink=e,this.network=t,this.maskSelectors=n,this.logger=r,this.captureConsoleErrors=i,this.installed=!1,this.lastUrl=null,this.originalPushState=null,this.originalReplaceState=null,this.originalConsole={},this.inConsoleHook=!1;var o=this;this.handleClick=C(r,"click breadcrumb",function(e){o.recordClick(e)}),this.handlePopState=C(r,"navigation breadcrumb",function(){o.recordNavigation("popstate")}),this.handleVisibility=C(r,"lifecycle breadcrumb",function(){var e=u();null!==e&&o.sink.onBreadcrumb({type:"lifecycle",message:"Page "+e.visibilityState})})}return e.prototype.install=function(){var e=this,t=a(),n=u();if(!this.installed&&null!==t&&null!==n){this.installed=!0,this.lastUrl=g(t.location.href),n.addEventListener("click",this.handleClick,!0),n.addEventListener("visibilitychange",this.handleVisibility),t.addEventListener("popstate",this.handlePopState),R(this.logger,"history instrumentation",function(){return e.wrapHistory(t)}),R(this.logger,"console instrumentation",function(){return e.wrapConsole()});var r=this;this.network.subscribe(function(e,t){var n=null!==t.failure?t.failure:String(e.status);r.sink.onBreadcrumb({type:"api",message:e.method+" "+e.url+" → "+n,data:{url:e.url,method:e.method,status:e.status,duration_ms:e.duration_ms,failure:t.failure}})})}},e.prototype.uninstall=function(){var e=a(),t=u();if(this.installed&&null!==e&&null!==t){t.removeEventListener("click",this.handleClick,!0),t.removeEventListener("visibilitychange",this.handleVisibility),e.removeEventListener("popstate",this.handlePopState),null!==this.originalPushState&&(e.history.pushState=this.originalPushState),null!==this.originalReplaceState&&(e.history.replaceState=this.originalReplaceState);for(var n=0;n<ie.length;n++){var r=this.originalConsole[ie[n]];void 0!==r&&(console[ie[n]]=r)}this.originalPushState=null,this.originalReplaceState=null,this.originalConsole={},this.installed=!1}},e.prototype.recordClick=function(e){var t=e.target;if(null!==t&&"undefined"!=typeof Element&&t instanceof Element){var n=t.closest('button, a, input, select, textarea, label, summary, [role="button"], [role="link"], [onclick]')||t,r=function(e,t){if(function(e,t){for(var n=0;n<t.length;n++)try{if(null!==e.closest(t[n]))return!0}catch(e){}return!1}(e,t))return"[masked]";if(-1!==oe.indexOf(e.tagName))return F(e.getAttribute("aria-label")||e.getAttribute("name")||e.getAttribute("type")||"",50);var n=e.getAttribute("aria-label");return null!==n&&n.length>0?F(n,50):F((e.textContent||"").replace(/\s+/g," ").trim(),50)}(n,this.maskSelectors),i=n.tagName.toLowerCase();this.sink.onBreadcrumb({type:"click",message:"Clicked "+(r.length>0?r:i),data:{tag:i,text:r,selector:se(n)}})}},e.prototype.recordNavigation=function(e){var t=a();if(null!==t){var n=g(t.location.href);if(n!==this.lastUrl){var r=this.lastUrl;this.lastUrl=n,this.sink.onBreadcrumb({type:"navigation",message:"Navigated to "+n,data:{from:r,to:n,trigger:e}}),this.sink.onNavigation()}}},e.prototype.wrapHistory=function(e){var t=e.history,n=this,r=t.pushState,i=t.replaceState;this.originalPushState=r,this.originalReplaceState=i,t.pushState=function(e,t,i){var o=r.call(this,e,t,i);return R(n.logger,"pushState breadcrumb",function(){n.recordNavigation("pushState")}),o},t.replaceState=function(e,t,r){var o=i.call(this,e,t,r);return R(n.logger,"replaceState breadcrumb",function(){n.recordNavigation("replaceState")}),o}},e.prototype.wrapConsole=function(){if("undefined"!=typeof console){var e=this;ie.forEach(function(t){var r=console[t];"function"==typeof r&&(e.originalConsole[t]=r,console[t]=function(){for(var i=[],o=0;o<arguments.length;o++)i[o]=arguments[o];var s="string"==typeof i[0]&&0===i[0].indexOf(w);if(!e.inConsoleHook&&!s){if(e.inConsoleHook=!0,R(e.logger,"console breadcrumb",function(){var r=i.map(q).join(" ");e.sink.onBreadcrumb({type:"log",message:F(r,n),data:{level:t}})}),"error"===t&&e.captureConsoleErrors){var l=(new Error).stack;R(e.logger,"console error event",function(){var t=function(e,t){for(var r=F(e.map(q).join(" "),n),i=0;i<e.length;i++){var o=e[i];if(o instanceof Error){if(x(o))return null;var s=te(o,!0);return s.context={console_message:r},s}}return{error:{message:r,type:"ConsoleError",handled:!0},stacktrace:W(t).slice(1)}}(i,l);null!==t&&e.sink.onError(t)})}e.inConsoleHook=!1}r.apply(console,i)})})}},e}(),ae="csp-violation",ue=["inline","eval","self","data","blob","wasm-eval","trusted-types-policy","trusted-types-sink"];function ce(e){return{blocked:e.blockedURL||"inline",directive:e.effectiveDirective||"unknown-directive",disposition:e.disposition||null,sourceFile:e.sourceFile||null,lineNumber:e.lineNumber||null,columnNumber:e.columnNumber||null}}var he=function(){function e(e,t,i,o){var s;void 0===i&&(i=[]),void 0===o&&(o="function"==typeof(s="undefined"!=typeof window?window:{}).ReportingObserver?s.ReportingObserver:null),this.sink=e,this.logger=t,this.reportingObserver=o,this.installed=!1,this.observer=null;var l=this,a=i.map(g),u=function(e){null!==e.sourceFile&&-1!==a.indexOf(g(e.sourceFile))||l.sink.onError(function(e){var t=-1!==ue.indexOf(e.blocked)?e.blocked:g(e.blocked),i="report"===e.disposition?"would block":"blocked",o=null!==e.sourceFile?[{filename:g(e.sourceFile),lineno:e.lineNumber,colno:e.columnNumber,function:r}]:[];return{error:{message:F("CSP "+i+" "+t+" ("+e.directive+")",n),type:"CspViolation",handled:!1},stacktrace:o,context:{directive:e.directive,blocked_uri:t,disposition:e.disposition}}}(e))};this.handleEvent=C(t,"CSP violation handler",function(e){u(function(e){return{blocked:e.blockedURI||"inline",directive:e.effectiveDirective||e.violatedDirective||"unknown-directive",disposition:e.disposition||null,sourceFile:e.sourceFile||null,lineNumber:e.lineNumber||null,columnNumber:e.columnNumber||null}}(e))}),this.handleReports=C(t,"CSP report handler",function(e){for(var t=0;t<e.length;t++)e[t].type===ae&&u(ce(e[t].body))})}return e.prototype.install=function(){var e=u();if(!this.installed&&null!==e){this.installed=!0;var t=this.reportingObserver;if(null!==t){var n=this;if(R(this.logger,"CSP reporting observer",function(){var e=new t(n.handleReports,{types:[ae],buffered:!0});e.observe(),n.observer=e}),null!==this.observer)return}e.addEventListener("securitypolicyviolation",this.handleEvent)}},e.prototype.uninstall=function(){var e=u();if(this.installed&&null!==e){if(null!==this.observer){var t=this.observer;R(this.logger,"disconnect CSP observer",function(){t.disconnect()}),this.observer=null}else e.removeEventListener("securitypolicyviolation",this.handleEvent);this.installed=!1}},e}();var fe={offline:"device offline",timeout:"timed out",aborted:"aborted",network:"no response (connection refused, DNS, SSL or CORS)"};var pe=function(){function e(e,t,n){this.sink=e,this.network=t,this.options=n,this.installed=!1}return e.prototype.install=function(){if(!this.installed){this.installed=!0;var e=this;this.network.subscribe(function(t,n){e.installed&&e.handle(t,n)})}},e.prototype.uninstall=function(){this.installed=!1},e.prototype.handle=function(e,t){null!==t.failure?this.options.networkErrors&&"aborted"!==t.failure&&(L(t.error),this.sink.onError(function(e,t){var r=null!==t.failure?t.failure:"network";return{error:{message:F(e.method+" "+e.url+" failed: "+fe[r],n),type:"NetworkError",handled:!0},stacktrace:t.callSite(),context:{url:e.url,method:e.method,failure:r,duration_ms:e.duration_ms}}}(e,t))):this.options.httpErrors&&e.status>=400&&this.sink.onError(function(e,t){return{error:{message:F(e.method+" "+e.url+" → "+e.status,n),type:"HttpError",handled:!0},stacktrace:void 0!==t?t.callSite():[],context:{url:e.url,method:e.method,status:e.status,duration_ms:e.duration_ms}}}(e,t))},e}();var de=function(){function e(e,t,n){this.sink=e,this.logger=t,this.isSdkUrl=n,this.original=null,this.patched=null}return e.prototype.install=function(){if(null===this.original&&null!==a()&&"undefined"!=typeof Response&&"function"==typeof Response.prototype.json){var e=Response.prototype.json,t=this,r=function(){var r=this,i=(new Error).stack;return e.call(r).then(null,function(e){throw e instanceof Error&&"SyntaxError"===e.name&&R(t.logger,"invalid JSON report",function(){var o=g(y(r.url||""));t.isSdkUrl(o)||(L(e),t.sink.onError(function(e,t,r,i){return{error:{message:F("Invalid JSON from "+e+" (status "+t+"): "+(r instanceof Error?r.message:String(r)),n),type:"InvalidJsonResponse",handled:!0},stacktrace:W(i).slice(1),context:{url:e,status:t}}}(o,r.status,e,i)))}),e})};this.original=e,this.patched=r,Response.prototype.json=r}},e.prototype.uninstall=function(){null!==this.original&&(Response.prototype.json===this.patched&&(Response.prototype.json=this.original),this.original=null,this.patched=null)},e}();function me(){var e=h();return null===e||void 0===e.memory?null:{usedBytes:e.memory.usedJSHeapSize,totalBytes:e.memory.totalJSHeapSize}}function ve(e){return Math.round(e/1048576*10)/10}var ge=function(){function e(e,t,n,r){void 0===n&&(n=me),void 0===r&&(r=3e4),this.sink=e,this.read=n,this.intervalMs=r,this.timer=null,this.readings=[],this.latest=null,this.leakSuspected=!1;var i=this;this.poll=C(t,"memory poll",function(){i.sample()})}return e.prototype.install=function(){null===this.timer&&null!==this.read()&&(this.sample(),this.timer=setInterval(this.poll,this.intervalMs))},e.prototype.uninstall=function(){null!==this.timer&&clearInterval(this.timer),this.timer=null},e.prototype.resetBaseline=function(){this.readings=[],this.leakSuspected=!1},e.prototype.sample=function(){var e=this.read();null!==e&&(this.latest=e,this.readings.push(e.usedBytes),this.readings.length>3&&this.readings.shift(),!this.leakSuspected&&function(e,t,n){if(void 0===t&&(t=3),void 0===n&&(n=.2),e.length<t)return!1;for(var r=e.slice(-t),i=1;i<r.length;i++)if(r[i]<=r[i-1])return!1;return r[0]>0&&(r[r.length-1]-r[0])/r[0]>n}(this.readings)&&(this.leakSuspected=!0,this.sink.onPerformanceIssue("MemoryLeakSuspected","JS heap grew from "+ve(this.readings[0])+"MB to "+ve(e.usedBytes)+"MB across 3 readings without navigation")))},e.prototype.snapshot=function(){return null===this.latest?{used_mb:null,total_mb:null,leak_suspected:null,oom_kill:null}:{used_mb:ve(this.latest.usedBytes),total_mb:ve(this.latest.totalBytes),leak_suspected:this.leakSuspected,oom_kill:null}},e}();function ye(e){var t=null!==e&&"object"==typeof e?e.name:void 0;return"AbortError"===t?"aborted":"TimeoutError"===t?"timeout":p()?"network":"offline"}function be(){try{return(new Error).stack}catch(e){return}}function we(e){var t=null;return function(){return null===t&&(t=W(e).slice(2)),t}}var ke=function(){function e(e,t){this.logger=t,this.listeners=[],this.installed=!1,this.originalFetch=null,this.patchedFetch=null,this.originalOpen=null,this.originalSend=null,this.patchedOpen=null,this.patchedSend=null,this.ignoredUrl=g(y(e))}return e.prototype.subscribe=function(e){this.listeners.push(e)},e.prototype.isSdkUrl=function(e){return g(y(e))===this.ignoredUrl},e.prototype.install=function(){var e=this;if(!this.installed){var t=a();null!==t&&(this.installed=!0,R(this.logger,"fetch instrumentation",function(){return e.wrapFetch(t)}),R(this.logger,"XHR instrumentation",function(){return e.wrapXhr()}))}},e.prototype.uninstall=function(){if(this.installed){var e=a();if(null!==e&&(null!==this.originalFetch&&e.fetch===this.patchedFetch&&(e.fetch=this.originalFetch),"undefined"!=typeof XMLHttpRequest)){var t=XMLHttpRequest.prototype;null!==this.originalOpen&&t.open===this.patchedOpen&&(t.open=this.originalOpen),null!==this.originalSend&&t.send===this.patchedSend&&(t.send=this.originalSend)}this.originalFetch=null,this.patchedFetch=null,this.originalOpen=null,this.originalSend=null,this.patchedOpen=null,this.patchedSend=null,this.listeners=[],this.installed=!1}},e.prototype.emit=function(e,t,n,r,i){if(!this.isSdkUrl(t))for(var o={url:g(y(t)),method:e.toUpperCase(),status:n,duration_ms:Math.max(0,Math.round(v()-r))},s=function(e){var t=l.listeners[e];R(l.logger,"network listener",function(){t(o,i)})},l=this,a=0;a<this.listeners.length;a++)s(a)},e.prototype.wrapFetch=function(e){if("function"==typeof e.fetch){var t=e.fetch,n=this;this.originalFetch=t;var r=function(r,i){var o=v(),s=we(be()),l="GET",a="";return R(n.logger,"fetch argument parsing",function(){"string"==typeof r?a=r:"undefined"!=typeof URL&&r instanceof URL?a=r.href:(a=r.url,l=r.method||l),null!=i&&"string"==typeof i.method&&(l=i.method)}),t.call(void 0===this?e:this,r,i).then(function(e){return n.emit(l,a,e.status,o,{failure:null,error:null,callSite:s}),e},function(e){throw n.emit(l,a,0,o,{failure:ye(e),error:e,callSite:s}),e})};this.patchedFetch=r,e.fetch=r}},e.prototype.wrapXhr=function(){if("undefined"!=typeof XMLHttpRequest){var e=XMLHttpRequest.prototype,t=e.open,n=e.send,r=this;this.originalOpen=t,this.originalSend=n,e.open=function(e,n){var i=this;return R(r.logger,"XHR open tracking",function(){i.__et_method=e,i.__et_url="string"==typeof n?n:n.href,i.__et_failure=null}),t.apply(this,arguments)},e.send=function(e){var t=this;return R(r.logger,"XHR send tracking",function(){var e=v(),n=we(be()),i=function(e){return function(){t.__et_failure=e}};t.addEventListener("abort",i("aborted")),t.addEventListener("timeout",i("timeout")),t.addEventListener("error",function(){t.__et_failure=p()?"network":"offline"}),t.addEventListener("loadend",function(){var i=t.__et_failure||null;null===i&&0===t.status&&(i=p()?"network":"offline"),r.emit(t.__et_method||"GET",t.__et_url||"",t.status,e,{failure:i,error:null,callSite:n})})}),n.call(this,e)},this.patchedOpen=e.open,this.patchedSend=e.send}},e}(),Se=function(){function e(e){this.capacity=e,this.start=0,this.count=0,this.items=new Array(Math.max(0,e))}return e.prototype.push=function(e){if(0!==this.capacity){var t=(this.start+this.count)%this.capacity;this.items[t]=e,this.count<this.capacity?this.count++:this.start=(this.start+1)%this.capacity}},e.prototype.toArray=function(){for(var e=[],t=0;t<this.count;t++){var n=this.items[(this.start+t)%this.capacity];void 0!==n&&e.push(n)}return e},Object.defineProperty(e.prototype,"size",{get:function(){return this.count},enumerable:!1,configurable:!0}),e.prototype.clear=function(){for(var e=0;e<this.items.length;e++)this.items[e]=void 0;this.start=0,this.count=0},e}();function Ee(t,n,r){return{sdk:{name:"error-tracker-js",version:e},api_key:n.apiKey,event_type:t.eventType,level:t.level,timestamp:r,environment:n.environment,app_version:n.appVersion,user:(i=n.user,null===i?{id:null,email:null,name:null}:{id:"string"==typeof i.id?i.id:String(i.id),email:"string"==typeof i.email?i.email:null,name:"string"==typeof i.name?i.name:null}),error:null!==t.error?{message:t.error.message,type:t.error.type,handled:t.error.handled}:null,stacktrace:t.stacktrace.slice(),breadcrumbs:n.breadcrumbs.slice(),screenshot:n.screenshot,performance:{page_load_ms:n.performance.page_load_ms,ttfb_ms:n.performance.ttfb_ms,fcp_ms:n.performance.fcp_ms,lcp_ms:n.performance.lcp_ms,cls:n.performance.cls,startup_ms:n.performance.startup_ms,frame_rate_fps:n.performance.frame_rate_fps,slow_screen:n.performance.slow_screen,api_calls:n.performance.api_calls.slice(),slow_api_calls:n.performance.slow_api_calls.slice()},memory:{used_mb:n.memory.used_mb,total_mb:n.memory.total_mb,leak_suspected:n.memory.leak_suspected,oom_kill:n.memory.oom_kill},device:{platform:n.device.platform,os:n.device.os,os_version:n.device.os_version,manufacturer:n.device.manufacturer,model:n.device.model,browser:n.device.browser,browser_version:n.device.browser_version,screen_width:n.device.screen_width,screen_height:n.device.screen_height,url:n.device.url,referrer:n.device.referrer,locale:n.device.locale},context:t.context};var i}function _e(e,t,n){var r={};return Object.keys(e).forEach(function(t){r[t]=e[t]}),r[t]=n,r}var Le=function(){function e(){this.sessionValue=0,this.sessionStart=0,this.sessionLast=0,this.max=0,this.seen=!1}return e.prototype.add=function(e,t,n){n||(this.seen=!0,this.sessionValue>0&&t-this.sessionLast<1e3&&t-this.sessionStart<5e3?this.sessionValue+=e:(this.sessionValue=e,this.sessionStart=t),this.sessionLast=t,this.sessionValue>this.max&&(this.max=this.sessionValue))},e.prototype.value=function(){return this.seen?Math.round(1e4*this.max)/1e4:null},e}(),xe=function(){function e(e,t,n){this.sink=e,this.network=t,this.logger=n,this.installed=!1,this.metrics={page_load_ms:null,ttfb_ms:null,fcp_ms:null,lcp_ms:null,cls:null,startup_ms:null,frame_rate_fps:null,slow_screen:!1,api_calls:[],slow_api_calls:[]},this.apiCalls=new Se(20),this.slowApiCalls=new Se(20),this.cls=new Le,this.observers=[],this.lcpFinal=!1;var r=this;this.handleLoad=C(n,"page load metrics",function(){setTimeout(C(n,"page load metrics",function(){r.measurePageLoad()}),0)}),this.finalizeLcp=function(){r.lcpFinal=!0}}return e.prototype.install=function(){var e=a(),t=u();if(!this.installed&&null!==e&&null!==t){this.installed=!0;var n=this;this.network.subscribe(function(e){n.recordApiCall(e)}),this.observe("paint",function(e){"first-contentful-paint"===e.name&&(n.metrics.fcp_ms=b(e.startTime))}),this.observe("largest-contentful-paint",function(e){if(!n.lcpFinal){var t=e;n.metrics.lcp_ms=b(t.renderTime||t.loadTime||t.startTime)}}),this.observe("layout-shift",function(e){var t=e;n.cls.add(t.value,t.startTime,t.hadRecentInput)}),e.addEventListener("keydown",this.finalizeLcp,{once:!0,capture:!0}),e.addEventListener("pointerdown",this.finalizeLcp,{once:!0,capture:!0}),"complete"===t.readyState?this.handleLoad():e.addEventListener("load",this.handleLoad)}},e.prototype.uninstall=function(){var e=a();if(this.installed&&null!==e){for(var t=0;t<this.observers.length;t++)R(this.logger,"disconnect observer",Pe(this.observers[t]));this.observers=[],e.removeEventListener("load",this.handleLoad),e.removeEventListener("keydown",this.finalizeLcp,!0),e.removeEventListener("pointerdown",this.finalizeLcp,!0),this.installed=!1}},e.prototype.snapshot=function(){var e=this.metrics;return{page_load_ms:e.page_load_ms,ttfb_ms:e.ttfb_ms,fcp_ms:e.fcp_ms,lcp_ms:e.lcp_ms,cls:this.cls.value(),startup_ms:null,frame_rate_fps:null,slow_screen:e.slow_screen,api_calls:this.apiCalls.toArray(),slow_api_calls:this.slowApiCalls.toArray()}},e.prototype.recordApiCall=function(e){this.apiCalls.push(e),e.duration_ms>2e3&&(this.slowApiCalls.push(e),this.sink.onPerformanceIssue("SlowApiCall","Slow API call: "+e.method+" "+e.url+" took "+e.duration_ms+"ms"))},e.prototype.measurePageLoad=function(){var e=h();if(null!==e){var t=function(e){var t="function"==typeof e.getEntriesByType?e.getEntriesByType("navigation"):[];if(t.length>0){var n=t[0];return{pageLoadMs:n.loadEventEnd>0?b(n.loadEventEnd-n.startTime):null,ttfbMs:n.responseStart>0?b(n.responseStart-n.startTime):null}}var r=e.timing;return void 0!==r&&r.navigationStart>0?{pageLoadMs:r.loadEventEnd>0?b(r.loadEventEnd-r.navigationStart):null,ttfbMs:r.responseStart>0?b(r.responseStart-r.navigationStart):null}:{pageLoadMs:null,ttfbMs:null}}(e);if(this.metrics.page_load_ms=t.pageLoadMs,this.metrics.ttfb_ms=t.ttfbMs,null===this.metrics.fcp_ms&&"function"==typeof e.getEntriesByName){var n=e.getEntriesByName("first-contentful-paint");n.length>0&&(this.metrics.fcp_ms=b(n[0].startTime))}null!==t.pageLoadMs&&t.pageLoadMs>3e3&&(this.metrics.slow_screen=!0,this.sink.onPerformanceIssue("SlowPageLoad","Slow page load: "+t.pageLoadMs+"ms"))}},e.prototype.observe=function(e,t){var n=this;if("undefined"!=typeof PerformanceObserver){var r=PerformanceObserver.supportedEntryTypes;if(void 0===r||-1!==r.indexOf(e)){var i=this.logger;R(i,"observe "+e,function(){var r=new PerformanceObserver(C(i,e+" observer",function(e){for(var n=e.getEntries(),r=0;r<n.length;r++)t(n[r])}));r.observe({type:e,buffered:!0}),n.observers.push(r)})}}},e}();function Pe(e){return function(){e.disconnect()}}var Oe="ResourceError",Te=/\.(woff2?|ttf|otf|eot)$/i,Re=["img","script","link"];function Ce(e){return{error:{message:F("Failed to load font '"+e+"'",n),type:Oe,handled:!1},stacktrace:[],context:{resource:"font",family:e}}}var Fe=function(){function e(e,t){this.sink=e,this.logger=t,this.observer=null,this.fonts=null,this.installedAt=0,this.earlyReported=[];var n=this;this.handleFontError=C(t,"font error handler",function(e){for(var t=e.fontfaces||[],r=0;r<t.length;r++)n.sink.onError(Ce(t[r].family.replace(/^["']|["']$/g,"")))})}return e.prototype.install=function(){var e=u();null!==e&&null===this.fonts&&null===this.observer&&(this.installedAt=v(),void 0!==e.fonts&&"function"==typeof e.fonts.addEventListener&&(e.fonts.addEventListener("loadingerror",this.handleFontError),this.fonts=e.fonts),this.observeCssResources())},e.prototype.uninstall=function(){if(null!==this.fonts&&this.fonts.removeEventListener("loadingerror",this.handleFontError),null!==this.observer){var e=this.observer;R(this.logger,"disconnect resource observer",function(){e.disconnect()})}this.fonts=null,this.observer=null},e.prototype.recordResource=function(e){var t=e.responseStatus;if(!("number"!=typeof t||t<400)){var r=g(e.name);if("css"!==e.initiatorType){if(-1!==Re.indexOf(e.initiatorType)&&e.responseEnd<=this.installedAt){if(-1!==this.earlyReported.indexOf(r))return;this.earlyReported.push(r),this.sink.onError(function(e,t,r){return{error:{message:F("Failed to load <"+e+"> "+t+" (status "+r+")",n),type:Oe,handled:!1},stacktrace:[],context:{resource:e,url:t,status:r,before_sdk_start:!0}}}(e.initiatorType,r,t))}}else Te.test(r)||this.sink.onError(function(e,t){return{error:{message:F("Failed to load CSS resource "+e+" (status "+t+")",n),type:Oe,handled:!1},stacktrace:[],context:{resource:"css",url:e,status:t}}}(r,t))}},e.prototype.observeCssResources=function(){if("undefined"!=typeof PerformanceObserver){var e=PerformanceObserver.supportedEntryTypes;if(void 0!==e&&-1!==e.indexOf("resource")){var t=this;R(this.logger,"observe resources",function(){var e=new PerformanceObserver(C(t.logger,"resource observer",function(e){for(var n=e.getEntries(),r=0;r<n.length;r++)t.recordResource(n[r])}));e.observe({type:"resource",buffered:!0}),t.observer=e})}}},e}(),Me=function(){function e(e,t,n){void 0===n&&(n={}),this.sink=e,this.logger=t,this.observer=null,this.timer=null,this.firstSampleTimer=null,this.sampling=!1,this.fps=null,this.lastFreezeReport=-1/0,this.lastLowFpsReport=-1/0,this.now=n.now||v;var r=a();this.requestFrame=n.requestFrame||(null!==r&&"function"==typeof r.requestAnimationFrame?function(e){r.requestAnimationFrame(e)}:null),this.sampleIntervalMs=void 0!==n.sampleIntervalMs?n.sampleIntervalMs:3e4;var i=this;this.runSample=C(t,"frame rate sample",function(){i.sampleFrameRate()})}return e.prototype.install=function(){null===this.timer&&null!==a()&&(this.observeLongTasks(),null!==this.requestFrame&&(this.firstSampleTimer=setTimeout(this.runSample,5e3),this.timer=setInterval(this.runSample,this.sampleIntervalMs)))},e.prototype.uninstall=function(){if(null!==this.observer){var e=this.observer;R(this.logger,"disconnect long task observer",function(){e.disconnect()})}null!==this.timer&&clearInterval(this.timer),null!==this.firstSampleTimer&&clearTimeout(this.firstSampleTimer),this.observer=null,this.timer=null,this.firstSampleTimer=null},e.prototype.frameRate=function(){return this.fps},e.prototype.recordLongTask=function(e){if(!(e<=1e3)){var t=this.now();t-this.lastFreezeReport<3e4||(this.lastFreezeReport=t,this.sink.onPerformanceIssue("MainThreadBlocked","Main thread blocked for "+Math.round(e)+"ms (page unresponsive)"))}},e.prototype.sampleFrameRate=function(){var e=this.requestFrame;if(!this.sampling&&null!==e&&d()){this.sampling=!0;var t=this,n=this.now(),r=0,i=C(this.logger,"frame rate sample",function i(){r++;var o=t.now()-n;o<1e3?e(i):(t.sampling=!1,o>2e3||!d()||t.recordFrameRate(Math.round(1e3*r/o)))});e(i)}},e.prototype.recordFrameRate=function(e){if(this.fps=e,!(e>=20)){var t=this.now();t-this.lastLowFpsReport<3e4||(this.lastLowFpsReport=t,this.sink.onPerformanceIssue("LowFrameRate","Low frame rate: "+e+" fps (janky scrolling/animation)"))}},e.prototype.observeLongTasks=function(){if("undefined"!=typeof PerformanceObserver){var e=PerformanceObserver.supportedEntryTypes;if(void 0!==e&&-1!==e.indexOf("longtask")){var t=this;R(this.logger,"observe long tasks",function(){var e=new PerformanceObserver(C(t.logger,"long task observer",function(e){for(var n=e.getEntries(),r=0;r<n.length;r++)t.recordLongTask(n[r].duration)}));e.observe({type:"longtask",buffered:!0}),t.observer=e})}}},e}();function Ae(e,t){for(var n=[],r=0;r<t.length;r++){var i=void 0;try{i=e.querySelectorAll(t[r])}catch(e){continue}for(var o=0;o<i.length;o++)-1===n.indexOf(i[o])&&n.push(i[o])}return n}var Ne=function(){function e(e,t,n){void 0===n&&(n=Date.now),this.options=e,this.logger=t,this.clock=n,this.loader=null,this.lastCaptureAt=0}return e.prototype.capture=function(){var e=a(),t=u();if(null===e||null===t||null===t.documentElement)return Promise.resolve(null);if(!d())return this.logger.warn("page is hidden; skipping screenshot"),Promise.resolve(null);var n=this.clock();if(n-this.lastCaptureAt<1e4)return this.logger.info("screenshot throttled"),Promise.resolve(null);this.lastCaptureAt=n;var r=this;return function(e,t,n){return new Promise(function(r){var i=!1,o=setTimeout(function(){i||(i=!0,n(),r(null))},t);e.then(function(e){i||(i=!0,clearTimeout(o),r(e))})})}(this.loadLibrary(e).then(function(n){return r.render(n,e,t)}).then(null,function(e){return r.logger.warn("screenshot failed",e),null}),3e3,function(){r.logger.warn("screenshot timed out")})},e.prototype.render=function(e,t,n){if(!d())return Promise.resolve(null);var r=this.options.maskSelectors,l=Math.min(t.devicePixelRatio||1,1),a=Ae(n,r),u=this.logger;return e(n.documentElement,{logging:!1,useCORS:!0,x:t.scrollX||t.pageXOffset||0,y:t.scrollY||t.pageYOffset||0,width:t.innerWidth,height:t.innerHeight,scale:l,onclone:function(e){R(u,"mask cloned document",function(){!function(e,t){for(var n=Ae(e,t),r=0;r<n.length;r++){var i=n[r];if(void 0!==i.style){i.style.setProperty("background",s,"important"),i.style.setProperty("color",s,"important"),i.style.setProperty("border-color",s,"important"),i.style.setProperty("text-shadow","none","important"),(i instanceof HTMLInputElement||i instanceof HTMLTextAreaElement)&&(i.value="",i.setAttribute("value",""),i.setAttribute("placeholder",""));for(var o=i.querySelectorAll("*"),l=0;l<o.length;l++)o[l].style.setProperty("visibility","hidden","important")}}}(e,r)})}}).then(function(e){var t=e.getContext("2d");if(null===t)return u.warn("canvas 2D context unavailable; discarding screenshot"),null;!function(e,t,n){e.fillStyle=s;for(var r=0;r<t.length;r++){var i=t[r].getBoundingClientRect();i.width<=0||i.height<=0||e.fillRect(i.left*n,i.top*n,i.width*n,i.height*n)}}(t,a,l);var n=e.toDataURL(i,.6);return n.length>o&&(n=e.toDataURL(i,.3)),n.length>o?(u.warn("screenshot exceeds size budget; discarding it"),null):n})},e.prototype.loadLibrary=function(e){if("function"==typeof e.html2canvas)return Promise.resolve(e.html2canvas);if(null!==this.loader)return this.loader;var t=this.options,n=this;return this.loader=new Promise(function(n,r){var i=e.document,o=i.createElement("script");o.src=t.libraryUrl,o.async=!0,o.crossOrigin="anonymous",t.libraryIntegrity.length>0&&(o.integrity=t.libraryIntegrity),o.onload=function(){"function"==typeof e.html2canvas?n(e.html2canvas):r(new Error("html2canvas loaded but did not register itself"))},o.onerror=function(){r(new Error("failed to load html2canvas from "+t.libraryUrl))},(i.head||i.documentElement).appendChild(o)}).then(null,function(e){return n.loader=null,Promise.reject(e)}),this.loader},e}();var je=function(){function e(e,t){this.sink=e,this.logger=t,this.original=null,this.patched=null}return e.prototype.install=function(){var e=a();if(null===this.original&&null!==e&&"function"==typeof e.Worker){var t=e.Worker,i=this,o=function(e,o){var s=new t(e,o);return R(i.logger,"worker error tracking",function(){var t=g("string"==typeof e?e:e.href);s.addEventListener("error",C(i.logger,"worker error handler",function(e){var o,s,l=function(e,t){var i="undefined"!=typeof ErrorEvent&&e instanceof ErrorEvent?e:null,o=null!==i&&i.message?i.message:"Worker failed to start: "+t,s=null!==i&&i.filename?[{filename:g(i.filename),lineno:i.lineno||null,colno:i.colno||null,function:r}]:[];return{error:{message:F(o,n),type:"WorkerError",handled:!1},stacktrace:s,context:{worker_url:t}}}(e,t),a=l.stacktrace.length>0?l.stacktrace[0]:null;o=O(l.error.message,null!==a?a.filename:null,null!==a?a.lineno:null),void 0===s&&(s=Date.now()),P[o]=s,Object.keys(P).forEach(function(e){s-P[e]>2e3&&delete P[e]}),i.sink.onError(l)}))}),s};o.prototype=t.prototype,this.original=t,this.patched=o,e.Worker=o}},e.prototype.uninstall=function(){var e=a();null!==this.original&&null!==e&&(e.Worker===this.patched&&(e.Worker=this.original),this.original=null,this.patched=null)},e}();var qe=function(){function e(e,t,n,r){this.endpoint=e,this.apiKey=t,this.logger=n,void 0!==r?this.fetchFn=r:"function"==typeof fetch?this.fetchFn=fetch.bind("undefined"!=typeof window?window:void 0):this.fetchFn=null}return e.prototype.send=function(e){if(null===this.fetchFn)return this.logger.warn("fetch is not available in this environment; events cannot be sent"),Promise.resolve({ok:!1,retryable:!1,status:null});var t;try{t=this.serialize(e)}catch(e){return this.logger.warn("failed to serialize batch; dropping it",e),Promise.resolve({ok:!1,retryable:!1,status:null})}var n="undefined"!=typeof AbortController?new AbortController:null,r=null!==n?setTimeout(function(){n.abort()},3e4):null,i={"Content-Type":"application/json"};i["X-API-Key"]=this.apiKey;var o=this.logger;return this.fetchFn(this.endpoint,{method:"POST",headers:i,body:t,credentials:"omit",signal:null!==n?n.signal:void 0}).then(function(e){null!==r&&clearTimeout(r);var t,n,i=(t=e.status,{ok:n=t>=200&&t<=299,retryable:!n&&(t>=500||408===t||429===t),status:t});return i.ok||o.warn("endpoint responded with status "+e.status),i},function(e){return null!==r&&clearTimeout(r),o.warn("network error while sending events",e),{ok:!1,retryable:!0,status:null}})},e.prototype.serialize=function(e){var t=this.apiKey,n={events:e.map(function(e){return _e(e,"api_key",t)})};return JSON.stringify(n)},e}(),Ue=function(){function e(e,t,n){void 0===t&&(t=50),void 0===n&&(n="_et_queue"),this.logger=e,this.maxEvents=t,this.key=n}return e.prototype.append=function(e){if(0!==e.length){var t=f();if(null!==t){for(var n=this.read(t).concat(e.map(Ie)).slice(-this.maxEvents),r=!1;n.length>0;){if(this.write(t,n))return;r?n=n.slice(Math.ceil(n.length/2)):(n=n.map(Ve),r=!0)}this.logger.warn("localStorage is full; could not persist events")}else this.logger.warn("localStorage unavailable; dropping "+e.length+" undeliverable event(s)")}},e.prototype.takeAll=function(){var e=f();if(null===e)return[];var t=this.read(e);try{e.removeItem(this.key)}catch(e){this.logger.warn("failed to clear persisted queue",e)}return t},e.prototype.read=function(e){var t;try{t=e.getItem(this.key)}catch(e){return this.logger.warn("failed to read persisted queue",e),[]}if(null===t||0===t.length)return[];try{var n=JSON.parse(t);if("[object Array]"!==Object.prototype.toString.call(n))throw new Error("not an array");return n.filter(De)}catch(t){this.logger.warn("persisted queue was corrupt; discarding it",t);try{e.removeItem(this.key)}catch(e){}return[]}},e.prototype.write=function(e,t){try{return e.setItem(this.key,JSON.stringify(t)),!0}catch(e){return this.logger.warn("failed to write persisted queue ("+t.length+" event(s))",e),!1}},e}();function Ie(e){return _e(e,"api_key","")}function Ve(e){return _e(e,"screenshot",null)}function De(e){return null!==e&&"object"==typeof e&&"string"==typeof e.event_type&&"string"==typeof e.timestamp}var Be=[{name:"Edge",pattern:/Edg(?:e|A|iOS)?\/([\d.]+)/},{name:"Opera",pattern:/(?:OPR|Opera)\/([\d.]+)/},{name:"Samsung Internet",pattern:/SamsungBrowser\/([\d.]+)/},{name:"Firefox",pattern:/(?:Firefox|FxiOS)\/([\d.]+)/},{name:"Chrome",pattern:/(?:Chrome|CriOS)\/([\d.]+)/},{name:"Safari",pattern:/Version\/([\d.]+).*Safari/},{name:"Node.js",pattern:/Node\.js\/v?([\d.]+)/}],He={"10.0":"10",6.3:"8.1",6.2:"8",6.1:"7"};function ze(e){var t=e.split(".");return t.length>1?t[0]+"."+t[1]:t[0]+".0"}var We=function(){function e(){var e=c();this.parsed=function(e){for(var t,n={browser:null,browserVersion:null,os:null,osVersion:null,model:null},r=0;r<Be.length;r++){var i=Be[r].pattern.exec(e);if(null!==i){n.browser=Be[r].name,n.browserVersion=ze(i[1]);break}}if(null!==(t=/Windows NT ([\d.]+)/.exec(e))){var o=He[t[1]];n.os=void 0!==o?"Windows "+o:"Windows",n.osVersion=t[1]}else if(null!==(t=/Android ([\d.]+)/.exec(e))){n.os="Android "+t[1].split(".")[0],n.osVersion=t[1];var s=/Android [\d.]+; (?:[a-z]{2}-[a-z]{2}; )?([^;)]+?)(?: Build\/[^;)]*)?\)/i.exec(e);null!==s&&"K"!==s[1]&&(n.model=s[1].trim())}else if(null!==(t=/(?:iPhone|iPad|iPod).*? OS ([\d_]+)/.exec(e))){var l=t[1].replace(/_/g,".");n.os="iOS "+ze(l),n.osVersion=l;var a=/(iPhone|iPad|iPod)/.exec(e);n.model=null!==a?a[1]:null}else null!==(t=/Mac OS X ([\d_.]+)/.exec(e))?(l=t[1].replace(/_/g,"."),n.os="macOS "+ze(l),n.osVersion=l):/CrOS/.test(e)?n.os="ChromeOS":/Linux/.test(e)&&(n.os="Linux");return n}(null!==e&&"string"==typeof e.userAgent?e.userAgent:"")}return e.prototype.refine=function(){var e=c();if(null===e||void 0===e.userAgentData)return Promise.resolve();var t=this;return e.userAgentData.getHighEntropyValues(["platformVersion","model"]).then(function(e){if("Windows"===e.platform&&"string"==typeof e.platformVersion){var n=parseInt(e.platformVersion.split(".")[0],10);t.parsed.os=n>=13?"Windows 11":"Windows 10",t.parsed.osVersion=e.platformVersion}"string"==typeof e.model&&e.model.length>0&&(t.parsed.model=e.model)}).catch(function(){})},e.prototype.snapshot=function(){var e=a(),t=u(),n=c(),r=null!==e?e.screen:void 0;return{platform:"js",os:this.parsed.os,os_version:this.parsed.osVersion,manufacturer:null,model:this.parsed.model,browser:this.parsed.browser,browser_version:this.parsed.browserVersion,screen_width:void 0!==r?r.width:null,screen_height:void 0!==r?r.height:null,url:null!==e&&void 0!==e.location?g(e.location.href):null,referrer:null!==t&&t.referrer.length>0?g(t.referrer):null,locale:null!==n&&"string"==typeof n.language?n.language:null}},e}(),Ke=function(){return Date.now()},Xe=function(){function e(e,t,n){void 0===e&&(e=100),void 0===t&&(t=6e4),void 0===n&&(n=Ke),this.maxEvents=e,this.windowMs=t,this.clock=n,this.timestamps=[]}return e.prototype.tryAcquire=function(){for(var e=this.clock(),t=e-this.windowMs;this.timestamps.length>0&&this.timestamps[0]<=t;)this.timestamps.shift();return!(this.timestamps.length>=this.maxEvents)&&(this.timestamps.push(e),!0)},e}(),Je=function(){function e(e,t,n){void 0===e&&(e=5e3),void 0===t&&(t=200),void 0===n&&(n=Ke),this.windowMs=e,this.maxEntries=t,this.clock=n,this.seen={},this.order=[]}return e.prototype.isNew=function(e){var t=this.clock(),n=this.seen[e];if(void 0!==n&&t-n<this.windowMs)return!1;if(void 0===n&&(this.order.push(e),this.order.length>this.maxEntries)){var r=this.order.shift();void 0!==r&&delete this.seen[r]}return this.seen[e]=t,!0},e}();var $e=function(e,t){setTimeout(e,t)};var Ye=function(){function e(e){this.queue=[],this.flushTimer=null,this.inFlight=null,this.closed=!1,this.transport=e.transport,this.store=e.store,this.logger=e.logger,this.batchSize=void 0!==e.batchSize?e.batchSize:10,this.flushDelayMs=void 0!==e.flushDelayMs?e.flushDelayMs:2e3,this.retryDelaysMs=void 0!==e.retryDelaysMs?e.retryDelaysMs:t,this.schedule=e.schedule,this.online=void 0!==e.isOnline?e.isOnline:p}return Object.defineProperty(e.prototype,"size",{get:function(){return this.queue.length},enumerable:!1,configurable:!0}),e.prototype.enqueue=function(e){if(!this.closed){if(!this.online())return this.logger.info("offline; persisting event"),void this.store.append([e]);this.queue.push(e),this.queue.length>100&&(this.queue.splice(0,this.queue.length-100),this.logger.warn("queue full; dropped oldest events")),this.queue.length>=this.batchSize?this.flush():this.scheduleFlush()}},e.prototype.flush=function(){if(this.cancelTimer(),null!==this.inFlight){var e=this;return this.inFlight.then(function(){return e.queue.length>0?e.flush():void 0})}if(0===this.queue.length)return Promise.resolve();var t=this;return this.inFlight=this.drain().then(function(){t.inFlight=null}),this.inFlight},e.prototype.restoreFromStore=function(){if(this.closed||!this.online())return Promise.resolve();var e=this.store.takeAll();return 0===e.length?Promise.resolve():(this.logger.info("restoring "+e.length+" persisted event(s)"),this.queue=e.concat(this.queue).slice(-100),this.flush())},e.prototype.persistPending=function(){this.cancelTimer(),0!==this.queue.length&&(this.store.append(this.queue),this.queue=[])},e.prototype.close=function(){this.persistPending(),this.closed=!0},e.prototype.scheduleFlush=function(){if(null===this.flushTimer){var e=this;this.flushTimer=setTimeout(function(){e.flushTimer=null,e.flush()},this.flushDelayMs)}},e.prototype.cancelTimer=function(){null!==this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null)},e.prototype.drain=function(){if(0===this.queue.length)return Promise.resolve();if(!this.online())return this.persistPending(),Promise.resolve();var e,n,r,i=this.queue.splice(0,this.batchSize),o=this;return(e=function(){return o.transport.send(i)},n=this.retryDelaysMs,r=this.schedule,void 0===n&&(n=t),void 0===r&&(r=$e),new Promise(function(t){var i=0;!function o(){var s;i++;try{s=e()}catch(e){s=Promise.resolve({ok:!1,retryable:!0,status:null})}s.then(function(e){return e},function(){return{ok:!1,retryable:!0,status:null}}).then(function(e){var s=i-1;e.ok||!e.retryable||s>=n.length?t({ok:e.ok,retryable:e.retryable,status:e.status,attempts:i}):r(o,n[s])})}()})).then(function(e){return e.ok?(o.logger.info("sent "+i.length+" event(s)"),o.drain()):e.retryable?(o.logger.warn("delivery failed after "+e.attempts+" attempt(s); persisting for later"),o.store.append(i),void o.persistPending()):(o.logger.warn("endpoint rejected batch with status "+String(e.status)+"; dropping "+i.length+" event(s)"),o.drain())})},e}(),Ze=function(){function e(e,t){void 0===t&&(t={});var n=this;this.device=new We,this.user=null,this.rateLimitWarned=!1,this.droppedCount=0,this.droppedTimer=null,this.started=!1,this.pendingCaptures=[],this.config=e,this.logger=new k(e.debug),this.breadcrumbs=new Se(e.maxBreadcrumbs),this.random=t.random||Math.random,this.rateLimiter=t.rateLimiter||new Xe,this.deduplicator=t.deduplicator||new Je,this.queue=new Ye({transport:t.transport||new qe(e.endpoint,e.apiKey,this.logger),store:t.store||new Ue(this.logger),logger:this.logger,retryDelaysMs:t.queueRetryDelaysMs,flushDelayMs:t.queueFlushDelayMs}),this.network=new ke(e.endpoint,this.logger),this.performance=new xe(this,this.network,this.logger),this.memory=new ge(this,this.logger,t.readMemory),this.responsiveness=new Me(this,this.logger),this.screenshot=t.screenshot||new Ne({maskSelectors:e.maskSelectors,libraryUrl:e.html2canvasUrl,libraryIntegrity:e.html2canvasIntegrity},this.logger),this.collectors=[new ne(this,this.logger),new le(this,this.network,e.maskSelectors,this.logger,e.captureConsoleErrors),this.performance,this.memory,this.responsiveness,new he(this,this.logger,[e.html2canvasUrl]),new je(this,this.logger),new Fe(this,this.logger),new de(this,this.logger,function(e){return n.network.isSdkUrl(e)})],(e.captureHttpErrors||e.captureNetworkErrors)&&this.collectors.push(new pe(this,this.network,{httpErrors:e.captureHttpErrors,networkErrors:e.captureNetworkErrors})),this.collectors.push(this.network);var r=this;this.handleOnline=C(this.logger,"online handler",function(){r.queue.restoreFromStore()}),this.handleVisibility=C(this.logger,"visibility handler",function(){var e=u();null!==e&&("hidden"===e.visibilityState?r.queue.flush():r.queue.restoreFromStore())}),this.handlePageHide=C(this.logger,"pagehide handler",function(){r.queue.persistPending()})}return e.prototype.start=function(){if(!this.started){this.started=!0;for(var e=function(e){var n=t.collectors[e];R(t.logger,"install collector",function(){n.install()})},t=this,n=0;n<this.collectors.length;n++)e(n);var r=a(),i=u();null!==r&&(r.addEventListener("online",this.handleOnline),r.addEventListener("pagehide",this.handlePageHide)),null!==i&&i.addEventListener("visibilitychange",this.handleVisibility),this.device.refine(),this.queue.restoreFromStore(),this.logger.info("initialized",{environment:this.config.environment,sampleRate:this.config.sampleRate})}},e.prototype.close=function(){var e=this;return this.flush().then(function(){for(var t=function(t){var n=e.collectors[t];R(e.logger,"uninstall collector",function(){n.uninstall()})},n=0;n<e.collectors.length;n++)t(n);var r=a(),i=u();null!==r&&(r.removeEventListener("online",e.handleOnline),r.removeEventListener("pagehide",e.handlePageHide)),null!==i&&i.removeEventListener("visibilitychange",e.handleVisibility),null!==e.droppedTimer&&clearTimeout(e.droppedTimer),e.droppedTimer=null,e.queue.close(),e.started=!1})},e.prototype.flush=function(){var e=this,t=this.queue;return Promise.all(this.pendingCaptures.slice()).then(function(){return t.flush()}).then(null,function(){e.logger.warn("flush failed")})},e.prototype.captureError=function(e,t){var n=te(e,!0);this.capture({eventType:"error",level:"error",error:n.error,stacktrace:n.stacktrace,context:null!=t?A(t):null},!0)},e.prototype.captureMessage=function(e,t){this.capture({eventType:"message",level:t,error:{message:F(String(e),n),type:"Message",handled:!0},stacktrace:[],context:null},!1)},e.prototype.setUser=function(e){null!=e?"object"==typeof e&&void 0!==e.id&&null!==e.id?this.user={id:String(e.id),email:e.email,name:e.name}:this.logger.warn("setUser requires an object with an id; ignoring"):this.user=null},e.prototype.onError=function(e){this.capture({eventType:"error",level:"error",error:e.error,stacktrace:e.stacktrace,context:void 0!==e.context?e.context:null},!0)},e.prototype.onBreadcrumb=function(e){null!==e&&"object"==typeof e&&this.breadcrumbs.push({timestamp:m(),type:"string"==typeof e.type?e.type:"log",message:F(String(e.message),n),data:void 0!==e.data?A(e.data):{}})},e.prototype.onPerformanceIssue=function(e,t){this.capture({eventType:"performance",level:"warning",error:{message:t,type:e,handled:!0},stacktrace:[],context:null},!1)},e.prototype.onNavigation=function(){this.memory.resetBaseline()},e.prototype.capture=function(e,t){if(this.random()>this.config.sampleRate)this.logger.info("event dropped by sampleRate");else if(this.deduplicator.isNew((n=e.eventType,r=e.error,i=e.stacktrace,o=i.length>0?i[0]:null,[n,null!==r?r.type:"",null!==r?r.message:"",null!==o?String(o.filename)+":"+String(o.lineno)+":"+String(o.colno):""].join("|")))){var n,r,i,o;if(!this.rateLimiter.tryAcquire())return this.rateLimitWarned||this.logger.warn("rate limit reached; dropping events"),this.rateLimitWarned=!0,void this.recordDropped();this.rateLimitWarned=!1;var s=this.scope(),l=m(),a=this;if(t&&this.config.captureScreenshots){var u=this.screenshot.capture().then(function(t){s.screenshot=t,a.finish(Ee(e,s,l))},function(){a.finish(Ee(e,s,l))});this.pendingCaptures.push(u),u.then(function(){var e=a.pendingCaptures.indexOf(u);-1!==e&&a.pendingCaptures.splice(e,1)})}else this.finish(Ee(e,s,l))}else this.logger.info("duplicate event dropped")},e.prototype.recordDropped=function(){if(this.droppedCount++,null===this.droppedTimer){var e=this;this.droppedTimer=setTimeout(C(this.logger,"dropped events summary",function(){e.droppedTimer=null;var t=e.droppedCount;e.droppedCount=0,0!==t&&e.finish(Ee({eventType:"message",level:"warning",error:{message:"Rate limit dropped "+t+" event(s) during an error storm",type:"EventsDropped",handled:!0},stacktrace:[],context:{dropped_count:t}},e.scope(),m()))}),1e4)}},e.prototype.finish=function(e){var t=this;R(this.logger,"enqueue event",function(){var n=t.config.beforeSend,r=e;null!==n&&(r=T(t.logger,"beforeSend",function(){return n(e)},e)),null!=r?t.queue.enqueue(r):t.logger.info("event dropped by beforeSend")})},e.prototype.scope=function(){var e=this.performance.snapshot();return e.frame_rate_fps=this.responsiveness.frameRate(),{apiKey:this.config.apiKey,environment:this.config.environment,appVersion:this.config.appVersion,user:this.user,breadcrumbs:this.breadcrumbs.toArray(),performance:e,memory:this.memory.snapshot(),device:this.device.snapshot(),screenshot:null}},e}();function Ge(e,t,n){return Math.min(n,Math.max(t,e))}function Qe(e){if(null===e||"object"!=typeof e)return{ok:!1,reason:"config object is required"};if("string"!=typeof e.apiKey||0===e.apiKey.trim().length)return{ok:!1,reason:"apiKey must be a non-empty string"};if("string"!=typeof e.endpoint||!function(e){try{return new URL(e,"undefined"!=typeof document?document.baseURI:void 0),!0}catch(e){return!1}}(e.endpoint))return{ok:!1,reason:"endpoint must be a valid URL"};var t="number"!=typeof e.sampleRate||isNaN(e.sampleRate)?1:Ge(e.sampleRate,0,1),n="number"==typeof e.maxBreadcrumbs&&isFinite(e.maxBreadcrumbs)?Ge(Math.floor(e.maxBreadcrumbs),0,100):30,r="[object Array]"===Object.prototype.toString.call(e.maskSelectors)&&e.maskSelectors||[];return{ok:!0,config:{apiKey:e.apiKey,endpoint:e.endpoint,environment:"string"==typeof e.environment&&e.environment.length>0?e.environment:"production",appVersion:"string"==typeof e.appVersion&&e.appVersion.length>0?e.appVersion:null,sampleRate:t,maxBreadcrumbs:n,maskSelectors:l.concat(r.filter(function(e){return"string"==typeof e&&e.length>0})),debug:!0===e.debug,captureHttpErrors:!1!==e.captureHttpErrors,captureNetworkErrors:!1!==e.captureNetworkErrors,captureConsoleErrors:!0===e.captureConsoleErrors,captureScreenshots:!1!==e.captureScreenshots,html2canvasUrl:"string"==typeof e.html2canvasUrl&&e.html2canvasUrl.length>0?e.html2canvasUrl:"https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js",html2canvasIntegrity:"string"==typeof e.html2canvasIntegrity?e.html2canvasIntegrity:"string"==typeof e.html2canvasUrl&&e.html2canvasUrl.length>0?"":"sha384-ZZ1pncU3bQe8y31yfZdMFdSpttDoPmOZg2wguVK9almUodir1PghgT0eY7Mrty8H",beforeSend:"function"==typeof e.beforeSend?e.beforeSend:null}}}var et=null,tt=[];function nt(e,t){R(null!==et?et.logger:S,e,function(){null===et?tt.length>=100?S.warn(e+" called before init(); pre-init buffer full, dropping call"):tt.push(t):t(et)})}function rt(e){R(S,"init",function(){if(S.setEnabled(null!==e&&"object"==typeof e&&!0===e.debug),null===et){var t=Qe(e);if(t.ok){var n=new Ze(t.config);n.start(),et=n;var r=tt;tt=[];for(var i=function(e){var t=r[e];R(n.logger,"replay pre-init call",function(){t(n)})},o=0;o<r.length;o++)i(o)}else S.warn("invalid config: "+t.reason+"; SDK disabled")}else S.warn("init() called more than once; ignoring")})}function it(e,t){nt("captureError",function(n){n.captureError(e,t)})}function ot(e,t){void 0===t&&(t="info"),nt("captureMessage",function(n){n.captureMessage(e,t)})}function st(e){nt("setUser",function(t){t.setUser(e)})}function lt(e){nt("addBreadcrumb",function(t){t.onBreadcrumb(e)})}function at(){return T(S,"flush",function(){return null!==et?et.flush():Promise.resolve()},Promise.resolve())}function ut(){return T(S,"close",function(){var e=et;return et=null,tt=[],null!==e?e.close():Promise.resolve()},Promise.resolve())}function ct(){return null!==et}var ht={init:rt,captureError:it,captureMessage:ot,setUser:st,addBreadcrumb:lt,flush:at,close:ut,isInitialized:ct,version:e};exports.ErrorTracker=ht,exports.addBreadcrumb=lt,exports.captureError=it,exports.captureMessage=ot,exports.close=ut,exports.default=ht,exports.flush=at,exports.init=rt,exports.isInitialized=ct,exports.setUser=st;
2
+ //# sourceMappingURL=index.cjs.map