@cross-deck/web 1.3.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -1
- package/README.md +13 -1
- package/dist/crossdeck.umd.min.js +2 -2
- package/dist/crossdeck.umd.min.js.map +1 -1
- package/dist/error-codes.json +106 -1
- package/dist/index.cjs +483 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +483 -22
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +373 -22
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +373 -22
- package/dist/react.mjs.map +1 -1
- package/dist/{types-BzoKor4z.d.mts → types-Bu3jbmdq.d.mts} +4 -0
- package/dist/{types-BzoKor4z.d.ts → types-Bu3jbmdq.d.ts} +4 -0
- package/dist/vue.cjs +373 -22
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.mjs +373 -22
- package/dist/vue.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@cross-deck/web` will be documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
-
## [1.
|
|
5
|
+
## [1.4.2] — 2026-05-26
|
|
6
|
+
|
|
7
|
+
Patch — second npm publish pipeline fix. v1.4.1 fixed the Node 24
|
|
8
|
+
`navigator` test mutation, but the `prepublishOnly` hook still ran
|
|
9
|
+
the Playwright e2e suite at `npm publish` time even though the
|
|
10
|
+
publish workflow doesn't install Chromium. Removed `test:e2e` from
|
|
11
|
+
`prepublishOnly` — the publish workflow runs lint + unit tests +
|
|
12
|
+
build + size budget which covers everything except the
|
|
13
|
+
browser-bound e2e (which requires Playwright setup the publish
|
|
14
|
+
workflow doesn't provide; e2e still runs in monorepo CI). v1.4.2
|
|
15
|
+
is the first 1.4.x line to actually land on the npm registry.
|
|
16
|
+
**No SDK code changes vs v1.4.0 / v1.4.1**.
|
|
17
|
+
|
|
18
|
+
## [1.4.1] — 2026-05-26
|
|
19
|
+
|
|
20
|
+
Patch — Node 24 compatibility fix for the npm publish pipeline. The
|
|
21
|
+
`consent.test.ts` DNT cases mutated `globalThis.navigator` via direct
|
|
22
|
+
assignment; Node 24 (the public crossdeck-web repo's npm publish
|
|
23
|
+
workflow Node version) made navigator a read-only getter, so the
|
|
24
|
+
test threw `TypeError: Cannot set property navigator` and aborted
|
|
25
|
+
the publish. Pattern switched to `Object.defineProperty`. v1.4.0
|
|
26
|
+
was tagged on the public GitHub repo but never reached npm — v1.4.1
|
|
27
|
+
is the first 1.4.x line to land on the npm registry. **No SDK code
|
|
28
|
+
changes vs v1.4.0**; the entire bank-grade reconciliation surface
|
|
29
|
+
documented below ships unchanged.
|
|
30
|
+
|
|
31
|
+
## [1.4.0] — 2026-05-26
|
|
32
|
+
|
|
33
|
+
**Bank-grade reconciliation release.** 6-pillar KPMG-style audit closed across SDK + backend. Every behavioural guarantee registered in the monorepo's `contracts/` directory with a CI-enforced audit job — drift is now a PR-time error.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- **Deterministic `Idempotency-Key` on `syncPurchases()`.** Derived from the request body (SHA-256 of `crossdeck:purchases/sync:<rail>:<jws>`, formatted as UUID). Same purchase → same key → backend short-circuits with `idempotent_replay: true`. Cross-SDK parity oracle CI-pinned: every SDK produces `a66b1640-efaf-bb4d-1261-6650033bf111` for the canonical test vector.
|
|
38
|
+
- **Per-user entitlement cache isolation.** Storage key is now `crossdeck:entitlements:<sha256(userId)>` — a user-switch on a shared device cannot physically read prior user's cached entitlements even if the in-memory clear is somehow skipped. `reset()` wipes EVERY per-user slot via the persisted index. New pure-JS SHA-256 helper (no SubtleCrypto async cascade through hot-path reads).
|
|
39
|
+
- **`PurchaseResult.idempotent_replay?: boolean`** — true when the response came from the backend's idempotency cache instead of fresh processing.
|
|
40
|
+
- **`purchase.completed` event on every successful `syncPurchases()`** — schema matches the auto-track event so cross-platform funnels reconcile.
|
|
41
|
+
- **15 backend-emitted error codes** added to `crossdeck-error-codes.json` catalogue (`invalid_api_key`, `origin_not_allowed`, `bundle_id_not_allowed`, `package_name_not_allowed`, `env_mismatch`, `idempotency_key_in_use`, `rate_limited`, `internal_error`, `google_not_supported`, `stripe_not_supported`, etc.) — `getErrorCode()` now returns Stripe-style remediation for every wire code instead of `undefined`.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- **`init()` re-entry now drains the prior `EventQueue`'s pending timer** before swapping `this.state`. Pre-1.4.0 the timer fired AFTER the state swap, sending old-init events under new-init identity — cross-identity leak during HMR / config swap / multi-tenant SDK shells.
|
|
46
|
+
- **Default event-queue flush interval is now 2000ms** (was 1500ms) — parity with every other Crossdeck SDK on the Stripe-adjacent industry norm.
|
|
47
|
+
- **`reset()` now wipes every per-user entitlement slot on the device** via the persisted index, not just the active user's slot.
|
|
6
48
|
|
|
7
49
|
Patch fix for the 1.3.0 dist-load contract. 1.3.0 introduced
|
|
8
50
|
`import { version } from "../package.json"` to keep the runtime
|
package/README.md
CHANGED
|
@@ -163,6 +163,18 @@ Link the anonymous device to a developer-supplied user ID. Persists the resolved
|
|
|
163
163
|
|
|
164
164
|
If `mergePending: true`, both identifiers already pointed at different customers. Crossdeck **never silently merges** — your dashboard's operations queue surfaces the merge for human confirmation.
|
|
165
165
|
|
|
166
|
+
**Entitlement-cache isolation (v1.4.0).** Every `identify(userId)` switches the local entitlement cache to a per-user storage slot — `localStorage["crossdeck:entitlements:<sha256(userId)>"]` — and unconditionally wipes the in-memory snapshot. A user-switch on a shared device CANNOT cross-read a prior user's cached entitlements, even if the in-memory clear is somehow skipped, because the storage keys are physically separate. `reset()` then wipes every per-user slot on the device (logout-grade).
|
|
167
|
+
|
|
168
|
+
**Idempotency-Key (v1.4.0).** Every `syncPurchases()` derives a
|
|
169
|
+
deterministic `Idempotency-Key` from the request body — same
|
|
170
|
+
signed transaction in produces the same key out. The backend
|
|
171
|
+
short-circuits repeats with `idempotent_replay: true` in the
|
|
172
|
+
response, so a network blip / app crash mid-flight that re-fires
|
|
173
|
+
the same purchase doesn't double-process. The key is a UUID-shaped
|
|
174
|
+
SHA-256 digest of `crossdeck:purchases/sync:<rail>:<jws|token>`,
|
|
175
|
+
so two SDKs reporting the same Apple transaction land on the same
|
|
176
|
+
key.
|
|
177
|
+
|
|
166
178
|
### `await Crossdeck.getEntitlements()`
|
|
167
179
|
|
|
168
180
|
Fetch the current customer's active entitlements. Returns an array of `PublicEntitlement` and updates the local cache.
|
|
@@ -215,7 +227,7 @@ Manually send a heartbeat. Called automatically by `init()` unless `autoHeartbea
|
|
|
215
227
|
|
|
216
228
|
### `Crossdeck.reset()`
|
|
217
229
|
|
|
218
|
-
Wipe persisted identity + entitlement cache + queued events. Call on logout. The next session generates a fresh `anonymousId` and starts a clean identity-graph entry.
|
|
230
|
+
Wipe persisted identity + EVERY per-user entitlement cache slot on this device + queued events. Call on logout. The next session generates a fresh `anonymousId` and starts a clean identity-graph entry. The per-user scope of the cache wipe (introduced v1.4.0) means a shared-device logout cannot leave a separate user's entitlements readable from `localStorage`.
|
|
219
231
|
|
|
220
232
|
### `Crossdeck.flush()`
|
|
221
233
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var Crossdeck=(()=>{var re=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Re=Object.getOwnPropertyNames;var Ae=Object.prototype.hasOwnProperty;var Pe=(r,e)=>{for(var t in e)re(r,t,{get:e[t],enumerable:!0})},De=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Re(e))!Ae.call(r,s)&&s!==t&&re(r,s,{get:()=>e[s],enumerable:!(n=Ie(e,s))||n.enumerable});return r};var Fe=r=>De(re({},"__esModule",{value:!0}),r);var vt={};Pe(vt,{CROSSDECK_ERROR_CODES:()=>he,Crossdeck:()=>Ce,CrossdeckClient:()=>M,CrossdeckError:()=>b,DEFAULT_BASE_URL:()=>N,MemoryStorage:()=>_,SDK_NAME:()=>C,SDK_VERSION:()=>A,getErrorCode:()=>xe});var b=class r extends Error{constructor(e){super(e.message),this.name="CrossdeckError",this.type=e.type,this.code=e.code,this.requestId=e.requestId,this.status=e.status,this.retryAfterMs=e.retryAfterMs,Object.setPrototypeOf(this,r.prototype)}};async function ge(r){let e=r.headers.get("x-request-id")??void 0,t=Le(r.headers.get("retry-after")),n;try{n=await r.json()}catch{n=null}let s=n?.error;return s&&typeof s.type=="string"&&typeof s.code=="string"?new b({type:s.type,code:s.code,message:s.message??`HTTP ${r.status}`,requestId:s.request_id??e,status:r.status,retryAfterMs:t}):new b({type:Oe(r.status),code:`http_${r.status}`,message:`HTTP ${r.status} ${r.statusText||""}`.trim(),requestId:e,status:r.status,retryAfterMs:t})}function Le(r){if(!r)return;let e=r.trim();if(!e)return;if(/^\d+(\.\d+)?$/.test(e)){let s=Number(e);return!Number.isFinite(s)||s<0?void 0:Math.round(s*1e3)}if(!/[a-zA-Z,/:]/.test(e))return;let t=Date.parse(e);if(!Number.isFinite(t))return;let n=t-Date.now();return n>0?n:0}function Oe(r){return r===401?"authentication_error":r===403?"permission_error":r===429?"rate_limit_error":r>=400&&r<500?"invalid_request_error":"internal_error"}var A="1.3.0",C="@cross-deck/web";var N="https://api.cross-deck.com/v1",Me=15e3,B=class{constructor(e){this.config=e}async request(e,t,n={}){if(this.config.localDevMode)return Ue(t);let s=this.buildUrl(t,n.query),i={Authorization:`Bearer ${this.config.publicKey}`,"Crossdeck-Sdk-Version":`${C}@${this.config.sdkVersion}`,Accept:"application/json"};n.idempotencyKey&&(i["Idempotency-Key"]=n.idempotencyKey);let c;n.body!==void 0&&(i["Content-Type"]="application/json",c=JSON.stringify(n.body));let o=n.timeoutMs??this.config.timeoutMs??Me,a=typeof AbortController<"u"&&o>0?new AbortController:null,d=null;a&&o>0&&(d=setTimeout(()=>a.abort(),o));let u;try{u=await fetch(s,{method:e,headers:i,body:c,keepalive:n.keepalive===!0,signal:a?.signal})}catch(l){let p=a?.signal?.aborted===!0;throw new b({type:"network_error",code:p?"request_timeout":"fetch_failed",message:p?`Request to ${t} aborted after ${o}ms`:l instanceof Error?l.message:"fetch failed"})}finally{d!==null&&clearTimeout(d)}if(!u.ok)throw await ge(u);if(u.status!==204)try{return await u.json()}catch{throw new b({type:"internal_error",code:"invalid_json_response",message:"Server returned a 2xx with an unparseable body.",requestId:u.headers.get("x-request-id")??void 0,status:u.status})}}get isLocalDevMode(){return this.config.localDevMode===!0}buildUrl(e,t){let n=this.config.baseUrl.replace(/\/+$/,""),s=e.startsWith("/")?e:`/${e}`,i=n+s;if(t){let c=new URLSearchParams;for(let[a,d]of Object.entries(t))typeof d=="string"&&d.length>0&&c.append(a,d);let o=c.toString();o&&(i+=(i.includes("?")?"&":"?")+o)}return i}},$=null;function Ue(r){return r.startsWith("/sdk/heartbeat")?{object:"heartbeat",ok:!0,projectId:"proj_local_dev",appId:"app_local_dev",platform:"web",env:"sandbox",serverTime:Date.now()}:r.startsWith("/identity/alias")?($||($=`cdcust_local_${typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID().replace(/-/g,"").slice(0,16):Math.random().toString(36).slice(2,18)}`),{object:"alias_result",crossdeckCustomerId:$,linked:[],mergePending:!1,env:"sandbox"}):r.startsWith("/entitlements")?{object:"list",data:[],crossdeckCustomerId:$??"",env:"sandbox"}:r.startsWith("/events")?{object:"list",received:0,env:"sandbox"}:{}}var P="anon_id",D="cdcust_id",j=class{constructor(e,t,n){this.primary=e;this.prefix=t;this.secondary=n??null;let s=e.getItem(t+P),i=e.getItem(t+D),c=this.secondary?.getItem(t+P)??null,o=this.secondary?.getItem(t+D)??null,a=s??c,d=i??o;this.state={anonymousId:a??this.mintAnonymousId(),crossdeckCustomerId:d},(!s||!c)&&this.writeBoth(t+P,this.state.anonymousId),d&&(!i||!o)&&this.writeBoth(t+D,d)}get anonymousId(){return this.state.anonymousId}get crossdeckCustomerId(){return this.state.crossdeckCustomerId}setCrossdeckCustomerId(e){this.state.crossdeckCustomerId=e,this.writeBoth(this.prefix+D,e)}reset(){this.deleteBoth(this.prefix+P),this.deleteBoth(this.prefix+D),this.state={anonymousId:this.mintAnonymousId(),crossdeckCustomerId:null},this.writeBoth(this.prefix+P,this.state.anonymousId)}mintAnonymousId(){let e=Date.now().toString(36),t=w(10);return`anon_${e}${t}`}writeBoth(e,t){try{this.primary.setItem(e,t)}catch{}if(this.secondary)try{this.secondary.setItem(e,t)}catch{}}deleteBoth(e){try{this.primary.removeItem(e)}catch{}if(this.secondary)try{this.secondary.removeItem(e)}catch{}}};function w(r){let e="0123456789abcdefghijklmnopqrstuvwxyz",t=[],n=globalThis.crypto;if(n?.getRandomValues){let s=new Uint8Array(r);n.getRandomValues(s);for(let i=0;i<r;i++)t.push(e[s[i]%e.length]??"0")}else for(let s=0;s<r;s++)t.push(e[Math.floor(Math.random()*e.length)]??"0");return t.join("")}var H=class{constructor(e,t="crossdeck:entitlements",n=864e5){this.all=[];this.lastUpdated=0;this.lastRefreshFailedAt=0;this.listeners=new Set;this.listenerErrorCount=0;this.storage=e,this.storageKey=t,this.staleAfterMs=n,this.hydrate()}isEntitled(e){let t=Date.now()/1e3;return this.all.some(n=>n.key===e&&n.isActive&&(n.validUntil==null||n.validUntil>t))}list(){return this.all.slice()}get freshness(){return this.lastUpdated}get isStale(){return this.lastRefreshFailedAt>this.lastUpdated?!0:this.lastUpdated>0&&Date.now()-this.lastUpdated>this.staleAfterMs}get refreshFailedAt(){return this.lastRefreshFailedAt}get listenerErrors(){return this.listenerErrorCount}markRefreshFailed(){this.lastRefreshFailedAt=Date.now()}setFromList(e){this.all=e.slice(),this.lastUpdated=Date.now(),this.lastRefreshFailedAt=0,this.persist(),this.notify()}clear(){if(this.all=[],this.lastUpdated=0,this.lastRefreshFailedAt=0,this.storage)try{this.storage.removeItem(this.storageKey)}catch{}this.notify()}subscribe(e){this.listeners.add(e);let t=!1;return()=>{t||(t=!0,this.listeners.delete(e))}}hydrate(){if(this.storage)try{let e=this.storage.getItem(this.storageKey);if(!e)return;let t=JSON.parse(e);t&&t.v===1&&Array.isArray(t.entitlements)&&(this.all=t.entitlements,this.lastUpdated=typeof t.lastUpdated=="number"?t.lastUpdated:0)}catch{}}persist(){if(this.storage)try{let e={v:1,entitlements:this.all,lastUpdated:this.lastUpdated};this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}notify(){if(this.listeners.size===0)return;let e=this.all.slice(),t=[...this.listeners];for(let n of t)try{n(e)}catch{this.listenerErrorCount+=1}}};function Ve(r,e,t={},n=Math.random){let s=t.baseMs??1e3,i=t.maxMs??6e4,c=t.factor??2,o=Math.min(r,30),d=Math.min(i,s*Math.pow(c,o))*n();if(e!==void 0){let l=Math.min(864e5,e);if(l>d)return l}return Math.max(0,Math.round(d))}var K=class{constructor(e={}){this.options=e;this.attempts=0}get consecutiveFailures(){return this.attempts}get isWarning(){return this.attempts>=(this.options.failuresBeforeWarn??8)}nextDelay(e,t=Math.random){let n=Ve(this.attempts,e,this.options,t);return this.attempts+=1,n}recordSuccess(){this.attempts=0}};var F=1e3,W=class{constructor(e){this.cfg=e;this.buffer=[];this.pendingBatch=null;this.pendingBatchId=null;this.dropped=0;this.inFlight=0;this.lastFlushAt=0;this.lastError=null;this.cancelTimer=null;this.firstFlushFired=!1;this.nextRetryAt=null;if(this.retry=new K(e.retry??{}),this.persistent=e.persistentStore??null,this.persistent){let t=this.persistent.load();t.length>0&&(t.length>F?(this.dropped+=t.length-F,this.buffer=t.slice(t.length-F)):this.buffer=t,this.cfg.onBufferChange?.(this.buffer.length),this.scheduleIdleFlush())}}enqueue(e){if(this.buffer.push(e),this.buffer.length>F){let t=this.buffer.length-F;this.buffer.splice(0,t),this.dropped+=t,this.cfg.onDrop?.(t)}this.cfg.onBufferChange?.(this.buffer.length),this.persistAll(),this.buffer.length>=this.cfg.batchSize?this.flush():this.scheduleIdleFlush()}async flush(e={}){let t,n;if(this.pendingBatch!==null&&this.pendingBatchId!==null)t=this.pendingBatch,n=this.pendingBatchId;else{if(this.buffer.length===0)return null;t=this.buffer.splice(0),n=this.mintBatchId(),this.pendingBatch=t,this.pendingBatchId=n,this.inFlight+=t.length,this.cfg.onBufferChange?.(this.buffer.length),this.persistAll()}this.cancelTimerIfSet(),this.nextRetryAt=null;try{let s=this.cfg.envelope(),i=await this.cfg.http.request("POST","/events",{body:{appId:s.appId,environment:s.environment,sdk:s.sdk,events:t},keepalive:e.keepalive===!0,idempotencyKey:n});return this.lastFlushAt=Date.now(),this.lastError=null,this.inFlight-=t.length,this.pendingBatch=null,this.pendingBatchId=null,this.retry.recordSuccess(),this.persistAll(),this.firstFlushFired||(this.firstFlushFired=!0,this.cfg.onFirstFlushSuccess?.()),i}catch(s){let i=s instanceof Error?s.message:String(s);if(this.lastError=i,$e(s)){let a=t.length;return this.pendingBatch=null,this.pendingBatchId=null,this.inFlight-=a,this.dropped+=a,this.persistAll(),this.cfg.onDrop?.(a),this.cfg.onPermanentFailure?.({status:s.status??0,droppedCount:a,lastError:i}),null}let c=qe(s),o=this.retry.nextDelay(c);return this.scheduleRetry(o),this.cfg.onRetryScheduled?.({delayMs:o,consecutiveFailures:this.retry.consecutiveFailures,retryAfterMs:c,lastError:i}),null}}reset(){this.cancelTimerIfSet(),this.nextRetryAt=null,this.buffer=[],this.pendingBatch=null,this.pendingBatchId=null,this.dropped=0,this.inFlight=0,this.lastError=null,this.retry.recordSuccess(),this.persistent?.clear(),this.cfg.onBufferChange?.(0)}getStats(){return{buffered:this.buffer.length,dropped:this.dropped,inFlight:this.inFlight,lastFlushAt:this.lastFlushAt,lastError:this.lastError,consecutiveFailures:this.retry.consecutiveFailures,nextRetryAt:this.nextRetryAt}}get pendingIdempotencyKey(){return this.pendingBatchId}persistAll(){if(this.persistent){if(this.pendingBatch===null){this.persistent.save(this.buffer);return}this.persistent.save([...this.pendingBatch,...this.buffer])}}scheduleIdleFlush(){this.cancelTimerIfSet();let e=this.cfg.scheduler??me;this.cancelTimer=e(()=>{this.flush()},this.cfg.intervalMs)}scheduleRetry(e){this.cancelTimerIfSet(),this.nextRetryAt=Date.now()+e;let t=this.cfg.scheduler??me;this.cancelTimer=t(()=>{this.flush()},e)}cancelTimerIfSet(){this.cancelTimer&&(this.cancelTimer(),this.cancelTimer=null)}mintBatchId(){return`batch_${Date.now().toString(36)}${w(10)}`}};function qe(r){if(r&&typeof r=="object"&&"retryAfterMs"in r){let e=r.retryAfterMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}}function $e(r){if(!r||typeof r!="object")return!1;let e=r.status;return!(typeof e!="number"||!Number.isFinite(e)||e<400||e>=500||e===408||e===429)}function me(r,e){let t=setTimeout(r,e);if(typeof t.unref=="function")try{t.unref()}catch{}return()=>clearTimeout(t)}var z=class{constructor(e){this.options=e;this.writeScheduled=!1;this.pendingSnapshot=null;this.key=`${e.prefix}queue.v1`}load(){let e;try{e=this.options.storage.getItem(this.key)}catch{return[]}if(!e)return[];try{let t=JSON.parse(e);return!t||t.version!==1||!Array.isArray(t.events)?[]:t.events}catch{return[]}}save(e){this.pendingSnapshot=e.slice(),!this.writeScheduled&&(this.writeScheduled=!0,queueMicrotask(()=>this.flushWrite()))}saveSync(e){this.pendingSnapshot=e.slice(),this.flushWrite()}clear(){this.pendingSnapshot=null,this.writeScheduled=!1;try{this.options.storage.removeItem(this.key)}catch{}}flushWrite(){this.writeScheduled=!1;let e=this.pendingSnapshot;if(this.pendingSnapshot=null,e===null)return;if(e.length===0){try{this.options.storage.removeItem(this.key)}catch{}return}let t={version:1,events:e};try{this.options.storage.setItem(this.key,JSON.stringify(t))}catch{}}};var _=class{constructor(){this.store=new Map}getItem(e){return this.store.get(e)??null}setItem(e,t){this.store.set(e,t)}removeItem(e){this.store.delete(e)}},X=class{constructor(e){this.maxAgeSec=e?.maxAgeSec??63072e3,this.secure=e?.secure??Be(),this.sameSite=e?.sameSite??"Lax"}getItem(e){if(!ne())return null;let t=globalThis.document,n=t.cookie?t.cookie.split(/;\s*/):[],s=encodeURIComponent(e)+"=";for(let i of n)if(i.startsWith(s))try{return decodeURIComponent(i.slice(s.length))}catch{return null}return null}setItem(e,t){if(!ne())return;let n=globalThis.document,s=[`${encodeURIComponent(e)}=${encodeURIComponent(t)}`,"Path=/",`Max-Age=${this.maxAgeSec}`,`SameSite=${this.sameSite}`];this.secure&&s.push("Secure");try{n.cookie=s.join("; ")}catch{}}removeItem(e){if(!ne())return;let t=globalThis.document,n=[`${encodeURIComponent(e)}=`,"Path=/","Max-Age=0",`SameSite=${this.sameSite}`];this.secure&&n.push("Secure");try{t.cookie=n.join("; ")}catch{}}};function ye(){try{let r=globalThis.localStorage;if(r){let e="__crossdeck_probe__";return r.setItem(e,"1"),r.removeItem(e),r}}catch{}return new _}function Be(){try{return globalThis.location?.protocol==="https:"}catch{return!1}}function ne(){return typeof globalThis.document<"u"}function Ne(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"&&typeof globalThis.navigator<"u"}function be(r){let e={};if(r?.appVersion&&(e.appVersion=r.appVersion),!Ne())return e;let t=globalThis.window,n=globalThis.navigator,s=globalThis.document;try{typeof n.language=="string"&&(e.locale=n.language)}catch{}try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}try{t.screen&&(e.screenWidth=t.screen.width,e.screenHeight=t.screen.height),e.viewportWidth=t.innerWidth,e.viewportHeight=t.innerHeight,e.devicePixelRatio=t.devicePixelRatio}catch{}try{let i=n.userAgent??"",c=je(i);Object.assign(e,c)}catch{}try{let i=n.userAgentData;if(i?.platform&&!e.os&&(e.os=i.platform),i?.brands&&!e.browser){let c=i.brands.find(o=>!/Not[ .;A]*Brand/i.test(o.brand)&&!/Chromium/i.test(o.brand));c&&(e.browser=c.brand,e.browserVersion=c.version)}}catch{}return e}function je(r){let e={};if(/iPad|iPhone|iPod/.test(r)){e.os="iOS";let t=r.match(/OS (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else if(/Android/.test(r)){e.os="Android";let t=r.match(/Android (\d+(?:\.\d+)*)/);t?.[1]&&(e.osVersion=t[1])}else if(/Windows/.test(r)){e.os="Windows";let t=r.match(/Windows NT (\d+\.\d+)/);t?.[1]&&(e.osVersion=t[1])}else if(/Mac OS X|Macintosh/.test(r)){e.os="macOS";let t=r.match(/Mac OS X (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else/Linux/.test(r)&&(e.os="Linux");return/Edg\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Edge",e.browserVersion=r.match(/Edg\/(\d+(?:\.\d+)*)/)?.[1]):/Firefox\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Firefox",e.browserVersion=r.match(/Firefox\/(\d+(?:\.\d+)*)/)?.[1]):/OPR\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Opera",e.browserVersion=r.match(/OPR\/(\d+(?:\.\d+)*)/)?.[1]):/Chrome\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Chrome",e.browserVersion=r.match(/Chrome\/(\d+(?:\.\d+)*)/)?.[1]):/Version\/(\d+(?:\.\d+)*).*Safari/.test(r)&&(e.browser="Safari",e.browserVersion=r.match(/Version\/(\d+(?:\.\d+)*)/)?.[1]),e}var E={sessions:!0,pageViews:!0,deviceInfo:!0,clicks:!0,webVitals:!0,errors:!0},He=1800*1e3,se={utm_source:"",utm_medium:"",utm_campaign:"",utm_content:"",utm_term:"",referrer:"",gclid:"",fbclid:"",msclkid:"",ttclid:"",li_fat_id:"",twclid:""},L=class{constructor(e,t){this.cfg=e;this.track=t;this.session=null;this.cleanups=[];this.pageviewId=null}install(){ve()&&(this.cfg.sessions&&this.installSessionTracking(),this.cfg.pageViews&&this.installPageViewTracking(),this.cfg.clicks&&this.installClickTracking())}uninstall(){for(;this.cleanups.length;){let e=this.cleanups.pop();try{e?.()}catch{}}this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.session=null}resetSession(){this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.pageviewId=null,this.session=this.startNewSession(),this.emitSessionStart()}get currentSessionId(){return this.session?.sessionId??null}get currentPageviewId(){return this.pageviewId}get currentAcquisition(){return this.session?.acquisition??se}installSessionTracking(){this.session=this.startNewSession(),this.emitSessionStart();let e=()=>{if(!this.session)return;let i=globalThis.document;i.visibilityState==="hidden"?this.session.hiddenAt=Date.now():i.visibilityState==="visible"&&((this.session.hiddenAt?Date.now()-this.session.hiddenAt:0)>=He?(this.emitSessionEnd(),this.pageviewId=null,this.session=this.startNewSession(),this.emitSessionStart()):this.session.hiddenAt=null)},t=()=>this.emitSessionEnd(),n=globalThis.window,s=globalThis.document;s.addEventListener("visibilitychange",e),n.addEventListener("pagehide",t),n.addEventListener("beforeunload",t),this.cleanups.push(()=>{s.removeEventListener("visibilitychange",e),n.removeEventListener("pagehide",t),n.removeEventListener("beforeunload",t)})}startNewSession(){return{sessionId:Ze(),startedAt:Date.now(),hiddenAt:null,endedSent:!1,acquisition:et()}}emitSessionStart(){this.session&&this.track("session.started",{sessionId:this.session.sessionId})}emitSessionEnd(){if(!this.session||this.session.endedSent)return;let e=Date.now()-this.session.startedAt;this.track("session.ended",{sessionId:this.session.sessionId,durationMs:e}),this.session.endedSent=!0}installPageViewTracking(){let e=globalThis.window,t=globalThis.document,n=0,s="",i=250,c=(p=!1)=>{let h=e.location,f=h.href,m=Date.now();!p&&f===s&&m-n<i||(n=m,s=f,this.pageviewId=`pv_${Date.now().toString(36)}${w(10)}`,this.track("page.viewed",{pageviewId:this.pageviewId,path:h.pathname,url:f,search:h.search||void 0,hash:h.hash||void 0,title:t.title,referrer:t.referrer||void 0}))};c();let o=e.history.pushState,a=e.history.replaceState;function d(p,h,f){o.apply(this,[p,h,f]),queueMicrotask(c)}function u(p,h,f){a.apply(this,[p,h,f]),queueMicrotask(c)}e.history.pushState=d,e.history.replaceState=u;let l=()=>c(!0);e.addEventListener("popstate",l),this.cleanups.push(()=>{e.history.pushState===d&&(e.history.pushState=o),e.history.replaceState===u&&(e.history.replaceState=a),e.removeEventListener("popstate",l)})}installClickTracking(){let e=globalThis.window,t=globalThis.document,n=0,s=null,i=100,c=64,o=a=>{let d=a.target;if(!d||!(d instanceof Element))return;let u=Date.now();if(d===s&&u-n<i)return;n=u,s=d;let p=Ke(d)||d;if(We(p)||ze(p)||Xe(p))return;let h=p.tagName.toLowerCase(),f=Ge(Qe(p),c),m=p.href||void 0,g=p.target||void 0,v=p.id||void 0,S=p.getAttribute("role")||void 0,U=p.getAttribute("aria-label")||void 0,V=Je(p),y=Ye(p),k=h==="a"&&!!m,R=p.getAttribute("data-cd-event"),T={selector:V,tag:h,text:f,elementId:v,role:S,ariaLabel:U,href:m,isLink:k,linkTarget:g,viewportX:a.clientX,viewportY:a.clientY,pageX:a.pageX,pageY:a.pageY,...y};for(let q of Object.keys(T))(T[q]===void 0||T[q]===null||T[q]==="")&&delete T[q];this.track(R||"element.clicked",T)};t.addEventListener("click",o,{capture:!0,passive:!0}),this.cleanups.push(()=>{t.removeEventListener("click",o,{capture:!0})})}};function Ke(r){return r.closest("[data-cd-event]")||r.closest("[data-cd-noTrack]")||r.closest("button, a, [role='button'], [role='link'], input[type='button'], input[type='submit']")||null}function We(r){if(!(r instanceof HTMLElement))return!1;let e=r.tagName.toLowerCase();if(e==="textarea"||e==="select")return!0;if(e==="input"){let t=(r.type||"").toLowerCase();return t!=="button"&&t!=="submit"&&t!=="image"&&t!=="reset"}return!1}function ze(r){return!!r.closest("[data-cd-noTrack], [data-cd-no-track], .cd-noTrack, .cd-no-track")}function Xe(r){return!!r.closest('input[type="password"]')}function Qe(r){let e=d=>d.replace(/\s+/g," ").trim(),t=r.getAttribute("data-cd-track")||r.getAttribute("data-track")||r.getAttribute("data-testid");if(t){let d=e(t);if(d)return d}let n=r.getAttribute("aria-label");if(n){let d=e(n);if(d)return d}let s=r.getAttribute("aria-labelledby");if(s&&typeof r.ownerDocument?.getElementById=="function"){let d=[];for(let u of s.split(/\s+/)){let l=r.ownerDocument.getElementById(u),p=l?.textContent?e(l.textContent):"";p&&d.push(p)}if(d.length>0)return d.join(" ")}if(r instanceof HTMLInputElement&&r.value){let d=e(r.value);if(d)return d}let i=e(r.textContent||"");if(i)return i;let c=r.getAttribute("title");if(c){let d=e(c);if(d)return d}let o=r.querySelector("img[alt]");if(o){let d=o.getAttribute("alt")??"",u=e(d);if(u)return u}let a=r.querySelector("svg title");if(a?.textContent){let d=e(a.textContent);if(d)return d}return""}function Ge(r,e){return r.length<=e?r:r.slice(0,e-1)+"\u2026"}function Je(r){let e=[],t=r,n=0;for(;t&&t.nodeName.toLowerCase()!=="body"&&n<5;){let s=t.nodeName.toLowerCase();if(t.id){e.unshift(`${s}#${t.id}`);break}if(t.classList.length>0){let i=Array.from(t.classList).filter(c=>!c.startsWith("cd-")).slice(0,2).join(".");i&&(s+=`.${i}`)}e.unshift(s),t=t.parentElement,n++}return e.join(" > ")}function Ye(r){let e={};if(!(r instanceof HTMLElement))return e;for(let t of r.getAttributeNames()){if(!t.startsWith("data-")||t==="data-cd-noTrack"||t==="data-cd-no-track"||t==="data-cd-event")continue;let n=r.getAttribute(t)||"",s=t.replace(/^data-cd-prop-/,"").replace(/^data-/,"");e[s]=n}return e}function ve(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"}function Ze(){return`sess_${Date.now().toString(36)}${w(10)}`}function et(){if(!ve())return{...se};let r={...se};try{let e=globalThis.window,t=new URLSearchParams(e.location.search??"");r.utm_source=t.get("utm_source")??"",r.utm_medium=t.get("utm_medium")??"",r.utm_campaign=t.get("utm_campaign")??"",r.utm_content=t.get("utm_content")??"",r.utm_term=t.get("utm_term")??"",r.gclid=t.get("gclid")??"",r.fbclid=t.get("fbclid")??"",r.msclkid=t.get("msclkid")??"",r.ttclid=t.get("ttclid")??"",r.li_fat_id=t.get("li_fat_id")??"",r.twclid=t.get("twclid")??""}catch{}try{let e=globalThis.document;typeof e.referrer=="string"&&(r.referrer=e.referrer)}catch{}return r}var tt=[/^email$/i,/^password$/i,/^token$/i,/^secret$/i,/^card$/i,/^phone$/i,/password/i,/credit_?card/i];function ke(r){if(!r)return[];let e=[];for(let t of Object.keys(r))tt.some(n=>n.test(t))&&e.push(t);return e}var Q=class{constructor(){this.enabled=!1;this.seen=new Set}emit(e,t,n){if(!this.enabled)return;if(rt.has(e)){if(this.seen.has(e))return;this.seen.add(e)}let s=n?` ${nt(n)}`:"";console.info(`[crossdeck:${e}] ${t}${s}`)}},rt=new Set(["sdk.configured","sdk.first_event_sent","sdk.environment_mismatch"]);function nt(r){try{return JSON.stringify(r)}catch{return"[unserialisable context]"}}function O(r,e={}){let t=[];if(!r)return{properties:{},warnings:t};let n=e.maxStringLength??1024,s=e.maxBatchPropertyBytes??8192,i=e.maxDepth??5,c=new Set,o=(u,l,p)=>{if(p>i)return t.push({kind:"depth_exceeded",key:l}),{keep:!0,value:"[depth-exceeded]"};if(u===null)return{keep:!0,value:null};let h=typeof u;if(h==="string"){let f=u;return f.length>n?(t.push({kind:"truncated_string",key:l}),{keep:!0,value:f.slice(0,n-1)+"\u2026"}):{keep:!0,value:f}}if(h==="number")return Number.isFinite(u)?{keep:!0,value:u}:(t.push({kind:"non_serialisable",key:l}),{keep:!0,value:null});if(h==="boolean")return{keep:!0,value:u};if(h==="bigint")return t.push({kind:"coerced_bigint",key:l}),{keep:!0,value:u.toString()};if(h==="function")return t.push({kind:"dropped_function",key:l}),{keep:!1,value:void 0};if(h==="symbol")return t.push({kind:"dropped_symbol",key:l}),{keep:!1,value:void 0};if(h==="undefined")return t.push({kind:"dropped_undefined",key:l}),{keep:!1,value:void 0};if(u instanceof Date)return t.push({kind:"coerced_date",key:l}),{keep:!0,value:Number.isFinite(u.getTime())?u.toISOString():null};if(u instanceof Error)return t.push({kind:"coerced_error",key:l}),{keep:!0,value:{name:u.name,message:u.message,stack:typeof u.stack=="string"?u.stack.slice(0,n):void 0}};if(u instanceof Map){t.push({kind:"coerced_map",key:l});let f={};for(let[m,g]of u.entries()){let v=typeof m=="string"?m:String(m),S=o(g,`${l}.${v}`,p+1);S.keep&&(f[v]=S.value)}return{keep:!0,value:f}}if(u instanceof Set){t.push({kind:"coerced_set",key:l});let f=[],m=0;for(let g of u.values()){let v=o(g,`${l}[${m}]`,p+1);v.keep&&f.push(v.value),m++}return{keep:!0,value:f}}if(Array.isArray(u)){if(c.has(u))return t.push({kind:"circular_reference",key:l}),{keep:!0,value:"[circular]"};c.add(u);let f=[];for(let m=0;m<u.length;m++){let g=o(u[m],`${l}[${m}]`,p+1);g.keep&&f.push(g.value)}return c.delete(u),{keep:!0,value:f}}if(h==="object"){let f=u;if(c.has(f))return t.push({kind:"circular_reference",key:l}),{keep:!0,value:"[circular]"};c.add(f);let m={};for(let g of Object.keys(f)){let v=o(f[g],`${l}.${g}`,p+1);v.keep&&(m[g]=v.value)}return c.delete(f),{keep:!0,value:m}}t.push({kind:"non_serialisable",key:l});try{return{keep:!0,value:String(u)}}catch{return{keep:!1,value:void 0}}},a={};for(let u of Object.keys(r)){let l=o(r[u],u,0);l.keep&&(a[u]=l.value)}let d=we(a);if(d&&ie(d)>s){t.push({kind:"size_cap_exceeded",key:"*"});let u=Object.keys(a).map(p=>({k:p,size:ie(we(a[p])??"")})).sort((p,h)=>h.size-p.size),l=ie(d);for(let{k:p}of u){if(l<=s)break;l-=u.find(h=>h.k===p).size,delete a[p]}a.__truncated=!0}return{properties:a,warnings:t}}function we(r){try{return JSON.stringify(r)??null}catch{return null}}function ie(r){return typeof TextEncoder<"u"?new TextEncoder().encode(r).length:r.length*4}var G="super_props",oe="groups",J=class{constructor(e,t){this.storage=e;this.prefix=t;this.superProps={};this.groups={};this.superProps=_e(e,t+G)??{},this.groups=_e(e,t+oe)??{}}register(e){for(let[t,n]of Object.entries(e))n===null?delete this.superProps[t]:n!==void 0&&(this.superProps[t]=n);return ae(this.storage,this.prefix+G,this.superProps),{...this.superProps}}unregister(e){e in this.superProps&&(delete this.superProps[e],ae(this.storage,this.prefix+G,this.superProps))}getSuperProperties(){return{...this.superProps}}setGroup(e,t,n){t===null?delete this.groups[e]:this.groups[e]=n!==void 0?{id:t,traits:n}:{id:t},ae(this.storage,this.prefix+oe,this.groups)}getGroups(){return JSON.parse(JSON.stringify(this.groups))}getGroupIds(){let e={};for(let[t,n]of Object.entries(this.groups))e[t]=n.id;return e}clear(){this.superProps={},this.groups={};try{this.storage.removeItem(this.prefix+G)}catch{}try{this.storage.removeItem(this.prefix+oe)}catch{}}};function _e(r,e){let t;try{t=r.getItem(e)}catch{return null}if(!t)return null;try{return JSON.parse(t)}catch{return null}}function ae(r,e,t){try{r.setItem(e,JSON.stringify(t))}catch{}}var Y=class{constructor(e,t){this.cfg=e;this.report=t;this.observers=[];this.flushed=new Set;this.cls=0;this.clsEntries=[];this.inp=0;this.cleanups=[]}install(){if(!this.cfg.enabled||typeof PerformanceObserver>"u"||typeof globalThis>"u"||!("document"in globalThis))return;let e=globalThis.document;try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;a.responseStart>0&&!this.flushed.has("ttfb")&&(this.flushed.add("ttfb"),this.report("webvitals.ttfb",{valueMs:Math.round(a.responseStart-a.startTime)}))}});i.observe({type:"navigation",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries())o.name==="first-contentful-paint"&&!this.flushed.has("fcp")&&(this.flushed.add("fcp"),this.report("webvitals.fcp",{valueMs:Math.round(o.startTime)}))});i.observe({type:"paint",buffered:!0}),this.observers.push(i)}catch{}let t=0;try{let i=new PerformanceObserver(c=>{let o=c.getEntries(),a=o[o.length-1];a&&(t=a.startTime)});i.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;typeof a.value=="number"&&!a.hadRecentInput&&(this.cls+=a.value,this.clsEntries.push(o))}});i.observe({type:"layout-shift",buffered:!0}),this.observers.push(i)}catch{}try{let i=new PerformanceObserver(c=>{for(let o of c.getEntries()){let a=o;a.interactionId&&a.duration>this.inp&&(this.inp=a.duration)}});try{i.observe({type:"event",buffered:!0,durationThreshold:16})}catch{i.observe({type:"first-input",buffered:!0})}this.observers.push(i)}catch{}let n=()=>{t>0&&!this.flushed.has("lcp")&&(this.flushed.add("lcp"),this.report("webvitals.lcp",{valueMs:Math.round(t)})),this.cls>0&&!this.flushed.has("cls")&&(this.flushed.add("cls"),this.report("webvitals.cls",{value:Math.round(this.cls*1e3)/1e3})),this.inp>0&&!this.flushed.has("inp")&&(this.flushed.add("inp"),this.report("webvitals.inp",{valueMs:Math.round(this.inp)}))},s=()=>{e.visibilityState==="hidden"&&n()};e.addEventListener("visibilitychange",s),globalThis.window.addEventListener("pagehide",n),this.cleanups.push(()=>{e.removeEventListener("visibilitychange",s),globalThis.window.removeEventListener("pagehide",n)})}uninstall(){for(let e of this.observers)try{e.disconnect()}catch{}this.observers=[];for(let e of this.cleanups.splice(0))try{e()}catch{}}};var st={analytics:!0,marketing:!0,errors:!0},Z=class{constructor(e){this.state={...st};this.dntDenied=!1;e?.respectDnt&&this.detectDnt()&&(this.dntDenied=!0,this.state={analytics:!1,marketing:!1,errors:!1})}set(e){if(this.dntDenied)return{...this.state};for(let t of Object.keys(e)){let n=e[t];typeof n=="boolean"&&(this.state[t]=n)}return{...this.state}}get(){return{...this.state}}get analytics(){return this.state.analytics}get marketing(){return this.state.marketing}get errors(){return this.state.errors}get isDntDenied(){return this.dntDenied}detectDnt(){try{let e=globalThis.navigator;return e?[e.doNotTrack,e.msDoNotTrack,globalThis.doNotTrack].some(n=>n==="1"||n==="yes"):!1}catch{return!1}}},it=/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,ot=/\b\d(?:[ -]?\d){12,18}\b/g,at="<email>",ct="<card>";function ut(r){return r&&r.replace(it,at).replace(ot,ct)}function ce(r){let e={};for(let t of Object.keys(r))e[t]=Ee(r[t]);return e}function Ee(r){return typeof r=="string"?ut(r):Array.isArray(r)?r.map(Ee):r&&typeof r=="object"&&r.constructor===Object?ce(r):r}var ee=class{constructor(e=50){this.maxSize=e;this.items=[]}add(e){this.items.push(e),this.items.length>this.maxSize&&this.items.shift()}snapshot(){return this.items.slice()}clear(){this.items=[]}get size(){return this.items.length}};function le(r){if(!r||typeof r!="string")return[];let e=r.split(`
|
|
2
|
-
`),t=[];for(let n of e){let s=n.trim();if(!s)continue;let i=lt(s);i&&t.push(i)}return t}function lt(r){let e=/^at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)$/.exec(r);return e?ue({function:e[1],filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):(e=/^at\s+(.+?):(\d+):(\d+)$/.exec(r),e?ue({function:"?",filename:e[1],lineno:parseInt(e[2],10),colno:parseInt(e[3],10),raw:r}):(e=/^(.*?)@(.+?):(\d+):(\d+)$/.exec(r),e?ue({function:e[1]||"?",filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):/^\w*Error/.test(r)||!r.includes(":")?null:{function:"?",filename:"",lineno:0,colno:0,in_app:!0,raw:r}))}function ue(r){return{function:r.function||"?",filename:r.filename,lineno:Number.isFinite(r.lineno)?r.lineno:0,colno:Number.isFinite(r.colno)?r.colno:0,in_app:dt(r.filename),raw:r.raw}}function dt(r){return r?!(/^(?:chrome|moz|safari|webkit)-extension:\/\//.test(r)||/\bcdn\.jsdelivr\.net\b/.test(r)||/\bunpkg\.com\b/.test(r)||/\bgoogletagmanager\.com\b/.test(r)||/\bgoogle-analytics\.com\b/.test(r)||/\b@cross-deck\/web\b/.test(r)||/\/crossdeck\.umd\.min\.js$/.test(r)):!0}function x(r,e,t){let n=e.filter(i=>i.in_app).slice(0,3),s=[(r||"").slice(0,200),...n.map(i=>`${i.function}@${i.filename}:${i.lineno}`)];if(n.length===0&&t){let i=[t.errorType??"",t.filename??"",t.lineno??"",t.colno??""].join(":");i!==":::"&&s.push(i)}return pt(s.join("|"))}function pt(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e+r.charCodeAt(t)|0;return(e>>>0).toString(16).padStart(8,"0")}var Se={enabled:!0,onError:!0,onUnhandledRejection:!0,wrapFetch:!0,wrapXhr:!0,captureConsole:!1,ignoreErrors:["ResizeObserver loop limit exceeded","ResizeObserver loop completed with undelivered notifications","Non-Error promise rejection captured"],allowUrls:[],denyUrls:[/^chrome-extension:\/\//,/^moz-extension:\/\//,/^safari-extension:\/\//,/^webkit-extension:\/\//,/^safari-web-extension:\/\//],sampleRate:1,maxPerFingerprintPerMinute:5,maxPerSession:100},te=class{constructor(e){this.opts=e;this.installed=!1;this.cleanups=[];this._reporting=!1;this.sessionCount=0;this.fingerprintWindow=new Map}install(){if(this.installed||!this.opts.config.enabled||typeof globalThis>"u"||!("window"in globalThis))return;let e=globalThis.window;this.opts.config.onError&&this.installOnErrorListener(e),this.opts.config.onUnhandledRejection&&this.installRejectionListener(e),this.opts.config.wrapFetch&&this.installFetchWrap(e),this.opts.config.wrapXhr&&this.installXhrWrap(e),this.opts.config.captureConsole&&this.installConsoleWrap(),this.installed=!0}uninstall(){for(let e of this.cleanups.splice(0))try{e()}catch{}this.installed=!1}captureError(e,t){if(this.opts.isConsented())try{let n=this.buildFromUnknown(e,"error.handled",t?.level??"error");t?.context&&(n.context={...n.context,...t.context}),t?.tags&&(n.tags={...n.tags,...t.tags}),this.maybeReport(n)}catch{}}captureMessage(e,t="info"){if(this.opts.isConsented())try{let n={timestamp:Date.now(),kind:"error.message",level:t,message:e,errorType:null,frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:x(e,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags()};this.maybeReport(n)}catch{}}installOnErrorListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromErrorEvent(n);this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("error",t,!0),this.cleanups.push(()=>e.removeEventListener("error",t,!0))}installRejectionListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromUnknown(n.reason,"error.unhandledrejection","error");this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("unhandledrejection",t),this.cleanups.push(()=>e.removeEventListener("unhandledrejection",t))}installFetchWrap(e){let t=e.fetch?.bind(e);if(!t)return;let n=async(...s)=>{let i=s[0],c=s[1]??{},o=typeof i=="string"?i:i?.url??"",a=(c.method||"GET").toUpperCase(),d=Date.now();pe(o,this.opts.selfHostname)||this.opts.breadcrumbs.add({timestamp:d,category:"http",message:`${a} ${o}`,data:{url:o,method:a}});try{let u=await t(...s);return u.status>=500&&this.opts.isConsented()&&(pe(o,this.opts.selfHostname)||this.captureHttp({url:o,method:a,status:u.status,statusText:u.statusText})),u}catch(u){throw this.opts.isConsented()&&!o.includes("api.cross-deck.com")&&this.captureHttp({url:o,method:a,status:0,statusText:u instanceof Error?u.message:"network error"}),u}};e.fetch=n,this.cleanups.push(()=>{e.fetch===n&&(e.fetch=t)})}installXhrWrap(e){let n=e.XMLHttpRequest?.prototype;if(!n)return;let s=n.open,i=n.send,c=this;n.open=function(o,a,...d){return this._cdMethod=o,this._cdUrl=a,s.apply(this,[o,a,...d])},n.send=function(o){let a=this,d=()=>{try{if(a.status>=500&&c.opts.isConsented()){let u=a._cdUrl??"";pe(u,c.opts.selfHostname)||c.captureHttp({url:u,method:(a._cdMethod??"GET").toUpperCase(),status:a.status,statusText:a.statusText})}}catch{}};return a.addEventListener("loadend",d),i.apply(this,[o??null])},this.cleanups.push(()=>{n.open=s,n.send=i})}installConsoleWrap(){let e=globalThis.console;if(!e)return;let t=e.error.bind(e);e.error=(...n)=>{try{this.opts.isConsented()&&this.captureMessage(n.map(s=>ht(s)).join(" "),"error")}catch{}return t(...n)},this.cleanups.push(()=>{e.error=t})}buildFromErrorEvent(e){let t=e.error,n=e.filename||null,s=typeof e.lineno=="number"&&e.lineno>0?e.lineno:null,i=typeof e.colno=="number"&&e.colno>0?e.colno:null;if(t==null&&!n&&s==null&&(e.message==="Script error."||e.message==="Script error"||!e.message)){let h="Cross-origin script error (browser hid details \u2014 script needs crossorigin attribute + CORS headers)";return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:h,errorType:"ScriptError",frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:x(h,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:{...this.opts.getTags(),cross_origin:"true"}}}let o=fe(t),a=(o.message||e.message||"Unknown error").slice(0,1024),d=t instanceof Error?t.stack??null:null,u=le(d),l=o.errorType??null,p=o.extras?{...this.opts.getContext(),__error_extras:o.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:a,errorType:l,frames:u,rawStack:d,filename:n,lineno:s,colno:i,fingerprint:x(a,u,{filename:n,lineno:s,colno:i,errorType:l}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:p,tags:this.opts.getTags()}}buildFromUnknown(e,t,n){let s=fe(e),i=(s.message||"Unknown error").slice(0,1024),c=e instanceof Error?e.stack??null:null,o=le(c),a=s.errorType??null,d=s.extras?{...this.opts.getContext(),__error_extras:s.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:t,level:n,message:i,errorType:a,frames:o,rawStack:c,filename:null,lineno:null,colno:null,fingerprint:x(i,o,{errorType:a}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:d,tags:this.opts.getTags()}}captureHttp(e){try{let t=`HTTP ${e.status} ${e.method} ${e.url}`,n={timestamp:Date.now(),kind:"error.http",level:"error",message:t,errorType:"HTTPError",frames:[],rawStack:null,filename:e.url,lineno:null,colno:null,fingerprint:x(`HTTP ${e.status} ${e.method}`,[],{filename:e.url,errorType:"HTTPError"}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags(),http:e};this.maybeReport(n)}catch{}}maybeReport(e){if(this.sessionCount>=this.opts.config.maxPerSession||this.shouldIgnore(e)||!this.passesUrlGate(e)||!this.passesSample(e)||!this.passesRateLimit(e))return;let t=e,n=this.opts.beforeSend?.();if(n){try{t=n(e)}catch{t=e}if(!t)return}this.sessionCount+=1;try{this.opts.report(t)}catch{}}shouldIgnore(e){for(let t of this.opts.config.ignoreErrors)if(typeof t=="string"&&e.message.includes(t)||t instanceof RegExp&&t.test(e.message))return!0;return!1}passesUrlGate(e){let n=(e.frames.find(s=>s.filename)??null)?.filename??e.filename??"";if(!n)return!0;for(let s of this.opts.config.denyUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!1;if(this.opts.config.allowUrls.length>0){for(let s of this.opts.config.allowUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!0;return!1}return!0}passesSample(e){return this.opts.config.sampleRate>=1?!0:this.opts.config.sampleRate<=0?!1:parseInt(e.fingerprint.slice(0,2),16)/255<this.opts.config.sampleRate}passesRateLimit(e){let n=Date.now(),s=this.opts.config.maxPerFingerprintPerMinute,c=(this.fingerprintWindow.get(e.fingerprint)??[]).filter(o=>n-o<6e4);return c.length>=s?(this.fingerprintWindow.set(e.fingerprint,c),!1):(c.push(n),this.fingerprintWindow.set(e.fingerprint,c),!0)}};function fe(r){if(r===null)return{message:"(thrown: null)",errorType:null,extras:null};if(r===void 0)return{message:"(thrown: undefined)",errorType:null,extras:null};if(typeof r=="string")return{message:r,errorType:null,extras:null};if(typeof r=="number"||typeof r=="boolean"||typeof r=="bigint")return{message:String(r),errorType:typeof r,extras:null};if(typeof r=="symbol")return{message:r.toString(),errorType:"symbol",extras:null};if(typeof r=="function")return{message:`(thrown function: ${r.name||"anonymous"})`,errorType:"function",extras:null};if(r instanceof Error){let e=r.name||r.constructor?.name||"Error",t=typeof r.message=="string"&&r.message.length>0?r.message:I(r)||e,n={},s=ft(r);s.length>0&&(n.cause=s);for(let i of["code","status","statusCode","errno","response","data","detail","details"]){let c=r[i];c!==void 0&&typeof c!="function"&&(n[i]=de(c))}for(let i of Object.keys(r)){if(i==="message"||i==="stack"||i==="name"||i==="cause"||i in n)continue;let c=r[i];typeof c!="function"&&(n[i]=de(c))}return{message:t,errorType:e,extras:Object.keys(n).length>0?n:null}}if(typeof Response<"u"&&r instanceof Response)return{message:`HTTP ${r.status} ${r.statusText||""}${r.url?` ${r.url}`:""}`.trim(),errorType:"Response",extras:{status:r.status,statusText:r.statusText,url:r.url,type:r.type}};if(typeof r=="object"){let e=r,t=e.constructor&&typeof e.constructor=="function"&&e.constructor.name||null,n=typeof e.message=="string"&&e.message?e.message:null,s=typeof e.name=="string"&&e.name?e.name:null,i=null;try{let l=JSON.stringify(e);i=l==="{}"?null:l}catch{i=null}let c=I(e),o=n??i??(c&&c!=="[object Object]"?c:null)??(t?`(thrown ${t} with no message)`:"(thrown object with no message)"),a=s??t??null,d={},u=0;for(let l of Object.keys(e)){if(u>=20)break;if(l==="message"||l==="name")continue;let p=e[l];typeof p!="function"&&(d[l]=de(p),u++)}return{message:o,errorType:a,extras:Object.keys(d).length>0?d:null}}return{message:I(r)||"(unstringifiable thrown value)",errorType:null,extras:null}}function ft(r){let e=[],t=r.cause,n=0;for(;t!=null&&n<5;)t instanceof Error?(e.push({name:t.name||"Error",message:t.message||""}),t=t.cause):(e.push({name:"non-Error",message:I(t)}),t=null),n++;return e}function I(r){try{let e=Object.prototype.toString.call(r);if(e!=="[object Object]")return e;let t=r?.toString;if(typeof t=="function"&&t!==Object.prototype.toString){let n=t.call(r);if(typeof n=="string")return n}return e}catch{return"(throwing toString)"}}function de(r){if(r==null)return r;let e=typeof r;if(e==="string"||e==="number"||e==="boolean")return r;if(e==="bigint")return String(r);try{let t=JSON.stringify(r);return t===void 0?I(r):JSON.parse(t)}catch{return I(r)}}function ht(r){return fe(r).message}function Te(r){if(!r||typeof r!="string")return null;try{return new URL(r).hostname.toLowerCase()}catch{return null}}function pe(r,e){if(!e||!r)return!1;try{return new URL(r).hostname.toLowerCase()===e}catch{return!1}}var M=class{constructor(){this.state=null}init(e){if(this.state){try{this.state.uninstallUnloadFlush?.()}catch{}try{this.state.autoTracker?.uninstall()}catch{}try{this.state.webVitals?.uninstall()}catch{}try{this.state.errors?.uninstall()}catch{}}if(!e.publicKey||!e.publicKey.startsWith("cd_pub_"))throw new b({type:"configuration_error",code:"invalid_public_key",message:"Crossdeck.init requires a publishable key starting with cd_pub_."});if(!e.appId)throw new b({type:"configuration_error",code:"missing_app_id",message:"Crossdeck.init requires an appId. Find yours in the Crossdeck dashboard."});if(e.environment!=="production"&&e.environment!=="sandbox")throw new b({type:"configuration_error",code:"invalid_environment",message:'Crossdeck.init requires environment: "production" | "sandbox".'});let t=gt(e.publicKey);if(t&&t!==e.environment)throw new b({type:"configuration_error",code:"environment_mismatch",message:`Crossdeck.init: environment "${e.environment}" disagrees with key prefix (${t}). Reconcile the publishable key with the environment declaration.`});let n=mt(),s=e.storage??ye(),i=e.persistIdentity??!0,c=yt(e.autoTrack),o={appId:e.appId,publicKey:e.publicKey,environment:e.environment,baseUrl:e.baseUrl??N,persistIdentity:i,storagePrefix:e.storagePrefix??"crossdeck:",autoHeartbeat:e.autoHeartbeat??!0,eventFlushBatchSize:e.eventFlushBatchSize??20,eventFlushIntervalMs:e.eventFlushIntervalMs??1500,sdkVersion:e.sdkVersion??A,autoTrack:c,appVersion:e.appVersion??null},a=new Q;a.enabled=e.debug===!0;let d=new B({publicKey:o.publicKey,baseUrl:o.baseUrl,sdkVersion:o.sdkVersion,localDevMode:n});n&&console.log("[crossdeck] Localhost detected \u2014 running in dev mode (no network calls). Set publicKey: 'cd_pub_test_\u2026' and deploy to a real domain to test against the Crossdeck Sandbox.");let u=i?s:new _,p=i&&!e.storage&&typeof globalThis.document<"u"?new X:void 0,h=new j(u,o.storagePrefix,p),f=new H(u,o.storagePrefix+"entitlements"),m=i?new z({storage:u,prefix:o.storagePrefix}):null;m&&a.emit("sdk.queue_restored","Restored persisted event queue from a prior session.");let g=new W({http:d,batchSize:o.eventFlushBatchSize,intervalMs:o.eventFlushIntervalMs,envelope:()=>({appId:o.appId,environment:o.environment,sdk:{name:C,version:o.sdkVersion}}),persistentStore:m??void 0,onFirstFlushSuccess:()=>{a.emit("sdk.first_event_sent","First telemetry event received. View it in Live Events.",{appId:o.appId,environment:o.environment})},onRetryScheduled:y=>{a.emit("sdk.flush_retry_scheduled",`Event flush failed (${y.lastError}). Retrying in ${y.delayMs}ms (attempt ${y.consecutiveFailures}).`,{...y})},onPermanentFailure:y=>{let k=`[crossdeck] Event batch DROPPED (status ${y.status}): ${y.lastError}. ${y.droppedCount} event(s) lost \u2014 check your publishable key + app config.`;console.error(k),a.emit("sdk.flush_permanent_failure",k,{...y})}}),v=c.deviceInfo?be({appVersion:o.appVersion??void 0}):o.appVersion?{appVersion:o.appVersion}:{},S=new J(i?u:new _,o.storagePrefix),U=new Z({respectDnt:e.respectDnt===!0});U.isDntDenied&&a.emit("sdk.consent_dnt_applied","Do Not Track detected \u2014 all tracking dimensions denied at init.");let V=new ee(50);if(this.state={http:d,identity:h,entitlements:f,events:g,autoTracker:null,webVitals:null,errors:null,breadcrumbs:V,errorContext:{},errorTags:{},errorBeforeSend:null,superProps:S,consent:U,scrubPii:e.scrubPii!==!1,deviceInfo:v,options:o,debug:a,developerUserId:null,uninstallUnloadFlush:null,lastServerTime:null,lastClientTime:null},a.emit("sdk.configured",`Crossdeck connected to ${o.appId} in ${o.environment} mode.`,{appId:o.appId,environment:o.environment,sdkVersion:o.sdkVersion}),c.sessions||c.pageViews){let y=new L(c,(k,R)=>this.track(k,R));this.state.autoTracker=y,y.install()}if(c.webVitals){let y=new Y({enabled:!0},(k,R)=>this.track(k,R));this.state.webVitals=y,y.install()}if(c.errors){let y=new te({config:{...Se,enabled:!0},breadcrumbs:V,report:k=>this.reportError(k),getContext:()=>({...this.state.errorContext}),getTags:()=>({...this.state.errorTags}),beforeSend:()=>this.state.errorBeforeSend,isConsented:()=>this.state.consent.errors,selfHostname:Te(o.baseUrl)});this.state.errors=y,y.install()}this.state.uninstallUnloadFlush=bt(()=>{this.flush({keepalive:!0}).catch(()=>{})}),o.autoHeartbeat&&!n&&this.heartbeat().catch(()=>{})}start(e){typeof console<"u"&&console.warn("[crossdeck] Crossdeck.start() is deprecated \u2014 use Crossdeck.init() instead. The signature is the same."),this.init(e)}async identify(e,t){let n=this.requireStarted();if(!e)throw new b({type:"invalid_request_error",code:"missing_user_id",message:"identify(userId) requires a non-empty userId."});if(!n.consent.analytics)return n.debug.emit("sdk.consent_denied","identify() skipped \u2014 consent denied for analytics."),{object:"alias_result",crossdeckCustomerId:n.identity.crossdeckCustomerId??"",linked:[],mergePending:!1,env:n.options.environment};let s=t?.traits!==void 0?O(t.traits):null,i=s&&Object.keys(s.properties).length>0?s.properties:void 0;if(n.debug.enabled&&s&&s.warnings.length>0)for(let u of s.warnings)n.debug.emit("sdk.property_coerced",`identify() traits key ${JSON.stringify(u.key)} was ${u.kind.replace(/_/g," ")} during validation.`,{key:u.key,kind:u.kind});let c={userId:e,anonymousId:n.identity.anonymousId};t?.email&&(c.email=t.email),i&&(c.traits=i);let o=await n.http.request("POST","/identity/alias",{body:c}),a=n.identity.crossdeckCustomerId,d=n.entitlements.list().length>0;return(a&&o.crossdeckCustomerId&&a!==o.crossdeckCustomerId||!a&&d)&&n.entitlements.clear(),n.identity.setCrossdeckCustomerId(o.crossdeckCustomerId),n.developerUserId=e,o}register(e){let t=this.requireStarted(),n=O(e);return t.superProps.register(n.properties)}unregister(e){this.requireStarted().superProps.unregister(e)}getSuperProperties(){return this.state?this.state.superProps.getSuperProperties():{}}group(e,t,n){let s=this.requireStarted();if(!e)throw new b({type:"invalid_request_error",code:"missing_group_type",message:"group(type, id) requires a non-empty type."});let i=n?O(n).properties:void 0;s.superProps.setGroup(e,t,i)}getGroups(){return this.state?this.state.superProps.getGroups():{}}consent(e){let t=this.requireStarted(),n=t.consent.set(e);return t.debug.emit("sdk.consent_changed","Consent state updated.",{...n}),n}consentStatus(){return this.state?this.state.consent.get():{analytics:!0,marketing:!0,errors:!0}}captureError(e,t){this.state?.errors&&this.state.errors.captureError(e,t)}captureMessage(e,t="info"){this.state?.errors&&this.state.errors.captureMessage(e,t)}setTag(e,t){this.state&&(this.state.errorTags[e]=t)}setTags(e){this.state&&Object.assign(this.state.errorTags,e)}setContext(e,t){this.state&&(this.state.errorContext[e]=t)}addBreadcrumb(e){this.state&&this.state.breadcrumbs.add(e)}setErrorBeforeSend(e){this.state&&(this.state.errorBeforeSend=e)}reportError(e){let t={fingerprint:e.fingerprint,level:e.level,errorType:e.errorType,message:e.message,stack:e.rawStack??void 0,frames:e.frames,filename:e.filename??void 0,lineno:e.lineno??void 0,colno:e.colno??void 0,tags:e.tags,context:e.context,breadcrumbs:e.breadcrumbs,http:e.http};for(let n of Object.keys(t))t[n]===void 0&&delete t[n];this.track(e.kind,t)}async forget(){let e=this.requireStarted(),t=this.identityQueryParams();try{await e.http.request("POST","/identity/forget",{body:{...t}})}catch(n){e.debug.emit("sdk.consent_denied",`forget() server call failed (${n instanceof Error?n.message:String(n)}). Local state wiped anyway.`)}this.reset()}async getEntitlements(){let e=this.requireStarted(),t=this.identityQueryParams(),n;try{n=await e.http.request("GET","/entitlements",{query:t})}catch(s){throw e.entitlements.markRefreshFailed(),s}return n.crossdeckCustomerId&&e.identity.setCrossdeckCustomerId(n.crossdeckCustomerId),e.entitlements.setFromList(n.data),n.data}isEntitled(e){return this.requireStarted().entitlements.isEntitled(e)}listEntitlements(){return this.requireStarted().entitlements.list()}onEntitlementsChange(e){return this.requireStarted().entitlements.subscribe(e)}track(e,t){let n=this.requireStarted();if(!e)throw new b({type:"invalid_request_error",code:"missing_event_name",message:"track(name) requires a non-empty name."});let s=e.startsWith("error."),i=e.startsWith("webvitals.");if(!(s||i?n.consent.errors:n.consent.analytics)){n.debug.enabled&&n.debug.emit("sdk.consent_denied",`Dropped event "${e}" \u2014 consent denied for ${i?"errors":"analytics"}.`);return}if(n.debug.enabled&&t){let g=ke(t);g.length>0&&n.debug.emit("sdk.sensitive_property_warning",`Event "${e}" has potentially sensitive property names: ${g.join(", ")}. Crossdeck is privacy-first \u2014 avoid sending PII unless intentional.`,{eventName:e,flagged:g})}n.debug.enabled&&!n.developerUserId&&!n.identity.crossdeckCustomerId&&n.debug.emit("sdk.no_identity","Using anonymous user until identify(userId) is called.");let o=O(t);if(n.debug.enabled&&o.warnings.length>0)for(let g of o.warnings)n.debug.emit("sdk.property_coerced",`Event "${e}" property ${JSON.stringify(g.key)} was ${g.kind.replace(/_/g," ")} during validation.`,{eventName:e,key:g.key,kind:g.kind});let a={...n.deviceInfo},d=n.autoTracker?.currentSessionId;d&&(a.sessionId=d);let u=n.autoTracker?.currentPageviewId;u&&(a.pageviewId=u);let l=n.autoTracker?.currentAcquisition;l&&(l.utm_source&&(a.utm_source=l.utm_source),l.utm_medium&&(a.utm_medium=l.utm_medium),l.utm_campaign&&(a.utm_campaign=l.utm_campaign),l.utm_content&&(a.utm_content=l.utm_content),l.utm_term&&(a.utm_term=l.utm_term),l.referrer&&n.consent.marketing&&(a.referrer=l.referrer),n.consent.marketing&&(l.gclid&&(a.gclid=l.gclid),l.fbclid&&(a.fbclid=l.fbclid),l.msclkid&&(a.msclkid=l.msclkid),l.ttclid&&(a.ttclid=l.ttclid),l.li_fat_id&&(a.li_fat_id=l.li_fat_id),l.twclid&&(a.twclid=l.twclid)));let p=n.superProps.getSuperProperties();for(let g of Object.keys(p))g in a||(a[g]=p[g]);let h=n.superProps.getGroupIds();Object.keys(h).length>0&&(a.$groups=h),Object.assign(a,o.properties);let f=n.scrubPii?ce(a):a,m={eventId:this.mintEventId(),name:e,timestamp:Date.now(),properties:f};if(Object.assign(m,this.identityHintForEvent()),n.events.enqueue(m),!s&&!i){let g=e.startsWith("page.")?"navigation":e.startsWith("element.")||e==="session.started"?"ui.click":"custom";n.breadcrumbs.add({timestamp:m.timestamp,category:g,message:e,data:t?{...t}:void 0})}}async flush(e={}){await this.requireStarted().events.flush(e)}async flushEvents(){return this.flush()}async syncPurchases(e){let t=this.requireStarted();if(!e.signedTransactionInfo)throw new b({type:"invalid_request_error",code:"missing_signed_transaction_info",message:"syncPurchases requires a signedTransactionInfo string from StoreKit 2."});let n=e.rail??"apple",s=await t.http.request("POST","/purchases/sync",{body:{...e,rail:n}});return t.identity.setCrossdeckCustomerId(s.crossdeckCustomerId),t.entitlements.setFromList(s.entitlements),t.debug.emit("sdk.purchase_evidence_sent","StoreKit transaction forwarded. Waiting for backend verification.",{rail:e.rail??"apple"}),s}async purchaseApple(e){return this.syncPurchases({rail:"apple",...e})}setDebugMode(e){let t=this.requireStarted();t.debug.enabled=e,e&&t.debug.emit("sdk.configured",`Debug mode enabled for ${t.options.appId} in ${t.options.environment} mode.`,{appId:t.options.appId,environment:t.options.environment})}async heartbeat(){let e=this.requireStarted(),t=await e.http.request("GET","/sdk/heartbeat");return typeof t?.serverTime=="number"&&Number.isFinite(t.serverTime)&&(e.lastServerTime=t.serverTime,e.lastClientTime=Date.now()),t}reset(){if(this.state){if(this.state.developerUserId)try{this.track("user.signed_out",{auto:!0})}catch{}if(this.state.autoTracker?.uninstall(),this.state.identity.reset(),this.state.entitlements.clear(),this.state.events.reset(),this.state.superProps.clear(),this.state.breadcrumbs.clear(),this.state.errorContext={},this.state.errorTags={},this.state.developerUserId=null,this.state.lastServerTime=null,this.state.lastClientTime=null,this.state.autoTracker){let e=new L(this.state.options.autoTrack,(t,n)=>this.track(t,n));this.state.autoTracker=e,e.install()}}}diagnostics(){if(!this.state)return{started:!1,anonymousId:null,crossdeckCustomerId:null,developerUserId:null,sdkVersion:null,baseUrl:null,clock:{lastServerTime:null,lastClientTime:null,skewMs:null},entitlements:{count:0,lastUpdated:0,stale:!1,listenerErrors:0},events:{buffered:0,dropped:0,inFlight:0,lastFlushAt:0,lastError:null,consecutiveFailures:0,nextRetryAt:null}};let e=this.state,t=e.lastServerTime!==null&&e.lastClientTime!==null?e.lastClientTime-e.lastServerTime:null;return{started:!0,anonymousId:e.identity.anonymousId,crossdeckCustomerId:e.identity.crossdeckCustomerId,developerUserId:e.developerUserId,sdkVersion:e.options.sdkVersion,baseUrl:e.options.baseUrl,clock:{lastServerTime:e.lastServerTime,lastClientTime:e.lastClientTime,skewMs:t},entitlements:{count:e.entitlements.list().length,lastUpdated:e.entitlements.freshness,stale:e.entitlements.isStale,listenerErrors:e.entitlements.listenerErrors},events:e.events.getStats()}}requireStarted(){if(!this.state)throw new b({type:"configuration_error",code:"not_initialized",message:"Call Crossdeck.init({ appId, publicKey, environment }) before any other method."});return this.state}identityQueryParams(){let e=this.requireStarted();return e.identity.crossdeckCustomerId?{customerId:e.identity.crossdeckCustomerId}:e.developerUserId?{userId:e.developerUserId}:{anonymousId:e.identity.anonymousId}}identityHintForEvent(){let e=this.requireStarted(),t={anonymousId:e.identity.anonymousId};return e.developerUserId&&(t.developerUserId=e.developerUserId),e.identity.crossdeckCustomerId&&(t.crossdeckCustomerId=e.identity.crossdeckCustomerId),t}mintEventId(){return`evt_${Date.now().toString(36)}${w(8)}`}},Ce=new M;function gt(r){return r.startsWith("cd_pub_test_")?"sandbox":r.startsWith("cd_pub_live_")?"production":null}function mt(){let r=globalThis.window;if(r?.__CROSSDECK_FORCE_LIVE__===!0)return!1;let e=r?.location?.hostname;return e?!!(e==="localhost"||e==="127.0.0.1"||e==="0.0.0.0"||e==="::1"||e==="[::1]"||/^\[?fe80::/i.test(e)||e.endsWith(".local")||/^10\./.test(e)||/^192\.168\./.test(e)||/^172\.(1[6-9]|2\d|3[0-1])\./.test(e)):!1}function yt(r){return r===!1?{sessions:!1,pageViews:!1,deviceInfo:!1,clicks:!1,webVitals:!1,errors:!1}:r===void 0||r===!0?{...E}:{sessions:r.sessions??E.sessions,pageViews:r.pageViews??E.pageViews,deviceInfo:r.deviceInfo??E.deviceInfo,clicks:r.clicks??E.clicks,webVitals:r.webVitals??E.webVitals,errors:r.errors??E.errors}}function bt(r){let e=globalThis.window,t=globalThis.document;if(!e||!t)return()=>{};let n=()=>{t.visibilityState==="hidden"&&r()},s=()=>r();return t.addEventListener("visibilitychange",n),e.addEventListener("pagehide",s),e.addEventListener("beforeunload",s),()=>{t.removeEventListener("visibilitychange",n),e.removeEventListener("pagehide",s),e.removeEventListener("beforeunload",s)}}var he=Object.freeze([{code:"invalid_public_key",type:"configuration_error",description:"The publishable key passed to Crossdeck.init() doesn't start with cd_pub_.",resolution:"Copy the key from your Crossdeck dashboard \u2192 API keys page.",retryable:!1},{code:"missing_app_id",type:"configuration_error",description:"Crossdeck.init() was called without an appId.",resolution:"Add appId to your init options \u2014 find it in the dashboard's Apps page.",retryable:!1},{code:"invalid_environment",type:"configuration_error",description:"Crossdeck.init() requires environment: 'production' | 'sandbox'.",resolution:'Pass the literal string "production" or "sandbox" \u2014 no other values are accepted.',retryable:!1},{code:"environment_mismatch",type:"configuration_error",description:"The publishable key's env prefix doesn't match the declared environment option.",resolution:"Either change `environment` to match the key prefix (cd_pub_test_ \u2194 sandbox, cd_pub_live_ \u2194 production), or swap the key for one minted in the right env.",retryable:!1},{code:"not_initialized",type:"configuration_error",description:"An SDK method was called before Crossdeck.init().",resolution:"Call Crossdeck.init({ appId, publicKey, environment }) once at app startup before any other method.",retryable:!1},{code:"missing_user_id",type:"invalid_request_error",description:"identify() was called with an empty userId.",resolution:"Pass a stable, non-empty user identifier from your auth layer \u2014 never a hardcoded placeholder.",retryable:!1},{code:"missing_event_name",type:"invalid_request_error",description:"track() was called without an event name.",resolution:"Pass a non-empty string as the first argument.",retryable:!1},{code:"missing_group_type",type:"invalid_request_error",description:"group() was called without a group type.",resolution:'Pass a non-empty type (e.g. "org", "team") as the first argument.',retryable:!1},{code:"missing_signed_transaction_info",type:"invalid_request_error",description:"syncPurchases() was called without StoreKit 2 signed transaction info.",resolution:"Pass the JWS string from Transaction.currentEntitlements / Transaction.updates.",retryable:!1},{code:"fetch_failed",type:"network_error",description:"The underlying fetch() call failed (typically a network outage or DNS issue).",resolution:"Check the user's network. The SDK will retry automatically with exponential backoff.",retryable:!0},{code:"request_timeout",type:"network_error",description:"A request was aborted after the configured timeoutMs (default 15s).",resolution:"Check the user's connection. Increase timeoutMs in init options if the user is on a known-slow network.",retryable:!0},{code:"invalid_json_response",type:"internal_error",description:"The server returned a 2xx with an unparseable body.",resolution:"Likely a transient backend bug. Retry; if it persists, contact support with the requestId.",retryable:!0}]);function xe(r){return he.find(e=>e.code===r)}return Fe(vt);})();
|
|
1
|
+
"use strict";var Crossdeck=(()=>{var se=Object.defineProperty;var Fe=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var Le=Object.prototype.hasOwnProperty;var Ue=(r,e)=>{for(var t in e)se(r,t,{get:e[t],enumerable:!0})},Me=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Oe(e))!Le.call(r,s)&&s!==t&&se(r,s,{get:()=>e[s],enumerable:!(n=Fe(e,s))||n.enumerable});return r};var qe=r=>Me(se({},"__esModule",{value:!0}),r);var At={};Ue(At,{CROSSDECK_ERROR_CODES:()=>me,Crossdeck:()=>Ae,CrossdeckClient:()=>V,CrossdeckError:()=>v,DEFAULT_BASE_URL:()=>N,MemoryStorage:()=>C,SDK_NAME:()=>R,SDK_VERSION:()=>F,getErrorCode:()=>Re});var v=class r extends Error{constructor(e){super(e.message),this.name="CrossdeckError",this.type=e.type,this.code=e.code,this.requestId=e.requestId,this.status=e.status,this.retryAfterMs=e.retryAfterMs,Object.setPrototypeOf(this,r.prototype)}};async function ye(r){let e=r.headers.get("x-request-id")??void 0,t=Ve(r.headers.get("retry-after")),n;try{n=await r.json()}catch{n=null}let s=n?.error;return s&&typeof s.type=="string"&&typeof s.code=="string"?new v({type:s.type,code:s.code,message:s.message??`HTTP ${r.status}`,requestId:s.request_id??e,status:r.status,retryAfterMs:t}):new v({type:$e(r.status),code:`http_${r.status}`,message:`HTTP ${r.status} ${r.statusText||""}`.trim(),requestId:e,status:r.status,retryAfterMs:t})}function Ve(r){if(!r)return;let e=r.trim();if(!e)return;if(/^\d+(\.\d+)?$/.test(e)){let s=Number(e);return!Number.isFinite(s)||s<0?void 0:Math.round(s*1e3)}if(!/[a-zA-Z,/:]/.test(e))return;let t=Date.parse(e);if(!Number.isFinite(t))return;let n=t-Date.now();return n>0?n:0}function $e(r){return r===401?"authentication_error":r===403?"permission_error":r===429?"rate_limit_error":r>=400&&r<500?"invalid_request_error":"internal_error"}var F="1.4.2",R="@cross-deck/web";var N="https://api.cross-deck.com/v1",Ke=15e3,K=class{constructor(e){this.config=e}async request(e,t,n={}){if(this.config.localDevMode)return Ne(t);let s=this.buildUrl(t,n.query),o={Authorization:`Bearer ${this.config.publicKey}`,"Crossdeck-Sdk-Version":`${R}@${this.config.sdkVersion}`,Accept:"application/json"};n.idempotencyKey&&(o["Idempotency-Key"]=n.idempotencyKey);let c;n.body!==void 0&&(o["Content-Type"]="application/json",c=JSON.stringify(n.body));let a=n.timeoutMs??this.config.timeoutMs??Ke,i=typeof AbortController<"u"&&a>0?new AbortController:null,u=null;i&&a>0&&(u=setTimeout(()=>i.abort(),a));let d;try{d=await fetch(s,{method:e,headers:o,body:c,keepalive:n.keepalive===!0,signal:i?.signal})}catch(l){let p=i?.signal?.aborted===!0;throw new v({type:"network_error",code:p?"request_timeout":"fetch_failed",message:p?`Request to ${t} aborted after ${a}ms`:l instanceof Error?l.message:"fetch failed"})}finally{u!==null&&clearTimeout(u)}if(!d.ok)throw await ye(d);if(d.status!==204)try{return await d.json()}catch{throw new v({type:"internal_error",code:"invalid_json_response",message:"Server returned a 2xx with an unparseable body.",requestId:d.headers.get("x-request-id")??void 0,status:d.status})}}get isLocalDevMode(){return this.config.localDevMode===!0}buildUrl(e,t){let n=this.config.baseUrl.replace(/\/+$/,""),s=e.startsWith("/")?e:`/${e}`,o=n+s;if(t){let c=new URLSearchParams;for(let[i,u]of Object.entries(t))typeof u=="string"&&u.length>0&&c.append(i,u);let a=c.toString();a&&(o+=(o.includes("?")?"&":"?")+a)}return o}},$=null;function Ne(r){return r.startsWith("/sdk/heartbeat")?{object:"heartbeat",ok:!0,projectId:"proj_local_dev",appId:"app_local_dev",platform:"web",env:"sandbox",serverTime:Date.now()}:r.startsWith("/identity/alias")?($||($=`cdcust_local_${typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID().replace(/-/g,"").slice(0,16):Math.random().toString(36).slice(2,18)}`),{object:"alias_result",crossdeckCustomerId:$,linked:[],mergePending:!1,env:"sandbox"}):r.startsWith("/entitlements")?{object:"list",data:[],crossdeckCustomerId:$??"",env:"sandbox"}:r.startsWith("/events")?{object:"list",received:0,env:"sandbox"}:{}}var O="anon_id",L="cdcust_id",B=class{constructor(e,t,n){this.primary=e;this.prefix=t;this.secondary=n??null;let s=e.getItem(t+O),o=e.getItem(t+L),c=this.secondary?.getItem(t+O)??null,a=this.secondary?.getItem(t+L)??null,i=s??c,u=o??a;this.state={anonymousId:i??this.mintAnonymousId(),crossdeckCustomerId:u},(!s||!c)&&this.writeBoth(t+O,this.state.anonymousId),u&&(!o||!a)&&this.writeBoth(t+L,u)}get anonymousId(){return this.state.anonymousId}get crossdeckCustomerId(){return this.state.crossdeckCustomerId}setCrossdeckCustomerId(e){this.state.crossdeckCustomerId=e,this.writeBoth(this.prefix+L,e)}reset(){this.deleteBoth(this.prefix+O),this.deleteBoth(this.prefix+L),this.state={anonymousId:this.mintAnonymousId(),crossdeckCustomerId:null},this.writeBoth(this.prefix+O,this.state.anonymousId)}mintAnonymousId(){let e=Date.now().toString(36),t=I(10);return`anon_${e}${t}`}writeBoth(e,t){try{this.primary.setItem(e,t)}catch{}if(this.secondary)try{this.secondary.setItem(e,t)}catch{}}deleteBoth(e){try{this.primary.removeItem(e)}catch{}if(this.secondary)try{this.secondary.removeItem(e)}catch{}}};function I(r){let e="0123456789abcdefghijklmnopqrstuvwxyz",t=[],n=globalThis.crypto;if(n?.getRandomValues){let s=new Uint8Array(r);n.getRandomValues(s);for(let o=0;o<r;o++)t.push(e[s[o]%e.length]??"0")}else for(let s=0;s<r;s++)t.push(e[Math.floor(Math.random()*e.length)]??"0");return t.join("")}var Be=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function je(r){if(typeof TextEncoder<"u")return new TextEncoder().encode(r);let e=[];for(let t=0;t<r.length;t++){let n=r.charCodeAt(t);if(n>=55296&&n<=56319&&t+1<r.length){let s=r.charCodeAt(t+1);s>=56320&&s<=57343&&(n=65536+(n-55296<<10)+(s-56320),t++)}n<128?e.push(n):n<2048?(e.push(192|n>>6),e.push(128|n&63)):n<65536?(e.push(224|n>>12),e.push(128|n>>6&63),e.push(128|n&63)):(e.push(240|n>>18),e.push(128|n>>12&63),e.push(128|n>>6&63),e.push(128|n&63))}return new Uint8Array(e)}function j(r){let e=je(r),t=e.length*8,n=Math.floor((e.length+9+63)/64),s=new Uint8Array(n*64);s.set(e),s[e.length]=128;let o=Math.floor(t/4294967296),c=t>>>0,a=s.length-8;s[a+0]=o>>>24&255,s[a+1]=o>>>16&255,s[a+2]=o>>>8&255,s[a+3]=o&255,s[a+4]=c>>>24&255,s[a+5]=c>>>16&255,s[a+6]=c>>>8&255,s[a+7]=c&255;let i=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),u=new Uint32Array(64);for(let l=0;l<n;l++){let p=l*64;for(let h=0;h<16;h++)u[h]=(s[p+h*4]<<24|s[p+h*4+1]<<16|s[p+h*4+2]<<8|s[p+h*4+3])>>>0;for(let h=16;h<64;h++){let k=u[h-15],w=u[h-2],x=(k>>>7|k<<25)^(k>>>18|k<<14)^k>>>3,T=(w>>>17|w<<15)^(w>>>19|w<<13)^w>>>10;u[h]=u[h-16]+x+u[h-7]+T>>>0}let f=i[0],g=i[1],m=i[2],y=i[3],b=i[4],_=i[5],S=i[6],E=i[7];for(let h=0;h<64;h++){let k=(b>>>6|b<<26)^(b>>>11|b<<21)^(b>>>25|b<<7),w=b&_^~b&S,x=E+k+w+Be[h]+u[h]>>>0,T=(f>>>2|f<<30)^(f>>>13|f<<19)^(f>>>22|f<<10),Pe=f&g^f&m^g&m,De=T+Pe>>>0;E=S,S=_,_=b,b=y+x>>>0,y=m,m=g,g=f,f=x+De>>>0}i[0]=i[0]+f>>>0,i[1]=i[1]+g>>>0,i[2]=i[2]+m>>>0,i[3]=i[3]+y>>>0,i[4]=i[4]+b>>>0,i[5]=i[5]+_>>>0,i[6]=i[6]+S>>>0,i[7]=i[7]+E>>>0}let d="";for(let l=0;l<8;l++)d+=i[l].toString(16).padStart(8,"0");return d}var He=1440*60*1e3,H="_anon",We="_index",W=class r{constructor(e,t="crossdeck:entitlements",n=He){this.all=[];this.lastUpdated=0;this.lastRefreshFailedAt=0;this.listeners=new Set;this.listenerErrorCount=0;this.currentSuffix=H;this.storage=e,this.storageKeyPrefix=t,this.staleAfterMs=n,this.hydrate()}get storageKey(){return`${this.storageKeyPrefix}:${this.currentSuffix}`}get indexKey(){return`${this.storageKeyPrefix}:${We}`}static suffixForUserId(e){return e==null||e===""?H:j(e)}setUserKey(e){let t=r.suffixForUserId(e);if(t===this.currentSuffix){this.all=[],this.lastUpdated=0,this.lastRefreshFailedAt=0,this.notify(),this.hydrate();return}this.currentSuffix=t,this.all=[],this.lastUpdated=0,this.lastRefreshFailedAt=0,this.hydrate(),this.notify()}isEntitled(e){let t=Date.now()/1e3;return this.all.some(n=>n.key===e&&n.isActive&&(n.validUntil==null||n.validUntil>t))}list(){return this.all.slice()}get freshness(){return this.lastUpdated}get isStale(){return this.lastRefreshFailedAt>this.lastUpdated?!0:this.lastUpdated>0&&Date.now()-this.lastUpdated>this.staleAfterMs}get refreshFailedAt(){return this.lastRefreshFailedAt}get listenerErrors(){return this.listenerErrorCount}markRefreshFailed(){this.lastRefreshFailedAt=Date.now()}setFromList(e){this.all=e.slice(),this.lastUpdated=Date.now(),this.lastRefreshFailedAt=0,this.persist(),this.recordSuffixInIndex(this.currentSuffix),this.notify()}clear(){if(this.all=[],this.lastUpdated=0,this.lastRefreshFailedAt=0,this.storage)try{this.storage.removeItem(this.storageKey)}catch{}this.removeSuffixFromIndex(this.currentSuffix),this.notify()}clearAll(){if(this.all=[],this.lastUpdated=0,this.lastRefreshFailedAt=0,this.currentSuffix=H,this.storage){let e=this.readIndex();for(let t of e)try{this.storage.removeItem(`${this.storageKeyPrefix}:${t}`)}catch{}try{this.storage.removeItem(`${this.storageKeyPrefix}:${H}`)}catch{}try{this.storage.removeItem(this.indexKey)}catch{}}this.notify()}subscribe(e){this.listeners.add(e);let t=!1;return()=>{t||(t=!0,this.listeners.delete(e))}}hydrate(){if(this.storage)try{let e=this.storage.getItem(this.storageKey);if(!e)return;let t=JSON.parse(e);t&&t.v===1&&Array.isArray(t.entitlements)&&(this.all=t.entitlements,this.lastUpdated=typeof t.lastUpdated=="number"?t.lastUpdated:0)}catch{}}persist(){if(this.storage)try{let e={v:1,entitlements:this.all,lastUpdated:this.lastUpdated};this.storage.setItem(this.storageKey,JSON.stringify(e))}catch{}}readIndex(){if(!this.storage)return[];try{let e=this.storage.getItem(this.indexKey);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(n=>typeof n=="string"):[]}catch{return[]}}recordSuffixInIndex(e){if(!this.storage)return;let t=this.readIndex();if(!t.includes(e)){t.push(e);try{this.storage.setItem(this.indexKey,JSON.stringify(t))}catch{}}}removeSuffixFromIndex(e){if(!this.storage)return;let t=this.readIndex(),n=t.filter(s=>s!==e);if(n.length!==t.length)try{n.length===0?this.storage.removeItem(this.indexKey):this.storage.setItem(this.indexKey,JSON.stringify(n))}catch{}}notify(){if(this.listeners.size===0)return;let e=this.all.slice(),t=[...this.listeners];for(let n of t)try{n(e)}catch{this.listenerErrorCount+=1}}};function Xe(r){return[r.slice(0,8),r.slice(8,12),r.slice(12,16),r.slice(16,20),r.slice(20,32)].join("-")}function be(r){let e;if(r.rail==="apple"?e=r.signedTransactionInfo??"":r.rail==="google"?e=r.purchaseToken??"":e="",!e)throw new Error(`deriveIdempotencyKeyForPurchase: no stable identifier in body (rail=${r.rail}). Apple needs signedTransactionInfo; Google needs purchaseToken.`);let t=`crossdeck:purchases/sync:${r.rail}:${e}`;return Xe(j(t))}function ze(r,e,t={},n=Math.random){let s=t.baseMs??1e3,o=t.maxMs??6e4,c=t.factor??2,a=Math.min(r,30),u=Math.min(o,s*Math.pow(c,a))*n();if(e!==void 0){let l=Math.min(864e5,e);if(l>u)return l}return Math.max(0,Math.round(u))}var X=class{constructor(e={}){this.options=e;this.attempts=0}get consecutiveFailures(){return this.attempts}get isWarning(){return this.attempts>=(this.options.failuresBeforeWarn??8)}nextDelay(e,t=Math.random){let n=ze(this.attempts,e,this.options,t);return this.attempts+=1,n}recordSuccess(){this.attempts=0}};var U=1e3,z=class{constructor(e){this.cfg=e;this.buffer=[];this.pendingBatch=null;this.pendingBatchId=null;this.dropped=0;this.inFlight=0;this.lastFlushAt=0;this.lastError=null;this.cancelTimer=null;this.firstFlushFired=!1;this.nextRetryAt=null;if(this.retry=new X(e.retry??{}),this.persistent=e.persistentStore??null,this.persistent){let t=this.persistent.load();t.length>0&&(t.length>U?(this.dropped+=t.length-U,this.buffer=t.slice(t.length-U)):this.buffer=t,this.cfg.onBufferChange?.(this.buffer.length),this.scheduleIdleFlush())}}enqueue(e){if(this.buffer.push(e),this.buffer.length>U){let t=this.buffer.length-U;this.buffer.splice(0,t),this.dropped+=t,this.cfg.onDrop?.(t)}this.cfg.onBufferChange?.(this.buffer.length),this.persistAll(),this.buffer.length>=this.cfg.batchSize?this.flush():this.scheduleIdleFlush()}async flush(e={}){let t,n;if(this.pendingBatch!==null&&this.pendingBatchId!==null)t=this.pendingBatch,n=this.pendingBatchId;else{if(this.buffer.length===0)return null;t=this.buffer.splice(0),n=this.mintBatchId(),this.pendingBatch=t,this.pendingBatchId=n,this.inFlight+=t.length,this.cfg.onBufferChange?.(this.buffer.length),this.persistAll()}this.cancelTimerIfSet(),this.nextRetryAt=null;try{let s=this.cfg.envelope(),o=await this.cfg.http.request("POST","/events",{body:{appId:s.appId,environment:s.environment,sdk:s.sdk,events:t},keepalive:e.keepalive===!0,idempotencyKey:n});return this.lastFlushAt=Date.now(),this.lastError=null,this.inFlight-=t.length,this.pendingBatch=null,this.pendingBatchId=null,this.retry.recordSuccess(),this.persistAll(),this.firstFlushFired||(this.firstFlushFired=!0,this.cfg.onFirstFlushSuccess?.()),o}catch(s){let o=s instanceof Error?s.message:String(s);if(this.lastError=o,Qe(s)){let i=t.length;return this.pendingBatch=null,this.pendingBatchId=null,this.inFlight-=i,this.dropped+=i,this.persistAll(),this.cfg.onDrop?.(i),this.cfg.onPermanentFailure?.({status:s.status??0,droppedCount:i,lastError:o}),null}let c=Ge(s),a=this.retry.nextDelay(c);return this.scheduleRetry(a),this.cfg.onRetryScheduled?.({delayMs:a,consecutiveFailures:this.retry.consecutiveFailures,retryAfterMs:c,lastError:o}),null}}reset(){this.cancelTimerIfSet(),this.nextRetryAt=null,this.buffer=[],this.pendingBatch=null,this.pendingBatchId=null,this.dropped=0,this.inFlight=0,this.lastError=null,this.retry.recordSuccess(),this.persistent?.clear(),this.cfg.onBufferChange?.(0)}getStats(){return{buffered:this.buffer.length,dropped:this.dropped,inFlight:this.inFlight,lastFlushAt:this.lastFlushAt,lastError:this.lastError,consecutiveFailures:this.retry.consecutiveFailures,nextRetryAt:this.nextRetryAt}}get pendingIdempotencyKey(){return this.pendingBatchId}persistAll(){if(this.persistent){if(this.pendingBatch===null){this.persistent.save(this.buffer);return}this.persistent.save([...this.pendingBatch,...this.buffer])}}scheduleIdleFlush(){this.cancelTimerIfSet();let e=this.cfg.scheduler??ve;this.cancelTimer=e(()=>{this.flush()},this.cfg.intervalMs)}scheduleRetry(e){this.cancelTimerIfSet(),this.nextRetryAt=Date.now()+e;let t=this.cfg.scheduler??ve;this.cancelTimer=t(()=>{this.flush()},e)}cancelTimerIfSet(){this.cancelTimer&&(this.cancelTimer(),this.cancelTimer=null)}mintBatchId(){return`batch_${Date.now().toString(36)}${I(10)}`}};function Ge(r){if(r&&typeof r=="object"&&"retryAfterMs"in r){let e=r.retryAfterMs;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}}function Qe(r){if(!r||typeof r!="object")return!1;let e=r.status;return!(typeof e!="number"||!Number.isFinite(e)||e<400||e>=500||e===408||e===429)}function ve(r,e){let t=setTimeout(r,e);if(typeof t.unref=="function")try{t.unref()}catch{}return()=>clearTimeout(t)}var G=class{constructor(e){this.options=e;this.writeScheduled=!1;this.pendingSnapshot=null;this.key=`${e.prefix}queue.v1`}load(){let e;try{e=this.options.storage.getItem(this.key)}catch{return[]}if(!e)return[];try{let t=JSON.parse(e);return!t||t.version!==1||!Array.isArray(t.events)?[]:t.events}catch{return[]}}save(e){this.pendingSnapshot=e.slice(),!this.writeScheduled&&(this.writeScheduled=!0,queueMicrotask(()=>this.flushWrite()))}saveSync(e){this.pendingSnapshot=e.slice(),this.flushWrite()}clear(){this.pendingSnapshot=null,this.writeScheduled=!1;try{this.options.storage.removeItem(this.key)}catch{}}flushWrite(){this.writeScheduled=!1;let e=this.pendingSnapshot;if(this.pendingSnapshot=null,e===null)return;if(e.length===0){try{this.options.storage.removeItem(this.key)}catch{}return}let t={version:1,events:e};try{this.options.storage.setItem(this.key,JSON.stringify(t))}catch{}}};var C=class{constructor(){this.store=new Map}getItem(e){return this.store.get(e)??null}setItem(e,t){this.store.set(e,t)}removeItem(e){this.store.delete(e)}},Q=class{constructor(e){this.maxAgeSec=e?.maxAgeSec??63072e3,this.secure=e?.secure??Je(),this.sameSite=e?.sameSite??"Lax"}getItem(e){if(!ie())return null;let t=globalThis.document,n=t.cookie?t.cookie.split(/;\s*/):[],s=encodeURIComponent(e)+"=";for(let o of n)if(o.startsWith(s))try{return decodeURIComponent(o.slice(s.length))}catch{return null}return null}setItem(e,t){if(!ie())return;let n=globalThis.document,s=[`${encodeURIComponent(e)}=${encodeURIComponent(t)}`,"Path=/",`Max-Age=${this.maxAgeSec}`,`SameSite=${this.sameSite}`];this.secure&&s.push("Secure");try{n.cookie=s.join("; ")}catch{}}removeItem(e){if(!ie())return;let t=globalThis.document,n=[`${encodeURIComponent(e)}=`,"Path=/","Max-Age=0",`SameSite=${this.sameSite}`];this.secure&&n.push("Secure");try{t.cookie=n.join("; ")}catch{}}};function ke(){try{let r=globalThis.localStorage;if(r){let e="__crossdeck_probe__";return r.setItem(e,"1"),r.removeItem(e),r}}catch{}return new C}function Je(){try{return globalThis.location?.protocol==="https:"}catch{return!1}}function ie(){return typeof globalThis.document<"u"}function Ye(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"&&typeof globalThis.navigator<"u"}function we(r){let e={};if(r?.appVersion&&(e.appVersion=r.appVersion),!Ye())return e;let t=globalThis.window,n=globalThis.navigator,s=globalThis.document;try{typeof n.language=="string"&&(e.locale=n.language)}catch{}try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}try{t.screen&&(e.screenWidth=t.screen.width,e.screenHeight=t.screen.height),e.viewportWidth=t.innerWidth,e.viewportHeight=t.innerHeight,e.devicePixelRatio=t.devicePixelRatio}catch{}try{let o=n.userAgent??"",c=Ze(o);Object.assign(e,c)}catch{}try{let o=n.userAgentData;if(o?.platform&&!e.os&&(e.os=o.platform),o?.brands&&!e.browser){let c=o.brands.find(a=>!/Not[ .;A]*Brand/i.test(a.brand)&&!/Chromium/i.test(a.brand));c&&(e.browser=c.brand,e.browserVersion=c.version)}}catch{}return e}function Ze(r){let e={};if(/iPad|iPhone|iPod/.test(r)){e.os="iOS";let t=r.match(/OS (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else if(/Android/.test(r)){e.os="Android";let t=r.match(/Android (\d+(?:\.\d+)*)/);t?.[1]&&(e.osVersion=t[1])}else if(/Windows/.test(r)){e.os="Windows";let t=r.match(/Windows NT (\d+\.\d+)/);t?.[1]&&(e.osVersion=t[1])}else if(/Mac OS X|Macintosh/.test(r)){e.os="macOS";let t=r.match(/Mac OS X (\d+[._]\d+(?:[._]\d+)?)/);t?.[1]&&(e.osVersion=t[1].replace(/_/g,"."))}else/Linux/.test(r)&&(e.os="Linux");return/Edg\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Edge",e.browserVersion=r.match(/Edg\/(\d+(?:\.\d+)*)/)?.[1]):/Firefox\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Firefox",e.browserVersion=r.match(/Firefox\/(\d+(?:\.\d+)*)/)?.[1]):/OPR\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Opera",e.browserVersion=r.match(/OPR\/(\d+(?:\.\d+)*)/)?.[1]):/Chrome\/(\d+(?:\.\d+)*)/.test(r)?(e.browser="Chrome",e.browserVersion=r.match(/Chrome\/(\d+(?:\.\d+)*)/)?.[1]):/Version\/(\d+(?:\.\d+)*).*Safari/.test(r)&&(e.browser="Safari",e.browserVersion=r.match(/Version\/(\d+(?:\.\d+)*)/)?.[1]),e}var A={sessions:!0,pageViews:!0,deviceInfo:!0,clicks:!0,webVitals:!0,errors:!0},et=1800*1e3,oe={utm_source:"",utm_medium:"",utm_campaign:"",utm_content:"",utm_term:"",referrer:"",gclid:"",fbclid:"",msclkid:"",ttclid:"",li_fat_id:"",twclid:""},M=class{constructor(e,t){this.cfg=e;this.track=t;this.session=null;this.cleanups=[];this.pageviewId=null}install(){_e()&&(this.cfg.sessions&&this.installSessionTracking(),this.cfg.pageViews&&this.installPageViewTracking(),this.cfg.clicks&&this.installClickTracking())}uninstall(){for(;this.cleanups.length;){let e=this.cleanups.pop();try{e?.()}catch{}}this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.session=null}resetSession(){this.session&&!this.session.endedSent&&this.emitSessionEnd(),this.pageviewId=null,this.session=this.startNewSession(),this.emitSessionStart()}get currentSessionId(){return this.session?.sessionId??null}get currentPageviewId(){return this.pageviewId}get currentAcquisition(){return this.session?.acquisition??oe}installSessionTracking(){this.session=this.startNewSession(),this.emitSessionStart();let e=()=>{if(!this.session)return;let o=globalThis.document;o.visibilityState==="hidden"?this.session.hiddenAt=Date.now():o.visibilityState==="visible"&&((this.session.hiddenAt?Date.now()-this.session.hiddenAt:0)>=et?(this.emitSessionEnd(),this.pageviewId=null,this.session=this.startNewSession(),this.emitSessionStart()):this.session.hiddenAt=null)},t=()=>this.emitSessionEnd(),n=globalThis.window,s=globalThis.document;s.addEventListener("visibilitychange",e),n.addEventListener("pagehide",t),n.addEventListener("beforeunload",t),this.cleanups.push(()=>{s.removeEventListener("visibilitychange",e),n.removeEventListener("pagehide",t),n.removeEventListener("beforeunload",t)})}startNewSession(){return{sessionId:ut(),startedAt:Date.now(),hiddenAt:null,endedSent:!1,acquisition:lt()}}emitSessionStart(){this.session&&this.track("session.started",{sessionId:this.session.sessionId})}emitSessionEnd(){if(!this.session||this.session.endedSent)return;let e=Date.now()-this.session.startedAt;this.track("session.ended",{sessionId:this.session.sessionId,durationMs:e}),this.session.endedSent=!0}installPageViewTracking(){let e=globalThis.window,t=globalThis.document,n=0,s="",o=250,c=(p=!1)=>{let f=e.location,g=f.href,m=Date.now();!p&&g===s&&m-n<o||(n=m,s=g,this.pageviewId=`pv_${Date.now().toString(36)}${I(10)}`,this.track("page.viewed",{pageviewId:this.pageviewId,path:f.pathname,url:g,search:f.search||void 0,hash:f.hash||void 0,title:t.title,referrer:t.referrer||void 0}))};c();let a=e.history.pushState,i=e.history.replaceState;function u(p,f,g){a.apply(this,[p,f,g]),queueMicrotask(c)}function d(p,f,g){i.apply(this,[p,f,g]),queueMicrotask(c)}e.history.pushState=u,e.history.replaceState=d;let l=()=>c(!0);e.addEventListener("popstate",l),this.cleanups.push(()=>{e.history.pushState===u&&(e.history.pushState=a),e.history.replaceState===d&&(e.history.replaceState=i),e.removeEventListener("popstate",l)})}installClickTracking(){let e=globalThis.window,t=globalThis.document,n=0,s=null,o=100,c=64,a=i=>{let u=i.target;if(!u||!(u instanceof Element))return;let d=Date.now();if(u===s&&d-n<o)return;n=d,s=u;let p=tt(u)||u;if(rt(p)||nt(p)||st(p))return;let f=p.tagName.toLowerCase(),g=ot(it(p),c),m=p.href||void 0,y=p.target||void 0,b=p.id||void 0,_=p.getAttribute("role")||void 0,S=p.getAttribute("aria-label")||void 0,E=at(p),h=ct(p),k=f==="a"&&!!m,w=p.getAttribute("data-cd-event"),x={selector:E,tag:f,text:g,elementId:b,role:_,ariaLabel:S,href:m,isLink:k,linkTarget:y,viewportX:i.clientX,viewportY:i.clientY,pageX:i.pageX,pageY:i.pageY,...h};for(let T of Object.keys(x))(x[T]===void 0||x[T]===null||x[T]==="")&&delete x[T];this.track(w||"element.clicked",x)};t.addEventListener("click",a,{capture:!0,passive:!0}),this.cleanups.push(()=>{t.removeEventListener("click",a,{capture:!0})})}};function tt(r){return r.closest("[data-cd-event]")||r.closest("[data-cd-noTrack]")||r.closest("button, a, [role='button'], [role='link'], input[type='button'], input[type='submit']")||null}function rt(r){if(!(r instanceof HTMLElement))return!1;let e=r.tagName.toLowerCase();if(e==="textarea"||e==="select")return!0;if(e==="input"){let t=(r.type||"").toLowerCase();return t!=="button"&&t!=="submit"&&t!=="image"&&t!=="reset"}return!1}function nt(r){return!!r.closest("[data-cd-noTrack], [data-cd-no-track], .cd-noTrack, .cd-no-track")}function st(r){return!!r.closest('input[type="password"]')}function it(r){let e=u=>u.replace(/\s+/g," ").trim(),t=r.getAttribute("data-cd-track")||r.getAttribute("data-track")||r.getAttribute("data-testid");if(t){let u=e(t);if(u)return u}let n=r.getAttribute("aria-label");if(n){let u=e(n);if(u)return u}let s=r.getAttribute("aria-labelledby");if(s&&typeof r.ownerDocument?.getElementById=="function"){let u=[];for(let d of s.split(/\s+/)){let l=r.ownerDocument.getElementById(d),p=l?.textContent?e(l.textContent):"";p&&u.push(p)}if(u.length>0)return u.join(" ")}if(r instanceof HTMLInputElement&&r.value){let u=e(r.value);if(u)return u}let o=e(r.textContent||"");if(o)return o;let c=r.getAttribute("title");if(c){let u=e(c);if(u)return u}let a=r.querySelector("img[alt]");if(a){let u=a.getAttribute("alt")??"",d=e(u);if(d)return d}let i=r.querySelector("svg title");if(i?.textContent){let u=e(i.textContent);if(u)return u}return""}function ot(r,e){return r.length<=e?r:r.slice(0,e-1)+"\u2026"}function at(r){let e=[],t=r,n=0;for(;t&&t.nodeName.toLowerCase()!=="body"&&n<5;){let s=t.nodeName.toLowerCase();if(t.id){e.unshift(`${s}#${t.id}`);break}if(t.classList.length>0){let o=Array.from(t.classList).filter(c=>!c.startsWith("cd-")).slice(0,2).join(".");o&&(s+=`.${o}`)}e.unshift(s),t=t.parentElement,n++}return e.join(" > ")}function ct(r){let e={};if(!(r instanceof HTMLElement))return e;for(let t of r.getAttributeNames()){if(!t.startsWith("data-")||t==="data-cd-noTrack"||t==="data-cd-no-track"||t==="data-cd-event")continue;let n=r.getAttribute(t)||"",s=t.replace(/^data-cd-prop-/,"").replace(/^data-/,"");e[s]=n}return e}function _e(){return typeof globalThis.window<"u"&&typeof globalThis.document<"u"}function ut(){return`sess_${Date.now().toString(36)}${I(10)}`}function lt(){if(!_e())return{...oe};let r={...oe};try{let e=globalThis.window,t=new URLSearchParams(e.location.search??"");r.utm_source=t.get("utm_source")??"",r.utm_medium=t.get("utm_medium")??"",r.utm_campaign=t.get("utm_campaign")??"",r.utm_content=t.get("utm_content")??"",r.utm_term=t.get("utm_term")??"",r.gclid=t.get("gclid")??"",r.fbclid=t.get("fbclid")??"",r.msclkid=t.get("msclkid")??"",r.ttclid=t.get("ttclid")??"",r.li_fat_id=t.get("li_fat_id")??"",r.twclid=t.get("twclid")??""}catch{}try{let e=globalThis.document;typeof e.referrer=="string"&&(r.referrer=e.referrer)}catch{}return r}var dt=[/^email$/i,/^password$/i,/^token$/i,/^secret$/i,/^card$/i,/^phone$/i,/password/i,/credit_?card/i];function xe(r){if(!r)return[];let e=[];for(let t of Object.keys(r))dt.some(n=>n.test(t))&&e.push(t);return e}var J=class{constructor(){this.enabled=!1;this.seen=new Set}emit(e,t,n){if(!this.enabled)return;if(pt.has(e)){if(this.seen.has(e))return;this.seen.add(e)}let s=n?` ${ft(n)}`:"";console.info(`[crossdeck:${e}] ${t}${s}`)}},pt=new Set(["sdk.configured","sdk.first_event_sent","sdk.environment_mismatch"]);function ft(r){try{return JSON.stringify(r)}catch{return"[unserialisable context]"}}function q(r,e={}){let t=[];if(!r)return{properties:{},warnings:t};let n=e.maxStringLength??1024,s=e.maxBatchPropertyBytes??8192,o=e.maxDepth??5,c=new Set,a=(d,l,p)=>{if(p>o)return t.push({kind:"depth_exceeded",key:l}),{keep:!0,value:"[depth-exceeded]"};if(d===null)return{keep:!0,value:null};let f=typeof d;if(f==="string"){let g=d;return g.length>n?(t.push({kind:"truncated_string",key:l}),{keep:!0,value:g.slice(0,n-1)+"\u2026"}):{keep:!0,value:g}}if(f==="number")return Number.isFinite(d)?{keep:!0,value:d}:(t.push({kind:"non_serialisable",key:l}),{keep:!0,value:null});if(f==="boolean")return{keep:!0,value:d};if(f==="bigint")return t.push({kind:"coerced_bigint",key:l}),{keep:!0,value:d.toString()};if(f==="function")return t.push({kind:"dropped_function",key:l}),{keep:!1,value:void 0};if(f==="symbol")return t.push({kind:"dropped_symbol",key:l}),{keep:!1,value:void 0};if(f==="undefined")return t.push({kind:"dropped_undefined",key:l}),{keep:!1,value:void 0};if(d instanceof Date)return t.push({kind:"coerced_date",key:l}),{keep:!0,value:Number.isFinite(d.getTime())?d.toISOString():null};if(d instanceof Error)return t.push({kind:"coerced_error",key:l}),{keep:!0,value:{name:d.name,message:d.message,stack:typeof d.stack=="string"?d.stack.slice(0,n):void 0}};if(d instanceof Map){t.push({kind:"coerced_map",key:l});let g={};for(let[m,y]of d.entries()){let b=typeof m=="string"?m:String(m),_=a(y,`${l}.${b}`,p+1);_.keep&&(g[b]=_.value)}return{keep:!0,value:g}}if(d instanceof Set){t.push({kind:"coerced_set",key:l});let g=[],m=0;for(let y of d.values()){let b=a(y,`${l}[${m}]`,p+1);b.keep&&g.push(b.value),m++}return{keep:!0,value:g}}if(Array.isArray(d)){if(c.has(d))return t.push({kind:"circular_reference",key:l}),{keep:!0,value:"[circular]"};c.add(d);let g=[];for(let m=0;m<d.length;m++){let y=a(d[m],`${l}[${m}]`,p+1);y.keep&&g.push(y.value)}return c.delete(d),{keep:!0,value:g}}if(f==="object"){let g=d;if(c.has(g))return t.push({kind:"circular_reference",key:l}),{keep:!0,value:"[circular]"};c.add(g);let m={};for(let y of Object.keys(g)){let b=a(g[y],`${l}.${y}`,p+1);b.keep&&(m[y]=b.value)}return c.delete(g),{keep:!0,value:m}}t.push({kind:"non_serialisable",key:l});try{return{keep:!0,value:String(d)}}catch{return{keep:!1,value:void 0}}},i={};for(let d of Object.keys(r)){let l=a(r[d],d,0);l.keep&&(i[d]=l.value)}let u=Se(i);if(u&&ae(u)>s){t.push({kind:"size_cap_exceeded",key:"*"});let d=Object.keys(i).map(p=>({k:p,size:ae(Se(i[p])??"")})).sort((p,f)=>f.size-p.size),l=ae(u);for(let{k:p}of d){if(l<=s)break;l-=d.find(f=>f.k===p).size,delete i[p]}i.__truncated=!0}return{properties:i,warnings:t}}function Se(r){try{return JSON.stringify(r)??null}catch{return null}}function ae(r){return typeof TextEncoder<"u"?new TextEncoder().encode(r).length:r.length*4}var Y="super_props",ce="groups",Z=class{constructor(e,t){this.storage=e;this.prefix=t;this.superProps={};this.groups={};this.superProps=Ee(e,t+Y)??{},this.groups=Ee(e,t+ce)??{}}register(e){for(let[t,n]of Object.entries(e))n===null?delete this.superProps[t]:n!==void 0&&(this.superProps[t]=n);return ue(this.storage,this.prefix+Y,this.superProps),{...this.superProps}}unregister(e){e in this.superProps&&(delete this.superProps[e],ue(this.storage,this.prefix+Y,this.superProps))}getSuperProperties(){return{...this.superProps}}setGroup(e,t,n){t===null?delete this.groups[e]:this.groups[e]=n!==void 0?{id:t,traits:n}:{id:t},ue(this.storage,this.prefix+ce,this.groups)}getGroups(){return JSON.parse(JSON.stringify(this.groups))}getGroupIds(){let e={};for(let[t,n]of Object.entries(this.groups))e[t]=n.id;return e}clear(){this.superProps={},this.groups={};try{this.storage.removeItem(this.prefix+Y)}catch{}try{this.storage.removeItem(this.prefix+ce)}catch{}}};function Ee(r,e){let t;try{t=r.getItem(e)}catch{return null}if(!t)return null;try{return JSON.parse(t)}catch{return null}}function ue(r,e,t){try{r.setItem(e,JSON.stringify(t))}catch{}}var ee=class{constructor(e,t){this.cfg=e;this.report=t;this.observers=[];this.flushed=new Set;this.cls=0;this.clsEntries=[];this.inp=0;this.cleanups=[]}install(){if(!this.cfg.enabled||typeof PerformanceObserver>"u"||typeof globalThis>"u"||!("document"in globalThis))return;let e=globalThis.document;try{let o=new PerformanceObserver(c=>{for(let a of c.getEntries()){let i=a;i.responseStart>0&&!this.flushed.has("ttfb")&&(this.flushed.add("ttfb"),this.report("webvitals.ttfb",{valueMs:Math.round(i.responseStart-i.startTime)}))}});o.observe({type:"navigation",buffered:!0}),this.observers.push(o)}catch{}try{let o=new PerformanceObserver(c=>{for(let a of c.getEntries())a.name==="first-contentful-paint"&&!this.flushed.has("fcp")&&(this.flushed.add("fcp"),this.report("webvitals.fcp",{valueMs:Math.round(a.startTime)}))});o.observe({type:"paint",buffered:!0}),this.observers.push(o)}catch{}let t=0;try{let o=new PerformanceObserver(c=>{let a=c.getEntries(),i=a[a.length-1];i&&(t=i.startTime)});o.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(o)}catch{}try{let o=new PerformanceObserver(c=>{for(let a of c.getEntries()){let i=a;typeof i.value=="number"&&!i.hadRecentInput&&(this.cls+=i.value,this.clsEntries.push(a))}});o.observe({type:"layout-shift",buffered:!0}),this.observers.push(o)}catch{}try{let o=new PerformanceObserver(c=>{for(let a of c.getEntries()){let i=a;i.interactionId&&i.duration>this.inp&&(this.inp=i.duration)}});try{o.observe({type:"event",buffered:!0,durationThreshold:16})}catch{o.observe({type:"first-input",buffered:!0})}this.observers.push(o)}catch{}let n=()=>{t>0&&!this.flushed.has("lcp")&&(this.flushed.add("lcp"),this.report("webvitals.lcp",{valueMs:Math.round(t)})),this.cls>0&&!this.flushed.has("cls")&&(this.flushed.add("cls"),this.report("webvitals.cls",{value:Math.round(this.cls*1e3)/1e3})),this.inp>0&&!this.flushed.has("inp")&&(this.flushed.add("inp"),this.report("webvitals.inp",{valueMs:Math.round(this.inp)}))},s=()=>{e.visibilityState==="hidden"&&n()};e.addEventListener("visibilitychange",s),globalThis.window.addEventListener("pagehide",n),this.cleanups.push(()=>{e.removeEventListener("visibilitychange",s),globalThis.window.removeEventListener("pagehide",n)})}uninstall(){for(let e of this.observers)try{e.disconnect()}catch{}this.observers=[];for(let e of this.cleanups.splice(0))try{e()}catch{}}};var ht={analytics:!0,marketing:!0,errors:!0},te=class{constructor(e){this.state={...ht};this.dntDenied=!1;e?.respectDnt&&this.detectDnt()&&(this.dntDenied=!0,this.state={analytics:!1,marketing:!1,errors:!1})}set(e){if(this.dntDenied)return{...this.state};for(let t of Object.keys(e)){let n=e[t];typeof n=="boolean"&&(this.state[t]=n)}return{...this.state}}get(){return{...this.state}}get analytics(){return this.state.analytics}get marketing(){return this.state.marketing}get errors(){return this.state.errors}get isDntDenied(){return this.dntDenied}detectDnt(){try{let e=globalThis.navigator;return e?[e.doNotTrack,e.msDoNotTrack,globalThis.doNotTrack].some(n=>n==="1"||n==="yes"):!1}catch{return!1}}},gt=/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,mt=/\b\d(?:[ -]?\d){12,18}\b/g,yt="<email>",bt="<card>";function vt(r){return r&&r.replace(gt,yt).replace(mt,bt)}function le(r){let e={};for(let t of Object.keys(r))e[t]=Te(r[t]);return e}function Te(r){return typeof r=="string"?vt(r):Array.isArray(r)?r.map(Te):r&&typeof r=="object"&&r.constructor===Object?le(r):r}var re=class{constructor(e=50){this.maxSize=e;this.items=[]}add(e){this.items.push(e),this.items.length>this.maxSize&&this.items.shift()}snapshot(){return this.items.slice()}clear(){this.items=[]}get size(){return this.items.length}};function pe(r){if(!r||typeof r!="string")return[];let e=r.split(`
|
|
2
|
+
`),t=[];for(let n of e){let s=n.trim();if(!s)continue;let o=kt(s);o&&t.push(o)}return t}function kt(r){let e=/^at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)$/.exec(r);return e?de({function:e[1],filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):(e=/^at\s+(.+?):(\d+):(\d+)$/.exec(r),e?de({function:"?",filename:e[1],lineno:parseInt(e[2],10),colno:parseInt(e[3],10),raw:r}):(e=/^(.*?)@(.+?):(\d+):(\d+)$/.exec(r),e?de({function:e[1]||"?",filename:e[2],lineno:parseInt(e[3],10),colno:parseInt(e[4],10),raw:r}):/^\w*Error/.test(r)||!r.includes(":")?null:{function:"?",filename:"",lineno:0,colno:0,in_app:!0,raw:r}))}function de(r){return{function:r.function||"?",filename:r.filename,lineno:Number.isFinite(r.lineno)?r.lineno:0,colno:Number.isFinite(r.colno)?r.colno:0,in_app:wt(r.filename),raw:r.raw}}function wt(r){return r?!(/^(?:chrome|moz|safari|webkit)-extension:\/\//.test(r)||/\bcdn\.jsdelivr\.net\b/.test(r)||/\bunpkg\.com\b/.test(r)||/\bgoogletagmanager\.com\b/.test(r)||/\bgoogle-analytics\.com\b/.test(r)||/\b@cross-deck\/web\b/.test(r)||/\/crossdeck\.umd\.min\.js$/.test(r)):!0}function P(r,e,t){let n=e.filter(o=>o.in_app).slice(0,3),s=[(r||"").slice(0,200),...n.map(o=>`${o.function}@${o.filename}:${o.lineno}`)];if(n.length===0&&t){let o=[t.errorType??"",t.filename??"",t.lineno??"",t.colno??""].join(":");o!==":::"&&s.push(o)}return _t(s.join("|"))}function _t(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e+r.charCodeAt(t)|0;return(e>>>0).toString(16).padStart(8,"0")}var Ie={enabled:!0,onError:!0,onUnhandledRejection:!0,wrapFetch:!0,wrapXhr:!0,captureConsole:!1,ignoreErrors:["ResizeObserver loop limit exceeded","ResizeObserver loop completed with undelivered notifications","Non-Error promise rejection captured"],allowUrls:[],denyUrls:[/^chrome-extension:\/\//,/^moz-extension:\/\//,/^safari-extension:\/\//,/^webkit-extension:\/\//,/^safari-web-extension:\/\//],sampleRate:1,maxPerFingerprintPerMinute:5,maxPerSession:100},ne=class{constructor(e){this.opts=e;this.installed=!1;this.cleanups=[];this._reporting=!1;this.sessionCount=0;this.fingerprintWindow=new Map}install(){if(this.installed||!this.opts.config.enabled||typeof globalThis>"u"||!("window"in globalThis))return;let e=globalThis.window;this.opts.config.onError&&this.installOnErrorListener(e),this.opts.config.onUnhandledRejection&&this.installRejectionListener(e),this.opts.config.wrapFetch&&this.installFetchWrap(e),this.opts.config.wrapXhr&&this.installXhrWrap(e),this.opts.config.captureConsole&&this.installConsoleWrap(),this.installed=!0}uninstall(){for(let e of this.cleanups.splice(0))try{e()}catch{}this.installed=!1}captureError(e,t){if(this.opts.isConsented())try{let n=this.buildFromUnknown(e,"error.handled",t?.level??"error");t?.context&&(n.context={...n.context,...t.context}),t?.tags&&(n.tags={...n.tags,...t.tags}),this.maybeReport(n)}catch{}}captureMessage(e,t="info"){if(this.opts.isConsented())try{let n={timestamp:Date.now(),kind:"error.message",level:t,message:e,errorType:null,frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:P(e,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags()};this.maybeReport(n)}catch{}}installOnErrorListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromErrorEvent(n);this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("error",t,!0),this.cleanups.push(()=>e.removeEventListener("error",t,!0))}installRejectionListener(e){let t=n=>{if(!this._reporting&&this.opts.isConsented())try{this._reporting=!0;let s=this.buildFromUnknown(n.reason,"error.unhandledrejection","error");this.maybeReport(s)}catch{}finally{this._reporting=!1}};e.addEventListener("unhandledrejection",t),this.cleanups.push(()=>e.removeEventListener("unhandledrejection",t))}installFetchWrap(e){let t=e.fetch?.bind(e);if(!t)return;let n=async(...s)=>{let o=s[0],c=s[1]??{},a=typeof o=="string"?o:o?.url??"",i=(c.method||"GET").toUpperCase(),u=Date.now();he(a,this.opts.selfHostname)||this.opts.breadcrumbs.add({timestamp:u,category:"http",message:`${i} ${a}`,data:{url:a,method:i}});try{let d=await t(...s);return d.status>=500&&this.opts.isConsented()&&(he(a,this.opts.selfHostname)||this.captureHttp({url:a,method:i,status:d.status,statusText:d.statusText})),d}catch(d){throw this.opts.isConsented()&&!a.includes("api.cross-deck.com")&&this.captureHttp({url:a,method:i,status:0,statusText:d instanceof Error?d.message:"network error"}),d}};e.fetch=n,this.cleanups.push(()=>{e.fetch===n&&(e.fetch=t)})}installXhrWrap(e){let n=e.XMLHttpRequest?.prototype;if(!n)return;let s=n.open,o=n.send,c=this;n.open=function(a,i,...u){return this._cdMethod=a,this._cdUrl=i,s.apply(this,[a,i,...u])},n.send=function(a){let i=this,u=()=>{try{if(i.status>=500&&c.opts.isConsented()){let d=i._cdUrl??"";he(d,c.opts.selfHostname)||c.captureHttp({url:d,method:(i._cdMethod??"GET").toUpperCase(),status:i.status,statusText:i.statusText})}}catch{}};return i.addEventListener("loadend",u),o.apply(this,[a??null])},this.cleanups.push(()=>{n.open=s,n.send=o})}installConsoleWrap(){let e=globalThis.console;if(!e)return;let t=e.error.bind(e);e.error=(...n)=>{try{this.opts.isConsented()&&this.captureMessage(n.map(s=>St(s)).join(" "),"error")}catch{}return t(...n)},this.cleanups.push(()=>{e.error=t})}buildFromErrorEvent(e){let t=e.error,n=e.filename||null,s=typeof e.lineno=="number"&&e.lineno>0?e.lineno:null,o=typeof e.colno=="number"&&e.colno>0?e.colno:null;if(t==null&&!n&&s==null&&(e.message==="Script error."||e.message==="Script error"||!e.message)){let f="Cross-origin script error (browser hid details \u2014 script needs crossorigin attribute + CORS headers)";return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:f,errorType:"ScriptError",frames:[],rawStack:null,filename:null,lineno:null,colno:null,fingerprint:P(f,[]),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:{...this.opts.getTags(),cross_origin:"true"}}}let a=ge(t),i=(a.message||e.message||"Unknown error").slice(0,1024),u=t instanceof Error?t.stack??null:null,d=pe(u),l=a.errorType??null,p=a.extras?{...this.opts.getContext(),__error_extras:a.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:"error.unhandled",level:"error",message:i,errorType:l,frames:d,rawStack:u,filename:n,lineno:s,colno:o,fingerprint:P(i,d,{filename:n,lineno:s,colno:o,errorType:l}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:p,tags:this.opts.getTags()}}buildFromUnknown(e,t,n){let s=ge(e),o=(s.message||"Unknown error").slice(0,1024),c=e instanceof Error?e.stack??null:null,a=pe(c),i=s.errorType??null,u=s.extras?{...this.opts.getContext(),__error_extras:s.extras}:this.opts.getContext();return{timestamp:Date.now(),kind:t,level:n,message:o,errorType:i,frames:a,rawStack:c,filename:null,lineno:null,colno:null,fingerprint:P(o,a,{errorType:i}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:u,tags:this.opts.getTags()}}captureHttp(e){try{let t=`HTTP ${e.status} ${e.method} ${e.url}`,n={timestamp:Date.now(),kind:"error.http",level:"error",message:t,errorType:"HTTPError",frames:[],rawStack:null,filename:e.url,lineno:null,colno:null,fingerprint:P(`HTTP ${e.status} ${e.method}`,[],{filename:e.url,errorType:"HTTPError"}),breadcrumbs:this.opts.breadcrumbs.snapshot(),context:this.opts.getContext(),tags:this.opts.getTags(),http:e};this.maybeReport(n)}catch{}}maybeReport(e){if(this.sessionCount>=this.opts.config.maxPerSession||this.shouldIgnore(e)||!this.passesUrlGate(e)||!this.passesSample(e)||!this.passesRateLimit(e))return;let t=e,n=this.opts.beforeSend?.();if(n){try{t=n(e)}catch{t=e}if(!t)return}this.sessionCount+=1;try{this.opts.report(t)}catch{}}shouldIgnore(e){for(let t of this.opts.config.ignoreErrors)if(typeof t=="string"&&e.message.includes(t)||t instanceof RegExp&&t.test(e.message))return!0;return!1}passesUrlGate(e){let n=(e.frames.find(s=>s.filename)??null)?.filename??e.filename??"";if(!n)return!0;for(let s of this.opts.config.denyUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!1;if(this.opts.config.allowUrls.length>0){for(let s of this.opts.config.allowUrls)if(typeof s=="string"&&n.includes(s)||s instanceof RegExp&&s.test(n))return!0;return!1}return!0}passesSample(e){return this.opts.config.sampleRate>=1?!0:this.opts.config.sampleRate<=0?!1:parseInt(e.fingerprint.slice(0,2),16)/255<this.opts.config.sampleRate}passesRateLimit(e){let n=Date.now(),s=this.opts.config.maxPerFingerprintPerMinute,c=(this.fingerprintWindow.get(e.fingerprint)??[]).filter(a=>n-a<6e4);return c.length>=s?(this.fingerprintWindow.set(e.fingerprint,c),!1):(c.push(n),this.fingerprintWindow.set(e.fingerprint,c),!0)}};function ge(r){if(r===null)return{message:"(thrown: null)",errorType:null,extras:null};if(r===void 0)return{message:"(thrown: undefined)",errorType:null,extras:null};if(typeof r=="string")return{message:r,errorType:null,extras:null};if(typeof r=="number"||typeof r=="boolean"||typeof r=="bigint")return{message:String(r),errorType:typeof r,extras:null};if(typeof r=="symbol")return{message:r.toString(),errorType:"symbol",extras:null};if(typeof r=="function")return{message:`(thrown function: ${r.name||"anonymous"})`,errorType:"function",extras:null};if(r instanceof Error){let e=r.name||r.constructor?.name||"Error",t=typeof r.message=="string"&&r.message.length>0?r.message:D(r)||e,n={},s=xt(r);s.length>0&&(n.cause=s);for(let o of["code","status","statusCode","errno","response","data","detail","details"]){let c=r[o];c!==void 0&&typeof c!="function"&&(n[o]=fe(c))}for(let o of Object.keys(r)){if(o==="message"||o==="stack"||o==="name"||o==="cause"||o in n)continue;let c=r[o];typeof c!="function"&&(n[o]=fe(c))}return{message:t,errorType:e,extras:Object.keys(n).length>0?n:null}}if(typeof Response<"u"&&r instanceof Response)return{message:`HTTP ${r.status} ${r.statusText||""}${r.url?` ${r.url}`:""}`.trim(),errorType:"Response",extras:{status:r.status,statusText:r.statusText,url:r.url,type:r.type}};if(typeof r=="object"){let e=r,t=e.constructor&&typeof e.constructor=="function"&&e.constructor.name||null,n=typeof e.message=="string"&&e.message?e.message:null,s=typeof e.name=="string"&&e.name?e.name:null,o=null;try{let l=JSON.stringify(e);o=l==="{}"?null:l}catch{o=null}let c=D(e),a=n??o??(c&&c!=="[object Object]"?c:null)??(t?`(thrown ${t} with no message)`:"(thrown object with no message)"),i=s??t??null,u={},d=0;for(let l of Object.keys(e)){if(d>=20)break;if(l==="message"||l==="name")continue;let p=e[l];typeof p!="function"&&(u[l]=fe(p),d++)}return{message:a,errorType:i,extras:Object.keys(u).length>0?u:null}}return{message:D(r)||"(unstringifiable thrown value)",errorType:null,extras:null}}function xt(r){let e=[],t=r.cause,n=0;for(;t!=null&&n<5;)t instanceof Error?(e.push({name:t.name||"Error",message:t.message||""}),t=t.cause):(e.push({name:"non-Error",message:D(t)}),t=null),n++;return e}function D(r){try{let e=Object.prototype.toString.call(r);if(e!=="[object Object]")return e;let t=r?.toString;if(typeof t=="function"&&t!==Object.prototype.toString){let n=t.call(r);if(typeof n=="string")return n}return e}catch{return"(throwing toString)"}}function fe(r){if(r==null)return r;let e=typeof r;if(e==="string"||e==="number"||e==="boolean")return r;if(e==="bigint")return String(r);try{let t=JSON.stringify(r);return t===void 0?D(r):JSON.parse(t)}catch{return D(r)}}function St(r){return ge(r).message}function Ce(r){if(!r||typeof r!="string")return null;try{return new URL(r).hostname.toLowerCase()}catch{return null}}function he(r,e){if(!e||!r)return!1;try{return new URL(r).hostname.toLowerCase()===e}catch{return!1}}var V=class{constructor(){this.state=null}init(e){if(this.state){try{this.state.uninstallUnloadFlush?.()}catch{}try{this.state.autoTracker?.uninstall()}catch{}try{this.state.webVitals?.uninstall()}catch{}try{this.state.errors?.uninstall()}catch{}try{this.state.events.flush({keepalive:!0})}catch{}}if(!e.publicKey||!e.publicKey.startsWith("cd_pub_"))throw new v({type:"configuration_error",code:"invalid_public_key",message:"Crossdeck.init requires a publishable key starting with cd_pub_."});if(!e.appId)throw new v({type:"configuration_error",code:"missing_app_id",message:"Crossdeck.init requires an appId. Find yours in the Crossdeck dashboard."});if(e.environment!=="production"&&e.environment!=="sandbox")throw new v({type:"configuration_error",code:"invalid_environment",message:'Crossdeck.init requires environment: "production" | "sandbox".'});let t=Et(e.publicKey);if(t&&t!==e.environment)throw new v({type:"configuration_error",code:"environment_mismatch",message:`Crossdeck.init: environment "${e.environment}" disagrees with key prefix (${t}). Reconcile the publishable key with the environment declaration.`});let n=Tt(),s=e.storage??ke(),o=e.persistIdentity??!0,c=It(e.autoTrack),a={appId:e.appId,publicKey:e.publicKey,environment:e.environment,baseUrl:e.baseUrl??N,persistIdentity:o,storagePrefix:e.storagePrefix??"crossdeck:",autoHeartbeat:e.autoHeartbeat??!0,eventFlushBatchSize:e.eventFlushBatchSize??20,eventFlushIntervalMs:e.eventFlushIntervalMs??2e3,sdkVersion:e.sdkVersion??F,autoTrack:c,appVersion:e.appVersion??null},i=new J;i.enabled=e.debug===!0;let u=new K({publicKey:a.publicKey,baseUrl:a.baseUrl,sdkVersion:a.sdkVersion,localDevMode:n});n&&console.log("[crossdeck] Localhost detected \u2014 running in dev mode (no network calls). Set publicKey: 'cd_pub_test_\u2026' and deploy to a real domain to test against the Crossdeck Sandbox.");let d=o?s:new C,p=o&&!e.storage&&typeof globalThis.document<"u"?new Q:void 0,f=new B(d,a.storagePrefix,p),g=new W(d,a.storagePrefix+"entitlements"),m=o?new G({storage:d,prefix:a.storagePrefix}):null;m&&i.emit("sdk.queue_restored","Restored persisted event queue from a prior session.");let y=new z({http:u,batchSize:a.eventFlushBatchSize,intervalMs:a.eventFlushIntervalMs,envelope:()=>({appId:a.appId,environment:a.environment,sdk:{name:R,version:a.sdkVersion}}),persistentStore:m??void 0,onFirstFlushSuccess:()=>{i.emit("sdk.first_event_sent","First telemetry event received. View it in Live Events.",{appId:a.appId,environment:a.environment})},onRetryScheduled:h=>{i.emit("sdk.flush_retry_scheduled",`Event flush failed (${h.lastError}). Retrying in ${h.delayMs}ms (attempt ${h.consecutiveFailures}).`,{...h})},onPermanentFailure:h=>{let k=`[crossdeck] Event batch DROPPED (status ${h.status}): ${h.lastError}. ${h.droppedCount} event(s) lost \u2014 check your publishable key + app config.`;console.error(k),i.emit("sdk.flush_permanent_failure",k,{...h})}}),b=c.deviceInfo?we({appVersion:a.appVersion??void 0}):a.appVersion?{appVersion:a.appVersion}:{},_=new Z(o?d:new C,a.storagePrefix),S=new te({respectDnt:e.respectDnt===!0});S.isDntDenied&&i.emit("sdk.consent_dnt_applied","Do Not Track detected \u2014 all tracking dimensions denied at init.");let E=new re(50);if(this.state={http:u,identity:f,entitlements:g,events:y,autoTracker:null,webVitals:null,errors:null,breadcrumbs:E,errorContext:{},errorTags:{},errorBeforeSend:null,superProps:_,consent:S,scrubPii:e.scrubPii!==!1,deviceInfo:b,options:a,debug:i,developerUserId:null,uninstallUnloadFlush:null,lastServerTime:null,lastClientTime:null},i.emit("sdk.configured",`Crossdeck connected to ${a.appId} in ${a.environment} mode.`,{appId:a.appId,environment:a.environment,sdkVersion:a.sdkVersion}),c.sessions||c.pageViews){let h=new M(c,(k,w)=>this.track(k,w));this.state.autoTracker=h,h.install()}if(c.webVitals){let h=new ee({enabled:!0},(k,w)=>this.track(k,w));this.state.webVitals=h,h.install()}if(c.errors){let h=new ne({config:{...Ie,enabled:!0},breadcrumbs:E,report:k=>this.reportError(k),getContext:()=>({...this.state.errorContext}),getTags:()=>({...this.state.errorTags}),beforeSend:()=>this.state.errorBeforeSend,isConsented:()=>this.state.consent.errors,selfHostname:Ce(a.baseUrl)});this.state.errors=h,h.install()}this.state.uninstallUnloadFlush=Ct(()=>{this.flush({keepalive:!0}).catch(()=>{})}),a.autoHeartbeat&&!n&&this.heartbeat().catch(()=>{})}start(e){typeof console<"u"&&console.warn("[crossdeck] Crossdeck.start() is deprecated \u2014 use Crossdeck.init() instead. The signature is the same."),this.init(e)}async identify(e,t){let n=this.requireStarted();if(!e)throw new v({type:"invalid_request_error",code:"missing_user_id",message:"identify(userId) requires a non-empty userId."});if(!n.consent.analytics)return n.debug.emit("sdk.consent_denied","identify() skipped \u2014 consent denied for analytics."),{object:"alias_result",crossdeckCustomerId:n.identity.crossdeckCustomerId??"",linked:[],mergePending:!1,env:n.options.environment};let s=t?.traits!==void 0?q(t.traits):null,o=s&&Object.keys(s.properties).length>0?s.properties:void 0;if(n.debug.enabled&&s&&s.warnings.length>0)for(let i of s.warnings)n.debug.emit("sdk.property_coerced",`identify() traits key ${JSON.stringify(i.key)} was ${i.kind.replace(/_/g," ")} during validation.`,{key:i.key,kind:i.kind});let c={userId:e,anonymousId:n.identity.anonymousId};t?.email&&(c.email=t.email),o&&(c.traits=o),n.entitlements.setUserKey(e);let a=await n.http.request("POST","/identity/alias",{body:c});return n.identity.setCrossdeckCustomerId(a.crossdeckCustomerId),n.developerUserId=e,a}register(e){let t=this.requireStarted(),n=q(e);return t.superProps.register(n.properties)}unregister(e){this.requireStarted().superProps.unregister(e)}getSuperProperties(){return this.state?this.state.superProps.getSuperProperties():{}}group(e,t,n){let s=this.requireStarted();if(!e)throw new v({type:"invalid_request_error",code:"missing_group_type",message:"group(type, id) requires a non-empty type."});let o=n?q(n).properties:void 0;s.superProps.setGroup(e,t,o)}getGroups(){return this.state?this.state.superProps.getGroups():{}}consent(e){let t=this.requireStarted(),n=t.consent.set(e);return t.debug.emit("sdk.consent_changed","Consent state updated.",{...n}),n}consentStatus(){return this.state?this.state.consent.get():{analytics:!0,marketing:!0,errors:!0}}captureError(e,t){this.state?.errors&&this.state.errors.captureError(e,t)}captureMessage(e,t="info"){this.state?.errors&&this.state.errors.captureMessage(e,t)}setTag(e,t){this.state&&(this.state.errorTags[e]=t)}setTags(e){this.state&&Object.assign(this.state.errorTags,e)}setContext(e,t){this.state&&(this.state.errorContext[e]=t)}addBreadcrumb(e){this.state&&this.state.breadcrumbs.add(e)}setErrorBeforeSend(e){this.state&&(this.state.errorBeforeSend=e)}reportError(e){let t={fingerprint:e.fingerprint,level:e.level,errorType:e.errorType,message:e.message,stack:e.rawStack??void 0,frames:e.frames,filename:e.filename??void 0,lineno:e.lineno??void 0,colno:e.colno??void 0,tags:e.tags,context:e.context,breadcrumbs:e.breadcrumbs,http:e.http};for(let n of Object.keys(t))t[n]===void 0&&delete t[n];this.track(e.kind,t)}async forget(){let e=this.requireStarted(),t=this.identityQueryParams();try{await e.http.request("POST","/identity/forget",{body:{...t}})}catch(n){e.debug.emit("sdk.consent_denied",`forget() server call failed (${n instanceof Error?n.message:String(n)}). Local state wiped anyway.`)}this.reset()}async getEntitlements(){let e=this.requireStarted(),t=this.identityQueryParams(),n;try{n=await e.http.request("GET","/entitlements",{query:t})}catch(s){throw e.entitlements.markRefreshFailed(),s}return n.crossdeckCustomerId&&e.identity.setCrossdeckCustomerId(n.crossdeckCustomerId),e.entitlements.setFromList(n.data),n.data}isEntitled(e){return this.requireStarted().entitlements.isEntitled(e)}listEntitlements(){return this.requireStarted().entitlements.list()}onEntitlementsChange(e){return this.requireStarted().entitlements.subscribe(e)}track(e,t){let n=this.requireStarted();if(!e)throw new v({type:"invalid_request_error",code:"missing_event_name",message:"track(name) requires a non-empty name."});let s=e.startsWith("error."),o=e.startsWith("webvitals.");if(!(s||o?n.consent.errors:n.consent.analytics)){n.debug.enabled&&n.debug.emit("sdk.consent_denied",`Dropped event "${e}" \u2014 consent denied for ${o?"errors":"analytics"}.`);return}if(n.debug.enabled&&t){let y=xe(t);y.length>0&&n.debug.emit("sdk.sensitive_property_warning",`Event "${e}" has potentially sensitive property names: ${y.join(", ")}. Crossdeck is privacy-first \u2014 avoid sending PII unless intentional.`,{eventName:e,flagged:y})}n.debug.enabled&&!n.developerUserId&&!n.identity.crossdeckCustomerId&&n.debug.emit("sdk.no_identity","Using anonymous user until identify(userId) is called.");let a=q(t);if(n.debug.enabled&&a.warnings.length>0)for(let y of a.warnings)n.debug.emit("sdk.property_coerced",`Event "${e}" property ${JSON.stringify(y.key)} was ${y.kind.replace(/_/g," ")} during validation.`,{eventName:e,key:y.key,kind:y.kind});let i={...n.deviceInfo},u=n.autoTracker?.currentSessionId;u&&(i.sessionId=u);let d=n.autoTracker?.currentPageviewId;d&&(i.pageviewId=d);let l=n.autoTracker?.currentAcquisition;l&&(l.utm_source&&(i.utm_source=l.utm_source),l.utm_medium&&(i.utm_medium=l.utm_medium),l.utm_campaign&&(i.utm_campaign=l.utm_campaign),l.utm_content&&(i.utm_content=l.utm_content),l.utm_term&&(i.utm_term=l.utm_term),l.referrer&&n.consent.marketing&&(i.referrer=l.referrer),n.consent.marketing&&(l.gclid&&(i.gclid=l.gclid),l.fbclid&&(i.fbclid=l.fbclid),l.msclkid&&(i.msclkid=l.msclkid),l.ttclid&&(i.ttclid=l.ttclid),l.li_fat_id&&(i.li_fat_id=l.li_fat_id),l.twclid&&(i.twclid=l.twclid)));let p=n.superProps.getSuperProperties();for(let y of Object.keys(p))y in i||(i[y]=p[y]);let f=n.superProps.getGroupIds();Object.keys(f).length>0&&(i.$groups=f),Object.assign(i,a.properties);let g=n.scrubPii?le(i):i,m={eventId:this.mintEventId(),name:e,timestamp:Date.now(),properties:g};if(Object.assign(m,this.identityHintForEvent()),n.events.enqueue(m),!s&&!o){let y=e.startsWith("page.")?"navigation":e.startsWith("element.")||e==="session.started"?"ui.click":"custom";n.breadcrumbs.add({timestamp:m.timestamp,category:y,message:e,data:t?{...t}:void 0})}}async flush(e={}){await this.requireStarted().events.flush(e)}async flushEvents(){return this.flush()}async syncPurchases(e){let t=this.requireStarted();if(!e.signedTransactionInfo)throw new v({type:"invalid_request_error",code:"missing_signed_transaction_info",message:"syncPurchases requires a signedTransactionInfo string from StoreKit 2."});let n=e.rail??"apple",s={...e,rail:n},o=be(s),c=await t.http.request("POST","/purchases/sync",{body:s,idempotencyKey:o});t.identity.setCrossdeckCustomerId(c.crossdeckCustomerId),t.entitlements.setFromList(c.entitlements);try{let a=c.entitlements[0]?.source.productId,i=c.entitlements[0]?.source.subscriptionId,u={rail:n};a&&(u.productId=a),i&&(u.subscriptionId=i),c.idempotent_replay&&(u.idempotent_replay=!0),this.track("purchase.completed",u)}catch{}return t.debug.emit("sdk.purchase_evidence_sent","StoreKit transaction forwarded. Waiting for backend verification.",{rail:e.rail??"apple"}),c}async purchaseApple(e){return this.syncPurchases({rail:"apple",...e})}setDebugMode(e){let t=this.requireStarted();t.debug.enabled=e,e&&t.debug.emit("sdk.configured",`Debug mode enabled for ${t.options.appId} in ${t.options.environment} mode.`,{appId:t.options.appId,environment:t.options.environment})}async heartbeat(){let e=this.requireStarted(),t=await e.http.request("GET","/sdk/heartbeat");return typeof t?.serverTime=="number"&&Number.isFinite(t.serverTime)&&(e.lastServerTime=t.serverTime,e.lastClientTime=Date.now()),t}reset(){if(this.state){if(this.state.developerUserId)try{this.track("user.signed_out",{auto:!0})}catch{}if(this.state.autoTracker?.uninstall(),this.state.identity.reset(),this.state.entitlements.clearAll(),this.state.events.reset(),this.state.superProps.clear(),this.state.breadcrumbs.clear(),this.state.errorContext={},this.state.errorTags={},this.state.developerUserId=null,this.state.lastServerTime=null,this.state.lastClientTime=null,this.state.autoTracker){let e=new M(this.state.options.autoTrack,(t,n)=>this.track(t,n));this.state.autoTracker=e,e.install()}}}diagnostics(){if(!this.state)return{started:!1,anonymousId:null,crossdeckCustomerId:null,developerUserId:null,sdkVersion:null,baseUrl:null,clock:{lastServerTime:null,lastClientTime:null,skewMs:null},entitlements:{count:0,lastUpdated:0,stale:!1,listenerErrors:0},events:{buffered:0,dropped:0,inFlight:0,lastFlushAt:0,lastError:null,consecutiveFailures:0,nextRetryAt:null}};let e=this.state,t=e.lastServerTime!==null&&e.lastClientTime!==null?e.lastClientTime-e.lastServerTime:null;return{started:!0,anonymousId:e.identity.anonymousId,crossdeckCustomerId:e.identity.crossdeckCustomerId,developerUserId:e.developerUserId,sdkVersion:e.options.sdkVersion,baseUrl:e.options.baseUrl,clock:{lastServerTime:e.lastServerTime,lastClientTime:e.lastClientTime,skewMs:t},entitlements:{count:e.entitlements.list().length,lastUpdated:e.entitlements.freshness,stale:e.entitlements.isStale,listenerErrors:e.entitlements.listenerErrors},events:e.events.getStats()}}requireStarted(){if(!this.state)throw new v({type:"configuration_error",code:"not_initialized",message:"Call Crossdeck.init({ appId, publicKey, environment }) before any other method."});return this.state}identityQueryParams(){let e=this.requireStarted();return e.identity.crossdeckCustomerId?{customerId:e.identity.crossdeckCustomerId}:e.developerUserId?{userId:e.developerUserId}:{anonymousId:e.identity.anonymousId}}identityHintForEvent(){let e=this.requireStarted(),t={anonymousId:e.identity.anonymousId};return e.developerUserId&&(t.developerUserId=e.developerUserId),e.identity.crossdeckCustomerId&&(t.crossdeckCustomerId=e.identity.crossdeckCustomerId),t}mintEventId(){return`evt_${Date.now().toString(36)}${I(8)}`}},Ae=new V;function Et(r){return r.startsWith("cd_pub_test_")?"sandbox":r.startsWith("cd_pub_live_")?"production":null}function Tt(){let r=globalThis.window;if(r?.__CROSSDECK_FORCE_LIVE__===!0)return!1;let e=r?.location?.hostname;return e?!!(e==="localhost"||e==="127.0.0.1"||e==="0.0.0.0"||e==="::1"||e==="[::1]"||/^\[?fe80::/i.test(e)||e.endsWith(".local")||/^10\./.test(e)||/^192\.168\./.test(e)||/^172\.(1[6-9]|2\d|3[0-1])\./.test(e)):!1}function It(r){return r===!1?{sessions:!1,pageViews:!1,deviceInfo:!1,clicks:!1,webVitals:!1,errors:!1}:r===void 0||r===!0?{...A}:{sessions:r.sessions??A.sessions,pageViews:r.pageViews??A.pageViews,deviceInfo:r.deviceInfo??A.deviceInfo,clicks:r.clicks??A.clicks,webVitals:r.webVitals??A.webVitals,errors:r.errors??A.errors}}function Ct(r){let e=globalThis.window,t=globalThis.document;if(!e||!t)return()=>{};let n=()=>{t.visibilityState==="hidden"&&r()},s=()=>r();return t.addEventListener("visibilitychange",n),e.addEventListener("pagehide",s),e.addEventListener("beforeunload",s),()=>{t.removeEventListener("visibilitychange",n),e.removeEventListener("pagehide",s),e.removeEventListener("beforeunload",s)}}var me=Object.freeze([{code:"invalid_public_key",type:"configuration_error",description:"The publishable key passed to Crossdeck.init() doesn't start with cd_pub_.",resolution:"Copy the key from your Crossdeck dashboard \u2192 API keys page.",retryable:!1},{code:"missing_app_id",type:"configuration_error",description:"Crossdeck.init() was called without an appId.",resolution:"Add appId to your init options \u2014 find it in the dashboard's Apps page.",retryable:!1},{code:"invalid_environment",type:"configuration_error",description:"Crossdeck.init() requires environment: 'production' | 'sandbox'.",resolution:'Pass the literal string "production" or "sandbox" \u2014 no other values are accepted.',retryable:!1},{code:"environment_mismatch",type:"configuration_error",description:"The publishable key's env prefix doesn't match the declared environment option.",resolution:"Either change `environment` to match the key prefix (cd_pub_test_ \u2194 sandbox, cd_pub_live_ \u2194 production), or swap the key for one minted in the right env.",retryable:!1},{code:"not_initialized",type:"configuration_error",description:"An SDK method was called before Crossdeck.init().",resolution:"Call Crossdeck.init({ appId, publicKey, environment }) once at app startup before any other method.",retryable:!1},{code:"missing_user_id",type:"invalid_request_error",description:"identify() was called with an empty userId.",resolution:"Pass a stable, non-empty user identifier from your auth layer \u2014 never a hardcoded placeholder.",retryable:!1},{code:"missing_event_name",type:"invalid_request_error",description:"track() was called without an event name.",resolution:"Pass a non-empty string as the first argument.",retryable:!1},{code:"missing_group_type",type:"invalid_request_error",description:"group() was called without a group type.",resolution:'Pass a non-empty type (e.g. "org", "team") as the first argument.',retryable:!1},{code:"missing_signed_transaction_info",type:"invalid_request_error",description:"syncPurchases() was called without StoreKit 2 signed transaction info.",resolution:"Pass the JWS string from Transaction.currentEntitlements / Transaction.updates.",retryable:!1},{code:"fetch_failed",type:"network_error",description:"The underlying fetch() call failed (typically a network outage or DNS issue).",resolution:"Check the user's network. The SDK will retry automatically with exponential backoff.",retryable:!0},{code:"request_timeout",type:"network_error",description:"A request was aborted after the configured timeoutMs (default 15s).",resolution:"Check the user's connection. Increase timeoutMs in init options if the user is on a known-slow network.",retryable:!0},{code:"invalid_json_response",type:"internal_error",description:"The server returned a 2xx with an unparseable body.",resolution:"Likely a transient backend bug. Retry; if it persists, contact support with the requestId.",retryable:!0},{code:"missing_api_key",type:"authentication_error",description:"No Authorization header (or Crossdeck-Api-Key header) on the request.",resolution:"Make sure Crossdeck.init({ publicKey }) was called with a cd_pub_\u2026 key before the request fired. Re-check your env-vars in CI / Docker if the key is empty at runtime.",retryable:!1},{code:"invalid_api_key",type:"authentication_error",description:"The API key is malformed, unknown, or doesn't resolve to a project.",resolution:"Copy the key from your Crossdeck dashboard \u2192 API keys. Confirm prefix is cd_pub_test_ / cd_pub_live_ for client SDKs and cd_sk_test_ / cd_sk_live_ for the Node server SDK.",retryable:!1},{code:"key_revoked",type:"authentication_error",description:"The API key was revoked in the Crossdeck dashboard.",resolution:"Mint a fresh key in the dashboard \u2192 API keys \u2192 Create new, swap it in, and redeploy. The revoked key cannot be reactivated.",retryable:!1},{code:"identity_token_invalid",type:"authentication_error",description:"The Firebase / Apple / Google ID token supplied with the request didn't verify against the dashboard's configured signers.",resolution:"Refresh the token client-side (Firebase auth.currentUser.getIdToken(true)) and retry. If the failure persists, confirm the signer is registered under dashboard \u2192 Authentication \u2192 Identity sources.",retryable:!0},{code:"origin_not_allowed",type:"permission_error",description:"The Origin header isn't in the project's Allowed origins list.",resolution:"Add the origin (e.g. https://app.example.com) under dashboard \u2192 Settings \u2192 Allowed origins. Wildcards like https://*.example.com are supported.",retryable:!1},{code:"bundle_id_not_allowed",type:"permission_error",description:"The iOS bundle ID sent via X-Crossdeck-Bundle-Id isn't registered under this app's Apple identity lock.",resolution:"Add the bundle ID under dashboard \u2192 Apps \u2192 <your app> \u2192 iOS bundle IDs.",retryable:!1},{code:"package_name_not_allowed",type:"permission_error",description:"The Android package name sent via X-Crossdeck-Package-Name isn't registered under this app's Android identity lock.",resolution:"Add the package name under dashboard \u2192 Apps \u2192 <your app> \u2192 Android package names.",retryable:!1},{code:"env_mismatch",type:"permission_error",description:"The request env (inferred from key prefix) doesn't match the resolved app's configured env.",resolution:"Use a cd_pub_live_ / cd_sk_live_ key with a production app, cd_pub_test_ / cd_sk_test_ with a sandbox app. The two cannot cross.",retryable:!1},{code:"idempotency_key_in_use",type:"invalid_request_error",description:"An Idempotency-Key was reused for a request with a different body (Stripe-grade contract).",resolution:"Generate a fresh key for a different transaction, or reuse the key only with the EXACT same body. The v1.4.0 SDKs derive keys deterministically from the body so this should never fire on SDK-managed calls.",retryable:!1},{code:"rate_limited",type:"rate_limit_error",description:"Request rate exceeded the project's per-second cap.",resolution:"Honour the Retry-After header \u2014 the SDK does this automatically on managed retries. If you're hitting it from a custom code path, throttle to <100 req/s/key.",retryable:!0},{code:"internal_error",type:"internal_error",description:"Server-side issue. Safe to retry with backoff.",resolution:"The SDK retries automatically. If your code paths through to this error, contact support with the requestId from the response envelope.",retryable:!0},{code:"google_not_supported",type:"invalid_request_error",description:"POST /purchases/sync with rail=google is gated until the Play Developer API reconciliation worker ships.",resolution:"Until v1.5+, Google Play purchases verify via Real-time Developer Notifications. The SDK auto-track path handles this transparently for Android consumers.",retryable:!1},{code:"stripe_not_supported",type:"invalid_request_error",description:"POST /purchases/sync with rail=stripe is unsupported \u2014 Stripe Checkout's redirect flow uses platform webhooks instead.",resolution:"Wire Stripe via the standard Checkout / Customer Portal flow; Crossdeck reconciles via the platform webhook automatically. No SDK call needed.",retryable:!1},{code:"missing_required_param",type:"invalid_request_error",description:"A required field is absent from the request body.",resolution:"Inspect the error.message \u2014 the missing field name is included verbatim. Refer to the SDK's TypeScript types for the canonical request shape.",retryable:!1},{code:"invalid_param_value",type:"invalid_request_error",description:"A field is present but the value failed validation (wrong shape, wrong length, wrong enum value).",resolution:"Read error.message for the specific field + reason. SDK-managed call sites should never emit this \u2014 file a bug if you do.",retryable:!1}]);function Re(r){return me.find(e=>e.code===r)}return qe(At);})();
|
|
3
3
|
//# sourceMappingURL=crossdeck.umd.min.js.map
|