unshared-react-sdk 2.1.0-rc.3

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/README.md ADDED
@@ -0,0 +1,280 @@
1
+ # unshared-react-sdk
2
+
3
+ React SDK for [Unshared Labs](https://unshared.ai) — account-sharing detection for React apps. A provider + hooks layer over [`unshared-frontend-sdk`](../../browser) with automatic SPA route tracking and flagged-account handling.
4
+
5
+ Works the way Adobe Launch or BlueConic tags work: configure it with the **publishable key** we issue you and you're done — no backend integration required. (A proxy mode through your own backend is also supported.)
6
+
7
+ > Pass `publishableKey` explicitly for direct mode or `baseUrl` explicitly for proxy mode. Omitting both defaults to same-origin proxy mode — unless you're consuming a client-specific build with a baked-in key (see "Packaged publishable key").
8
+
9
+ ---
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install unshared-react-sdk
15
+ ```
16
+
17
+ React 18+ is a peer dependency.
18
+
19
+ Not on npm yet? The current build is hosted at `https://unshared-public.s3.amazonaws.com/react@18/` (`index.mjs` for bundlers, `index.umd.js` for script tags, `index.d.ts` for types) — see "Publishing React artifacts to S3" below.
20
+
21
+ ---
22
+
23
+ ## Quick start (direct mode — recommended)
24
+
25
+ Wrap your app once, near the root, with the publishable key from your Unshared Labs dashboard:
26
+
27
+ ```tsx
28
+ import { UnsharedProvider } from 'unshared-react-sdk';
29
+
30
+ function Root() {
31
+ const { user } = useAuth(); // your auth state
32
+
33
+ return (
34
+ <UnsharedProvider
35
+ publishableKey="upk_your_key_here"
36
+ user={user ? { userId: user.id, email: user.email } : null}
37
+ >
38
+ <App />
39
+ </UnsharedProvider>
40
+ );
41
+ }
42
+ ```
43
+
44
+ That's everything:
45
+
46
+ - A device fingerprint is collected once per tab and submitted when the user is identified.
47
+ - SPA navigations (`pushState`, `replaceState`, `popstate`) are tracked automatically — Next.js, React Router, and custom routers all work without adapters.
48
+ - Logout (`user` → `null`) clears all SDK state.
49
+ - All failures are silent — the SDK never throws at runtime and never blocks your UI.
50
+
51
+ The publishable key is public by design: it can only submit events, never read data. Lock it to your domains by configuring **allowed origins** in your dashboard.
52
+
53
+ ---
54
+
55
+ ## Identifying the user from deeper in the tree
56
+
57
+ If auth state isn't available where the provider mounts:
58
+
59
+ ```tsx
60
+ import { useUnshared } from 'unshared-react-sdk';
61
+
62
+ function LoginForm() {
63
+ const { identify, logout } = useUnshared();
64
+
65
+ async function onLoginSuccess(user) {
66
+ identify({ userId: user.id, email: user.email });
67
+ }
68
+
69
+ async function onLogout() {
70
+ logout();
71
+ }
72
+ }
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Reacting to flagged accounts
78
+
79
+ ```tsx
80
+ <UnsharedProvider
81
+ publishableKey="upk_..."
82
+ user={user}
83
+ onFlagged={() => router.push('/account-suspended')}
84
+ >
85
+ ```
86
+
87
+ `onFlagged` fires when any same-page `fetch` returns an `account_flagged` 403, or when an `unshared:flagged` CustomEvent is dispatched. The provider installs (and removes on unmount) a `window.fetch` interceptor to detect this.
88
+
89
+ ### Interstitial modal
90
+
91
+ Instead of (or alongside) `onFlagged`, the provider can render a **server-driven
92
+ interstitial modal** — a JSON flow authored in the Unshared dashboard (e.g. email-OTP
93
+ verification) fetched from the backend and rendered in a Shadow-DOM modal whose actions
94
+ route back through the SDK's own verification calls.
95
+
96
+ ```tsx
97
+ <UnsharedProvider
98
+ publishableKey="upk_..."
99
+ user={user}
100
+ enableInterstitial // auto-show when flagged
101
+ interstitialFlowType="email_verification" // optional, this is the default
102
+ >
103
+ ```
104
+
105
+ With `enableInterstitial`, the modal renders automatically on the same flagged signals
106
+ as `onFlagged` (the 403 interceptor **and** the `unshared:flagged` event). To trigger it
107
+ yourself instead, call `useUnshared().showInterstitial()`. The modal is removed on
108
+ logout/unmount (`client.destroy()`).
109
+
110
+ This works in **proxy mode** as well: set `baseUrl` (instead of `publishableKey`) with the Node middleware mounted, and the modal is served and verified through your backend with the secret key — no publishable key in the frontend.
111
+
112
+ ---
113
+
114
+ ## Props
115
+
116
+ | Prop | Type | Description |
117
+ |------|------|-------------|
118
+ | `publishableKey` | `string` | **Direct mode.** Publishable key (`upk_…`). Events go straight to the Unshared Labs platform. May only be omitted in client-specific builds with a baked-in key. |
119
+ | `apiUrl` | `string` | Direct mode platform origin. Default `https://api.unshared.ai`. |
120
+ | `baseUrl` | `string` | **Proxy mode.** Base URL of your backend running `unshared-clientjs-sdk` middleware. Use `baseUrl=""` for same-origin proxy mode. |
121
+ | `user` | `{ userId, email, isPaidSubscriber? } \| null` | The logged-in user. `null` while logged out; the transition to `null` clears SDK state. `isPaidSubscriber: false` means the SDK collects and submits **nothing** for this user — non-subscriber data is never received. |
122
+ | `onFlagged` | `() => void` | Called when the platform flags the account. |
123
+ | `enableInterstitial` | `boolean` | Direct mode: auto-render the interstitial modal when flagged (on the 403 interceptor or `unshared:flagged` event). Default `false`. |
124
+ | `interstitialFlowType` | `string` | Flow type to fetch for the interstitial. Default `email_verification`. |
125
+ | `skipPaths` | `string[]` | Path prefixes to never submit events for. |
126
+ | `includePathPrefix` | `string[]` | If set, only these path prefixes submit events. |
127
+ | `sessionId` | `() => string \| undefined` | Supply your own session ID (e.g. your auth/analytics session) instead of the SDK-generated UUID — it becomes the `session_hash` correlation key on every event. |
128
+ | `deviceId` | `() => string \| undefined` | Supply your own device ID instead of the stable fingerprint hash. |
129
+ | `maxRetries` | `number` | Delivery retries per request (default 3). |
130
+ | `timeout` | `number` | Per-request timeout ms (default 30000). |
131
+
132
+ ## `useUnshared()`
133
+
134
+ Returns `{ client, identify, logout, showInterstitial }`. `client` is the underlying `UnsharedBrowser` instance (`null` during SSR and before mount). `showInterstitial(flowType?)` fetches and renders the interstitial modal on demand (direct mode). Throws if called outside an `<UnsharedProvider>`.
135
+
136
+ In direct mode, `client` also carries the read/verification API — enough to build a fully frontend verify-wall:
137
+
138
+ ```tsx
139
+ const { client } = useUnshared();
140
+
141
+ const check = await client?.checkUser();
142
+ if (check?.data?.is_user_flagged) {
143
+ await client.triggerEmailVerification(); // emails a 6-digit code
144
+ // ...collect the code from the user...
145
+ const result = await client.verify(enteredCode); // → { verified: true }
146
+ }
147
+ ```
148
+
149
+ `triggerEmailVerification` and `verify` are never retried by the SDK (each trigger sends a real email; verify attempts are budgeted server-side). Rate-limited responses include `error.retryAfter` seconds for countdown UIs.
150
+
151
+ ---
152
+
153
+ ## Script tag / UMD (no bundler)
154
+
155
+ The published `dist/index.umd.js` is fully self-contained except for React itself — `unshared-frontend-sdk` (and its fingerprint engine) are bundled in. Load React 18's UMD first, then this package; the API lands on `window.UnsharedReact`:
156
+
157
+ ```html
158
+ <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
159
+ <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
160
+ <script src="https://unshared-public.s3.amazonaws.com/react@18/index.umd.js"></script>
161
+ <script>
162
+ const { UnsharedProvider, useUnshared } = window.UnsharedReact;
163
+ // Use exactly like the npm import, e.g. wrap your root render:
164
+ // ReactDOM.createRoot(el).render(
165
+ // React.createElement(UnsharedProvider, { publishableKey: 'upk_...', user }, React.createElement(App))
166
+ // );
167
+ </script>
168
+ ```
169
+
170
+ > React 19 ships no UMD builds — React 19 apps must use the npm path (which is unaffected; the package targets `react >= 18` either way). Pages without React at all should use the plain browser SDK / `/v2/sdk/{key}.js` loader — or the standalone build below.
171
+
172
+ ### Standalone: true one-tag-and-done (niche — read the warnings)
173
+
174
+ `dist/index.standalone.js` (~200K min) bundles **React, ReactDOM, and the SDK** and auto-mounts an invisible provider from `window.__unshared` — no React on the page, no glue code.
175
+
176
+ **When NOT to use it:**
177
+
178
+ - **Never on a page that already runs React.** The standalone's React renders an isolated, detached tree — it can't break the host's hooks/context (the trees never touch), but it also means `useUnshared()` from the host's own components **cannot** see this provider. React apps must use the npm/ESM path (peer-dependency React, single instance) or the UMD.
179
+ - **Pages with no React should usually prefer the browser tag loader** (`/v2/sdk/{key}.js`) — it has no React dependency at all, is ~4× smaller, and does the same job. Reach for the standalone only when you specifically want the provider-style config surface (`window.__unshared` identity contract, `identify`/`logout`) on a React-less page.
180
+
181
+ React remains a **peer dependency** (`react >= 18`) for every module output (ESM/CJS/UMD) — the host app supplies the single React instance; only this opt-in standalone file carries its own copy.
182
+
183
+ ```html
184
+ <script>
185
+ window.__unshared = {
186
+ publishableKey: 'upk_...', // omit in client-keyed builds
187
+ identity: () => window.Arc?.identity
188
+ ? { userId: Arc.identity.uuid, email: Arc.identity.email, isPaidSubscriber: true }
189
+ : null,
190
+ onFlagged: () => location.assign('/account-suspended'), // optional
191
+ // sessionId, deviceId, skipPaths, includePathPrefix also accepted
192
+ };
193
+ </script>
194
+ <script async src="https://unshared-public.s3.amazonaws.com/react@18/index.standalone.js"></script>
195
+ ```
196
+
197
+ If auth resolves after the tag loads, call `window.UnsharedReact.identify({ userId, email, isPaidSubscriber })` / `window.UnsharedReact.logout()`.
198
+
199
+ ---
200
+
201
+ ## SSR / Next.js
202
+
203
+ The provider is SSR-safe: the SDK is constructed in a mount effect and all browser APIs are touched client-side only. In the Next.js App Router, mount it in a `"use client"` layout component.
204
+
205
+ ---
206
+
207
+ ## Proxy mode
208
+
209
+ If you prefer events to flow through your own backend (secret API key stays server-side, richer middleware features like verdict caching and email verification):
210
+
211
+ ```tsx
212
+ // Same-origin proxy mode:
213
+ <UnsharedProvider baseUrl="" user={user}>
214
+
215
+ // Cross-origin proxy mode:
216
+ <UnsharedProvider baseUrl="https://app.example.com" user={user}>
217
+ ```
218
+
219
+ Your backend must run [`unshared-clientjs-sdk`](../../node)'s `createUnsharedMiddleware`. See that package's docs.
220
+
221
+ ## Packaged publishable key
222
+
223
+ For client-specific builds, the React SDK can inherit a publishable key packaged into `unshared-frontend-sdk`:
224
+
225
+ 1. Explicit `publishableKey` prop.
226
+ 2. Build-time `UNSHARED_PUBLISHABLE_API_KEY` baked into `unshared-frontend-sdk` (client-specific builds only, e.g. the S3 flow).
227
+ 3. Otherwise **no key** — same-origin proxy mode. There is no hardcoded fallback; builds made without the env var (including every npm release) never carry a usable key.
228
+
229
+ Build distribution files in order (the React build bundles whatever browser dist it finds, so the browser build's env var determines whether a key is baked in):
230
+
231
+ ```bash
232
+ UNSHARED_PUBLISHABLE_API_KEY=upk_test_or_client_key npm --prefix sdks/javascript/browser run build
233
+ npm --prefix sdks/javascript/frameworks/react run build
234
+ ```
235
+
236
+ Passing `baseUrl`, including `baseUrl=""`, keeps proxy mode and suppresses the packaged-key fallback.
237
+
238
+ ## Publishing React artifacts to S3
239
+
240
+ The canonical public distribution lives at **`s3://unshared-public/react@18/`** (versioned per major):
241
+
242
+ ```
243
+ https://unshared-public.s3.amazonaws.com/react@18/index.mjs ← ESM (primary; bundlers / import maps)
244
+ https://unshared-public.s3.amazonaws.com/react@18/index.umd.js ← UMD (script tag; page provides window.React)
245
+ https://unshared-public.s3.amazonaws.com/react@18/index.standalone.js ← one-tag: bundles React, auto-mounts from window.__unshared
246
+ https://unshared-public.s3.amazonaws.com/react@18/index.cjs ← CommonJS
247
+ https://unshared-public.s3.amazonaws.com/react@18/index.d.ts ← TypeScript types
248
+ ```
249
+
250
+ Every file is self-contained except for React itself (`unshared-frontend-sdk` and the fingerprint engine are bundled at build time). The publish script uploads `dist/index.mjs`; pass the prefix as part of the bucket value to target the versioned path:
251
+
252
+ ```bash
253
+ S3_BUCKET_NAME=unshared-public/react@18 npm --prefix sdks/javascript/frameworks/react run publish:s3
254
+ ```
255
+
256
+ `S3_BUCKET_NAME` is intentionally deployment config rather than a hardcoded value in the script; the additional dist files (`index.umd.js`, `index.cjs`, `index.d.ts`) are uploaded alongside when a full set is wanted.
257
+
258
+ Before uploading, the script runs `aws sts get-caller-identity`. If credentials are missing or expired, it runs `aws login` and checks identity again. For SSO/profile setups, override the login command:
259
+
260
+ ```bash
261
+ AWS_LOGIN_COMMAND="aws sso login --profile client-profile" \
262
+ S3_BUCKET_NAME=client-sdk-bucket \
263
+ npm --prefix sdks/javascript/frameworks/react run publish:s3
264
+ ```
265
+
266
+ Force publishing is available for local or emergency use, but should not be used for normal releases:
267
+
268
+ ```bash
269
+ FORCE_PUBLISH=1 \
270
+ S3_BUCKET_NAME=client-sdk-bucket \
271
+ npm --prefix sdks/javascript/frameworks/react run publish:s3
272
+ ```
273
+
274
+ Only `react` remains an external dependency of the S3 artifacts — `index.umd.js` is the script-tag option (see "Script tag / UMD" above) and `index.mjs` suits bundlers or browser import maps that map `react`.
275
+
276
+ ---
277
+
278
+ ## Releasing
279
+
280
+ `unshared-frontend-sdk` is a `file:` **devDependency** that gets **bundled** into every dist output (ESM/CJS/UMD) at build time — consumers only ever need React. No dependency rewriting is required at publish; `release-js.yml` (and the S3 publish script) build the browser package first so rollup can resolve it.
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";var React=require("react");function _interopNamespaceDefault(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var React__namespace=_interopNamespaceDefault(React),commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},index_umd={exports:{}};!function(e){const t="1.3.3",n=1282368115,r={exclude:[],include:[],timeout:3e3,stabilize:["private","iframe","always"],experimental:!1,debug:!1,salt:""},o=new Set(["audio","timing","navigatorConnection","domrect","permissions","fonts","speech","display","cssLayout"]),i=new Set(["domrect"]),a=new Set(["screen","mediaCapabilities","storage","features","sensors","battery","gamepads","webApis","notificationState","extendedLocale","privacyPrefs","performanceContext","canvas","audioOscillator","webglRender","canvasTextMetrics","vendorFlavors","fontPreferences","screenFrame","clientHints","domBlockers","privateClickMeasurement","automationDetection","agentDetection","tamperDetection","vmDetection","devtoolsDetection"]),s={always:[{exclude:["speech"],browsers:["brave","firefox"]},{exclude:["keyboard"],browsers:["firefox","safari"]},{exclude:["workers"],browsers:["firefox"]},{exclude:["hardwareSensitive","navigatorProps"],browsers:["brave"]},{exclude:["canvas","audioOscillator","webglRender","canvasTextMetrics"],browsers:["brave"]},{exclude:["canvas"],browsers:["firefox"]}],private:[{exclude:["fonts"],browsers:["firefox"]},{exclude:["audio"],browsers:["safari","brave"]},{exclude:["audioOscillator"],browsers:["safari"]}],iframe:[{exclude:["applePay"],browsers:["safari"]},{exclude:["permissions"]},{exclude:["keyboard"]}]};let c=null;function u(){if(c)return c;const e=navigator.userAgent;return c=function(){const e=navigator.brave;return!!e&&"function"==typeof e.isBrave}()?{name:"brave",version:l(e,/Chrome\/([\d.]+)/)}:/Edg\//i.test(e)?{name:"edge",version:l(e,/Edg\/([\d.]+)/)}:/OPR\//i.test(e)||/Opera/i.test(e)?{name:"opera",version:l(e,/OPR\/([\d.]+)/)||l(e,/Opera\/([\d.]+)/)}:/SamsungBrowser/i.test(e)?{name:"samsung",version:l(e,/SamsungBrowser\/([\d.]+)/)}:/Firefox\//i.test(e)?{name:"firefox",version:l(e,/Firefox\/([\d.]+)/)}:/Safari\//i.test(e)&&!/Chrome/i.test(e)?{name:"safari",version:l(e,/Version\/([\d.]+)/)}:/Chrome\//i.test(e)?{name:"chrome",version:l(e,/Chrome\/([\d.]+)/)}:{name:"unknown",version:""},c}function l(e,t){const n=e.match(t);return n?.[1]??""}function d(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16;let u=0,l=0,d=0,f=0,m=0;return l=i+(65535&t[1]),u=l>>>16,l&=65535,d=o+c+u,u=d>>>16,d&=65535,f=r+s+u,u=f>>>16,f&=65535,m=n+a+u,m&=65535,[m<<16|f,d<<16|l]}function f(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16,u=65535&t[1];let l=0,d=0,f=0,m=0,h=0;return d=i*u,l=d>>>16,d&=65535,f=o*u+l,l=f>>>16,f&=65535,f+=i*c,l+=f>>>16,f&=65535,m=r*u+l,l=m>>>16,m&=65535,m+=o*c,l+=m>>>16,m&=65535,m+=i*s,l+=m>>>16,m&=65535,h=n*u+r*c+o*s+i*a+l,h&=65535,[h<<16|m,f<<16|d]}function m(e,t){return 32==(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])}function h(e,t){return 0==(t%=64)?[e[0],e[1]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]}function p(e,t){return[e[0]^t[0],e[1]^t[1]]}function y(e){let t=[e[0],e[1]];return t=p(t,[0,t[0]>>>1]),t=f(t,[4283543511,3981806797]),t=p(t,[0,t[0]>>>1]),t=f(t,[3301882366,444984403]),t=p(t,[0,t[0]>>>1]),t}function g(e){return("00000000"+(e>>>0).toString(16)).slice(-8)}function w(e,t=0){const n=e.length%16,r=e.length-n;let o=[0,t],i=[0,t];const a=[2277735313,289559509],s=[1291169091,658871167];for(let t=0;t<r;t+=16){let n=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],r=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24];n=f(n,a),n=m(n,31),n=f(n,s),o=p(o,n),o=m(o,27),o=d(o,i),o=d(f(o,[0,5]),[0,1390208809]),r=f(r,s),r=m(r,33),r=f(r,a),i=p(i,r),i=m(i,31),i=d(i,o),i=d(f(i,[0,5]),[0,944331445])}let c=[0,0],u=[0,0];switch(n){case 15:u=p(u,h([0,e.charCodeAt(r+14)],48));case 14:u=p(u,h([0,e.charCodeAt(r+13)],40));case 13:u=p(u,h([0,e.charCodeAt(r+12)],32));case 12:u=p(u,h([0,e.charCodeAt(r+11)],24));case 11:u=p(u,h([0,e.charCodeAt(r+10)],16));case 10:u=p(u,h([0,e.charCodeAt(r+9)],8));case 9:u=p(u,[0,e.charCodeAt(r+8)]),u=f(u,s),u=m(u,33),u=f(u,a),i=p(i,u);case 8:c=p(c,h([0,e.charCodeAt(r+7)],56));case 7:c=p(c,h([0,e.charCodeAt(r+6)],48));case 6:c=p(c,h([0,e.charCodeAt(r+5)],40));case 5:c=p(c,h([0,e.charCodeAt(r+4)],32));case 4:c=p(c,h([0,e.charCodeAt(r+3)],24));case 3:c=p(c,h([0,e.charCodeAt(r+2)],16));case 2:c=p(c,h([0,e.charCodeAt(r+1)],8));case 1:c=p(c,[0,e.charCodeAt(r)]),c=f(c,a),c=m(c,31),c=f(c,s),o=p(o,c)}return o=p(o,[0,e.length]),i=p(i,[0,e.length]),o=d(o,i),i=d(i,o),o=y(o),i=y(i),o=d(o,i),i=d(i,o),g(o[0])+g(o[1])+g(i[0])+g(i[1])}function v(e){return b(e,new Set)}function b(e,t){if(null===e)return"null";if(void 0===e)return"undefined";const n=typeof e;if("boolean"===n||"number"===n)return String(e);if("string"===n)return JSON.stringify(e);if(Array.isArray(e)){if(t.has(e))return'"[Circular]"';t.add(e);const n=e.map(e=>b(e,t));return t.delete(e),"["+n.join(",")+"]"}if("object"===n){const n=e;if(t.has(n))return'"[Circular]"';t.add(n);const r=Object.keys(n).sort().filter(e=>void 0!==n[e]).map(e=>JSON.stringify(e)+":"+b(n[e],t));return t.delete(n),"{"+r.join(",")+"}"}return String(e)}const x=w("",n);function S(e,t){const r=function(e){if(0===e.length)return w("",n);if(1===e.length)return w(e[0],n);let t=[...e];for(;t.length>1;){const e=[];for(let r=0;r<t.length;r+=2){const o=r+1<t.length?t[r+1]:x;e.push(w(t[r]+o,n))}t=e}return t[0]}(Object.keys(e).sort().map(t=>{const r=function(e){let t=n;for(let n=0;n<e.length;n++)t=Math.imul(t^e.charCodeAt(n),1540483477),t^=t>>>13;return t>>>0}(t);return w(v(e[t]),r)})),o=String.fromCharCode(76,111,98,115),i=t?w(t,n):"";return w(r+o+i,n)}const _={name:"webgl",tier:1,async collect(){const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!(t&&t instanceof WebGLRenderingContext))return null;const n=t.getExtension("WEBGL_debug_renderer_info"),r=t.getSupportedExtensions()??[],o=function(e){const t={},n=[e.VERTEX_SHADER,e.FRAGMENT_SHADER],r=[e.LOW_FLOAT,e.MEDIUM_FLOAT,e.HIGH_FLOAT,e.LOW_INT,e.MEDIUM_INT,e.HIGH_INT],o=["vertex","fragment"],i=["lowFloat","mediumFloat","highFloat","lowInt","mediumInt","highInt"];for(let a=0;a<n.length;a++){const s={};for(let t=0;t<r.length;t++){const o=e.getShaderPrecisionFormat(n[a],r[t]);o&&(s[i[t]]={rangeMin:o.rangeMin,rangeMax:o.rangeMax,precision:o.precision})}t[o[a]]=s}return t}(t),i={vendor:t.getParameter(t.VENDOR),renderer:t.getParameter(t.RENDERER),version:t.getParameter(t.VERSION),shadingLanguageVersion:t.getParameter(t.SHADING_LANGUAGE_VERSION),unmaskedVendor:n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):null,unmaskedRenderer:n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):null,extensions:r.sort(),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE),maxViewportDims:Array.from(t.getParameter(t.MAX_VIEWPORT_DIMS)),maxVertexAttribs:t.getParameter(t.MAX_VERTEX_ATTRIBS),maxVertexUniformVectors:t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),maxFragmentUniformVectors:t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:t.getParameter(t.MAX_VARYING_VECTORS),aliasedLineWidthRange:Array.from(t.getParameter(t.ALIASED_LINE_WIDTH_RANGE)),aliasedPointSizeRange:Array.from(t.getParameter(t.ALIASED_POINT_SIZE_RANGE)),maxCombinedTextureImageUnits:t.getParameter(t.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxTextureImageUnits:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextureImageUnits:t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),shaderPrecision:o,maxAnisotropy:k(t),webgl2:C(e)};return t.getExtension("WEBGL_lose_context")?.loseContext(),i}};function k(e){try{const t=e.getExtension("EXT_texture_filter_anisotropic")??e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")??e.getExtension("MOZ_EXT_texture_filter_anisotropic");return t?e.getParameter(t.MAX_TEXTURE_MAX_ANISOTROPY_EXT):null}catch{return null}}function C(e){try{const t=e.getContext("webgl2");if(!t)return null;const n={version:t.getParameter(t.VERSION),maxSamples:t.getParameter(t.MAX_SAMPLES),max3DTextureSize:t.getParameter(t.MAX_3D_TEXTURE_SIZE),maxArrayTextureLayers:t.getParameter(t.MAX_ARRAY_TEXTURE_LAYERS),maxUniformBlockSize:t.getParameter(t.MAX_UNIFORM_BLOCK_SIZE),maxVertexUniformComponents:t.getParameter(t.MAX_VERTEX_UNIFORM_COMPONENTS),maxFragmentUniformComponents:t.getParameter(t.MAX_FRAGMENT_UNIFORM_COMPONENTS),maxColorAttachments:t.getParameter(t.MAX_COLOR_ATTACHMENTS),maxDrawBuffers:t.getParameter(t.MAX_DRAW_BUFFERS)};return t.getExtension("WEBGL_lose_context")?.loseContext(),n}catch{return null}}const E={name:"hardware",tier:1,collect:async()=>({architecture:T(),platform:I()})},A={name:"hardwareSensitive",tier:1,collect:async()=>({deviceMemory:navigator.deviceMemory??null,hardwareConcurrency:navigator.hardwareConcurrency??null})};function I(){const e=navigator.userAgentData;if(e?.platform)return e.platform;const t=navigator.userAgent??"";return/Windows/.test(t)?"Windows":/Macintosh|Mac OS X/.test(t)?"macOS":/CrOS/.test(t)?"Chrome OS":/Android/.test(t)?"Android":/Linux/.test(t)?"Linux":/iPhone|iPad|iPod/.test(t)?"iOS":""}function T(){try{const e=new ArrayBuffer(4),t=new Float32Array(e),n=new Uint8Array(e);return t[0]=1/0,n[3]}catch{return 0}}const P={name:"math",tier:1,collect:async()=>({acos:Math.acos(.5),asin:M(Math.asin,-1,1,97),cos:M(Math.cos,0,Math.PI,97),cosLarge:Math.cos(1e20),sinLarge:Math.sin(1e20),tanLarge:Math.tan(1e20),sin:M(Math.sin,0,Math.PI,97),tan:M(Math.tan,0,Math.PI/4,97)})};function M(e,t,n,r){const o=(n-t)/r;let i=e(t)+e(n);for(let n=1;n<r;n++)i+=e(t+n*o)*(n%2==0?2:4);return i*o/3}const D={name:"i18n",tier:1,collect:async()=>({dateTimeFormat:R(),numberFormat:$(),collator:O(),pluralRules:L(),relativeTimeFormat:B(),listFormat:U()})};function R(){try{const e=(new Intl.DateTimeFormat).resolvedOptions();return{locale:e.locale,calendar:e.calendar,numberingSystem:e.numberingSystem,timeZone:e.timeZone}}catch{return{}}}function $(){try{const e=(new Intl.NumberFormat).resolvedOptions();return{locale:e.locale,numberingSystem:e.numberingSystem,style:e.style,minimumIntegerDigits:e.minimumIntegerDigits,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,useGrouping:e.useGrouping}}catch{return{}}}function O(){try{const e=(new Intl.Collator).resolvedOptions();return{locale:e.locale,usage:e.usage,sensitivity:e.sensitivity,collation:e.collation,numeric:e.numeric,caseFirst:e.caseFirst}}catch{return{}}}function L(){try{const e=(new Intl.PluralRules).resolvedOptions(),t=new Intl.PluralRules(void 0,{type:"ordinal"}).resolvedOptions();return{locale:e.locale,type:e.type,cardinalCategories:(new Intl.PluralRules).select(0)+","+(new Intl.PluralRules).select(1)+","+(new Intl.PluralRules).select(2)+","+(new Intl.PluralRules).select(5)+","+(new Intl.PluralRules).select(11)+","+(new Intl.PluralRules).select(100),ordinalCategory1:t.type,minimumIntegerDigits:e.minimumIntegerDigits}}catch{return{}}}function B(){try{const e=new Intl.RelativeTimeFormat;if(!e)return{};const t=e.resolvedOptions();return{locale:t.locale,style:t.style,numeric:t.numeric,numberingSystem:t.numberingSystem}}catch{return{}}}function U(){try{const e=new Intl.ListFormat;if(!e)return{};const t=e.resolvedOptions(),n=["X","Y","Z"],r=new Intl.ListFormat(void 0,{type:"conjunction",style:"long"}),o=new Intl.ListFormat(void 0,{type:"disjunction",style:"long"});return{locale:t.locale,type:t.type,style:t.style,conjunctionSample:r.format(n),disjunctionSample:o.format(n)}}catch{return{}}}const F={name:"domrect",tier:1,collect:async()=>({basic:function(){const e=document.createElement("div");e.style.cssText="position:fixed;left:-9999px;width:100px;height:100px;",document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}(),precision:function(){const e=document.createElement("div");e.style.cssText=`position:absolute;left:-9999px;width:${Math.PI}px;height:${Math.E}px;`,document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{width:t.width,height:t.height}}(),fromRect:"undefined"!=typeof DOMRectReadOnly&&"function"==typeof DOMRectReadOnly.fromRect})},j={name:"touch",tier:1,collect:async()=>({supported:"ontouchstart"in window||navigator.maxTouchPoints>0,maxTouchPoints:navigator.maxTouchPoints??0})},V={name:"display",tier:1,collect:async()=>({colorDepth:screen.colorDepth??0,pixelDepth:screen.pixelDepth??0})},z={name:"locale",tier:1,collect:async()=>({timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"",language:navigator.language??""})},W={name:"workers",tier:1,collect:async()=>({webWorker:"undefined"!=typeof Worker,sharedWorker:"undefined"!=typeof SharedWorker,serviceWorker:"serviceWorker"in navigator})},N={name:"plugins",tier:1,async collect(){const e=[];if(navigator.plugins)for(let t=0;t<navigator.plugins.length;t++){const n=navigator.plugins[t];"internal-pdf-viewer"===n.filename&&e.push(`${n.name}|${n.filename}|${n.description}`)}return{plugins:e.sort(),pdfViewerEnabled:navigator.pdfViewerEnabled??!1}}},G=[["backdrop-filter","blur(1px)"],["container-type","inline-size"],["text-wrap","balance"],["overscroll-behavior","contain"],["hanging-punctuation","first"],["-webkit-line-clamp","1"],["appearance","none"],["font-size-adjust","ex-height 0.5"],["font-palette","normal"],["field-sizing","content"],["-webkit-text-stroke","1px black"],["zoom","1"],["scrollbar-width","thin"],["scrollbar-color","red blue"],["animation-timeline","auto"],["mask-composite","add"],["offset-path","none"],["text-decoration-thickness","1px"],["content-visibility","auto"],["contain-intrinsic-size","auto 100px"],["aspect-ratio","16/9"],["gap","10px"],["color-mix","in srgb, red 50%, blue"],["linear-gradient(in oklch, red, blue)",""]],q={name:"css",tier:1,collect:async()=>({supports:H(),safeArea:K()})};function H(){const e={};if("undefined"==typeof CSS||"function"!=typeof CSS.supports)return e;for(const[t,n]of G)e[t]=n?CSS.supports(t,n):CSS.supports(t);return e}function K(){try{const e=document.createElement("div");e.style.cssText=["position:fixed","top:0","left:0","width:0","height:0","visibility:hidden","padding-top:env(safe-area-inset-top,0px)","padding-bottom:env(safe-area-inset-bottom,0px)","padding-left:env(safe-area-inset-left,0px)","padding-right:env(safe-area-inset-right,0px)"].join(";"),document.body.appendChild(e);const t=getComputedStyle(e),n={top:t.paddingTop,bottom:t.paddingBottom,left:t.paddingLeft,right:t.paddingRight};return document.body.removeChild(e),n}catch{return null}}const J={name:"cssLayout",tier:1,collect:async()=>({scrollbarWidth:Y()})};function Y(){try{const e=document.createElement("div");e.style.cssText="visibility:hidden;overflow:scroll;position:absolute;top:-9999px;width:100px;height:100px",document.body.appendChild(e);const t=document.createElement("div");e.appendChild(t);const n=e.offsetWidth-t.offsetWidth;return document.body.removeChild(e),n}catch{return-1}}const X={name:"navigatorProps",tier:1,collect:async()=>({vendor:navigator.vendor??"",productSub:navigator.productSub??"",cookieEnabled:navigator.cookieEnabled})},Z={name:"navigatorConnection",tier:2,async collect(){const e=navigator,t=e.connection??e.mozConnection??e.webkitConnection??null,n=performance.memory??null;return{connection:t?{type:t.type??null,effectiveType:t.effectiveType??null,saveData:t.saveData??null}:null,memory:n?{jsHeapSizeLimit:n.jsHeapSizeLimit}:null}}},Q={name:"timing",tier:2,collect:async()=>({performancePrecisionUs:ee()})};function ee(){try{const e=performance.now();let t=1/0,n=e;for(let r=0;r<50;r++){const r=performance.now(),o=r-n;if(o>0&&o<t&&(t=o),n=r,r-e>=1)break}if(t===1/0)return-1;const r=1e3*t;if(r<=0)return-1;const o=Math.max(0,Math.round(Math.log10(r)));return Math.pow(10,o)}catch{return-1}}const te={name:"webgpu",tier:2,async collect(){const e=navigator.gpu;if(!e)return null;const t=await e.requestAdapter();if(!t)return null;let n="",r="",o="",i="";if(t.info)n=t.info.vendor??"",r=t.info.architecture??"",o=t.info.device??"",i=t.info.description??"";else if("function"==typeof t.requestAdapterInfo){const e=await t.requestAdapterInfo();n=e.vendor??"",r=e.architecture??"",o=e.device??"",i=e.description??""}const a=[];t.features&&(t.features.forEach(e=>a.push(e)),a.sort());const s={};if(t.limits){const e=["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderComponents","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension"];for(const n of e){const e=t.limits[n];void 0!==e&&(s[n]=e)}}return{vendor:n,architecture:r,device:o,description:i,features:a,limits:s}}},ne={name:"audio",tier:2,async collect(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return null;let t=null;try{t=new e;const n=t.destination;return{sampleRate:t.sampleRate,maxChannelCount:n.maxChannelCount,channelCount:n.channelCount,channelCountMode:n.channelCountMode,channelInterpretation:n.channelInterpretation,baseLatency:t.baseLatency??null,outputLatency:t.outputLatency??null}}finally{if(t&&"closed"!==t.state)try{await t.close()}catch{}}}},re=["Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Bookman Old Style","Bradley Hand","Calibri","Cambria","Cambria Math","Century","Century Gothic","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Gill Sans","Helvetica","Helvetica Neue","Impact","Lucida Console","Lucida Grande","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3","Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Ubuntu","Merriweather","Playfair Display","Source Sans Pro","Source Code Pro","Fira Code","JetBrains Mono","Cascadia Code","Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","SF Pro","SF Pro Display","SF Mono","San Francisco","Menlo","Andale Mono","Futura","MS Gothic","MS Mincho","MS PGothic","MS PMincho","Yu Gothic","Meiryo","Hiragino Sans","Hiragino Kaku Gothic Pro","SimSun","SimHei","Microsoft YaHei","PingFang SC","Noto Sans CJK","Malgun Gothic","Arial Hebrew"],oe=["monospace","sans-serif","serif"],ie="mmMwWLliI0O&1",ae={name:"fonts",tier:2,collect:()=>new Promise(e=>{const t=()=>e(function(){try{if("undefined"==typeof document)return{available:[],method:"css-layout"};const e=new Set,t=[];if("function"==typeof document.fonts?.check)for(const n of re)document.fonts.check(`72px "${n}"`)?e.add(n):t.push(n);else t.push(...re);const n=new Set;if(t.length>0){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px;left:-9999px;pointer-events:none;";const r=oe.map(t=>{const n=document.createElement("span");return n.style.cssText=`font-size:72px;font-family:${t};white-space:nowrap;display:inline-block`,n.textContent=ie,e.appendChild(n),n}),o=t.map(t=>oe.map(n=>{const r=document.createElement("span");return r.style.cssText=`font-size:72px;font-family:'${t}',${n};white-space:nowrap;display:inline-block`,r.textContent=ie,e.appendChild(r),r}));document.body.appendChild(e);const i=r.map(e=>e.getBoundingClientRect().width),a=o.map(e=>e.map(e=>e.getBoundingClientRect().width));document.body.removeChild(e);for(let e=0;e<t.length;e++)for(let r=0;r<oe.length;r++)if(a[e][r]!==i[r]){n.add(t[e]);break}}return{available:re.filter(t=>e.has(t)||n.has(t)),method:"css-layout"}}catch{return{available:[],method:"css-layout"}}}());"undefined"!=typeof requestIdleCallback?requestIdleCallback(t,{timeout:2e3}):setTimeout(t,0)})},se={name:"webrtc",tier:2,async collect(){if("undefined"==typeof RTCPeerConnection)return{supported:!1,audioCodecCount:0,videoCodecCount:0,audioCodecs:[],videoCodecs:[],extensions:[]};const e=new RTCPeerConnection({iceServers:[]});try{e.addTransceiver("audio"),e.addTransceiver("video");const t=(await e.createOffer()).sdp??"",n=ce(t,"audio"),r=ce(t,"video"),o=function(e){const t=new Set,n=e.split("\r\n");for(const e of n)if(e.startsWith("a=extmap:")){const n=e.match(/^a=extmap:\d+(?:\/\w+)?\s+(.+)$/);n&&t.add(n[1].trim())}return Array.from(t)}(t);return{supported:!0,audioCodecCount:n.length,videoCodecCount:r.length,audioCodecs:n.sort(),videoCodecs:r.sort(),extensions:o.sort()}}finally{e.close()}}};function ce(e,t){const n=[],r=e.split("\r\n");let o=!1;for(const e of r)if(e.startsWith(`m=${t}`))o=!0;else{if(e.startsWith("m=")&&o)break;if(o&&e.startsWith("a=rtpmap:")){const t=e.match(/^a=rtpmap:\d+\s+(.+)$/);t&&n.push(t[1])}}return n}const ue=["accelerometer","accessibility-events","ambient-light-sensor","background-fetch","background-sync","bluetooth","camera","clipboard-read","clipboard-write","display-capture","geolocation","gyroscope","local-fonts","magnetometer","microphone","midi","nfc","notifications","payment-handler","persistent-storage","push","screen-wake-lock","speaker-selection","storage-access","top-level-storage-access","window-management","xr-spatial-tracking"],le={name:"permissions",tier:2,async collect(){if(!navigator.permissions?.query)return{states:{}};const e=()=>Promise.allSettled(ue.map(async e=>{try{return{name:e,state:(await navigator.permissions.query({name:e})).state}}catch{return{name:e,state:"error"}}})),t=await Promise.all([e(),e(),e()]),n={};for(const e of t)for(const t of e)if("fulfilled"===t.status){const{name:e,state:r}=t.value;n[e]||(n[e]=[]),n[e].push(r)}const r={};for(const[e,t]of Object.entries(n))r[e]=de(t);return{states:r}}};function de(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;let n=e[0],r=0;for(const[e,o]of Object.entries(t))o>r&&(n=e,r=o);return n}const fe={name:"speech",tier:2,async collect(){if("undefined"==typeof speechSynthesis)return{supported:!1,voiceCount:0,voices:[]};const e=await new Promise(e=>{const t=speechSynthesis.getVoices();if(t.length>0)return void e(t);const n=setTimeout(()=>e([]),800);speechSynthesis.addEventListener("voiceschanged",()=>{clearTimeout(n),e(speechSynthesis.getVoices())},{once:!0})}),t=e.map(e=>`${e.name}|${e.lang}|${e.localService}`).sort();return{supported:!0,voiceCount:e.length,voices:t}}},me=[{name:"prefers-contrast",values:["no-preference","more","less","custom"]},{name:"any-hover",values:["none","hover"]},{name:"any-pointer",values:["none","coarse","fine"]},{name:"pointer",values:["none","coarse","fine"]},{name:"hover",values:["none","hover"]},{name:"update",values:["none","slow","fast"]},{name:"inverted-colors",values:["none","inverted"]},{name:"prefers-reduced-motion",values:["no-preference","reduce"]},{name:"prefers-reduced-transparency",values:["no-preference","reduce"]},{name:"scripting",values:["none","initial-only","enabled"]},{name:"forced-colors",values:["none","active"]},{name:"prefers-color-scheme",values:["light","dark"]},{name:"color-gamut",values:["srgb","p3","rec2020"]},{name:"dynamic-range",values:["standard","high"]}],he={name:"mediaQueries",tier:2,async collect(){if("function"!=typeof matchMedia){const e={};for(const t of me)e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]="unsupported";return{...e,monochrome:0}}const e={};for(const t of me){let n="unknown";for(const e of t.values){const r=matchMedia(`(${t.name}: ${e})`);if(r?.matches){n=e;break}}e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]=n}let t=0;for(let e=100;e>=0;e--)if(matchMedia(`(monochrome: ${e})`)?.matches){t=e;break}return{...e,monochrome:t}}},pe={name:"applePay",tier:2,async collect(){const e=window.ApplePaySession;if(!e||"function"!=typeof e.supportsVersion)return{supported:!1,maxVersion:0};let t=0;for(let n=15;n>=1;n--)try{if(e.supportsVersion(n)){t=n;break}}catch{continue}return{supported:!0,maxVersion:t}}},ye=["KeyQ","KeyW","KeyA","KeyS","KeyZ","KeyX","KeyY","KeyM","Semicolon","BracketLeft","Quote","Digit1","Digit2","Digit3"],ge={name:"keyboard",tier:2,async collect(){const e=navigator.keyboard;if(!e||"function"!=typeof e.getLayoutMap)return{supported:!1,layoutKeys:null,layoutHint:null};try{const t=await e.getLayoutMap(),n={};for(const e of ye){const r=t.get(e);void 0!==r&&(n[e]=r)}return{supported:!0,layoutKeys:n,layoutHint:we(n)}}catch{return{supported:!1,layoutKeys:null,layoutHint:null}}}};function we(e){const t=e.KeyQ,n=e.KeyZ,r=e.KeyY;return t?"a"===t?"azerty":"q"===t&&"z"===r?"qwertz":"q"===t&&"z"===n?"qwerty":"'"===t?"dvorak":"other":null}const ve={name:"canvas",tier:2,async collect(){const e=document.createElement("canvas"),t=e.getContext("2d");if(!t)return null;e.width=240,e.height=120,t.textBaseline="alphabetic",t.fillStyle="#f60",t.fillRect(100,1,62,20),t.fillStyle="#069",t.font='11pt "Times New Roman"',t.fillText("Cwm fjordbank gly"+String.fromCharCode(55357,56835),2,15),t.fillStyle="rgba(102,204,0,0.2)",t.font="18pt Arial",t.fillText("Cwm fjordbank gly"+String.fromCharCode(55357,56835),4,45);const n=e.toDataURL("image/png");t.clearRect(0,0,e.width,e.height),t.globalCompositeOperation="multiply",t.fillStyle="#f2f",t.beginPath(),t.arc(40,40,40,0,2*Math.PI),t.fill(),t.fillStyle="#2ff",t.beginPath(),t.arc(80,40,40,0,2*Math.PI),t.fill(),t.fillStyle="#ff2",t.beginPath(),t.arc(60,80,40,0,2*Math.PI),t.fill(),t.globalCompositeOperation="source-over",t.fillStyle="#f9c",t.beginPath(),t.arc(60,60,60,0,2*Math.PI),t.arc(60,60,20,0,2*Math.PI),t.fill("evenodd");const r=e.toDataURL("image/png");return{textDataUrl:n,geometryDataUrl:r,readbackAllowed:n.length>=1e3&&r.length>=1e3,windingRule:0===t.getImageData(60,60,1,1).data[3]}}},be={name:"audioOscillator",tier:2,async collect(){const e=window.OfflineAudioContext||window.webkitOfflineAudioContext;if(!e)return null;const t=new e(1,5e3,44100),n=t.createOscillator();n.type="triangle",n.frequency.value=1e4;const r=t.createDynamicsCompressor();r.threshold.value=-50,r.knee.value=40,r.ratio.value=12,r.attack.value=0,r.release.value=.25,n.connect(r),r.connect(t.destination),n.start(0);const o=(await t.startRendering()).getChannelData(0).slice(4500,5e3);let i=0;for(let e=0;e<o.length;e++)i+=Math.abs(o[e]);return{sampleSum:i,sampleCount:o.length}}},xe={name:"webglRender",tier:2,async collect(){const e=document.createElement("canvas");e.width=256,e.height=256;const t=e.getContext("webgl",{preserveDrawingBuffer:!0});if(!t)return null;try{const e="\n attribute vec2 position;\n attribute vec3 color;\n varying vec3 vColor;\n void main() {\n gl_Position = vec4(position, 0.0, 1.0);\n vColor = color;\n }\n ",n="\n precision mediump float;\n varying vec3 vColor;\n void main() {\n gl_FragColor = vec4(vColor, 1.0);\n }\n ",r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,e),t.compileShader(r);const o=t.createShader(t.FRAGMENT_SHADER);t.shaderSource(o,n),t.compileShader(o);const i=t.createProgram();t.attachShader(i,r),t.attachShader(i,o),t.linkProgram(i),t.useProgram(i);const a=new Float32Array([-.5,-.5,1,0,0,.5,-.5,0,1,0,0,.5,0,0,1]),s=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,s),t.bufferData(t.ARRAY_BUFFER,a,t.STATIC_DRAW);const c=t.getAttribLocation(i,"position");t.enableVertexAttribArray(c),t.vertexAttribPointer(c,2,t.FLOAT,!1,20,0);const u=t.getAttribLocation(i,"color");t.enableVertexAttribArray(u),t.vertexAttribPointer(u,3,t.FLOAT,!1,20,8),t.clearColor(0,0,0,1),t.clear(t.COLOR_BUFFER_BIT),t.drawArrays(t.TRIANGLES,0,3),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),t.drawArrays(t.TRIANGLES,0,3);const l=new Uint8Array(262144);t.readPixels(0,0,256,256,t.RGBA,t.UNSIGNED_BYTE,l);const d=function(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e[n],t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}(l);let f=!1;for(let e=0;e<l.length;e++)if(0!==l[e]){f=!0;break}return{pixelHash:d,readbackAllowed:f}}finally{t.getExtension("WEBGL_lose_context")?.loseContext()}}},Se=["14px Arial","14px Georgia","14px monospace"],_e={name:"canvasTextMetrics",tier:2,async collect(){const e=document.createElement("canvas").getContext("2d");if(!e)return null;const t=[];for(const n of Se){e.font=n;const r=e.measureText("Sphinx of black quartz, judge my vow. 0123456789");t.push({font:n,width:r.width,actualBoundingBoxAscent:r.actualBoundingBoxAscent??null,actualBoundingBoxDescent:r.actualBoundingBoxDescent??null,actualBoundingBoxLeft:r.actualBoundingBoxLeft??null,actualBoundingBoxRight:r.actualBoundingBoxRight??null,fontBoundingBoxAscent:r.fontBoundingBoxAscent??null,fontBoundingBoxDescent:r.fontBoundingBoxDescent??null})}return{metrics:t}}},ke=["chrome","safari","__crWeb","__gCrWeb","yandex","__yb","__ybro","__firefox__","__edgeTrackingPreventionStatistics","webkit","oprt","samsungAr","ucweb","UCShellJava","puffinDevice"],Ce={name:"vendorFlavors",tier:2,async collect(){const e=window,t=[];for(const n of ke)void 0!==e[n]&&t.push(n);return t.sort(),{flavors:t}}},Ee=[{key:"default",family:""},{key:"apple",family:"-apple-system, BlinkMacSystemFont"},{key:"serif",family:"serif"},{key:"sansSerif",family:"sans-serif"},{key:"monospace",family:"monospace"},{key:"systemUi",family:"system-ui"}],Ae={name:"fontPreferences",tier:2,async collect(){if("undefined"==typeof document||!document.body)return null;const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px";const t=Ee.map(({family:t})=>{const n=document.createElement("span");return n.textContent="mmMwWLliI0fiflO&1",n.style.fontSize="72px",t&&(n.style.fontFamily=t),e.appendChild(n),n});document.body.appendChild(e);const n={};for(let e=0;e<Ee.length;e++){const r=t[e].getBoundingClientRect().width;n[Ee[e].key]=Math.round(1e3*r)/1e3}return document.body.removeChild(e),n}},Ie={name:"screenFrame",tier:2,async collect(){const e=screen,t=e.availTop??0,n=e.availLeft??0;return{top:t,right:screen.width-(e.availWidth??screen.width)-n,bottom:screen.height-(e.availHeight??screen.height)-t,left:n}}};function Te(e){return/Not[ ;)\/]/i.test(e)}const Pe={name:"clientHints",tier:2,async collect(){const e=navigator;if(!e.userAgentData)return null;const t=(e.userAgentData.brands??[]).filter(e=>!Te(e.brand)),n=e.userAgentData.mobile??!1,r=e.userAgentData.platform??"",o=await e.userAgentData.getHighEntropyValues(["architecture","bitness","model","platformVersion","fullVersionList"]),i=(o.fullVersionList??[]).filter(e=>!Te(e.brand));return{brands:t,mobile:n,platform:r,architecture:o.architecture??"",bitness:o.bitness??"",model:o.model??"",platformVersion:o.platformVersion??"",fullVersionList:i}}},Me=[{name:"EasyList",selectors:[".ad-banner",".ad_banner","#ad-banner",".adsbygoogle",".ad-container"]},{name:"AdGuard Base",selectors:[".BannerAd",".ad-rotate","#ad-box",".ad-placement",".ad-zone"]},{name:"EasyPrivacy",selectors:["#tracking-pixel",".tracking",".analytics-tag","#beacon",".pixel-tracker"]},{name:"Fanboy Annoyances",selectors:["#newsletter-popup",".cookie-banner",".consent-dialog","#gdpr-notice",".subscribe-modal"]},{name:"AdGuard Tracking",selectors:[".tracker-frame","#analytics-beacon",".telemetry-pixel",".data-tracker","#stats-counter"]}],De={name:"domBlockers",tier:2,async collect(){if("undefined"==typeof document||!document.body)return{activeFilters:[]};const e=[],t=[];try{for(const n of Me){const r=[];for(const t of n.selectors){const n=document.createElement("div");t.startsWith("#")?n.id=t.slice(1):n.className=t.slice(1),document.body.appendChild(n),r.push(n),e.push(n)}t.push({name:n.name,elements:r})}await new Promise(e=>setTimeout(e,0));const n=[];for(const{name:e,elements:r}of t){let t=0;for(const e of r)null===e.offsetParent&&t++;t/r.length>.6&&n.push(e)}return{activeFilters:n}}catch{return{activeFilters:[]}}finally{for(const t of e)try{t.parentNode?.removeChild(t)}catch{}}}},Re={name:"privateClickMeasurement",tier:2,collect:async()=>({supported:"attributionSourceId"in document.createElement("a")})},$e={name:"automationDetection",tier:2,async collect(){const e=!!navigator.webdriver,t=function(){const e=[];try{const t=Object.getOwnPropertyNames(document);for(const n of t)/^\$?cdc_/.test(n)&&e.push(n)}catch{}const t=[["_Selenium_IDE_Recorder",()=>"t"in window],["__webdriver_evaluate",()=>"o"in document],["__driver_evaluate",()=>"i"in document],["__puppeteer_evaluation_script__",()=>"u"in window],["__playwright__binding__",()=>"l"in window],["__pwInitScripts",()=>"m"in window],["callPhantom",()=>"callPhantom"in window],["_phantom",()=>"h"in window],["__nightmare",()=>"p"in window],["domAutomation",()=>"domAutomation"in window],["domAutomationController",()=>"domAutomationController"in window]];for(const[n,r]of t)try{r()&&e.push(n)}catch{}return e}(),n=await async function(){try{if("undefined"==typeof Proxy)return!1;let e=!1;const t={};return Object.setPrototypeOf(t,new Proxy(Object.create(null),{ownKeys:()=>(e=!0,[])})),console.groupEnd(t),await new Promise(e=>setTimeout(e,100)),e}catch{return!1}}(),r=await async function(){const e=[];try{0===navigator.plugins.length&&window.chrome&&e.push("no_plugins_with_chrome")}catch{}0!==window.outerWidth&&0!==window.outerHeight||e.push("zero_outer_dimensions"),0===screen.availHeight&&e.push("zero_avail_height");try{0===navigator.languages.length&&e.push("empty_languages")}catch{}try{window.chrome&&void 0===window.chrome?.runtime&&e.push("chrome_without_runtime")}catch{}try{"undefined"!=typeof Notification&&"denied"===Notification.permission&&"prompt"===(await navigator.permissions.query({name:"notifications"})).state&&e.push("notification_permission_contradiction")}catch{}return e}(),o=function(){let e=null;try{if(e=document.createElement("canvas").getContext("webgl"),!e)return!1;const t=e.getExtension("WEBGL_debug_renderer_info");if(!t)return!1;const n=e.getParameter(t.UNMASKED_RENDERER_WEBGL);if("string"!=typeof n)return!1;const r=["swiftshader","google swiftshader","llvmpipe","mesa","software rasterizer","microsoft basic render driver"],o=n.toLowerCase();return r.some(e=>o.includes(e))}catch{return!1}finally{if(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}}}();let i=0;return e&&(i+=30),t.length>0&&(i+=20),n&&(i+=25),r.length>=2&&(i+=15),o&&(i+=20),{webdriver:e,automationMarkers:t,cdpDetected:n,headlessIndicators:r,softwareRenderer:o,botScore:i}}},Oe={name:"agentDetection",tier:2,async collect(){const e=function(){const e=[];try{13===navigator.hardwareConcurrency&&e.push("unusual_core_count_13")}catch{}try{4===navigator.deviceMemory&&6===navigator.hardwareConcurrency&&e.push("manus_hardware_signature")}catch{}try{1280===screen.width&&1100===screen.height&&e.push("manus_resolution")}catch{}try{if("UTC"===Intl.DateTimeFormat().resolvedOptions().timeZone){const t=navigator.languages||[],n=["en-GB","pt-PT","is","is-IS"];t.some(e=>n.includes(e))||e.push("utc_timezone_mismatch")}}catch{}return e}(),t=function(){try{const e=navigator.userAgent||"",t=navigator.userAgentData?.platform,n=navigator.platform||"";let r="";if(/Windows/.test(e)?r="Windows":/Macintosh|Mac OS X/.test(e)?r="macOS":/Android/.test(e)?r="Android":/iPhone|iPad|iPod/.test(e)?r="iOS":/Linux/.test(e)&&(r="Linux"),t){const e=t.toLowerCase();if("linux"===e&&("macOS"===r||"Windows"===r))return!1;if("windows"===e&&"macOS"===r)return!1;if("macos"===e&&"Windows"===r)return!1}if(n){const e=n.toLowerCase();if(e.includes("linux")&&("macOS"===r||"Windows"===r))return!1;if(e.includes("win")&&"macOS"===r)return!1;if(e.includes("mac")&&"Windows"===r)return!1}return!0}catch{return!0}}(),n=function(){try{const e=Intl.DateTimeFormat().resolvedOptions().timeZone,t=(new Date).getTimezoneOffset();return"UTC"!==e||0===t}catch{return!0}}(),r=function(e,t){return e.includes("unusual_core_count_13")?"chatgpt":e.includes("manus_hardware_signature")&&e.includes("manus_resolution")?"manus":t?null:"operator"}(e,t);let o=0;return o+=25*e.length,t||(o+=30),r&&(o+=50),{fingerprintAnomalies:e,uaPlatformMatch:t,timezoneConsistent:n,detectedAgent:r,agentScore:o}}},Le={name:"tamperDetection",tier:2,async collect(){const e=function(){try{const e=navigator.userAgent||"",t=/Chrome\//.test(e)&&!/Edg\//.test(e),n=/Firefox\//.test(e)&&!/Chrome/.test(e),r="undefined"!=typeof CSS&&CSS.supports&&CSS.supports("-moz-appearance","none"),o=void 0!==window.chrome;return!(t&&r||n&&o)}catch{return!0}}(),t=function(){try{const e=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");if(!e)return!1;if(!e.get)return!1;const t=e.get.toString();return!!/\[native code\]/.test(t)}catch{return!0}}(),n=function(){try{const e=eval.toString().length;if(33!==e&&37!==e&&39!==e&&(e<20||e>60))return!1;try{if(1!==new(0,navigator.userAgent.constructor.constructor)("return 1")())return!1}catch{return!1}return!0}catch{return!0}}(),r=function(){const e=[];try{"v"in window&&e.push("multilogin")}catch{}try{void 0!==window.chrome&&0===navigator.plugins.length&&e.push("empty_plugins_chromium")}catch{}try{const t=window;if(t.safari){const n=t.safari.toString?.();n&&!/\[object Safari\]/.test(n)&&e.push("safari_object_spoofed")}}catch{}try{const t=navigator.userAgent||"",n=t.match(/Chrome\/(\d+)/);n&&parseInt(n[1],10)>=88&&/Macintosh/.test(t)&&void 0===window.BarcodeDetector&&e.push("missing_barcode_detector")}catch{}return e}(),o=function(){try{const e=((new Error).stack||"").split("\n").filter(e=>e.trim().length>0);for(const t of e){const e=t.trim();if("Error"!==e){if(/^\s*at\s/.test(e))return"chromium";if(/@/.test(e)&&!e.startsWith("at"))return/^\w+@/.test(e)?"gecko":"webkit"}}return"unknown"}catch{return"unknown"}}(),i=eval.toString().length;let a=0;if(e||(a+=30),t||(a+=25),n||(a+=20),a+=15*r.length,"unknown"!==o){const e=navigator.userAgent||"";("gecko"===o&&!/Firefox/.test(e)||"chromium"===o&&/Firefox/.test(e)&&!/Chrome/.test(e))&&(a+=10)}return{uaEngineConsistent:e,navigatorPropsNative:t,prototypeChainIntact:n,antiDetectMarkers:r,stackTraceFormat:o,evalLength:i,tamperScore:a}}},Be={name:"vmDetection",tier:2,async collect(){const e=function(){const e=[];try{navigator.hardwareConcurrency<=2&&e.push("low_core_count")}catch{}try{const t=navigator.deviceMemory;"number"==typeof t&&t<=2&&e.push("low_memory")}catch{}try{screen.colorDepth<24&&e.push("low_color_depth")}catch{}try{screen.colorDepth!==screen.pixelDepth&&e.push("depth_mismatch")}catch{}return e}();let t="",n=null;try{if(n=document.createElement("canvas").getContext("webgl"),n){const e=n.getExtension("WEBGL_debug_renderer_info");e&&(t=n.getParameter(e.UNMASKED_RENDERER_WEBGL)||"")}}catch{}finally{if(n)try{const e=n.getExtension("WEBGL_lose_context");e&&e.loseContext()}catch{}}const r=function(e){if(!e)return[];const t=e.toLowerCase();return Ue.filter(e=>t.includes(e))}(t),o=function(e){if(!e)return!1;const t=e.toLowerCase();return Fe.some(e=>t.includes(e))}(t);let i=0;return r.length>0?i=.9:o?i=.5:e.length>=3&&(i=.3),{isVM:r.length>0,vmRendererMatches:r,softwareRenderer:o,confidence:i,indicators:e}}},Ue=["virtualbox","vmware","svga3d","qemu","parallels","hyper-v","qxl","red hat","virtio","citrix"],Fe=["swiftshader","google swiftshader","llvmpipe","mesa","software rasterizer","microsoft basic render driver","softpipe"],je=[{label:"h264",contentType:'video/mp4; codecs="avc1.42E01E"',width:1920,height:1080,bitrate:5e6,framerate:30},{label:"vp8",contentType:'video/webm; codecs="vp8"',width:1920,height:1080,bitrate:5e6,framerate:30},{label:"vp9",contentType:'video/webm; codecs="vp09.00.10.08"',width:1920,height:1080,bitrate:5e6,framerate:30},{label:"av1",contentType:'video/mp4; codecs="av01.0.05M.08"',width:1920,height:1080,bitrate:5e6,framerate:30}],Ve=[{label:"aac",contentType:'audio/mp4; codecs="mp4a.40.2"',channels:"2",bitrate:128e3,samplerate:44100},{label:"opus",contentType:'audio/webm; codecs="opus"',channels:"2",bitrate:128e3,samplerate:48e3}],ze=[_,E,A,P,D,F,j,V,z,W,N,q,J,X,Q,Z,te,ne,ae,se,le,fe,he,pe,ge,ve,be,xe,_e,Ce,Ae,Ie,Pe,De,Re,$e,Oe,Le,Be,{name:"devtoolsDetection",tier:2,collect:async()=>({dimensionDelta:function(){const e=window.outerHeight-window.innerHeight,t=window.outerWidth-window.innerWidth;return{heightDelta:e,widthDelta:t,likelyOpen:e>200||t>200}}(),consoleTimingAnomaly:function(){try{const e={};for(let t=0;t<1e3;t++)e[`key${t}`]=t;const t=performance.now();return console.log(e),performance.now()-t>1}catch{return!1}}(),consoleNative:function(){try{return/\[native code\]/.test(Function.prototype.toString.call(console.log))}catch{return!0}}()})},{name:"webApis",tier:2,async collect(){const e=navigator,t=window;return{credentials:void 0!==e.credentials,usb:void 0!==e.usb,bluetooth:void 0!==e.bluetooth,clipboard:void 0!==e.clipboard,serial:void 0!==e.serial,hid:void 0!==e.hid,xr:void 0!==e.xr,share:"function"==typeof e.share,wakeLock:void 0!==e.wakeLock,presentation:void 0!==e.presentation,mediaSession:void 0!==e.mediaSession,ink:void 0!==e.ink,virtualKeyboard:void 0!==e.virtualKeyboard,eyeDropper:void 0!==t.EyeDropper,getScreenDetails:"function"==typeof t.getScreenDetails,paymentRequest:void 0!==t.PaymentRequest,adoptedStyleSheets:void 0!==document.adoptedStyleSheets,cssHighlights:void 0!==t.CSS?.highlights}}},{name:"notificationState",tier:2,async collect(){const e="undefined"!=typeof Notification;return{supported:e,permission:e?Notification.permission:null}}},{name:"extendedLocale",tier:2,collect:async()=>({languages:Array.from(navigator.languages??[])})},{name:"privacyPrefs",tier:2,async collect(){const e=navigator;return{doNotTrack:navigator.doNotTrack??null,globalPrivacyControl:e.globalPrivacyControl??null}}},{name:"performanceContext",tier:2,async collect(){let e=null;try{const t=performance.getEntriesByType("navigation");t.length>0&&(e=t[0].nextHopProtocol||null)}catch{}let t=[];try{t=Array.from(PerformanceObserver.supportedEntryTypes??[])}catch{}return{nextHopProtocol:e,supportedEntryTypes:t}}},{name:"sensors",tier:2,async collect(){const e=window;return{deviceOrientation:void 0!==e.DeviceOrientationEvent,deviceMotion:void 0!==e.DeviceMotionEvent,gyroscope:void 0!==e.Gyroscope,accelerometer:void 0!==e.Accelerometer,ambientLightSensor:void 0!==e.AmbientLightSensor,absoluteOrientationSensor:void 0!==e.AbsoluteOrientationSensor,relativeOrientationSensor:void 0!==e.RelativeOrientationSensor}}},{name:"battery",tier:2,collect:async()=>({supported:"function"==typeof navigator.getBattery})},{name:"gamepads",tier:2,collect:async()=>({supported:"function"==typeof navigator.getGamepads})},{name:"storage",tier:2,async collect(){let e=null;try{navigator.storage?.estimate&&(e=(await navigator.storage.estimate()).quota??null)}catch{}let t=!1;try{t=void 0!==window.indexedDB}catch{}let n=!1;try{n=void 0!==window.localStorage}catch{}return{quota:e,indexedDB:t,localStorage:n,cacheApi:void 0!==window.caches}}},{name:"features",tier:2,async collect(){const e=window;return{isSecureContext:!!e.isSecureContext,webdriver:!!navigator.webdriver,crossOriginIsolated:!!e.crossOriginIsolated,sharedArrayBuffer:void 0!==e.SharedArrayBuffer,webAssembly:void 0!==e.WebAssembly,bigInt:void 0!==e.BigInt,offscreenCanvas:void 0!==e.OffscreenCanvas}}},{name:"screen",tier:2,async collect(){const e=window.visualViewport;return{availWidth:screen.availWidth??0,availHeight:screen.availHeight??0,devicePixelRatio:window.devicePixelRatio??1,orientationType:screen.orientation?.type??null,orientationAngle:screen.orientation?.angle??null,visualViewport:e?{width:e.width,height:e.height,offsetLeft:e.offsetLeft,offsetTop:e.offsetTop,scale:e.scale}:null}}},{name:"mediaCapabilities",tier:2,async collect(){if(!navigator.mediaCapabilities?.decodingInfo)return null;const e={},t=[...je.map(e=>({label:e.label,config:{type:"file",video:{contentType:e.contentType,width:e.width,height:e.height,bitrate:e.bitrate,framerate:e.framerate}}})),...Ve.map(e=>({label:e.label,config:{type:"file",audio:{contentType:e.contentType,channels:e.channels,bitrate:e.bitrate,samplerate:e.samplerate}}}))];return await Promise.allSettled(t.map(async({label:t,config:n})=>{try{const r=await navigator.mediaCapabilities.decodingInfo(n);e[t]={supported:r.supported,smooth:r.smooth,powerEfficient:r.powerEfficient}}catch{e[t]=null}})),e}}];async function We(e){const n=function(e){return e?{exclude:e.exclude??r.exclude,include:e.include??r.include,timeout:e.timeout??r.timeout,stabilize:e.stabilize??r.stabilize,experimental:e.experimental??r.experimental,debug:e.debug??r.debug,salt:e.salt??r.salt}:{...r}}(e),c=u(),l=function(){try{return window.self!==window.top}catch{return!0}}();let d=!1;try{d=await async function(e){try{switch(e){case"chrome":case"edge":case"opera":default:return await async function(){if(!navigator.storage?.estimate)return!1;const{quota:e}=await navigator.storage.estimate();return void 0!==e&&e<4294967296}();case"brave":return await async function(){return!1}();case"safari":return await async function(){if(navigator.storage?.estimate){const{quota:e}=await navigator.storage.estimate();if(void 0!==e)return e<4294967296}try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"NotFoundError"===e?.name}}();case"firefox":return await async function(){if(!("serviceWorker"in navigator))return!0;try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"SecurityError"===e?.name}}()}}catch{return!1}}(c.name)}catch{}const f=function(e,t,n,r){const o=new Set;for(const i of e){if("private"===i&&!n)continue;if("iframe"===i&&!r)continue;const e=s[i];if(e)for(const n of e)if(!n.browsers||n.browsers.includes(t))for(const e of n.exclude)o.add(e)}return o}(n.stabilize,c.name,d,l),m=new Set(f);for(const e of n.exclude)m.add(e);for(const e of n.include)m.delete(e);const{components:h,errors:p}=await async function(e,t,n){const r={},o=[],i=ze.filter(t=>!e.has(t.name)&&(n||3!==t.tier)),a=await Promise.allSettled(i.map(async e=>{const n=await(r=e.collect(),o=t,new Promise((e,t)=>{const n=setTimeout(()=>e(null),o);r.then(t=>{clearTimeout(n),e(t)},e=>{clearTimeout(n),t(e)})}));var r,o;return{name:e.name,value:n}}));for(let e=0;e<a.length;e++){const t=a[e],n=i[e].name;"fulfilled"===t.status&&null!==t.value.value?r[n]=t.value.value:"rejected"===t.status&&o.push({signal:n,error:String(t.reason?.message??t.reason)})}return{components:r,errors:o}}(m,n.timeout,n.experimental),y={_:t};for(const[e,t]of Object.entries(h))i.has(e)||a.has(e)||(y[e]=t);const g=S(y,n.salt),w={_:t};for(const[e,t]of Object.entries(h))o.has(e)||a.has(e)||(w[e]=t);const v=S(w,n.salt),b={hash:g,stableHash:v,components:{...h,_:t},timestamp:(new Date).toISOString(),version:t,isIncognito:d,errors:p};return n.debug&&(console.log("[fingerprint] components:",h),console.log("[fingerprint] hash:",g,"stableHash:",v),p.length>0&&console.warn("[fingerprint] errors:",p)),b}const Ne=new RegExp(["googlebot","bingbot","slurp","baiduspider","duckduckbot","yandex","sogou","exabot","ia_archiver","curl","wget","python-requests","python-urllib","axios","node-fetch","go-http-client","java/","libwww-perl","okhttp","apache-httpclient","http_request","httpie","headlesschrome","phantomjs","puppeteer","playwright","cypress","selenium","webdriver","electron","jsdom","vercel-screenshot","screenshot","prerender","lighthouse","chrome-lighthouse","pagespeed","gtmetrix","pingdom","nessus","nikto","sqlmap","burp","zap","qualys","openvas","nmap","masscan","facebookexternalhit","twitterbot","linkedinbot","whatsapp","telegrambot","slackbot","discordbot","bot","crawl","spider","scrape","fetch","scan"].join("|"),"i");function Ge(e){return!!e&&Ne.test(e)}var qe={};!function(e){function t(e,t){return e&&(/^#[0-9a-fA-F]{3,8}$/.test(e)||/^rgba?\(\s*[\d.,\s]+\)$/.test(e))?e:t}function n(e,t){let n=e;for(const e of t.split(".")){if(null==n||"object"!=typeof n)return"";n=n[e]}return null==n?"":String(n)}function r(e){if(!e)return"";const t=e.indexOf("@");if(t>0){const n=e.slice(0,t),r=e.slice(t);return`${n.slice(0,1)}${"*".repeat(Math.max(n.length-1,1))}${r}`}return e.length<=4?"*".repeat(e.length):`${"*".repeat(e.length-4)}${e.slice(-4)}`}function o(e,t,r,o){return"runtime"===t.source?t.path?n({user:r.user??{},device:r.device??{}},t.path):"":o.get(e)??""}const i={email_verification:{"verify-email":{op:"triggerEmailVerification",inputs:["email","deviceId"]},"verify-otp":{op:"verify",inputs:["email","deviceId","otp"]},"resend-verification":{op:"triggerEmailVerification",inputs:["email","deviceId"]}}};function a(e){return{left:`${e.x}px`,top:`${e.y}px`,width:`${e.width}px`,height:`${e.height}px`}}function s(e,t){const n=t.props.fontSize;"number"==typeof n&&(e.style.fontSize=`${n}px`);const r=t.props.align;"string"==typeof r&&(e.style.textAlign=r)}function c(e,t){const n="string"==typeof e.props.binding?e.props.binding:"";return n&&t.flow.bindings[n]?function(e,t,n,i){if("never"===t.display)return"";const a=o(e,t,n,i);return"masked"===t.display?r(a):a}(n,t.flow.bindings[n],t.ctx,t.formState):String(e.props.text??"")}function u(e,t){const n=document.createElement("div");return n.className="el el-heading",Object.assign(n.style,a(e)),s(n,e),n.textContent=c(e,t),n}function l(e,t){const n=document.createElement("div");return n.className="el el-text",Object.assign(n.style,a(e)),s(n,e),n.textContent=c(e,t),n}function d(e){const t=document.createElement("img");return t.className="el el-image",Object.assign(t.style,a(e)),t.src=String(e.props.src??""),t.alt=String(e.props.alt??""),t}function f(e,t){const n=document.createElement("input");n.className="el el-input",Object.assign(n.style,a(e)),s(n,e),"string"==typeof e.props.placeholder&&(n.placeholder=e.props.placeholder),"number"==typeof e.props.maxLength&&(n.maxLength=e.props.maxLength),"string"==typeof e.props.pattern&&(n.pattern=e.props.pattern),"otp"===e.props.fieldType&&(n.inputMode="numeric"),!0===e.props.autoFocus&&(n.autofocus=!0);const r=t.elementToBinding.get(e.id)??String(e.props.name??e.id);return n.value=t.formState.get(r)??"",n.addEventListener("input",()=>t.formState.set(r,n.value)),n}function m(e,t,n){const r=document.createElement("button"),c="secondary"===e.props.variant?"secondary":"primary";return r.className=`el el-button el-button-${c}`,Object.assign(r.style,a(e)),s(r,e),r.textContent=String(e.props.text??"Continue"),r.addEventListener("click",()=>{!async function(e,t,n,r){const a=String(e.props.action??"");if(!a)return;const s=t.flow.actions[a],c=function(e,t,n,r){const a=i[e.flowType]?.[t];if(!a)return null;const s={};for(const t of a.inputs){const i=e.bindings[t];i&&(s[t]=o(t,i,n,r))}return{op:a.op,values:s}}(t.flow,a,t.ctx,t.formState);if(c){r.classList.remove("visible"),n.disabled=!0;try{await t.ctx.actions(c.op,c.values);const e=s?.onSuccess,n=e?.goTo??e?.advanceTo;e?.dismiss?t.close():"string"==typeof n&&(t.screenState.goTo(n),t.screenState.isLast&&t.complete())}catch(e){s?.onError?.showError&&(u=e instanceof Error&&e.message?e.message:"Something went wrong. Please try again.",r.textContent=u,r.classList.add("visible"))}finally{n.disabled=!1}var u}else"undefined"!=typeof console&&console.warn(`[interstitial] unknown action: ${a}`)}(e,t,r,n)}),r}function h(e,t,n){Array.from(t.children).forEach(e=>e.remove());const r=document.createElement("div");r.className="el-error",r.style.left="0",r.style.right="0",r.style.bottom="12px";for(const o of e.elements){let e=null;switch(o.type){case"heading":e=u(o,n);break;case"text":e=l(o,n);break;case"image":e=d(o);break;case"input":e=f(o,n);break;case"button":e=m(o,n,r);break;default:e=null}e&&t.appendChild(e)}t.appendChild(r)}e.maskValue=r,e.renderFlow=function(e,n){const r=n.container??document.body,o=new Map,i=function(e){const t=new Map;for(const[n,r]of Object.entries(e.bindings))"form"===r.source&&r.elementId&&t.set(r.elementId,n);return t}(e);let a=!1;const s=()=>{a||(a=!0,c.destroy())},c=function(e,n,r){const o=t(e.primaryColor,"#4f46e5"),i=t(e.backgroundColor,"#ffffff"),a=t(e.textColor,"#111827"),s=(u=e.fontFamily)&&/^[a-zA-Z0-9\s,\-'"]+$/.test(u)?u:"sans-serif",c=function(e){return e&&/^\d+(\.\d+)?(px|rem|em|%)?$/.test(e)?e:"8px"}(e.borderRadius);var u;const l=document.createElement("div");l.id="__unshared-interstitial-host",Object.assign(l.style,{position:"fixed",inset:"0",zIndex:"2147483647"}),r.appendChild(l);const d=l.attachShadow({mode:"open"}),f=document.createElement("style");f.textContent=`\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n :host { all: initial; }\n .backdrop {\n position: fixed; inset: 0;\n background: rgba(0,0,0,0.5);\n display: flex; align-items: center; justify-content: center;\n }\n .frame {\n position: relative;\n background: ${i};\n color: ${a};\n font-family: ${s};\n border-radius: ${c};\n width: ${n.width}px;\n height: ${n.height}px;\n max-width: 95vw; max-height: 95vh;\n overflow: hidden;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n }\n .frame:focus { outline: none; }\n .el { position: absolute; }\n .el-heading { font-weight: 700; line-height: 1.2; color: ${a}; }\n .el-text { color: ${a}; opacity: 0.75; line-height: 1.5; }\n .el-image { object-fit: contain; }\n .el-input {\n width: 100%; height: 100%;\n border: 1.5px solid #D1D5DB; border-radius: ${c};\n padding: 0 12px; font-family: ${s}; outline: none;\n transition: border-color 0.15s;\n }\n .el-input:focus { border-color: ${o}; }\n .el-button {\n width: 100%; height: 100%;\n border-radius: ${c}; font-weight: 600;\n font-family: ${s}; cursor: pointer; transition: opacity 0.15s;\n }\n .el-button:hover { opacity: 0.9; }\n .el-button:disabled { opacity: 0.5; cursor: not-allowed; }\n .el-button-primary { background: ${o}; color: #fff; border: none; }\n .el-button-secondary { background: transparent; color: ${o}; border: 1.5px solid ${o}; }\n .el-error {\n position: absolute; color: #DC2626; font-size: 13px;\n display: none; text-align: center;\n }\n .el-error.visible { display: block; }\n `,d.appendChild(f);const m=document.createElement("div");m.className="backdrop";const h=document.createElement("div");h.className="frame",h.setAttribute("role","dialog"),h.setAttribute("aria-modal","true"),h.tabIndex=-1,m.appendChild(h),d.appendChild(m);const p=document.body.style.overflow;document.body.style.overflow="hidden";const y=e=>{"Escape"===e.key&&(e.preventDefault(),e.stopPropagation())};document.addEventListener("keydown",y,!0);const g=e=>{const t=e.target;t&&!l.contains(t)&&h.focus()};return document.addEventListener("focusin",g,!0),h.focus(),{shadowRoot:d,frame:h,destroy:()=>{document.removeEventListener("keydown",y,!0),document.removeEventListener("focusin",g,!0),document.body.style.overflow=p,l.remove()}}}(e.theme,e.frame,r),u={flow:e,ctx:n,formState:o,elementToBinding:i,screenState:void 0,close:()=>{s(),n.onDismiss?.()},complete:()=>n.onComplete?.()},l=function(e,t,n){let r=Math.max(e.findIndex(e=>e.id===t),0);return{get current(){return e[r]},get isLast(){return r===e.length-1},next(){r<e.length-1&&(r++,n(e[r]))},goTo(t){const o=e.findIndex(e=>e.id===t);-1!==o&&o!==r&&(r=o,n(e[r]))}}}(e.screens,e.initialScreenId,e=>{h(e,c.frame,u)});return u.screenState=l,h(l.current,c.frame,u),{destroy:s}},e.resolvePath=n}(qe);var He=qe;const Ke=new Set(["__pre_auth__","anonymous","guest","undefined","null"]),Je=["http","s://","api.","unsh","ared",".ai"].join(""),Ye="__unshared_email",Xe="__unshared_fp",Ze="__unshared_last_submit",Qe="__unshared_device_id",et="__unshared_event_queue",tt="__unshared_uid",nt="__unshared_sid",rt="__UNSHARED_PUBLISHABLE_API_KEY__";function ot(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function it(e){return new Promise(t=>setTimeout(t,e))}function at(e){const t=Math.min(1e3*Math.pow(2,e-1),3e4),n=500*Math.random()-250;return Math.max(0,t+n)}function st(e){if("undefined"==typeof document)return;const t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):void 0}function ct(){return"undefined"!=typeof location&&"https:"===location.protocol?"; Secure":""}function ut(e,t){"undefined"!=typeof document&&(document.cookie=`${e}=${encodeURIComponent(t)}; Path=/; SameSite=Lax${ct()}`)}function lt(e){if("undefined"!=typeof localStorage)try{return localStorage.getItem(e)??void 0}catch{return}}function dt(e,t){if("undefined"!=typeof localStorage)try{localStorage.setItem(e,t)}catch{}}function ft(e){try{return new URL(e),!0}catch{return!1}}function mt(e){let t="";for(const n of e)t+=String.fromCharCode(n);return btoa(t)}function ht(e){const t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}function pt(e){return new Uint8Array(Array.from(e))}function yt(){return"undefined"!=typeof crypto&&!!crypto.subtle&&!!crypto.getRandomValues}e.UnsharedBrowser=class{constructor(e={}){if(this.S=!1,this.C=!1,this.k=!1,this.A="",e.baseUrl&&!ft(e.baseUrl))throw new Error('baseUrl must be a valid URL (e.g. "https://app.example.com")');if(e.apiUrl&&!ft(e.apiUrl))throw new Error('apiUrl must be a valid URL (e.g. ["http","s://","api.","unsh","ared",".ai"].join(""))');let t,n;this.I=e.baseUrl?e.baseUrl.replace(/\/$/,""):"",this.D=e.publishableKey??function(e){if(void 0===e)return rt.startsWith("__UNSHARED_")?void 0:rt}(e.baseUrl),this.M=(e.apiUrl??Je).replace(/\/$/,""),this.T=e.maxRetries??3,this.P=e.timeout??3e4,this.$=e.includePathPrefix,this.L=e.skipPaths,this.O=e.sessionId,this.R=e.deviceId,this.B=e.enableInterstitial??!1,this.F=e.interstitialFlowType??"email_verification",this.A=function(e){if("undefined"!=typeof sessionStorage)try{return sessionStorage.getItem(e)??void 0}catch{return}}(Ze)??"";try{t=this.O?.()}catch{}this.U=t??st(nt)??ot(),ut(nt,this.U);try{n=this.R?.()}catch{}n?(this.W=n,dt(Qe,n)):this.W=lt(Qe)??"",this.j(),this.B&&this.V()}async init(e){try{if("undefined"!=typeof navigator&&Ge(navigator.userAgent))return;if("string"==typeof(t=e.userId)&&Ke.has(t))return void this.N;if(!1===e.isPaidSubscriber)return void(this.S=!0);this.S=!1,this.N=e.userId,this.G=e.emailAddress,"undefined"!=typeof sessionStorage&&sessionStorage.setItem(Ye,e.emailAddress),ut(tt,e.userId);let n,r=this.q();r||(r=await this.collect(),this.H(r));try{n=this.R?.()}catch{}n?(this.W=n,dt(Qe,n)):r.fingerprint_id&&(this.W=r.fingerprint_id,dt(Qe,r.fingerprint_id)),this.K(r).catch(()=>{})}catch{}var t}onRouteChange(){try{if(!this.J())return;const e=this.q();if(!e)return;this.K(e).catch(()=>{})}catch{}}destroy(){try{"undefined"!=typeof sessionStorage&&(sessionStorage.removeItem(Ye),sessionStorage.removeItem(Xe),sessionStorage.removeItem(Ze)),this.A="",e=tt,"undefined"!=typeof document&&(document.cookie=`${e}=; Path=/; SameSite=Lax; Expires=Thu, 01 Jan 1970 00:00:00 GMT${ct()}`),this.Y&&"undefined"!=typeof document&&(document.removeEventListener("DOMContentLoaded",this.Y),this.Y=void 0),this.X&&"undefined"!=typeof window&&(window.removeEventListener("unshared:flagged",this.X),this.X=void 0),this.Z?.destroy(),this.Z=void 0,this.k=!1,this.N=void 0,this.G=void 0,this.S=!1}catch{}var e}async collect(e){const t=[...new Set(["timing","speech",...e?.exclude??[]])],n=await We({...e,exclude:t});return{fingerprint_id:n.stableHash,full_hash:n.hash,components:n.components,timestamp:n.timestamp,isIncognito:n.isIncognito,version:n.version}}async submitFingerprintEvent(e,t){try{const n=this.ee(e,t),r=ot();return await this.te(this.ne(),JSON.stringify(n),r)}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}async checkUser(e){const t=this.re(e);return"success"in t?t:this.oe("GET","/v2/browser/check-user",{query:{email_address:await this.ie(t.email),device_id:t.deviceId},retry:!0})}async triggerEmailVerification(e){const t=this.re(e);return"success"in t?t:this.oe("POST","/v2/browser/trigger-email-verification",{body:{email_address:await this.ie(t.email),device_id:t.deviceId},retry:!1})}async verify(e,t){const n=this.re(t);return"success"in n?n:this.oe("POST","/v2/browser/verify",{body:{email_address:await this.ie(n.email),device_id:n.deviceId,code:e},retry:!1})}async emailVerificationStatus(e){const t=this.re(e);return"success"in t?t:this.oe("GET","/v2/browser/email-verification-status",{query:{email_address:await this.ie(t.email),device_id:t.deviceId},retry:!0})}async showInterstitial(e){const t=!this.D&&!!this.I;if(!this.D&&!this.I)return{success:!1,error:{code:"INTERSTITIAL_UNAVAILABLE",message:"showInterstitial requires a publishableKey (direct mode) or baseUrl (proxy mode)."}};if("undefined"==typeof document)return{success:!1,error:{code:"NO_DOM",message:"showInterstitial requires a browser DOM."}};if(this.k)return{success:!0,data:{shown:!1}};const n=e?.flowType??this.F,r=t?await this.ae(n):await this.se(n);if(!r.success||!r.data)return{success:!1,error:r.error};try{return this.k=!0,this.Z=He.renderFlow(r.data,{user:t?{}:{email:this.G??this.J()??""},device:t?{}:{id:this.W},actions:t?this.ce():this.ue(),container:e?.container,onComplete:()=>{e?.onComplete?.()},onDismiss:()=>{this.k=!1,this.Z=void 0,e?.onDismiss?.()}}),{success:!0,data:{shown:!0}}}catch(e){return this.k=!1,{success:!1,error:{code:"RENDER_FAILED",message:e instanceof Error?e.message:String(e)}}}}async se(e){return this.oe("GET","/v2/browser/interstitial-flow",{query:{flow_type:e,platform:"web"},retry:!0})}async ae(e){try{const t=`${this.I}/__unshared/interstitial-flow?flow_type=${encodeURIComponent(e)}&platform=web`,n=await fetch(t,{method:"GET",credentials:"include"}),r=await n.json().catch(()=>({}));return n.ok&&!1!==r?.success&&r?.data?{success:!0,data:r.data}:{success:!1,error:r?.error??{code:"FLOW_FETCH_FAILED",message:`Flow fetch failed (${n.status})`}}}catch(e){return{success:!1,error:{code:"FLOW_FETCH_FAILED",message:e instanceof Error?e.message:String(e)}}}}ce(){const e=async(e,t)=>{const n=await fetch(`${this.I}${e}`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(t)}),r=await n.json().catch(()=>({}));if(!n.ok||!1===r?.success)throw new Error(r?.error?.message??"Request failed. Please try again.");return r};return async(t,n)=>{if("triggerEmailVerification"!==t){if("verify"===t){const t=await e("/__unshared/verify",{code:n.otp});if(!1===t?.data?.verified)throw new Error("Incorrect or expired code. Please try again.");return}throw new Error(`Unsupported interstitial action: ${t}`)}await e("/__unshared/verify-trigger",{})}}ue(){return async(e,t)=>{const n={email:t.email,deviceId:t.deviceId};if("triggerEmailVerification"===e){const e=await this.triggerEmailVerification(n);if(!e.success)throw new Error(e.error?.message??"Could not send the verification code.");return}if("verify"===e){const e=await this.verify(t.otp,n);if(!e.success)throw new Error(e.error?.message??"Verification failed.");if(e.data&&!1===e.data.verified)throw new Error("Incorrect or expired code. Please try again.");return}throw new Error(`Unsupported interstitial action: ${e}`)}}V(){"undefined"!=typeof window&&(this.X=()=>{this.showInterstitial()},window.addEventListener("unshared:flagged",this.X))}re(e){if(!this.D)return{success:!1,error:{code:"DIRECT_MODE_REQUIRED",message:"This method requires direct mode — construct the SDK with a publishableKey."}};const t=e?.email??this.G??this.J(),n=e?.deviceId??this.W;return t&&n?{email:t,deviceId:n}:{success:!1,error:{code:"MISSING_IDENTITY",message:"No email/deviceId available — call init() first or pass them explicitly."}}}async oe(e,t,n){try{let r=`${this.M}${t}`;n.query&&(r+=`?${new URLSearchParams(n.query).toString()}`);const o={"X-Publishable-Key":this.D,"X-Session-Id":this.U,"X-Device-Id":this.W},i={method:e,headers:o};void 0!==n.body&&(o["Content-Type"]="application/json",i.body=JSON.stringify(n.body));const a=n.retry?this.T+1:1;let s={code:"DELIVERY_FAILED",message:"Request failed"};for(let t=1;t<=a;t++){t>1&&await it(at(t-1));const n=new AbortController,o=setTimeout(()=>n.abort(),this.P);try{const e=await fetch(r,{...i,signal:n.signal});clearTimeout(o);const t=await e.text().catch(()=>"{}");let a;try{a=JSON.parse(t)}catch{a={}}if(e.status>=500){s={code:"DELIVERY_FAILED",message:`Backend returned ${e.status}`};continue}if(e.status>=400||!1===a?.success){const t=a?.error??{};return{success:!1,error:{code:"string"==typeof t.code?t.code:"UPSTREAM_ERROR",message:"string"==typeof t.message?t.message:`Backend returned ${e.status}`,retryAfter:t.details?.retry_after_seconds,nextAllowedAt:t.details?.next_allowed_at}}}return{success:!0,data:a?.data}}catch(e){clearTimeout(o),s={code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}return{success:!1,error:s}}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}J(){if("undefined"!=typeof sessionStorage)return sessionStorage.getItem(Ye)??void 0}q(){if("undefined"==typeof sessionStorage)return;const e=sessionStorage.getItem(Xe);if(e)try{return JSON.parse(e)}catch{return}}H(e){"undefined"!=typeof sessionStorage&&sessionStorage.setItem(Xe,JSON.stringify(e))}le(){if("undefined"==typeof location)return!0;const e=location.pathname||"/";if(this.L)for(const t of this.L)if(e.startsWith(t))return!1;return!this.$||this.$.some(t=>e.startsWith(t))}async K(e){if("undefined"!=typeof navigator&&Ge(navigator.userAgent))return{success:!0};if(this.S)return{success:!0};if(!this.le())return{success:!0};const t=this.G??this.J(),n=this.N??st(tt),r="undefined"!=typeof location?(location.pathname||"/")+(location.search||""):"/";if(n){const e=`${n}|${r}`,t=function(){if("undefined"==typeof window)return;const e=window;return e.de=e.de||{}}();if(e===this.A||t?.lastKey===e)return{success:!0};t&&(t.lastKey=e),this.A=e,function(e,t){if("undefined"!=typeof sessionStorage)try{sessionStorage.setItem(e,t)}catch{}}(Ze,e)}const o={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:(new Date).toISOString(),is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.U,event_type:r};this.D?(n&&(o.user_id=await this.ie(n)),t&&(o.email_address=await this.ie(t))):(n&&(o.user_id=n),t&&(o.email=t));const i=`${e.fingerprint_id}|${n??""}|${r}`,a=await async function(e){if(yt())try{const t=await crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e));return Array.from(new Uint8Array(t)).map(e=>e.toString(16).padStart(2,"0")).join("")}catch{return}}(i),s=a??(this.D?`${i}|${Math.floor(Date.now()/6e4)}`:i);return this.te(this.ne(),JSON.stringify(o),s)}ne(){return this.D?`${this.M}/v2/browser/submit-fingerprint-event`:`${this.I}/__unshared/submit-fp`}j(){"undefined"!=typeof document&&(this.Y&&document.removeEventListener("DOMContentLoaded",this.Y),this.Y=()=>{if(!this.J())return;const e=this.q();e&&this.K(e).catch(()=>{})},document.addEventListener("DOMContentLoaded",this.Y))}async te(e,t,n,r={}){r.skipFlush||await this.fe();const o=this.T+1;let i={success:!1,error:{code:"DELIVERY_FAILED",message:"Request failed"}};for(let r=1;r<=o;r++){r>1&&await it(at(r-1));const o=new AbortController,a=setTimeout(()=>o.abort(),this.P),s={"Content-Type":"application/json","X-Idempotency-Key":n,"X-Session-Id":this.U,"X-Device-Id":this.W};this.D&&(s["X-Publishable-Key"]=this.D);try{const n=await fetch(e,{method:"POST",headers:s,body:t,signal:o.signal});if(clearTimeout(a),n.status>=500){i={success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${n.status}`}};continue}if(n.status>=400)return{success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${n.status}`}};const r=await n.text().catch(()=>"{}");let c;try{c=JSON.parse(r)}catch{c={}}return!1===c?.success?{success:!1,error:c.error??{code:"UPSTREAM_ERROR",message:"Upstream failed"}}:{success:!0,data:c?.data}}catch(e){clearTimeout(a),i={success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}return r.skipQueue||await this.me({url:e,payload:t,idempotencyKey:n,queuedAt:(new Date).toISOString()}),i}he(){if(!this.D||!yt())return Promise.resolve(void 0);if(!this.pe){const e=this.D;this.pe=(async()=>{const t=await crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e));return crypto.subtle.importKey("raw",t,"AES-GCM",!1,["encrypt"])})().catch(()=>{})}return this.pe}async ie(e){try{const t=await this.he();if(!t)return e;const n=crypto.getRandomValues(new Uint8Array(12)),r=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:n},t,(new TextEncoder).encode(e))),o=r.slice(r.length-16),i=r.slice(0,r.length-16);return`${mt(n)}:${mt(o)}:${mt(i)}`}catch{return e}}async ye(){if(!yt())return;const e=`unshared-browser-queue:${this.D??this.I}:${this.U}`,t=await crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e));return crypto.subtle.importKey("raw",t,"AES-GCM",!1,["encrypt","decrypt"])}async ge(e){const t=await this.ye();if(!t)return;const n=crypto.getRandomValues(new Uint8Array(12)),r=(new TextEncoder).encode(JSON.stringify(e)),o=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:n},t,r));return`v1:${mt(n)}:${mt(o)}`}async we(e){const[t,n,r]=e.split(":");if("v1"!==t||!n||!r)return;const o=await this.ye();if(!o)return;const i=pt(ht(n)),a=pt(ht(r)),s=await crypto.subtle.decrypt({name:"AES-GCM",iv:i},o,a);return JSON.parse((new TextDecoder).decode(s))}ve(){const e=lt(et);if(!e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>"string"==typeof e):[]}catch{return[]}}be(e){0!==e.length?dt(et,JSON.stringify(e.slice(-20))):function(e){if("undefined"!=typeof localStorage)try{localStorage.removeItem(e)}catch{}}(et)}async me(e){try{const t=await this.ge(e);if(!t)return;this.be([...this.ve(),t])}catch{}}async fe(){if(this.C)return;const e=this.ve();if(0===e.length)return;this.C=!0;const t=[];try{for(let n=0;n<e.length;n++){const r=e[n];let o;try{o=await this.we(r)}catch{continue}if(o&&!(await this.te(o.url,o.payload,o.idempotencyKey,{skipFlush:!0,skipQueue:!0})).success){t.push(r,...e.slice(n+1));break}}this.be(t)}catch{}finally{this.C=!1}}ee(e,t){const n={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:e.timestamp,is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.U};n.user_id=t.userId,null!=t?.eventType&&(n.event_type=t.eventType);const r=this.G??this.J();return r&&(n.email=r),n}},e.createAxiosInterceptor=function(e){return t=>{if(403===t?.response?.status&&"account_flagged"===t?.response?.data?.error)try{e.onFlagged()}catch{}return Promise.reject(t)}},e.createFetchInterceptor=function(e,t){return async(...n)=>{const r=await e(...n);if(403===r.status){const e=r.clone();try{const n=await e.json();if("account_flagged"===n?.error)try{t.onFlagged()}catch{}}catch{}}return r}}}(index_umd.exports);var index_umdExports=index_umd.exports;function installRouteTracking(e){if("undefined"==typeof window||"undefined"==typeof history)return()=>{};let t=!0;const n=()=>{if(t)try{e()}catch{}},r=history.pushState,o=history.replaceState,i=function(...e){const t=r.apply(this,e);return n(),t},a=function(...e){const t=o.apply(this,e);return n(),t};return history.pushState=i,history.replaceState=a,window.addEventListener("popstate",n),()=>{t=!1,window.removeEventListener("popstate",n),history.pushState===i&&(history.pushState=r),history.replaceState===a&&(history.replaceState=o)}}const UnsharedContext=React.createContext(void 0);function UnsharedProvider(e){const{publishableKey:t,apiUrl:n,baseUrl:r,maxRetries:o,timeout:i,includePathPrefix:a,skipPaths:s,sessionId:c,deviceId:u,user:l,onFlagged:d,enableInterstitial:f,interstitialFlowType:m,children:h}=e,[p,y]=React.useState(null),g=React.useRef(d);React.useEffect(()=>{g.current=d});const w=React.useRef(null);React.useEffect(()=>{w.current=p},[p]);const v=React.useRef({enabled:f,flowType:m});React.useEffect(()=>{v.current={enabled:f,flowType:m}}),React.useEffect(()=>{let e=null;try{e=new index_umdExports.UnsharedBrowser({publishableKey:t,apiUrl:n,baseUrl:r,maxRetries:o,timeout:i,includePathPrefix:a,skipPaths:s,sessionId:c,deviceId:u})}catch(e){console.error("[unshared-react-sdk] failed to initialize:",e)}y(e)},[]),React.useEffect(()=>{if(p)return installRouteTracking(()=>p.onRouteChange())},[p]);const b=React.useRef(null);React.useEffect(()=>{if(!p)return;const e=b.current;l&&l.userId&&l.email?e&&e.userId===l.userId&&e.email===l.email&&e.isPaidSubscriber===l.isPaidSubscriber||(b.current={userId:l.userId,email:l.email,isPaidSubscriber:l.isPaidSubscriber},p.init({userId:l.userId,emailAddress:l.email,isPaidSubscriber:l.isPaidSubscriber})):e&&(b.current=null,p.destroy())},[p,l,l?.userId,l?.email,l?.isPaidSubscriber]),React.useEffect(()=>{if("undefined"==typeof window)return;const e=()=>{const e=g.current;if(e)try{e()}catch{}const{enabled:t,flowType:n}=v.current;if(t)try{w.current?.showInterstitial({flowType:n})}catch{}};window.addEventListener("unshared:flagged",e);const t=window.fetch;let n;return t&&(n=index_umdExports.createFetchInterceptor(t.bind(window),{onFlagged:e}),window.fetch=n),()=>{window.removeEventListener("unshared:flagged",e),n&&window.fetch===n&&t&&(window.fetch=t)}},[]);const x=React.useCallback(e=>{p&&e?.userId&&e?.email&&(b.current={userId:e.userId,email:e.email,isPaidSubscriber:e.isPaidSubscriber},p.init({userId:e.userId,emailAddress:e.email,isPaidSubscriber:e.isPaidSubscriber}))},[p]),S=React.useCallback(()=>{b.current=null,p?.destroy()},[p]),_=React.useCallback(e=>{p?.showInterstitial({flowType:e??m})},[p,m]);return React__namespace.createElement(UnsharedContext.Provider,{value:{client:p,identify:x,logout:S,showInterstitial:_}},h)}function useUnshared(){const e=React.useContext(UnsharedContext);if(!e)throw new Error("useUnshared must be used within an <UnsharedProvider>");return e}exports.UnsharedContext=UnsharedContext,exports.UnsharedProvider=UnsharedProvider,exports.createAxiosInterceptor=index_umdExports.createAxiosInterceptor,exports.createFetchInterceptor=index_umdExports.createFetchInterceptor,exports.installRouteTracking=installRouteTracking,exports.useUnshared=useUnshared;
@@ -0,0 +1,6 @@
1
+ export { UnsharedProvider, UnsharedContext } from './provider';
2
+ export type { UnsharedProviderProps, UnsharedContextValue, UnsharedUser, } from './provider';
3
+ export { useUnshared } from './use-unshared';
4
+ export { installRouteTracking } from './route-tracking';
5
+ export { createAxiosInterceptor, createFetchInterceptor } from 'unshared-frontend-sdk';
6
+ export type { UnsharedBrowser, BrowserApiResult } from 'unshared-frontend-sdk';