@sentientui/core 0.21.2 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engagement/capture.ts"],"sourcesContent":["import { classifySection, SEMANTIC_TYPES, type SemanticType } from './classify';\nimport { isDoNotTrackEnabled } from '../index.js';\nimport { attachMicroSignalDetectors } from '../micro-signals.js';\n\n// Shared engagement capture (spec 2026-07-22-persona-signal-capture). Detects\n// semantic sections, registers them via /v1/section-map, and records per-section\n// dwell/scroll via IntersectionObserver — emitting the same 'dwell' events the\n// persona pipeline consumes. Used by the React provider (default on) and the\n// no-code snippet. Defense-in-depth: checks DNT internally even though callers\n// gate on consent/DNT too; a missing IntersectionObserver → no-op.\n\ntype CaptureClient = {\n track(event: { projectId: string; componentId: string; eventType: string; payload: Record<string, unknown> }): void;\n};\n\nexport type EngagementCaptureOptions = {\n apiKey: string;\n /** API base, no trailing slash. Defaults to the hosted API. */\n apiBase?: string;\n doc?: Document;\n /**\n * Also attach per-section micro-signal detectors (rage click, text copy,\n * scroll hesitation, tab loss), attributed to the section's `nc-<type>`\n * component. For the no-code snippet, whose pages have no `<Adaptive>`\n * components carrying their own detectors. Default false — the React SDK\n * keeps its per-component detectors and must not double-attach.\n */\n microSignals?: boolean;\n /**\n * Server-served section-map lookup (persona-coverage auto-classification):\n * consulted after explicit `data-sentient-type` markup, before the local\n * heuristic. Return null when the element has no served label.\n */\n typeOf?: (el: Element) => SemanticType | null;\n};\n\nconst SECTION_SELECTOR = 'section, header, footer, nav, main > div, [data-sentient-section]';\n\n/** Bank cadence for visible dwell. Dwell used to leave the page only on\n * visibilitychange/pagehide, and in production that path delivered for ~5-8%\n * of sessions (Bodyshop audit 2026-08-30): a visitor who reads and closes the\n * tab races the unload pipeline, and mobile browsers can kill a page with no\n * lifecycle event at all. The heartbeat caps the loss at one interval. */\nconst HEARTBEAT_MS = 20_000;\n\n/**\n * Pick the elements to observe. Two rules, in order:\n * 1. A candidate that CONTAINS two or more other candidates is a layout\n * wrapper, not a section — drop it. Pages built from bare divs match\n * `main > div` with their page-wide content wrapper; keeping that outer\n * match swallowed every real <section> inside it, collapsing the whole page\n * into one nc-generic component whose intersectionRatio could never exceed\n * viewport-height / page-height (a constant ~0.05 scroll_depth on the\n * audited site). A candidate with exactly one nested candidate (header >\n * nav) is NOT a wrapper — rule 2 keeps the outer one, as before.\n * 2. Of what remains, skip a section nested inside another kept section\n * (avoid double count).\n */\nfunction selectSections(doc: Document): Element[] {\n const candidates = Array.from(doc.querySelectorAll(SECTION_SELECTOR));\n const kept = candidates.filter(\n (el) => candidates.filter((c) => c !== el && el.contains(c)).length < 2,\n );\n return kept.filter((el) => !kept.some((k) => k !== el && k.contains(el)));\n}\n\nfunction registerSections(\n apiKey: string,\n apiBase: string,\n pageUrl: string,\n sections: Array<{ componentId: string; semanticType: SemanticType; source: 'markup' | 'auto' }>,\n): void {\n try {\n void fetch(`${apiBase}/v1/section-map`, {\n method: 'POST',\n keepalive: true,\n headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({ pageUrl, sections }),\n }).catch(() => undefined);\n } catch {\n /* fail-safe */\n }\n}\n\nconst NOOP = (): void => undefined;\n\nexport function startEngagementCapture(\n client: CaptureClient,\n opts: EngagementCaptureOptions,\n): () => void {\n const doc = opts.doc ?? (typeof document !== 'undefined' ? document : undefined);\n if (!doc || typeof IntersectionObserver === 'undefined') return NOOP;\n if (isDoNotTrackEnabled()) return NOOP;\n // Keyless zero-network contract: capture exists to feed the hosted persona\n // pipeline — with no api key there is nothing to feed, and the section-map\n // registration fetch must never fire.\n if (!opts.apiKey) return NOOP;\n // Normalize so both a ROOT base (`https://api.sentient-ui.com`) and a\n // `/v1`-suffixed base resolve to exactly one `/v1/section-map` — some callers\n // pass the versioned base, which would otherwise produce `/v1/v1/section-map`\n // (a silent 404). Strip trailing slashes, then a single trailing `/v1`.\n const apiBase = (opts.apiBase ?? 'https://api.sentient-ui.com')\n .replace(/\\/+$/, '')\n .replace(/\\/v1$/, '');\n\n const els = selectSections(doc);\n if (els.length === 0) return NOOP;\n\n // Collapse to one component per semantic type per page (the matrix aggregates\n // by semantic type anyway). Per-element precedence: explicit data-sentient-type\n // markup → served section map (opts.typeOf) → local heuristic.\n const componentOf = new Map<Element, string>();\n const types = new Map<string, SemanticType>();\n const sources = new Map<string, 'markup' | 'auto'>();\n for (const el of els) {\n const explicit = el.getAttribute('data-sentient-type');\n const markup = explicit && (SEMANTIC_TYPES as readonly string[]).includes(explicit)\n ? (explicit as SemanticType)\n : null;\n const type = markup ?? opts.typeOf?.(el) ?? classifySection(el);\n const componentId = `nc-${type}`;\n componentOf.set(el, componentId);\n types.set(componentId, type);\n // Markup wins if the same collapsed component gets both provenances.\n if (markup) sources.set(componentId, 'markup');\n else if (!sources.has(componentId)) sources.set(componentId, 'auto');\n }\n\n const pageUrl = (doc.defaultView ?? (typeof window !== 'undefined' ? window : undefined))?.location?.pathname ?? '/';\n registerSections(opts.apiKey, apiBase, pageUrl, [...types.entries()].map(([componentId, semanticType]) => ({\n componentId, semanticType, source: sources.get(componentId) ?? 'auto',\n })));\n\n // Accumulate visible dwell (ms) + max scroll ratio per component. `intersecting`\n // tracks in-viewport state independently of `enterAt` (the running clock) so a\n // tab-hide can pause the clock and a tab-show can resume it for still-visible\n // sections — IntersectionObserver does not re-fire on visibilitychange.\n const state = new Map<string, { ms: number; scroll: number; enterAt: number | null; intersecting: boolean }>();\n const get = (id: string) => {\n let s = state.get(id);\n if (!s) { s = { ms: 0, scroll: 0, enterAt: null, intersecting: false }; state.set(id, s); }\n return s;\n };\n\n const observer = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n const id = componentOf.get(entry.target);\n if (!id) continue;\n const s = get(id);\n if (entry.isIntersecting) {\n s.intersecting = true;\n s.enterAt = Date.now();\n if (entry.intersectionRatio > s.scroll) s.scroll = entry.intersectionRatio;\n } else {\n s.intersecting = false;\n if (s.enterAt != null) { s.ms += Date.now() - s.enterAt; s.enterAt = null; }\n }\n }\n }, { threshold: [0, 0.25, 0.5, 0.75, 1] });\n for (const el of componentOf.keys()) observer.observe(el);\n\n // Bank accumulated dwell and RESET the accumulators (so a later emit can't\n // double-count) WITHOUT disconnecting — a visitor who hides/re-shows the tab\n // or tab-switches keeps being measured. Pauses the running clock; the tab-show\n // handler restarts it for still-visible sections so hidden time isn't counted.\n const emit = (): void => {\n const now = Date.now();\n for (const [id, s] of state) {\n if (s.enterAt != null) { s.ms += now - s.enterAt; s.enterAt = null; }\n if (s.ms <= 0) continue;\n try {\n client.track({\n projectId: opts.apiKey, // SDK convention: server derives the real project from the key\n componentId: id,\n eventType: 'dwell',\n payload: { dwell_time: Math.round(s.ms), scroll_depth: Number(s.scroll.toFixed(2)) },\n });\n } catch {\n /* fail-safe */\n }\n s.ms = 0;\n }\n };\n\n const onVisibility = (): void => {\n if (doc.hidden) {\n emit(); // bank + pause\n } else {\n const now = Date.now(); // resume the clock for sections still on screen\n for (const s of state.values()) if (s.intersecting) s.enterAt = now;\n }\n };\n // A page can be FROZEN into the bfcache rather than torn down. Timers keep\n // firing on restore, and `intersecting` still holds whatever it held at\n // pagehide — so without this the heartbeat kept banking dwell for sections the\n // visitor had scrolled far past, forever, while the observer that could have\n // corrected them had been disconnected. Freeze the clocks instead, and only\n // tear down for real when the page is genuinely going away.\n let frozen = false;\n const onPageHide = (event?: { persisted?: boolean }): void => {\n emit(); // bank whatever is measured either way\n if (event?.persisted) {\n frozen = true; // bfcache: keep the observer, stop counting\n return;\n }\n try { observer.disconnect(); } catch { /* ignore */ }\n };\n const onPageShow = (event?: { persisted?: boolean }): void => {\n if (!event?.persisted || !frozen) return;\n frozen = false;\n // The observer stayed connected, so it will correct `intersecting` for\n // anything that moved. Restart clocks only for what is on screen NOW.\n const now = Date.now();\n for (const s of state.values()) s.enterAt = s.intersecting && !doc.hidden ? now : null;\n };\n doc.addEventListener('visibilitychange', onVisibility);\n const win = doc.defaultView ?? (typeof window !== 'undefined' ? window : undefined);\n win?.addEventListener('pagehide', onPageHide);\n win?.addEventListener('pageshow', onPageShow);\n\n // See HEARTBEAT_MS: bank visible dwell periodically so a hard close (or a\n // mobile page kill) loses at most one interval instead of the whole visit.\n // Hidden tabs skip the emit — their clock is already paused, and an empty\n // state map makes emit a no-op anyway.\n const heartbeat = setInterval(() => {\n if (doc.hidden || frozen) return;\n emit();\n // emit() pauses every running clock and only the tab-show handler restarts\n // them — here the page never went hidden, so restart the clock ourselves\n // or accumulation silently stops after the first heartbeat.\n const now = Date.now();\n for (const s of state.values()) if (s.intersecting) s.enterAt = now;\n }, HEARTBEAT_MS);\n\n // Per-section micro-signal detectors (opt-in; see EngagementCaptureOptions).\n // Attributed to the section's nc-<type> id with no variant — they feed the\n // persona attention fallback and auto-discovery, never rewards.\n const detectorCleanups: Array<() => void> = [];\n if (opts.microSignals) {\n // tab_loss is a single document-level `visibilitychange` signal, so enabling\n // it on every section detector would emit one tab_loss per nc-<type> section\n // on a single tab-hide — attributing one page-level exit to every section\n // (audit M5). Enable it on only the first section so the exit is recorded\n // once, mirroring the per-option path in slot-signals.ts ({ tabLoss: index === 0 }).\n [...componentOf.entries()].forEach(([el, componentId], i) => {\n detectorCleanups.push(\n attachMicroSignalDetectors((signalType, extra = {}) => {\n try {\n client.track({\n projectId: opts.apiKey,\n componentId,\n eventType: 'micro_signal',\n payload: { signalType, ...extra },\n });\n } catch {\n /* fail-safe */\n }\n }, el, undefined, { tabLoss: i === 0 }),\n );\n });\n }\n\n // Cleanup: bank any remaining dwell, then detach everything (provider unmount\n // / consent re-init must not leak observers or listeners).\n return () => {\n emit();\n clearInterval(heartbeat);\n doc.removeEventListener('visibilitychange', onVisibility);\n win?.removeEventListener('pagehide', onPageHide);\n win?.removeEventListener('pageshow', onPageShow);\n for (const c of detectorCleanups) c();\n try { observer.disconnect(); } catch { /* ignore */ }\n };\n}\n"],"mappings":"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","names":["SECTION_SELECTOR","HEARTBEAT_MS","selectSections","doc","candidates","kept","el","k","registerSections","apiKey","apiBase","pageUrl","sections","e","NOOP","startEngagementCapture","client","opts","_a","_b","_c","_d","_e","_f","_g","_h","_i","isDoNotTrackEnabled","els","componentOf","types","sources","explicit","markup","SEMANTIC_TYPES","type","classifySection","componentId","semanticType","state","get","id","s","observer","entries","entry","emit","now","onVisibility","frozen","onPageHide","event","onPageShow","win","heartbeat","detectorCleanups","i","attachMicroSignalDetectors","signalType","extra","__spreadValues","c"]}
1
+ {"version":3,"sources":["../src/engagement/capture.ts"],"sourcesContent":["import { classifySection, SEMANTIC_TYPES, type SemanticType } from './classify';\nimport { isDoNotTrackEnabled } from '../index.js';\nimport { attachMicroSignalDetectors } from '../micro-signals.js';\n\n// Shared engagement capture (spec 2026-07-22-persona-signal-capture). Detects\n// semantic sections, registers them via /v1/section-map, and records per-section\n// dwell/scroll via IntersectionObserver — emitting the same 'dwell' events the\n// persona pipeline consumes. Used by the React provider (default on) and the\n// no-code snippet. Defense-in-depth: checks DNT internally even though callers\n// gate on consent/DNT too; a missing IntersectionObserver → no-op.\n\ntype CaptureClient = {\n track(event: { projectId: string; componentId: string; eventType: string; payload: Record<string, unknown> }): void;\n};\n\nexport type EngagementCaptureOptions = {\n apiKey: string;\n /** API base, no trailing slash. Defaults to the hosted API. */\n apiBase?: string;\n doc?: Document;\n /**\n * Also attach per-section micro-signal detectors (rage click, text copy,\n * scroll hesitation, tab loss), attributed to the section's `nc-<type>`\n * component. For the no-code snippet, whose pages have no `<Adaptive>`\n * components carrying their own detectors. Default false — the React SDK\n * keeps its per-component detectors and must not double-attach.\n */\n microSignals?: boolean;\n /**\n * Server-served section-map lookup (persona-coverage auto-classification):\n * consulted after explicit `data-sentient-type` markup, before the local\n * heuristic. Return null when the element has no served label.\n */\n typeOf?: (el: Element) => SemanticType | null;\n};\n\nconst SECTION_SELECTOR = 'section, header, footer, nav, main > div, [data-sentient-section]';\n\n/** Bank cadence for visible dwell. Dwell used to leave the page only on\n * visibilitychange/pagehide, and in production that path delivered for ~5-8%\n * of sessions (Bodyshop audit 2026-08-30): a visitor who reads and closes the\n * tab races the unload pipeline, and mobile browsers can kill a page with no\n * lifecycle event at all. The heartbeat caps the loss at one interval. */\nconst HEARTBEAT_MS = 20_000;\n\n/**\n * Pick the elements to observe. Two rules, in order:\n * 1. A candidate that CONTAINS two or more other candidates is a layout\n * wrapper, not a section — drop it. Pages built from bare divs match\n * `main > div` with their page-wide content wrapper; keeping that outer\n * match swallowed every real <section> inside it, collapsing the whole page\n * into one nc-generic component whose intersectionRatio could never exceed\n * viewport-height / page-height (a constant ~0.05 scroll_depth on the\n * audited site). A candidate with exactly one nested candidate (header >\n * nav) is NOT a wrapper — rule 2 keeps the outer one, as before.\n * 2. Of what remains, skip a section nested inside another kept section\n * (avoid double count).\n */\nfunction selectSections(doc: Document): Element[] {\n const candidates = Array.from(doc.querySelectorAll(SECTION_SELECTOR));\n const kept = candidates.filter(\n (el) => candidates.filter((c) => c !== el && el.contains(c)).length < 2,\n );\n return kept.filter((el) => !kept.some((k) => k !== el && k.contains(el)));\n}\n\nfunction registerSections(\n apiKey: string,\n apiBase: string,\n pageUrl: string,\n sections: Array<{ componentId: string; semanticType: SemanticType; source: 'markup' | 'auto' }>,\n): void {\n try {\n void fetch(`${apiBase}/v1/section-map`, {\n method: 'POST',\n keepalive: true,\n headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({ pageUrl, sections }),\n }).catch(() => undefined);\n } catch {\n /* fail-safe */\n }\n}\n\nconst NOOP = (): void => undefined;\n\nexport function startEngagementCapture(\n client: CaptureClient,\n opts: EngagementCaptureOptions,\n): () => void {\n const doc = opts.doc ?? (typeof document !== 'undefined' ? document : undefined);\n if (!doc || typeof IntersectionObserver === 'undefined') return NOOP;\n if (isDoNotTrackEnabled()) return NOOP;\n // Keyless zero-network contract: capture exists to feed the hosted persona\n // pipeline — with no api key there is nothing to feed, and the section-map\n // registration fetch must never fire. Same validity rule as init() and the\n // graph entry: this used to check truthiness only, so an invalid non-`pk_`\n // (typo'd) key still fired /v1/section-map registration and dwell events\n // into a client that discards everything.\n if (!opts.apiKey || !opts.apiKey.startsWith('pk_')) return NOOP;\n // Normalize so both a ROOT base (`https://api.sentient-ui.com`) and a\n // `/v1`-suffixed base resolve to exactly one `/v1/section-map` — some callers\n // pass the versioned base, which would otherwise produce `/v1/v1/section-map`\n // (a silent 404). Strip trailing slashes, then a single trailing `/v1`.\n const apiBase = (opts.apiBase ?? 'https://api.sentient-ui.com')\n .replace(/\\/+$/, '')\n .replace(/\\/v1$/, '');\n\n const els = selectSections(doc);\n if (els.length === 0) return NOOP;\n\n // Collapse to one component per semantic type per page (the matrix aggregates\n // by semantic type anyway). Per-element precedence: explicit data-sentient-type\n // markup → served section map (opts.typeOf) → local heuristic.\n const componentOf = new Map<Element, string>();\n const types = new Map<string, SemanticType>();\n const sources = new Map<string, 'markup' | 'auto'>();\n for (const el of els) {\n const explicit = el.getAttribute('data-sentient-type');\n const markup = explicit && (SEMANTIC_TYPES as readonly string[]).includes(explicit)\n ? (explicit as SemanticType)\n : null;\n const type = markup ?? opts.typeOf?.(el) ?? classifySection(el);\n const componentId = `nc-${type}`;\n componentOf.set(el, componentId);\n types.set(componentId, type);\n // Markup wins if the same collapsed component gets both provenances.\n if (markup) sources.set(componentId, 'markup');\n else if (!sources.has(componentId)) sources.set(componentId, 'auto');\n }\n\n const pageUrl = (doc.defaultView ?? (typeof window !== 'undefined' ? window : undefined))?.location?.pathname ?? '/';\n registerSections(opts.apiKey, apiBase, pageUrl, [...types.entries()].map(([componentId, semanticType]) => ({\n componentId, semanticType, source: sources.get(componentId) ?? 'auto',\n })));\n\n // Accumulate visible dwell (ms) + max scroll ratio per component. `intersecting`\n // tracks in-viewport state independently of `enterAt` (the running clock) so a\n // tab-hide can pause the clock and a tab-show can resume it for still-visible\n // sections — IntersectionObserver does not re-fire on visibilitychange.\n const state = new Map<string, { ms: number; scroll: number; enterAt: number | null; intersecting: boolean }>();\n const get = (id: string) => {\n let s = state.get(id);\n if (!s) { s = { ms: 0, scroll: 0, enterAt: null, intersecting: false }; state.set(id, s); }\n return s;\n };\n\n const observer = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n const id = componentOf.get(entry.target);\n if (!id) continue;\n const s = get(id);\n if (entry.isIntersecting) {\n s.intersecting = true;\n s.enterAt = Date.now();\n if (entry.intersectionRatio > s.scroll) s.scroll = entry.intersectionRatio;\n } else {\n s.intersecting = false;\n if (s.enterAt != null) { s.ms += Date.now() - s.enterAt; s.enterAt = null; }\n }\n }\n }, { threshold: [0, 0.25, 0.5, 0.75, 1] });\n for (const el of componentOf.keys()) observer.observe(el);\n\n // Bank accumulated dwell and RESET the accumulators (so a later emit can't\n // double-count) WITHOUT disconnecting — a visitor who hides/re-shows the tab\n // or tab-switches keeps being measured. Pauses the running clock; the tab-show\n // handler restarts it for still-visible sections so hidden time isn't counted.\n const emit = (): void => {\n const now = Date.now();\n for (const [id, s] of state) {\n if (s.enterAt != null) { s.ms += now - s.enterAt; s.enterAt = null; }\n if (s.ms <= 0) continue;\n try {\n client.track({\n projectId: opts.apiKey, // SDK convention: server derives the real project from the key\n componentId: id,\n eventType: 'dwell',\n payload: { dwell_time: Math.round(s.ms), scroll_depth: Number(s.scroll.toFixed(2)) },\n });\n } catch {\n /* fail-safe */\n }\n s.ms = 0;\n }\n };\n\n const onVisibility = (): void => {\n if (doc.hidden) {\n emit(); // bank + pause\n } else {\n const now = Date.now(); // resume the clock for sections still on screen\n for (const s of state.values()) if (s.intersecting) s.enterAt = now;\n }\n };\n // A page can be FROZEN into the bfcache rather than torn down. Timers keep\n // firing on restore, and `intersecting` still holds whatever it held at\n // pagehide — so without this the heartbeat kept banking dwell for sections the\n // visitor had scrolled far past, forever, while the observer that could have\n // corrected them had been disconnected. Freeze the clocks instead, and only\n // tear down for real when the page is genuinely going away.\n let frozen = false;\n const onPageHide = (event?: { persisted?: boolean }): void => {\n emit(); // bank whatever is measured either way\n if (event?.persisted) {\n frozen = true; // bfcache: keep the observer, stop counting\n return;\n }\n try { observer.disconnect(); } catch { /* ignore */ }\n };\n const onPageShow = (event?: { persisted?: boolean }): void => {\n if (!event?.persisted || !frozen) return;\n frozen = false;\n // The observer stayed connected, so it will correct `intersecting` for\n // anything that moved. Restart clocks only for what is on screen NOW.\n const now = Date.now();\n for (const s of state.values()) s.enterAt = s.intersecting && !doc.hidden ? now : null;\n };\n doc.addEventListener('visibilitychange', onVisibility);\n const win = doc.defaultView ?? (typeof window !== 'undefined' ? window : undefined);\n win?.addEventListener('pagehide', onPageHide);\n win?.addEventListener('pageshow', onPageShow);\n\n // See HEARTBEAT_MS: bank visible dwell periodically so a hard close (or a\n // mobile page kill) loses at most one interval instead of the whole visit.\n // Hidden tabs skip the emit — their clock is already paused, and an empty\n // state map makes emit a no-op anyway.\n const heartbeat = setInterval(() => {\n if (doc.hidden || frozen) return;\n emit();\n // emit() pauses every running clock and only the tab-show handler restarts\n // them — here the page never went hidden, so restart the clock ourselves\n // or accumulation silently stops after the first heartbeat.\n const now = Date.now();\n for (const s of state.values()) if (s.intersecting) s.enterAt = now;\n }, HEARTBEAT_MS);\n\n // Per-section micro-signal detectors (opt-in; see EngagementCaptureOptions).\n // Attributed to the section's nc-<type> id with no variant — they feed the\n // persona attention fallback and auto-discovery, never rewards.\n const detectorCleanups: Array<() => void> = [];\n if (opts.microSignals) {\n // tab_loss is a single document-level `visibilitychange` signal, so enabling\n // it on every section detector would emit one tab_loss per nc-<type> section\n // on a single tab-hide — attributing one page-level exit to every section\n // (audit M5). Enable it on only the first section so the exit is recorded\n // once, mirroring the per-option path in slot-signals.ts ({ tabLoss: index === 0 }).\n [...componentOf.entries()].forEach(([el, componentId], i) => {\n detectorCleanups.push(\n attachMicroSignalDetectors((signalType, extra = {}) => {\n try {\n client.track({\n projectId: opts.apiKey,\n componentId,\n eventType: 'micro_signal',\n payload: { signalType, ...extra },\n });\n } catch {\n /* fail-safe */\n }\n }, el, undefined, { tabLoss: i === 0 }),\n );\n });\n }\n\n // Cleanup: bank any remaining dwell, then detach everything (provider unmount\n // / consent re-init must not leak observers or listeners).\n return () => {\n emit();\n clearInterval(heartbeat);\n doc.removeEventListener('visibilitychange', onVisibility);\n win?.removeEventListener('pagehide', onPageHide);\n win?.removeEventListener('pageshow', onPageShow);\n for (const c of detectorCleanups) c();\n try { observer.disconnect(); } catch { /* ignore */ }\n };\n}\n"],"mappings":"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","names":["SECTION_SELECTOR","HEARTBEAT_MS","selectSections","doc","candidates","kept","el","k","registerSections","apiKey","apiBase","pageUrl","sections","e","NOOP","startEngagementCapture","client","opts","_a","_b","_c","_d","_e","_f","_g","_h","_i","isDoNotTrackEnabled","els","componentOf","types","sources","explicit","markup","SEMANTIC_TYPES","type","classifySection","componentId","semanticType","state","get","id","s","observer","entries","entry","emit","now","onVisibility","frozen","onPageHide","event","onPageShow","win","heartbeat","detectorCleanups","i","attachMicroSignalDetectors","signalType","extra","__spreadValues","c"]}
@@ -1,7 +1,7 @@
1
- import { a5 as SentientConfig, a4 as SentientClient } from './index-BheP9F8h.cjs';
2
- export { A as AssignResult, a as Assignment, b as AssignmentCache, I as EventQueue, J as EventType, M as GraphClient, N as GraphConfig, O as GraphSnapshot, a0 as PageNode, a1 as QueueConfig, a6 as SentientEvent, a7 as SessionConfig, a8 as SessionManager, am as sanitizePageUrl } from './index-BheP9F8h.cjs';
3
- export { j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-BVvq5RBB.cjs';
4
- import '@sentientui/policy';
1
+ import { a6 as SentientConfig, a5 as SentientClient } from './index-CXxvWxCB.cjs';
2
+ export { A as AssignResult, a as Assignment, b as AssignmentCache, B as BLOCK_ALIGNS, c as BLOCK_EMPHASES, d as BLOCK_FITS, e as BLOCK_GAPS, f as BLOCK_GRID_COLUMNS, g as BLOCK_HEADING_LEVELS, h as BLOCK_JUSTIFIES, i as BLOCK_RATIOS, j as BLOCK_SIZES, k as BLOCK_TEXT_ALIGNS, l as BLOCK_TONES, m as BLOCK_WEIGHTS, n as BadgeBlock, o as BlockAlign, p as BlockEmphasis, q as BlockFit, r as BlockGap, s as BlockJustify, t as BlockNode, u as BlockRatio, v as BlockSize, w as BlockTextAlign, x as BlockTone, y as BlockWeight, z as ButtonBlock, E as CompoundLocator, H as DecisionSnapshot, I as EventQueue, J as EventType, M as GraphClient, N as GraphConfig, O as GraphSnapshot, P as GridBlock, Q as HeadingBlock, R as ImageBlock, S as LEGACY_SESSION_COOKIE_NAME, U as LinkBlock, V as MAX_BLOCK_ARMS, W as MAX_BLOCK_CHILDREN, X as MAX_BLOCK_DEPTH, Y as MAX_BLOCK_NODES, Z as MAX_BLOCK_TEXT_LEN, _ as MicroSignalEmitter, $ as MicroSignalType, a1 as PageNode, a2 as QueueConfig, a3 as SNAPSHOT_STORAGE_KEY_PREFIX, a7 as SentientEvent, a8 as SessionConfig, a9 as SessionManager, aa as SitePalette, ab as SlotConfigEntry, ac as SlotOps, ad as SpacerBlock, ae as StackBlock, af as TextBlock, ai as attachMicroSignalDetectors, aj as grantConsent, al as isDoNotTrackEnabled, am as readSnapshot, an as renderPrePaintScript, ao as sanitizePageUrl, ap as sessionCookieName, aq as writeSnapshot } from './index-CXxvWxCB.cjs';
3
+ export { b as SlotDeclInput, e as armOfResult, f as baselineResultFor, g as baselineSlots, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, r as referrerDomainFromReferer, t as toWireSlot } from './session-meta-BVvq5RBB.cjs';
4
+ export { SlotResult } from '@sentientui/policy';
5
5
 
6
6
  /** Reads the rendered DOM to build the page-side context graph. */
7
7
  type ScannedNode = {
@@ -1,7 +1,7 @@
1
- import { a5 as SentientConfig, a4 as SentientClient } from './index-BvHshOSe.js';
2
- export { A as AssignResult, a as Assignment, b as AssignmentCache, I as EventQueue, J as EventType, M as GraphClient, N as GraphConfig, O as GraphSnapshot, a0 as PageNode, a1 as QueueConfig, a6 as SentientEvent, a7 as SessionConfig, a8 as SessionManager, am as sanitizePageUrl } from './index-BvHshOSe.js';
3
- export { j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-BVvq5RBB.js';
4
- import '@sentientui/policy';
1
+ import { a6 as SentientConfig, a5 as SentientClient } from './index-BbrtAtrY.js';
2
+ export { A as AssignResult, a as Assignment, b as AssignmentCache, B as BLOCK_ALIGNS, c as BLOCK_EMPHASES, d as BLOCK_FITS, e as BLOCK_GAPS, f as BLOCK_GRID_COLUMNS, g as BLOCK_HEADING_LEVELS, h as BLOCK_JUSTIFIES, i as BLOCK_RATIOS, j as BLOCK_SIZES, k as BLOCK_TEXT_ALIGNS, l as BLOCK_TONES, m as BLOCK_WEIGHTS, n as BadgeBlock, o as BlockAlign, p as BlockEmphasis, q as BlockFit, r as BlockGap, s as BlockJustify, t as BlockNode, u as BlockRatio, v as BlockSize, w as BlockTextAlign, x as BlockTone, y as BlockWeight, z as ButtonBlock, E as CompoundLocator, H as DecisionSnapshot, I as EventQueue, J as EventType, M as GraphClient, N as GraphConfig, O as GraphSnapshot, P as GridBlock, Q as HeadingBlock, R as ImageBlock, S as LEGACY_SESSION_COOKIE_NAME, U as LinkBlock, V as MAX_BLOCK_ARMS, W as MAX_BLOCK_CHILDREN, X as MAX_BLOCK_DEPTH, Y as MAX_BLOCK_NODES, Z as MAX_BLOCK_TEXT_LEN, _ as MicroSignalEmitter, $ as MicroSignalType, a1 as PageNode, a2 as QueueConfig, a3 as SNAPSHOT_STORAGE_KEY_PREFIX, a7 as SentientEvent, a8 as SessionConfig, a9 as SessionManager, aa as SitePalette, ab as SlotConfigEntry, ac as SlotOps, ad as SpacerBlock, ae as StackBlock, af as TextBlock, ai as attachMicroSignalDetectors, aj as grantConsent, al as isDoNotTrackEnabled, am as readSnapshot, an as renderPrePaintScript, ao as sanitizePageUrl, ap as sessionCookieName, aq as writeSnapshot } from './index-BbrtAtrY.js';
3
+ export { b as SlotDeclInput, e as armOfResult, f as baselineResultFor, g as baselineSlots, j as deriveSessionSegment, k as detectDeviceClass, l as detectTimeOfDay, m as detectTrafficSource, r as referrerDomainFromReferer, t as toWireSlot } from './session-meta-BVvq5RBB.js';
4
+ export { SlotResult } from '@sentientui/policy';
5
5
 
6
6
  /** Reads the rendered DOM to build the page-side context graph. */
7
7
  type ScannedNode = {
@@ -1,2 +1,2 @@
1
- "use strict";var gt=Object.create;var fe=Object.defineProperty,ft=Object.defineProperties,mt=Object.getOwnPropertyDescriptor,yt=Object.getOwnPropertyDescriptors,ht=Object.getOwnPropertyNames,Ue=Object.getOwnPropertySymbols,St=Object.getPrototypeOf,Be=Object.prototype.hasOwnProperty,vt=Object.prototype.propertyIsEnumerable;var $e=(e,t,n)=>t in e?fe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,b=(e,t)=>{for(var n in t||(t={}))Be.call(t,n)&&$e(e,n,t[n]);if(Ue)for(var n of Ue(t))vt.call(t,n)&&$e(e,n,t[n]);return e},X=(e,t)=>ft(e,yt(t));var wt=(e,t)=>{for(var n in t)fe(e,n,{get:t[n],enumerable:!0})},Fe=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of ht(t))!Be.call(e,u)&&u!==n&&fe(e,u,{get:()=>t[u],enumerable:!(r=mt(t,u))||r.enumerable});return e};var bt=(e,t,n)=>(n=e!=null?gt(St(e)):{},Fe(t||!e||!e.__esModule?fe(n,"default",{value:e,enumerable:!0}):n,e)),It=e=>Fe(fe({},"__esModule",{value:!0}),e);var Rn={};wt(Rn,{deriveSessionSegment:()=>_e,detectDeviceClass:()=>se,detectTimeOfDay:()=>ce,detectTrafficSource:()=>ie,init:()=>kn,referrerDomainFromReferer:()=>ae,sanitizePageUrl:()=>Le});module.exports=It(Rn);function ye(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}try{if(typeof crypto!="undefined"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t="";for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,"0"),(n===3||n===5||n===7||n===9)&&(t+="-");return t}}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function oe(e){return e?`_${e.slice(0,12)}`:""}var xt="_snt_uid",Et=365,Ct="_snt_uid";function Tt(){return ye()}function At(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function kt(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(r){}}function Rt(e){try{return localStorage.getItem(e)}catch(t){return null}}function _t(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function Dt(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function Ot(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Pt(e){try{sessionStorage.removeItem(e)}catch(t){}}function Nt(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function Mt(e){try{localStorage.removeItem(e)}catch(t){}}function Lt(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Gt={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function he(e){var f,g,m,v,T,E;if(typeof window=="undefined")return Gt;let t=oe(e==null?void 0:e.apiKey),n=(f=e==null?void 0:e.cookieName)!=null?f:`${xt}${t}`,r=`${Ct}${t}`,l=((g=e==null?void 0:e.cookieTTLDays)!=null?g:Et)*24*60*60,i=_=>_&&_.length>0?_:null,d=(E=(T=(v=(m=i(At(n)))!=null?m:i(Rt(r)))!=null?v:i(Dt(r)))!=null?T:i(e==null?void 0:e.ssrSessionId))!=null?E:Tt();kt(n,d,l);let s=_t(r,d),o=Nt(n),a=s?!1:Ot(r,d),c=!s&&!o&&!a;return{getSessionId:()=>d,isEphemeral:()=>c,destroy:()=>{d=null,Lt(n),Mt(r),Pt(r)}}}function Z(e){return Math.min(6e4,1e3*2**Math.min(e,6))}function re(e){if(e.ok===!0)return"delivered";let{status:t}=e;return typeof t!="number"?"retry":t>=200&&t<300?"delivered":t>=400&&t<500&&t!==429?"dropped":"retry"}function Se(e,t){try{let n=localStorage.getItem(e);if(!n)return[];let r=JSON.parse(n);return Array.isArray(r)?(localStorage.removeItem(e),r.slice(-t)):[]}catch(n){return[]}}function ee(e,t,n){try{let r=(()=>{try{let l=localStorage.getItem(n);if(!l)return[];let i=JSON.parse(l);return Array.isArray(i)?i:[]}catch(l){return[]}})(),u=new Map;for(let l of r)u.set(l.id,l);for(let l of e)u.set(l.id,l);localStorage.setItem(n,JSON.stringify([...u.values()].slice(-t)))}catch(r){}}function ve(e,t){try{let n=localStorage.getItem(t);if(!n)return;let r=JSON.parse(n);if(!Array.isArray(r))return;let u=new Set(e),l=r.filter(i=>!u.has(i.id));if(l.length===r.length)return;l.length===0?localStorage.removeItem(t):localStorage.setItem(t,JSON.stringify(l))}catch(n){}}var Kt=500,Ut=56*1024;function ke(e){return`_snt_retry_${e.slice(0,12)}`}var $t={push:()=>{},flush:()=>{},destroy:()=>{}};function je(e){var U,M,Q;if(typeof window=="undefined")return $t;let t=(U=e.flushIntervalMs)!=null?U:5e3,n=(M=e.maxBatchSize)!=null?M:20,r=(Q=e.maxRetrySize)!=null?Q:100,u=e.ingestUrl,l=e.apiKey,i=ke(l),d=[],s=new Set,o=[],a=h=>{for(let I of h)c.delete(I),!s.has(I)&&(s.add(I),o.push(I));for(;o.length>Kt;){let I=o.shift();I&&s.delete(I)}ve(h,i)},c=new Set,f=h=>{s.has(h.id)||c.has(h.id)||(c.add(h.id),d.push(h))},g=h=>{for(let I of h)s.has(I.id)||(c.add(I.id),d.push(I))},m=Se(i,r);for(let h of m)f(h);let v=0,T=0,E=(h,I=!0)=>{if(h.length===0)return;let q=JSON.stringify(h),te=h.map(H=>H.id),F;try{F=fetch(u,{method:"POST",keepalive:!0,body:q,headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`}})}catch(H){ee(h,r,i),g(h),T++,v=Date.now()+Z(T);return}let le=H=>{if(re(H)!=="retry"){if(!H.ok&&I){let ne=h.filter(V=>V.eventType!=="pageview");if(ne.length>0&&ne.length<h.length){a(h.filter(V=>V.eventType==="pageview").map(V=>V.id)),E(ne,!1);return}}a(te),T=0,v=0;return}ee(h,r,i),g(h),T++,v=Date.now()+Z(T)};F instanceof Promise?F.then(le).catch(()=>{ee(h,r,i),g(h),T++,v=Date.now()+Z(T)}):le(F)},_=typeof TextEncoder!="undefined"?new TextEncoder:null,N=h=>_?_.encode(h).length:h.length,k=h=>{let I=[],q=2;for(let te of h){let F=N(JSON.stringify(te))+1;if(I.length>0&&q+F>Ut||I.length>=n)break;I.push(te),q+=F}return I},L=()=>{try{if(Date.now()<v)return;for(;d.length>0&&!(Date.now()<v);){let h=d.filter(q=>!s.has(q.id));if(d.length=0,h.length===0)break;let I=k(h);if(I.length===0)break;I.length<h.length&&d.push(...h.slice(I.length)),E(I)}}catch(h){}},K=!0,S=null;S=setInterval(()=>{K&&L()},t);let A=()=>{document.visibilityState==="hidden"&&L()},J=()=>{L()};return document.addEventListener("visibilitychange",A),window.addEventListener("pagehide",J),{push(h){f(h),d.length>=n&&L()},flush:L,destroy(){K=!1,S!==null&&(clearInterval(S),S=null),document.removeEventListener("visibilitychange",A),window.removeEventListener("pagehide",J),L()}}}var Bt=200;function Re(e){return`_snt_goal_retry_${e.slice(0,12)}`}var Ft={send:()=>{},flush:()=>{},destroy:()=>{}};function We(e){var k,L,K;if(typeof window=="undefined")return Ft;let t=(k=e.flushIntervalMs)!=null?k:5e3,n=(L=e.maxRetrySize)!=null?L:100,r=(K=e.maxPerFlush)!=null?K:5,u=Re(e.apiKey),l=[],i=new Set,d=new Set,s=[],o=0,a=0,c=!1,f=S=>{for(i.delete(S.id),d.has(S.id)||(d.add(S.id),s.push(S.id));s.length>Bt;){let A=s.shift();A&&d.delete(A)}ve([S.id],u)},g=S=>{ee([S],n,u),!d.has(S.id)&&!i.has(S.id)&&(i.add(S.id),l.push(S)),Date.now()>=o&&(a++,o=Date.now()+Z(a))},m=S=>{let A;try{A=fetch(e.url,{method:"POST",keepalive:!0,body:S.body,headers:e.headers})}catch(U){g(S);return}let J=U=>{var Q;let M=re(U);if(M==="retry"){g(S);return}M==="dropped"&&((Q=e.onDrop)==null||Q.call(e,S,U.status)),f(S),a=0,o=0};A instanceof Promise?A.then(J).catch(()=>g(S)):J(A)},v=()=>{try{if(c||Date.now()<o)return;let S=0;for(;l.length>0&&S<r&&!(Date.now()<o);){let A=l.shift();i.delete(A.id),!d.has(A.id)&&(S++,m(A))}}catch(S){}},T=Se(u,n);for(let S of T)i.has(S.id)||(i.add(S.id),l.push(S));T.length>0&&ee(T,n,u);let E=setInterval(v,t),_=()=>{document.visibilityState==="hidden"&&v()},N=()=>v();return document.addEventListener("visibilitychange",_),window.addEventListener("pagehide",N),{send(S){if(!c&&!(d.has(S.id)||i.has(S.id))){if(Date.now()<o){ee([S],n,u),i.add(S.id),l.push(S);return}m(S)}},flush:v,destroy(){clearInterval(E),document.removeEventListener("visibilitychange",_),window.removeEventListener("pagehide",N),v(),c=!0}}}var jt=1800*1e3;function we(e,t){return`${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function ze(e=jt,t){let n=new Map,r=`_snt_asgn${oe(t)}_`,u=(o,a)=>`${r}${encodeURIComponent(o)}:${encodeURIComponent(a)}`,l=o=>{let a=o.slice(r.length),c=a.indexOf(":");if(c<0)return null;try{return{componentId:decodeURIComponent(a.slice(0,c)),segment:decodeURIComponent(a.slice(c+1))}}catch(f){return null}},i=()=>{try{let o=[];for(let a=0;a<localStorage.length;a++){let c=localStorage.key(a);c!=null&&c.startsWith(r)&&o.push(c)}return o}catch(o){return[]}},d=o=>o.assignedAt+(o.ttlMs&&o.ttlMs>0?o.ttlMs:e)<Date.now();return typeof window!="undefined"&&(()=>{for(let o of i())try{let a=localStorage.getItem(o);if(!a)continue;let c=JSON.parse(a);if(d(c)){localStorage.removeItem(o);continue}let f=l(o);if(!f)continue;n.set(we(f.componentId,f.segment),c)}catch(a){}})(),{get(o,a){let c=n.get(we(o,a));return c?d(c)?(n.delete(we(o,a)),null):c:null},set(o,a,c){let f=we(o,a);n.set(f,c);try{localStorage.setItem(u(o,a),JSON.stringify(c))}catch(g){}},invalidate(o){let a=`${encodeURIComponent(o)}:`;for(let c of[...n.keys()])c.startsWith(a)&&n.delete(c);for(let c of i()){let f=l(c);if((f==null?void 0:f.componentId)===o)try{localStorage.removeItem(c)}catch(g){}}},clear(){n.clear();for(let o of i())try{localStorage.removeItem(o)}catch(a){}}}}var Qe=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function be(e){return qe(e)!==null}function qe(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=Qe.find(r=>t.includes(r.toLowerCase())))!=null?n:null}function se(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function ie(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(u){}let r=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(r)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(r)?"social":"referral"}catch(n){return"direct"}}function ae(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function ce(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function _e(e){let t=Wt("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Wt(e,t){var l,i,d,s,o,a,c;let n=(i=(l=t==null?void 0:t.userAgent)==null?void 0:l.trim())!=null?i:"",r=(s=(d=t==null?void 0:t.referer)==null?void 0:d.trim())!=null?s:"",u=(o=t==null?void 0:t.now)!=null?o:new Date;return{sessionId:e,ephemeral:!1,utmParams:(a=t==null?void 0:t.utmParams)!=null?a:{},deviceClass:n?se(n):"desktop",trafficSource:r?ie(r,t==null?void 0:t.appOrigin):"direct",referrerDomain:ae(r),timeOfDay:ce(u),dayOfWeek:(c=["sun","mon","tue","wed","thu","fri","sat"][u.getDay()])!=null?c:"sun",automation:(t==null?void 0:t.webdriver)===!0||be(n)}}var de=require("@sentientui/policy");function De(e){return b(b(b({id:e.id},e.arms?{arms:[...e.arms]}:{}),e.dims?{dims:Object.fromEntries(Object.entries(e.dims).map(([t,n])=>[t,[...n]]))}:{}),e.baseline!==void 0?{baseline:e.baseline}:{})}function Oe(e){let t=De(e);return(0,de.slotResultFor)(t,(0,de.slotBaselineArm)(t))}function Je(e){return typeof e=="string"?e:(0,de.canonicalArm)(e)}var Ie="_snt_snap:",zt=["low","medium","high"];function He(e){try{let t=localStorage.getItem(Ie+e);if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"||n.v!==1||typeof n.persona!="string"||typeof n.band!="string"||!zt.includes(n.band)||typeof n.slots!="object"||n.slots===null||Array.isArray(n.slots)||!(n.layoutOrder===null||Array.isArray(n.layoutOrder))||typeof n.savedAt!="number"||!(n.slotConfig===void 0||typeof n.slotConfig=="object"&&n.slotConfig!==null&&!Array.isArray(n.slotConfig))?null:n}catch(t){return null}}function xe(e,t){try{localStorage.setItem(Ie+e,JSON.stringify(t))}catch(n){}}var Ne=require("@sentientui/policy");var Ce=require("@sentientui/policy");var Ve="[sentient] No API key configured \u2014 nothing is being learned. Set NEXT_PUBLIC_SENTIENT_API_KEY or pass localMode: true for local development.",Qt="[sentient] Local mode \u2014 decisions are simulated on-device and nothing is sent over the network. Add an API key to learn from real traffic.",Ye=!1,Ee=!1;function qt(){var e;try{return(e=new URLSearchParams(window.location.search).get("sentient_persona"))!=null?e:void 0}catch(t){return}}function Xe(e){var d;let t=he({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),n=(d=t.getSessionId())!=null?d:"local",r=qt(),u=import("@sentientui/core/local").then(s=>{let o=s;return o.LOCAL_ENGINE_AVAILABLE?(Ye||(Ye=!0,console.info(Qt)),o):(Ee||(Ee=!0,console.error(Ve)),null)}).catch(()=>(Ee||(Ee=!0,console.error(Ve)),null)),l=null;function i(s){let o=document.documentElement;o.dataset.sentientPersona===void 0&&(o.dataset.sentientPersona=s.persona,o.dataset.sentientConfidence=(0,Ce.confidenceBand)(s.confidence))}return{isLocal:!0,async decide(s){var c,f,g;let o=await u;if(!o)return null;let a=o.createLocalEngine({sessionId:n,forcedPersona:r}).decide(s);return l=X(b({},a),{layoutOrder:(f=(c=a.layoutOrder)!=null?c:l==null?void 0:l.layoutOrder)!=null?f:null,slots:b(b({},(g=l==null?void 0:l.slots)!=null?g:{}),a.slots)}),xe(e.apiKey||"local",{v:1,persona:l.persona,band:(0,Ce.confidenceBand)(l.confidence),slots:l.slots,layoutOrder:l.layoutOrder,savedAt:Date.now()}),i(a),a},getSlotResult(s){var o,a,c;return(c=(a=l==null?void 0:l.slots[s])!=null?a:(o=e.initialSlots)==null?void 0:o[s])!=null?c:null},getPersona(){return l?{persona:l.persona,confidence:l.confidence,band:(0,Ce.confidenceBand)(l.confidence)}:null},async assign(s,o){var f;let a=await u;return!a||!o||o.length===0?o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null:{variantId:(f=a.createLocalEngine({sessionId:n,forcedPersona:r}).decide({components:[{id:s,variantIds:o}]}).assignments[s])!=null?f:o[0],assignmentTtlMs:0}},track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>t.destroy()}}var Ze="https://api.sentient-ui.com/v1/events",z=new Map,Jt=null;function Ht(e){return"value"in e||"currency"in e||"externalId"in e||"metadata"in e||"weight"in e||"stepIndex"in e}var Vt=3;function Pe(){return ye()}function Te(){var e;if(typeof window!="undefined")return((e=window.location)==null?void 0:e.pathname)||void 0}function Yt(e){if(typeof MessageChannel=="function"){let t=new MessageChannel;t.port1.onmessage=()=>{e.clear(),t.port1.close(),t.port2.close()},t.port2.postMessage(0)}else setTimeout(()=>e.clear(),0)}var et=new Set;function Xt(e,t,n){let r=typeof window=="undefined"?null:window.history;if(!r)return()=>{};let u=!1,l,i=()=>{if(u)return;let o=Te();!o||o===l||(l=o,e.track({projectId:t,componentId:"__page__",eventType:"pageview",payload:{}}),n(`${t}:${o}`))},d=[];for(let o of["pushState","replaceState"]){let a=r[o],c=function(...f){let g=a.apply(this,f);return i(),g};r[o]=c,d.push([o,a,c])}window.addEventListener("popstate",i);let s=Te();return s&&et.has(`${t}:${s}`)?l=s:i(),()=>{if(!u){u=!0,window.removeEventListener("popstate",i);for(let[o,a,c]of d)r[o]===c&&(r[o]=a)}}}var me={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}};function Zt(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,r]of t)n.startsWith("utm_")&&(e[n]=r);return e}catch(e){return{}}}function tt(e){return e.replace(/\/events\/?$/,"")}function Me(){return typeof navigator!="undefined"&&navigator.globalPrivacyControl===!0?!0:[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function en(e){var d;let t=e.preConsentBehavior==="statistical_winner",n=tt((d=e.ingestUrl)!=null?d:Ze),r={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(s,o,a){if(!t)return null;try{let c=new URLSearchParams({componentId:s});for(let m of o!=null?o:[])c.append("variantIds[]",m);let f=await fetch(`${n}/winner?${c.toString()}`,{headers:r});return f.ok?{variantId:(await f.json()).variantId,assignmentTtlMs:0}:o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}catch(c){return o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}},decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}},l={track:s=>u.track(s),goal:((s,o,a,c)=>u.goal(s,o,a,c)),componentGoal:(s,o,a)=>u.componentGoal(s,o,a),identify:s=>u.identify(s),getAssignment:(s,o)=>u.getAssignment(s,o),assign:(s,o,a,c)=>u.assign(s,o,a,c),decide:s=>u.decide(s),getSlotResult:s=>u.getSlotResult(s),getPersona:()=>u.getPersona(),fetchWeights:()=>u.fetchWeights(),getGraph:()=>u.getGraph(),dispose:()=>u.dispose(),destroy:()=>u.destroy()};function i(s){u=s}return{proxy:l,setInner:i}}function nt(e){var I,q,te,F,le,H,ne,V,Ke;if(typeof window=="undefined")return me;Jt=e.apiKey;let t=z.get(e.apiKey||"local");if(t!=null&&t.dispose)try{t.dispose()}catch(p){}let n=e.respectDoNotTrack!==!1&&Me(),r=e.consent===!1||n,u=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_");if(e.localMode===!0||!u&&e.localMode!==!1)return r?(z.set(e.apiKey||"local",{config:e,upgrade:null}),me):(z.set(e.apiKey||"local",{config:e,upgrade:null}),Xe(e));if(r){if(!e.apiKey||!e.apiKey.startsWith("pk_"))return e.preConsentBehavior==="statistical_winner"&&console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),z.set(e.apiKey,{config:e,upgrade:null}),me;let{proxy:p,setInner:y}=en(e);return z.set(e.apiKey,{config:e,upgrade:n?null:y}),p}if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),me;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),me;let l=(I=e.ingestUrl)!=null?I:Ze,i=Date.now(),d=he({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),s=ze(void 0,e.apiKey),o=je({ingestUrl:l,apiKey:e.apiKey}),a=tt(l),c={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},f=new Set,g=We({url:`${a}/goals`,apiKey:e.apiKey,headers:c,onDrop:(p,y)=>{if(!e.debug){if(f.has(y))return;f.add(y)}console.warn(`[sentient] goal dropped (HTTP ${y}) \u2014 this will not be retried. `+(y===400?"The session was not found: call init() and let the session upsert complete before firing goals.":y===401||y===403?"Check the API key and that this origin is on the project allowlist.":"See the response status for the cause."),p)}}),m=se((q=navigator.userAgent)!=null?q:""),v=typeof window!="undefined"?window.location.origin:void 0,T=ie((te=document.referrer)!=null?te:"",v),E=(F=e.sessionSegment)!=null?F:`${m}:${T}`,_=new Map,N=new Map,k=null,L=p=>{for(let y of p)N.has(y.id)||N.set(y.id,Oe(y))};if(e.initialSlots)for(let[p,y]of Object.entries(e.initialSlots))N.set(p,y);let K=He(e.apiKey);if(K)for(let[p,y]of Object.entries(K.slots))N.has(p)||N.set(p,y);let S={low:.15,medium:.5,high:.85};if(e.initialPersona)k=b({},e.initialPersona);else{let p=document.documentElement.dataset;p.sentientPersona?k={persona:p.sentientPersona,confidence:(H=S[(le=p.sentientConfidence)!=null?le:"low"])!=null?H:.15}:K&&(k={persona:K.persona,confidence:(ne=S[K.band])!=null?ne:.15})}if(e.initialAssignments)for(let[p,y]of Object.entries(e.initialAssignments))s.set(p,E,{variantId:y,assignedAt:Date.now(),segment:E,confidence:1});let A=Promise.resolve(),J=d.getSessionId();if(J){let p=ae((V=document.referrer)!=null?V:""),y=b(b(b({sessionId:J,deviceClass:m,trafficSource:T,referrerDomain:p,utmParams:Zt(),timeOfDay:ce(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:d.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||be((Ke=navigator.userAgent)!=null?Ke:"")},e.userId?{userId:e.userId}:{}),e.persona?{persona:e.persona}:{}),e.country?{country:e.country}:{}),w=async()=>{for(let D=0;;D++){try{let R=await fetch(`${a}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(y),headers:c});if(R.status===402){console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");return}if(R.ok||re(R)==="dropped")return}catch(R){}if(D>=Vt){console.warn("[SentientUI] Could not register the session after retries. Conversions in this visit may not be recorded.");return}await new Promise(R=>setTimeout(R,Z(D+1)))}};try{A=w()}catch(D){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let U=new Set,M=null,Q=!1,h={goal(p,y={},w=1,D=0){var P,ue,B,pe,x,Y;let R=d.getSessionId();if(!R)return;let C=Ht(y)?y:{metadata:y},j=`${p}\0${(P=C.externalId)!=null?P:""}\0${(ue=C.stepIndex)!=null?ue:D}\0${(B=C.weight)!=null?B:w}`;if(U.has(j)){e.debug&&console.log(`[sentient] goal("${p}") already recorded for this action \u2014 not sent twice`);return}U.add(j),U.size===1&&Yt(U);let $=Pe(),O={sessionId:R,name:p,metadata:(pe=C.metadata)!=null?pe:{},weight:(x=C.weight)!=null?x:w,stepIndex:(Y=C.stepIndex)!=null?Y:D,goalId:$,value:C.value,currency:C.currency,externalId:C.externalId};e.debug&&console.log("[sentient] goal",O);let W={id:$,body:JSON.stringify(O)};A.then(()=>g.send(W))},componentGoal(p,y,w){var O,W,P;let D=d.getSessionId();if(!D)return;let R=s.get(p,E),C=R?null:(O=N.get(p))!=null?O:null;if(!R&&C===null){e.debug&&console.warn(`[sentient] componentGoal("${p}"): no assignment or slot decision yet \u2014 render its <Adaptive>/adaptive hook or call assign()/decide() before recording a goal.`);return}let j=R?R.variantId:Je(C),$={id:Pe(),sessionId:D,projectId:e.apiKey,componentId:p,variantId:j,eventType:"goal_achieved",goalType:y,payload:b({reward:(W=w==null?void 0:w.reward)!=null?W:1,goalValue:w==null?void 0:w.value,currency:w==null?void 0:w.currency},(P=w==null?void 0:w.metadata)!=null?P:{}),timestamp:Date.now(),timeInSession:Date.now()-i,path:Te()};e.debug&&console.log("[sentient] componentGoal",$),A.then(()=>o.push($))},identify(p){let y=d.getSessionId();y&&A.then(()=>{fetch(`${a}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,userId:p,ephemeral:d.isEphemeral()}),headers:c}).catch(()=>{})})},track(p){let y=d.getSessionId();if(!y)return;let w=X(b({path:Te()},p),{id:Pe(),sessionId:y,timestamp:Date.now(),timeInSession:Date.now()-i});e.debug&&console.log("[sentient] track",w),A.then(()=>o.push(w))},getAssignment(p,y){return s.get(p,y)},async assign(p,y,w,D){let R=d.getSessionId();if(!R)return null;let C=s.get(p,E);if(C&&(y!=null&&y.length||C.content!==void 0)){let O=C.ttlMs&&C.ttlMs>0?Math.max(0,C.assignedAt+C.ttlMs-Date.now()):0;return{variantId:C.variantId,assignmentTtlMs:O,content:C.content}}let j=_.get(p);if(j)return j;let $=(async()=>{await A;try{let O={sessionId:R,componentId:p,variantIds:y};D!==void 0?O.agentDataByVariant=D:w!==void 0&&(O.agentData=w);let W=await fetch(`${a}/assign`,{method:"POST",body:JSON.stringify(O),headers:c});if(!W.ok)return null;let P=await W.json();return s.set(p,E,b({variantId:P.variantId,assignedAt:Date.now(),segment:E,confidence:1,content:P.content},P.assignmentTtlMs&&P.assignmentTtlMs>0?{ttlMs:P.assignmentTtlMs}:{})),P}catch(O){return null}finally{_.delete(p)}})();return _.set(p,$),$},async decide(p){var D,R,C,j,$,O,W,P,ue;let y=d.getSessionId();if(!y)return null;let w=(D=p.slots)!=null?D:[];await A;try{let B={sessionId:y};p.sections&&p.sections.length>0&&(B.sections=p.sections.map(G=>({id:G}))),B.components=(R=p.components)!=null?R:[],w.length>0&&(B.slots=w.map(De)),p.slotsFrom==="registry"&&(B.slotsFrom="registry"),p.v&&(B.v=p.v),e.persona&&(B.persona=e.persona);let pe=await fetch(`${a}/decide`,{method:"POST",body:JSON.stringify(B),headers:c});if(!pe.ok)return L(w),null;let x=await pe.json(),Y={};for(let G of w)Y[G.id]=(j=(C=x.slots)==null?void 0:C[G.id])!=null?j:Oe(G);if(x.slots)for(let[G,ge]of Object.entries(x.slots))G in Y||(Y[G]=ge);for(let[G,ge]of Object.entries(Y))N.set(G,ge);let pt=k!=null&&k.persona!=="unknown";x.persona&&!(x.persona==="unknown"&&pt)?k={persona:x.persona,confidence:($=x.confidence)!=null?$:0}:k||(k={persona:"unknown",confidence:0});for(let[G,ge]of Object.entries((O=x.assignments)!=null?O:{}))s.set(G,E,{variantId:ge,assignedAt:Date.now(),segment:E,confidence:1});return xe(e.apiKey,b(b({v:1,persona:k.persona,band:(0,Ne.confidenceBand)(k.confidence),slots:Object.fromEntries(N),layoutOrder:(W=x.layoutOrder)!=null?W:null,savedAt:Date.now()},x.slotConfig?{slotConfig:x.slotConfig}:{}),x.palette?{palette:x.palette}:{})),b(b(b(b({layoutOrder:(P=x.layoutOrder)!=null?P:null,assignments:(ue=x.assignments)!=null?ue:{},slots:Y,persona:k.persona,confidence:k.confidence},x.slotConfig?{slotConfig:x.slotConfig}:{}),x.goals?{goals:x.goals}:{}),x.sectionMap?{sectionMap:x.sectionMap}:{}),x.palette?{palette:x.palette}:{})}catch(B){return L(w),null}},getSlotResult(p){var y;return(y=N.get(p))!=null?y:null},getPersona(){return k?{persona:k.persona,confidence:k.confidence,band:(0,Ne.confidenceBand)(k.confidence)}:null},async fetchWeights(){var p;try{let y=await fetch(`${a}/weights`,{headers:c});return y.ok?(p=(await y.json()).components)!=null?p:[]:[]}catch(y){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},dispose(){var p;M==null||M(),Q=!0,o.destroy(),g.destroy(),((p=z.get(e.apiKey))==null?void 0:p.dispose)===h.dispose&&z.delete(e.apiKey),e.debug&&console.log("[sentient] disposed")},destroy(){var p;M==null||M(),Q=!0,o.destroy(),g.destroy(),d.destroy(),((p=z.get(e.apiKey))==null?void 0:p.dispose)===h.dispose&&z.delete(e.apiKey);try{localStorage.removeItem(Ie+e.apiKey),localStorage.removeItem(ke(e.apiKey)),localStorage.removeItem(Re(e.apiKey))}catch(y){}e.debug&&console.log("[sentient] destroyed")}};if(z.set(e.apiKey,{config:e,upgrade:null,dispose:h.dispose}),M=Xt(h,e.apiKey,p=>{A.then(()=>{Q||et.add(p)})}),e.debug){let p=window;p.__sentient&&(p.__sentient.client=h)}return h}var ot="_snt_graph_edges",tn={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function nn(e){var t;return(t=tn[e])!=null?t:[]}function on(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function rn(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var sn=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function an(e){return sn.has(e)?e:"generic"}function Le(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch(t){return"/"}}function cn(e,t,n){let r=`${e}:${t}:${n.join(",")}`,u=5381;for(let l=0;l<r.length;l++)u=(u<<5)+u+r.charCodeAt(l)&4294967295;return(u>>>0).toString(16).padStart(8,"0")}function rt(e){let t=new Map,n=new Map,r=`_snt_graph_nodes${oe(e==null?void 0:e.apiKey)}`,u=()=>{typeof window!="undefined"&&rn(r,[...t.values()])},l=i=>{var d;try{let s=JSON.parse(i);t.clear();for(let o of(d=s.pageNodes)!=null?d:[])t.set(o.componentId,o)}catch(s){}};if(typeof window!="undefined"){let i=on(r,[]);for(let d of i)t.set(d.componentId,d);try{localStorage.removeItem(ot)}catch(d){}}return{addPageNode(i){t.set(i.componentId,i),u()},addStructuralEdge(i){let d=`${i.fromComponentId}->${i.toComponentId}`;n.set(d,i)},syncOnce(){var d,s;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let i=[...t.values()];if(i.length!==0)try{let o=new Map;for(let m of i){let v=(d=o.get(m.semanticType))!=null?d:[];v.push(m),o.set(m.semanticType,v)}let a=[],c=new Set;for(let m of i)for(let v of nn(m.semanticType)){let T=(s=o.get(v))!=null?s:[];for(let E of T){if(E.componentId===m.componentId)continue;let _=`semantic:${m.componentId}->${E.componentId}`;c.has(_)||(c.add(_),a.push({fromComponentId:m.componentId,toComponentId:E.componentId,type:"semantic",weight:.4,confidence:.9}))}}let f=new Set(i.map(m=>m.componentId));for(let m of n.values()){if(!f.has(m.fromComponentId)||!f.has(m.toComponentId))continue;let v=`structural:${m.fromComponentId}->${m.toComponentId}`;c.has(v)||(c.add(v),a.push({fromComponentId:m.fromComponentId,toComponentId:m.toComponentId,type:"structural",weight:m.weight,confidence:1}))}let g=X(b(b({pageUrl:Le(window.location.href)},e.sessionId?{sessionId:e.sessionId}:{}),e.projectId?{projectId:e.projectId}:{}),{nodes:i.map(m=>{let v=an(m.semanticType);return{componentId:m.componentId,semanticType:v,answers:m.answers,contentHash:cn(m.componentId,v,m.answers),prominenceScore:m.prominenceScore,depthInPage:m.depth}}),edges:a});fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:b({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(g)}).catch(()=>{})}catch(o){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:l,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(r),localStorage.removeItem(ot)}catch(i){}}}}var st=["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"],dn=[["pricing",/\b(pricing|price|plans?|subscriptions?|per month|\/mo|tier)\b/i],["faq",/\b(faq|frequently asked|common questions?)\b/i],["comparison",/\b(compare|comparison|versus|vs\.)\b/i],["social_proof",/\b(testimonial|reviews?|trusted by|loved by|customers?|logos|rated|case stud)\b/i],["trust",/\b(security|guarantee|privacy|compliance|secure|gdpr|soc ?2|encrypt)\b/i],["features",/\b(features?|how it works|benefits?|capabilit|what you get)\b/i]],ln=[["pricing",/(?:[$€£]\s?\d[\d,.]*\s*(?:\/|per\s)\s*(?:mo|month|yr|year|seat|user))|(?:\b(?:starter|basic|pro|growth|premium|enterprise)\b[^.]{0,60}[$€£]\s?\d)/i],["social_proof",/(?:★{2,})|(?:\b\d(?:\.\d)?\s*(?:out of|\/)\s*5\b)|(?:\brated\b)|(?:["“][^"”]{20,160}["”]\s*[—–-]\s*[A-Z][a-z]+)/],["trust",/\b(?:money[- ]back guarantee|refund(?:s)? within|encrypted|soc ?2|iso ?27001|gdpr[- ]compliant|cancel anytime)\b/i],["comparison",/\b(?:vs|versus)\b\.?[^.!?]{0,80}\b(?:compare|comparison|plans?|features?|alternative)\b|\bhow (?:we|it) compares?\b/i]];function un(e){var n;let t=e.querySelector("h1, h2, h3");return((n=t==null?void 0:t.textContent)!=null?n:"").slice(0,160)}function pn(e){if(e.tag==="nav"||e.tag==="footer")return{type:"navigation",strength:"weak"};let t=`${e.idClass} ${e.headingText}`.toLowerCase();for(let[n,r]of dn)if(r.test(t))return{type:n,strength:"strong"};for(let[n,r]of ln)if(r.test(e.bodyText))return{type:n,strength:"strong"};return e.actionCount>=1&&e.textLength>0&&e.textLength<200?{type:"cta",strength:"weak"}:e.tag==="header"?{type:"hero",strength:"weak"}:/\b(hero|headline|banner)\b/i.test(t)?{type:"hero",strength:"weak"}:{type:"generic",strength:"weak"}}function gn(e){var n,r;let t=((n=e.textContent)!=null?n:"").replace(/\s+/g," ").trim();return{tag:e.tagName.toLowerCase(),idClass:`${e.id} ${String((r=e.className)!=null?r:"")}`,headingText:un(e),bodyText:t.slice(0,2e3),actionCount:e.querySelectorAll('a, button, [role="button"]').length,textLength:t.length}}function it(e){return pn(gn(e)).type}var fn=new Set(["SECTION","ARTICLE","MAIN","DIV"]),mn="h1, h2, h3",at=30,yn=1500,hn={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function ct(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function Sn(e){var t,n,r;try{let u=e;for(let l of Object.keys(u)){if(!l.startsWith("__reactFiber")&&!l.startsWith("__reactInternalInstance"))continue;let i=u[l],d=(r=(t=i==null?void 0:i.type)==null?void 0:t.displayName)!=null?r:(n=i==null?void 0:i.type)==null?void 0:n.name;if(d&&d.length>1)return d}}catch(u){}}function vn(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}var dt=new Set(st);function wn(e){let t=e.getAttribute("data-sentient-type");if(t&&dt.has(t))return t;let n=e.getAttribute("role");return n&&dt.has(n)?n:it(e)}function bn(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)&4294967295;return(t>>>0).toString(16).padStart(8,"0")}function In(e){let t=[],n=e;for(;n;){let r=n.parentElement;if(!r){t.push(n.tagName.toLowerCase());break}let u=Array.prototype.indexOf.call(r.children,n);t.push(`${n.tagName.toLowerCase()}[${u}]`),n=r}return t.reverse().join("/")}function xn(e){var n;let t=(n=e.getAttribute("data-sentient-id"))!=null?n:e.getAttribute("id");return t||`${e.tagName.toLowerCase()}-${bn(In(e))}`}function En(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function Ge(e,t){var r,u,l;let n=e.querySelector(mn);return{componentId:xn(e),semanticType:wn(e),ariaLabel:(r=e.getAttribute("aria-label"))!=null?r:void 0,headingText:(l=(u=n==null?void 0:n.textContent)==null?void 0:u.trim())!=null?l:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:En(e),reactComponentName:Sn(e),dataAttributes:vn(e)}}function lt(e){var l;let t=[],n=new Set,r="__root__",u=new Map;for(let[i,d]of e){let s=i.parentElement,o=r;for(;s;){if(e.has(s)){o=e.get(s);let c=e.get(i),f=`${o}->${c}`;!n.has(f)&&o!==c&&(n.add(f),t.push({fromComponentId:o,toComponentId:c,weight:.6}));break}s=s.parentElement}let a=(l=u.get(o))!=null?l:[];a.push(i),u.set(o,a)}for(let i of u.values()){if(i.length<2)continue;let d=i.length>at?i.slice(0,at):i;for(let s=0;s<d.length;s++)for(let o=s+1;o<d.length;o++){if(t.length>=yn)return t;let a=e.get(d[s]),c=e.get(d[o]);if(a===c)continue;let f=`${a}->${c}::sib`,g=`${c}->${a}::sib`;n.has(f)||(n.add(f),t.push({fromComponentId:a,toComponentId:c,weight:.3})),n.has(g)||(n.add(g),t.push({fromComponentId:c,toComponentId:a,weight:.3}))}}return t}function Cn(e){let t=[],n=new Set,r=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(i=>{if(i instanceof Element&&!n.has(i)){n.add(i);let d=Ge(i,e);t.push(d),r.set(i,d.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(i=>{if(!(i instanceof Element)||n.has(i))return;let d=i.hasAttribute("aria-label"),s=i.hasAttribute("data-sentient-id");if(!d&&!s)return;n.add(i);let o=Ge(i,e);t.push(o),r.set(i,o.componentId)}),{nodes:t,edges:lt(r),elementToId:r}}function ut(){if(typeof window=="undefined")return hn;let e=null,t=0,n=null,r=new Map,u=s=>{try{let o=window.getComputedStyle(s),a=parseFloat(o.fontSize)||12,c=parseFloat(o.zIndex)||0,f=s.getBoundingClientRect(),g=Math.max(f.top,0),m=window.innerHeight||1,v=1/(g/m+1),T=ct(a,12,48)*.4+v*.4+ct(c,0,100)*.2;return Math.max(0,Math.min(1,T))}catch(o){return .5}};return{scan:()=>new Promise(s=>{let o=()=>{let{nodes:a,edges:c,elementToId:f}=Cn(u);r.clear();for(let[g,m]of f)r.set(g,m);s({nodes:a,edges:c,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(o,{timeout:100}):o()}catch(a){o()}}),observe:s=>{n=s;try{e=new MutationObserver(o=>{let a=[],c=new Set;for(let g of o)g.type==="childList"&&g.addedNodes.forEach(m=>{if(!(m instanceof Element)||!fn.has(m.tagName))return;let v=m.hasAttribute("data-sentient-id"),T=m.hasAttribute("aria-label");if(!v&&!T)return;let E=Ge(m,u);a.push(E),c.add(E.componentId),r.set(m,E.componentId)});if(a.length===0||!n)return;for(let g of[...r.keys()])g.isConnected||r.delete(g);let f=lt(r).filter(g=>c.has(g.fromComponentId)||c.has(g.toComponentId));n({nodes:a,edges:f,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(o){}},getProminenceScore:u,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(s){}t=0,n=null,r.clear()}}}var Tn="https://api.sentient-ui.com/v1/events";function An(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}var Ae=new Map;function kn(e){var c;let t=nt(e),n=e.respectDoNotTrack!==!1&&Me(),r=e.consent===!1||n;if(!e.graph||!e.apiKey||r||typeof window=="undefined")return t;let u=Ae.get(e.apiKey);if(u)try{u()}catch(f){}let l=ut(),i=(c=e.ingestUrl)!=null?c:Tn,d=rt({syncUrl:i.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:An()});l.scan().then(f=>{for(let g of f.nodes)d.addPageNode({id:g.componentId,componentId:g.componentId,semanticType:g.semanticType,answers:e.captureDomText&&g.headingText?[g.headingText]:[],prominenceScore:g.prominenceScore,depth:g.depth});for(let g of f.edges)d.addStructuralEdge(g);d.syncOnce()});let s=null,o=()=>{s!==null&&clearTimeout(s),s=setTimeout(()=>{s=null,d.syncOnce()},500)};l.observe(f=>{for(let g of f.nodes)d.addPageNode({id:g.componentId,componentId:g.componentId,semanticType:g.semanticType,answers:e.captureDomText&&g.headingText?[g.headingText]:[],prominenceScore:g.prominenceScore,depth:g.depth});for(let g of f.edges)d.addStructuralEdge(g);o()});let a=()=>{s!==null&&(clearTimeout(s),s=null),l.destroy(),d.destroy(),Ae.get(e.apiKey)===a&&Ae.delete(e.apiKey)};return Ae.set(e.apiKey,a),X(b({},t),{getGraph:()=>d.snapshot(),dispose:()=>{a(),t.dispose()},destroy:()=>{a(),t.destroy()}})}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,referrerDomainFromReferer,sanitizePageUrl});
1
+ "use strict";var Ot=Object.create;var ve=Object.defineProperty,Dt=Object.defineProperties,Nt=Object.getOwnPropertyDescriptor,Pt=Object.getOwnPropertyDescriptors,Lt=Object.getOwnPropertyNames,Ye=Object.getOwnPropertySymbols,Bt=Object.getPrototypeOf,Ze=Object.prototype.hasOwnProperty,Mt=Object.prototype.propertyIsEnumerable;var Xe=(e,t,n)=>t in e?ve(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,w=(e,t)=>{for(var n in t||(t={}))Ze.call(t,n)&&Xe(e,n,t[n]);if(Ye)for(var n of Ye(t))Mt.call(t,n)&&Xe(e,n,t[n]);return e},j=(e,t)=>Dt(e,Pt(t));var Kt=(e,t)=>{for(var n in t)ve(e,n,{get:t[n],enumerable:!0})},et=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of Lt(t))!Ze.call(e,u)&&u!==n&&ve(e,u,{get:()=>t[u],enumerable:!(i=Nt(t,u))||i.enumerable});return e};var Gt=(e,t,n)=>(n=e!=null?Ot(Bt(e)):{},et(t||!e||!e.__esModule?ve(n,"default",{value:e,enumerable:!0}):n,e)),Ut=e=>et(ve({},"__esModule",{value:!0}),e);var ro={};Kt(ro,{BLOCK_ALIGNS:()=>ln,BLOCK_EMPHASES:()=>fn,BLOCK_FITS:()=>hn,BLOCK_GAPS:()=>cn,BLOCK_GRID_COLUMNS:()=>Sn,BLOCK_HEADING_LEVELS:()=>bn,BLOCK_JUSTIFIES:()=>dn,BLOCK_RATIOS:()=>yn,BLOCK_SIZES:()=>un,BLOCK_TEXT_ALIGNS:()=>mn,BLOCK_TONES:()=>gn,BLOCK_WEIGHTS:()=>pn,LEGACY_SESSION_COOKIE_NAME:()=>we,MAX_BLOCK_ARMS:()=>xn,MAX_BLOCK_CHILDREN:()=>En,MAX_BLOCK_DEPTH:()=>wn,MAX_BLOCK_NODES:()=>vn,MAX_BLOCK_TEXT_LEN:()=>Cn,SNAPSHOT_STORAGE_KEY_PREFIX:()=>oe,armOfResult:()=>Ne,attachMicroSignalDetectors:()=>ft,baselineResultFor:()=>fe,baselineSlots:()=>lt,deriveSessionSegment:()=>$e,detectDeviceClass:()=>le,detectTimeOfDay:()=>pe,detectTrafficSource:()=>de,grantConsent:()=>vt,init:()=>Rt,isDoNotTrackEnabled:()=>Ce,readSnapshot:()=>me,referrerDomainFromReferer:()=>ue,renderPrePaintScript:()=>dt,sanitizePageUrl:()=>ze,sessionCookieName:()=>ae,toWireSlot:()=>Ee,writeSnapshot:()=>ye});module.exports=Ut(ro);function ke(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}try{if(typeof crypto!="undefined"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t="";for(let n=0;n<16;n++)t+=e[n].toString(16).padStart(2,"0"),(n===3||n===5||n===7||n===9)&&(t+="-");return t}}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function ne(e){return e?`_${e.slice(0,12)}`:""}var we="_snt_uid";function ae(e){return`${we}${ne(e)}`}var $t="_snt_uid",Ft=365,Te="_snt_uid";function jt(){return ke()}function tt(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function Wt(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(i){}}function Ke(e){try{return localStorage.getItem(e)}catch(t){return null}}function nt(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ot(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function Ht(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function zt(e){try{sessionStorage.removeItem(e)}catch(t){}}function qt(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function Qt(e){try{localStorage.removeItem(e)}catch(t){}}function Jt(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Vt={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function Ae(e){var m,S,E,v,G,$,_;if(typeof window=="undefined")return Vt;let t=ne(e==null?void 0:e.apiKey),n=(m=e==null?void 0:e.cookieName)!=null?m:ae(e==null?void 0:e.apiKey),i=`${Te}${t}`,u=`${Te}_tomb${t}`,a=((S=e==null?void 0:e.cookieTTLDays)!=null?S:Ft)*24*60*60,l=C=>C&&C.length>0?C:null,d=()=>{var C,N;return t&&!(e!=null&&e.cookieName)&&Ke(u)===null?(N=(C=l(tt($t)))!=null?C:l(Ke(Te)))!=null?N:l(ot(Te)):null},r=(_=($=(G=(v=(E=l(tt(n)))!=null?E:l(Ke(i)))!=null?v:l(ot(i)))!=null?G:d())!=null?$:l(e==null?void 0:e.ssrSessionId))!=null?_:jt();Wt(n,r,a);let o=nt(i,r),s=qt(n),f=o?!1:Ht(i,r),p=!o&&!s&&!f;return{getSessionId:()=>r,isEphemeral:()=>p,destroy:()=>{r=null,Jt(n),Qt(i),zt(i),t&&!(e!=null&&e.cookieName)&&nt(u,"1")}}}function Y(e){return Math.min(6e4,1e3*2**Math.min(e,6))}function ce(e){if(e.ok===!0)return"delivered";let{status:t}=e;return typeof t!="number"?"retry":t>=200&&t<300?"delivered":t>=400&&t<500&&t!==429?"dropped":"retry"}function _e(e,t){try{let n=localStorage.getItem(e);if(!n)return[];let i=JSON.parse(n);return Array.isArray(i)?(localStorage.removeItem(e),i.slice(-t)):[]}catch(n){return[]}}function X(e,t,n){try{let i=(()=>{try{let c=localStorage.getItem(n);if(!c)return[];let a=JSON.parse(c);return Array.isArray(a)?a:[]}catch(c){return[]}})(),u=new Map;for(let c of i)u.set(c.id,c);for(let c of e)u.set(c.id,c);localStorage.setItem(n,JSON.stringify([...u.values()].slice(-t)))}catch(i){}}function Re(e,t){try{let n=localStorage.getItem(t);if(!n)return;let i=JSON.parse(n);if(!Array.isArray(i))return;let u=new Set(e),c=i.filter(a=>!u.has(a.id));if(c.length===i.length)return;c.length===0?localStorage.removeItem(t):localStorage.setItem(t,JSON.stringify(c))}catch(n){}}var Yt=500,Xt=56*1024;function Ge(e){return`_snt_retry_${e.slice(0,12)}`}var Zt={push:()=>{},flush:()=>{},destroy:()=>{}};function rt(e){var Z,B,re;if(typeof window=="undefined")return Zt;let t=(Z=e.flushIntervalMs)!=null?Z:5e3,n=(B=e.maxBatchSize)!=null?B:20,i=(re=e.maxRetrySize)!=null?re:100,u=e.ingestUrl,c=e.apiKey,a=Ge(c),l=[],d=new Set,r=[],o=h=>{for(let k of h)s.delete(k),!d.has(k)&&(d.add(k),r.push(k));for(;r.length>Yt;){let k=r.shift();k&&d.delete(k)}Re(h,a)},s=new Set,f=()=>{for(;l.length>i;){let h=l.shift();h&&s.delete(h.id)}},p=h=>{d.has(h.id)||s.has(h.id)||(s.add(h.id),l.push(h),f())},m=h=>{for(let k of h)d.has(k.id)||(s.add(k.id),l.push(k));f()},S=_e(a,i);for(let h of S)p(h);let E=0,v=0,G=(h,k=!0)=>{if(h.length===0)return;let H=JSON.stringify(h),ee=h.map(q=>q.id),F;try{F=fetch(u,{method:"POST",keepalive:!0,body:H,headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`}})}catch(q){X(h,i,a),m(h),v++,E=Date.now()+Y(v);return}let he=q=>{if(ce(q)!=="retry"){if(!q.ok&&k){let se=h.filter(Q=>Q.eventType!=="pageview");if(se.length>0&&se.length<h.length){o(h.filter(Q=>Q.eventType==="pageview").map(Q=>Q.id)),G(se,!1);return}}o(ee),v=0,E=0;return}X(h,i,a),m(h),v++,E=Date.now()+Y(v)};F instanceof Promise?F.then(he).catch(()=>{X(h,i,a),m(h),v++,E=Date.now()+Y(v)}):he(F)},$=typeof TextEncoder!="undefined"?new TextEncoder:null,_=h=>$?$.encode(h).length:h.length,C=h=>{let k=[],H=2;for(let ee of h){let F=_(JSON.stringify(ee))+1;if(k.length>0&&H+F>Xt||k.length>=n)break;k.push(ee),H+=F}return k},N=()=>{try{if(Date.now()<E)return;for(;l.length>0&&!(Date.now()<E);){let h=l.filter(H=>!d.has(H.id));if(l.length=0,h.length===0)break;let k=C(h);if(k.length===0)break;k.length<h.length&&l.push(...h.slice(k.length)),G(k)}}catch(h){}},b=!0,O=null;O=setInterval(()=>{b&&N()},t);let L=()=>{document.visibilityState==="hidden"&&N()},W=()=>{N()};return document.addEventListener("visibilitychange",L),window.addEventListener("pagehide",W),{push(h){p(h),l.length>=n&&N()},flush:N,destroy(){b=!1,O!==null&&(clearInterval(O),O=null),document.removeEventListener("visibilitychange",L),window.removeEventListener("pagehide",W),N()}}}var en=200;function Ue(e){return`_snt_goal_retry_${e.slice(0,12)}`}var tn={send:()=>{},flush:()=>{},destroy:()=>{}};function st(e){var _,C,N;if(typeof window=="undefined")return tn;let t=(_=e.flushIntervalMs)!=null?_:5e3,n=(C=e.maxRetrySize)!=null?C:100,i=(N=e.maxPerFlush)!=null?N:5,u=Ue(e.apiKey),c=[],a=new Set,l=new Set,d=[],r=0,o=0,s=!1,f=b=>{for(a.delete(b.id),l.has(b.id)||(l.add(b.id),d.push(b.id));d.length>en;){let O=d.shift();O&&l.delete(O)}Re([b.id],u)},p=b=>{X([b],n,u),!l.has(b.id)&&!a.has(b.id)&&(a.add(b.id),c.push(b)),Date.now()>=r&&(o++,r=Date.now()+Y(o))},m=b=>{let O;try{O=fetch(e.url,{method:"POST",keepalive:!0,body:b.body,headers:e.headers})}catch(W){p(b);return}let L=W=>{var B;let Z=ce(W);if(Z==="retry"){p(b);return}Z==="dropped"&&((B=e.onDrop)==null||B.call(e,b,W.status)),f(b),o=0,r=0};O instanceof Promise?O.then(L).catch(()=>p(b)):L(O)},S=()=>{try{if(s||Date.now()<r)return;let b=0;for(;c.length>0&&b<i&&!(Date.now()<r);){let O=c.shift();a.delete(O.id),!l.has(O.id)&&(b++,m(O))}}catch(b){}},E=_e(u,n);for(let b of E)a.has(b.id)||(a.add(b.id),c.push(b));E.length>0&&X(E,n,u);let v=setInterval(S,t),G=()=>{document.visibilityState==="hidden"&&S()},$=()=>S();return document.addEventListener("visibilitychange",G),window.addEventListener("pagehide",$),{send(b){if(!s&&!(l.has(b.id)||a.has(b.id))){if(Date.now()<r){X([b],n,u),a.add(b.id),c.push(b);return}m(b)}},flush:S,destroy(){clearInterval(v),document.removeEventListener("visibilitychange",G),window.removeEventListener("pagehide",$),S(),s=!0}}}var nn=1800*1e3;function Oe(e,t){return`${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function it(e=nn,t){let n=new Map,i=`_snt_asgn${ne(t)}_`,u=(r,o)=>`${i}${encodeURIComponent(r)}:${encodeURIComponent(o)}`,c=r=>{let o=r.slice(i.length),s=o.indexOf(":");if(s<0)return null;try{return{componentId:decodeURIComponent(o.slice(0,s)),segment:decodeURIComponent(o.slice(s+1))}}catch(f){return null}},a=()=>{try{let r=[];for(let o=0;o<localStorage.length;o++){let s=localStorage.key(o);s!=null&&s.startsWith(i)&&r.push(s)}return r}catch(r){return[]}},l=r=>r.assignedAt+(r.ttlMs&&r.ttlMs>0?r.ttlMs:e)<Date.now();return typeof window!="undefined"&&(()=>{for(let r of a())try{let o=localStorage.getItem(r);if(!o)continue;let s=JSON.parse(o);if(l(s)){localStorage.removeItem(r);continue}let f=c(r);if(!f)continue;n.set(Oe(f.componentId,f.segment),s)}catch(o){}})(),{get(r,o){let s=n.get(Oe(r,o));return s?l(s)?(n.delete(Oe(r,o)),null):s:null},set(r,o,s){let f=Oe(r,o);n.set(f,s);try{localStorage.setItem(u(r,o),JSON.stringify(s))}catch(p){}},clear(){n.clear();for(let r of a())try{localStorage.removeItem(r)}catch(o){}}}}var at=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function De(e){return ct(e)!==null}function ct(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=at.find(i=>t.includes(i.toLowerCase())))!=null?n:null}function le(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function de(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(u){}let i=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(i)?"search":/(^|\.)(twitter\.com|x\.com|facebook\.com|linkedin\.com|reddit\.com|t\.co)$/.test(i)?"social":"referral"}catch(n){return"direct"}}function ue(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function pe(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function $e(e){let t=on("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function on(e,t){var c,a,l,d,r,o,s;let n=(a=(c=t==null?void 0:t.userAgent)==null?void 0:c.trim())!=null?a:"",i=(d=(l=t==null?void 0:t.referer)==null?void 0:l.trim())!=null?d:"",u=(r=t==null?void 0:t.now)!=null?r:new Date;return{sessionId:e,ephemeral:!1,utmParams:(o=t==null?void 0:t.utmParams)!=null?o:{},deviceClass:n?le(n):"desktop",trafficSource:i?de(i,t==null?void 0:t.appOrigin):"direct",referrerDomain:ue(i),timeOfDay:pe(u),dayOfWeek:(s=["sun","mon","tue","wed","thu","fri","sat"][u.getDay()])!=null?s:"sun",automation:(t==null?void 0:t.webdriver)===!0||De(n)}}var ge=require("@sentientui/policy");function Ee(e){return w(w(w({id:e.id},e.arms?{arms:[...e.arms]}:{}),e.dims?{dims:Object.fromEntries(Object.entries(e.dims).map(([t,n])=>[t,[...n]]))}:{}),e.baseline!==void 0?{baseline:e.baseline}:{})}function fe(e){let t=Ee(e);return(0,ge.slotResultFor)(t,(0,ge.slotBaselineArm)(t))}function lt(e){let t={};for(let n of e)t[n.id]=fe(n);return t}function Ne(e){return typeof e=="string"?e:(0,ge.canonicalArm)(e)}var oe="_snt_snap:",rn=["low","medium","high"];function me(e){try{let t=localStorage.getItem(oe+e);if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"||n.v!==1||typeof n.persona!="string"||typeof n.band!="string"||!rn.includes(n.band)||typeof n.slots!="object"||n.slots===null||Array.isArray(n.slots)||!(n.layoutOrder===null||Array.isArray(n.layoutOrder))||typeof n.savedAt!="number"||!(n.slotConfig===void 0||typeof n.slotConfig=="object"&&n.slotConfig!==null&&!Array.isArray(n.slotConfig))?null:n}catch(t){return null}}function ye(e,t){try{localStorage.setItem(oe+e,JSON.stringify(t))}catch(n){}}function dt(e){return"(function(){try{var r=localStorage.getItem("+JSON.stringify(oe+e).replace(/</g,"\\u003c")+');if(!r)return;var s=JSON.parse(r);if(!s||s.v!==1||typeof s.persona!=="string"||typeof s.band!=="string")return;var d=document.documentElement;if(d.hasAttribute("data-sentient-persona"))return;d.setAttribute("data-sentient-persona",s.persona);d.setAttribute("data-sentient-confidence",s.band);}catch(e){}})();'}var je=require("@sentientui/policy");var Le=require("@sentientui/policy");var ut="[sentient] No API key configured \u2014 nothing is being learned. Set NEXT_PUBLIC_SENTIENT_API_KEY or pass localMode: true for local development.",sn="[sentient] Local mode \u2014 decisions are simulated on-device and nothing is sent over the network. Add an API key to learn from real traffic.",pt=!1,Pe=!1;function an(){var e;try{return(e=new URLSearchParams(window.location.search).get("sentient_persona"))!=null?e:void 0}catch(t){return}}function gt(e){var r;let t=Ae({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),n=(r=t.getSessionId())!=null?r:"local",i=an(),u=import("@sentientui/core/local").then(o=>{let s=o;return s.LOCAL_ENGINE_AVAILABLE?(pt||(pt=!0,console.info(sn)),s):(Pe||(Pe=!0,console.error(ut)),null)}).catch(()=>(Pe||(Pe=!0,console.error(ut)),null)),c=null,a={low:.15,medium:.5,high:.85},l=(()=>{var s;if(e.initialPersona)return w({},e.initialPersona);let o=me(e.apiKey||"local");return o?{persona:o.persona,confidence:(s=a[o.band])!=null?s:.15}:null})();function d(o){let s=document.documentElement;s.dataset.sentientPersona===void 0&&(s.dataset.sentientPersona=o.persona,s.dataset.sentientConfidence=(0,Le.confidenceBand)(o.confidence))}return{isLocal:!0,async decide(o){var p,m,S;let s=await u;if(!s)return null;let f=s.createLocalEngine({sessionId:n,forcedPersona:i}).decide(o);return c=j(w({},f),{layoutOrder:(m=(p=f.layoutOrder)!=null?p:c==null?void 0:c.layoutOrder)!=null?m:null,slots:w(w({},(S=c==null?void 0:c.slots)!=null?S:{}),f.slots)}),ye(e.apiKey||"local",{v:1,persona:c.persona,band:(0,Le.confidenceBand)(c.confidence),slots:c.slots,layoutOrder:c.layoutOrder,savedAt:Date.now()}),d(f),f},getSlotResult(o){var s,f,p;return(p=(f=c==null?void 0:c.slots[o])!=null?f:(s=e.initialSlots)==null?void 0:s[o])!=null?p:null},getPersona(){let o=c!=null?c:l;return o?{persona:o.persona,confidence:o.confidence,band:(0,Le.confidenceBand)(o.confidence)}:null},async assign(o,s){var m;let f=await u;return!f||!s||s.length===0?s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null:{variantId:(m=f.createLocalEngine({sessionId:n,forcedPersona:i}).decide({components:[{id:o,variantIds:s}]}).assignments[o])!=null?m:s[0],assignmentTtlMs:0}},track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>t.destroy()}}var cn=["none","sm","md","lg"],ln=["start","center","end","stretch"],dn=["start","center","end","between"],un=["sm","md","lg"],pn=["normal","medium","bold"],gn=["default","muted","accent"],fn=["primary","secondary","ghost"],mn=["left","center","right"],yn=["auto","square","landscape","wide"],hn=["cover","contain"],Sn=[2,3,4],bn=[2,3,4],vn=64,wn=5,En=12,xn=4,Cn=500;function ft(e,t,n,i){let u=[];{let l=!1,d=[],r=()=>{if(l)return;let o=Date.now();for(d.push(o);d.length>0&&o-d[0]>500;)d.shift();d.length>=3&&(l=!0,e("rage_click"))};t.addEventListener("click",r),u.push(()=>t.removeEventListener("click",r))}{let c=!1,a=l=>{if(c||!(l.target instanceof Node)||!t.contains(l.target)&&t!==l.target)return;c=!0;let d=typeof window!="undefined"?window.getSelection():null,r=d?d.toString().length:0;e("text_copy",{selectionLength:r})};document.addEventListener("copy",a),u.push(()=>document.removeEventListener("copy",a))}{let c=!1,a=!1,l=null,d=()=>{l!==null&&(clearTimeout(l),l=null)},r=()=>{c||!a||(d(),l=setTimeout(()=>{!c&&a&&(c=!0,e("scroll_hesitation"))},3e3))},o=()=>{d(),r()},s=p=>{for(let m of p)a=m.intersectionRatio>.3,a?r():d()},f=new IntersectionObserver(s,{threshold:[.3]});f.observe(t),window.addEventListener("scroll",o,{passive:!0}),u.push(()=>{f.disconnect(),window.removeEventListener("scroll",o),d()})}if((i==null?void 0:i.tabLoss)!==!1){let c=!1,a=n!=null?n:Date.now(),l=()=>{if(c||document.visibilityState!=="hidden")return;let d=Date.now()-a;d<15e3&&(c=!0,e("tab_loss",{timeOnPage:d}))};document.addEventListener("visibilitychange",l),u.push(()=>document.removeEventListener("visibilitychange",l))}return()=>{for(let c of u)c()}}var mt="https://api.sentient-ui.com/v1/events",K=new Map,yt=null;function ht(e,t){let n=K.get(e);n&&n.upgrade&&(n.reinit=t)}function In(e){return"value"in e||"currency"in e||"externalId"in e||"metadata"in e||"weight"in e||"stepIndex"in e}var kn=3;function Fe(){return ke()}function Be(){var e;if(typeof window!="undefined")return((e=window.location)==null?void 0:e.pathname)||void 0}function Tn(){let e=new WeakMap,t=new Map,n=!1,i=(l,d,r)=>{let o=l.get(d);return r===null?o?!0:(l.set(d,new Set),!1):o?o.has(r)?!0:(o.add(r),!1):(l.set(d,new Set([r])),!1)},u=typeof window!="undefined"&&"event"in window,c=()=>{if(!u)return;let l=window.event;return typeof Event=="function"&&l instanceof Event?l:void 0},a=()=>{if(u){Promise.resolve().then(()=>{n=!1,t.clear()});return}let l=!1,d=()=>{l||(l=!0,n=!1,t.clear())};if(setTimeout(d,0),typeof MessageChannel=="function"){let r=new MessageChannel;r.port1.onmessage=()=>{r.port1.close(),r.port2.close(),d()},r.port2.postMessage(0)}};return{firedBefore(l,d){let r=c();if(r){let s=e.get(r);return s||(s=new Map,e.set(r,s)),i(s,l,d)}let o=i(t,l,d);return!o&&!n&&(n=!0,a()),o}}}var St=new Set;function An(e,t,n){let i=typeof window=="undefined"?null:window.history;if(!i)return()=>{};let u=!1,c,a=()=>{if(u)return;let r=Be();!r||r===c||(c=r,e.track({projectId:t,componentId:"__page__",eventType:"pageview",payload:{}}),n(`${t}:${r}`))},l=[];for(let r of["pushState","replaceState"]){let o=i[r],s=function(...f){let p=o.apply(this,f);return a(),p};i[r]=s,l.push([r,o,s])}window.addEventListener("popstate",a);let d=Be();return d&&St.has(`${t}:${d}`)?c=d:a(),()=>{if(!u){u=!0,window.removeEventListener("popstate",a);for(let[r,o,s]of l)i[r]===s&&(i[r]=o)}}}var xe={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}};function _n(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,i]of t)n.startsWith("utm_")&&(e[n]=i);return e}catch(e){return{}}}function bt(e){return e.replace(/\/events\/?$/,"")}function Ce(){return typeof navigator!="undefined"&&navigator.globalPrivacyControl===!0?!0:[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function vt(e){var d;if(typeof window=="undefined")return;let t=e!=null?e:yt;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let n=K.get(t);if(!n){console.warn("[sentient] grantConsent() called before init()");return}let{config:i,upgrade:u,reinit:c}=n;if(!u){n.upgradeBlockedReason&&console.warn(n.upgradeBlockedReason);return}if(i.respectDoNotTrack!==!1&&Ce())return;let a=(c!=null?c:He)(j(w({},i),{consent:!0}));u(a);let l=(d=K.get(t))==null?void 0:d.dispose;K.set(t,{config:j(w({},i),{consent:!0}),upgrade:null,dispose:l})}function Rn(e){var r;let t=e.preConsentBehavior==="statistical_winner",n=bt((r=e.ingestUrl)!=null?r:mt),i={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u=new Map,c=new Map,a={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),assign(o,s,f){if(!t)return Promise.resolve(null);let p=u.get(o);return p?Promise.resolve(p):We(c,o,async()=>{try{let m=new URLSearchParams({componentId:o});for(let G of s!=null?s:[])m.append("variantIds[]",G);let S=await fetch(`${n}/winner?${m.toString()}`,{headers:i});if(!S.ok)return s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null;let v={variantId:(await S.json()).variantId,assignmentTtlMs:0};return u.set(o,v),v}catch(m){return s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}})},decide:()=>Promise.resolve(null),getSlotResult:()=>null,getPersona:()=>null,getGraph:()=>({pageNodes:[],capturedAt:0}),dispose:()=>{},destroy:()=>{}},l={track:o=>a.track(o),goal:((o,s,f,p)=>a.goal(o,s,f,p)),componentGoal:(o,s,f)=>a.componentGoal(o,s,f),identify:o=>a.identify(o),getAssignment:(o,s)=>a.getAssignment(o,s),assign:(o,s,f,p)=>a.assign(o,s,f,p),decide:o=>a.decide(o),getSlotResult:o=>a.getSlotResult(o),getPersona:()=>a.getPersona(),fetchWeights:()=>a.fetchWeights(),getGraph:()=>a.getGraph(),dispose:()=>a.dispose(),destroy:()=>a.destroy()};function d(o){a=o}return{proxy:l,setInner:d}}function We(e,t,n){let i=e.get(t);if(i)return i;let u=(async()=>{try{return await n()}finally{e.delete(t)}})();return e.set(t,u),u}function He(e){var k,H,ee,F,he,q,se,Q,Qe;if(typeof window=="undefined")return xe;yt=e.apiKey||"local";let t=K.get(e.apiKey||"local");if(t!=null&&t.dispose)try{t.dispose()}catch(g){}let n=e.respectDoNotTrack!==!1&&Ce(),i=e.consent===!1||n,u=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_");if(e.localMode===!0||!u&&e.localMode!==!1)return K.set(e.apiKey||"local",{config:e,upgrade:null,upgradeBlockedReason:"[sentient] grantConsent(): this client is keyless/local \u2014 there is no hosted client to upgrade to. Configure a pk_ API key to enable tracking."}),i?xe:gt(e);if(i){if(!e.apiKey||!e.apiKey.startsWith("pk_"))return e.preConsentBehavior==="statistical_winner"&&console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),K.set(e.apiKey||"local",{config:e,upgrade:null,upgradeBlockedReason:"[sentient] grantConsent(): the client was initialized with an invalid apiKey (expected a pk_ public key) \u2014 consent cannot enable tracking."}),xe;let{proxy:g,setInner:y}=Rn(e);return K.set(e.apiKey,{config:e,upgrade:n?null:y}),g}if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),xe;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),xe;let c=(k=e.ingestUrl)!=null?k:mt,a=Date.now(),l=Ae({ssrSessionId:e.ssrSessionId,apiKey:e.apiKey}),d=it(void 0,e.apiKey),r=rt({ingestUrl:c,apiKey:e.apiKey}),o=bt(c),s={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},f=new Set,p=st({url:`${o}/goals`,apiKey:e.apiKey,headers:s,onDrop:(g,y)=>{if(!e.debug){if(f.has(y))return;f.add(y)}console.warn(`[sentient] goal dropped (HTTP ${y}) \u2014 this will not be retried. `+(y===400?"The session was not found: call init() and let the session upsert complete before firing goals.":y===401||y===403?"Check the API key and that this origin is on the project allowlist.":"See the response status for the cause."),g)}}),m=le((H=navigator.userAgent)!=null?H:""),S=window.location.origin,E=de((ee=document.referrer)!=null?ee:"",S),v=(F=e.sessionSegment)!=null?F:`${m}:${E}`,G=new Map,$=new Map,_=new Map,C=null,N=g=>{for(let y of g)_.has(y.id)||_.set(y.id,fe(y))};if(e.initialSlots)for(let[g,y]of Object.entries(e.initialSlots))_.set(g,y);let b=me(e.apiKey);if(b)for(let[g,y]of Object.entries(b.slots))_.has(g)||_.set(g,y);let O={low:.15,medium:.5,high:.85};if(e.initialPersona)C=w({},e.initialPersona);else{let g=document.documentElement.dataset;g.sentientPersona?C={persona:g.sentientPersona,confidence:(q=O[(he=g.sentientConfidence)!=null?he:"low"])!=null?q:.15}:b&&(C={persona:b.persona,confidence:(se=O[b.band])!=null?se:.15})}if(e.initialAssignments)for(let[g,y]of Object.entries(e.initialAssignments))d.set(g,v,{variantId:y,assignedAt:Date.now(),segment:v,confidence:1});let L=Promise.resolve(),W=l.getSessionId();if(W){let g=ue((Q=document.referrer)!=null?Q:""),y=w(w(w({sessionId:W,deviceClass:m,trafficSource:E,referrerDomain:g,utmParams:_n(),timeOfDay:pe(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:l.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||De((Qe=navigator.userAgent)!=null?Qe:"")},e.userId?{userId:e.userId}:{}),e.persona?{persona:e.persona}:{}),e.country?{country:e.country}:{}),x=async()=>{for(let A=0;;A++){try{let R=await fetch(`${o}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(y),headers:s});if(R.status===402){console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");return}if(R.ok||ce(R)==="dropped")return}catch(R){}if(A>=kn){console.warn("[SentientUI] Could not register the session after retries. Conversions in this visit may not be recorded.");return}await new Promise(R=>setTimeout(R,Y(A+1)))}};try{L=x()}catch(A){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:r});let Z=Tn(),B=null,re=!1,h={goal(g,y={},x=1,A=0){var Se,be,ie,T,z,Ie,D;let R=l.getSessionId();if(!R)return;let I=In(y)?y:{metadata:y},M=[g,(Se=I.externalId)!=null?Se:"",(be=I.stepIndex)!=null?be:A,(ie=I.weight)!=null?ie:x].join("\0"),U=I.value!==void 0?`${I.value}\0${(T=I.currency)!=null?T:""}`:null;if(Z.firedBefore(M,U)){e.debug&&console.log(`[sentient] goal("${g}") already recorded for this action \u2014 not sent twice`);return}let P=Fe(),J={sessionId:R,name:g,metadata:(z=I.metadata)!=null?z:{},weight:(Ie=I.weight)!=null?Ie:x,stepIndex:(D=I.stepIndex)!=null?D:A,goalId:P,value:I.value,currency:I.currency,externalId:I.externalId};e.debug&&console.log("[sentient] goal",J);let te={id:P,body:JSON.stringify(J)};L.then(()=>p.send(te))},componentGoal(g,y,x){var P,J,te;let A=l.getSessionId();if(!A)return;let R=d.get(g,v),I=R?null:(P=_.get(g))!=null?P:null;if(!R&&I===null){e.debug&&console.warn(`[sentient] componentGoal("${g}"): no assignment or slot decision yet \u2014 render its <Adaptive>/adaptive hook or call assign()/decide() before recording a goal.`);return}let M=R?R.variantId:Ne(I),U={id:Fe(),sessionId:A,projectId:e.apiKey,componentId:g,variantId:M,eventType:"goal_achieved",goalType:y,payload:w({reward:(J=x==null?void 0:x.reward)!=null?J:1,goalValue:x==null?void 0:x.value,currency:x==null?void 0:x.currency},(te=x==null?void 0:x.metadata)!=null?te:{}),timestamp:Date.now(),timeInSession:Date.now()-a,path:Be()};e.debug&&console.log("[sentient] componentGoal",U),L.then(()=>r.push(U))},identify(g){let y=l.getSessionId();y&&L.then(()=>{fetch(`${o}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,userId:g,ephemeral:l.isEphemeral()}),headers:s}).catch(()=>{})})},track(g){let y=l.getSessionId();if(!y)return;let x=j(w({path:Be()},g),{id:Fe(),sessionId:y,timestamp:Date.now(),timeInSession:Date.now()-a});e.debug&&console.log("[sentient] track",x),L.then(()=>r.push(x))},getAssignment(g,y){return d.get(g,y)},async assign(g,y,x,A){let R=l.getSessionId();if(!R)return null;let I=d.get(g,v);if(I&&(y!=null&&y.length||I.content!==void 0)){let M=I.ttlMs&&I.ttlMs>0?Math.max(0,I.assignedAt+I.ttlMs-Date.now()):0;return{variantId:I.variantId,assignmentTtlMs:M,content:I.content}}return We(G,g,async()=>{await L;try{let M={sessionId:R,componentId:g,variantIds:y};A!==void 0?M.agentDataByVariant=A:x!==void 0&&(M.agentData=x);let U=await fetch(`${o}/assign`,{method:"POST",body:JSON.stringify(M),headers:s});if(!U.ok)return null;let P=await U.json();return d.set(g,v,w({variantId:P.variantId,assignedAt:Date.now(),segment:v,confidence:1,content:P.content},P.assignmentTtlMs&&P.assignmentTtlMs>0?{ttlMs:P.assignmentTtlMs}:{})),P}catch(M){return null}})},async decide(g){var I,M;let y=l.getSessionId();if(!y)return null;let x=(I=g.slots)!=null?I:[],A={sessionId:y};g.sections&&g.sections.length>0&&(A.sections=g.sections.map(U=>({id:U}))),A.components=(M=g.components)!=null?M:[],x.length>0&&(A.slots=x.map(Ee)),g.slotsFrom==="registry"&&(A.slotsFrom="registry"),g.v&&(A.v=g.v),e.persona&&(A.persona=e.persona);let R=JSON.stringify(A);return We($,R,async()=>{var U,P,J,te,Se,be;await L;try{let ie=await fetch(`${o}/decide`,{method:"POST",body:R,headers:s});if(!ie.ok)return N(x),null;let T=await ie.json(),z={};for(let D of x){let V=(U=T.slots)==null?void 0:U[D.id];if(V!==void 0){z[D.id]=V,_.set(D.id,V);continue}let Je=_.get(D.id);if(Je!==void 0)z[D.id]=Je;else{let Ve=fe(D);z[D.id]=Ve,_.set(D.id,Ve)}}if(T.slots)for(let[D,V]of Object.entries(T.slots))D in z||(z[D]=V,_.set(D,V));let Ie=C!=null&&C.persona!=="unknown";T.persona&&!(T.persona==="unknown"&&Ie)?C={persona:T.persona,confidence:(P=T.confidence)!=null?P:0}:C||(C={persona:"unknown",confidence:0});for(let[D,V]of Object.entries((J=T.assignments)!=null?J:{}))d.set(D,v,{variantId:V,assignedAt:Date.now(),segment:v,confidence:1});return ye(e.apiKey,w(w({v:1,persona:C.persona,band:(0,je.confidenceBand)(C.confidence),slots:Object.fromEntries(_),layoutOrder:(te=T.layoutOrder)!=null?te:null,savedAt:Date.now()},T.slotConfig?{slotConfig:T.slotConfig}:{}),T.palette?{palette:T.palette}:{})),w(w(w(w({layoutOrder:(Se=T.layoutOrder)!=null?Se:null,assignments:(be=T.assignments)!=null?be:{},slots:z,persona:C.persona,confidence:C.confidence},T.slotConfig?{slotConfig:T.slotConfig}:{}),T.goals?{goals:T.goals}:{}),T.sectionMap?{sectionMap:T.sectionMap}:{}),T.palette?{palette:T.palette}:{})}catch(ie){return N(x),null}})},getSlotResult(g){var y;return(y=_.get(g))!=null?y:null},getPersona(){return C?{persona:C.persona,confidence:C.confidence,band:(0,je.confidenceBand)(C.confidence)}:null},async fetchWeights(){var g;try{let y=await fetch(`${o}/weights`,{headers:s});return y.ok?(g=(await y.json()).components)!=null?g:[]:[]}catch(y){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},dispose(){var g;B==null||B(),re=!0,r.destroy(),p.destroy(),((g=K.get(e.apiKey))==null?void 0:g.dispose)===h.dispose&&K.delete(e.apiKey),e.debug&&console.log("[sentient] disposed")},destroy(){var g;B==null||B(),re=!0,r.destroy(),p.destroy(),l.destroy(),d.clear(),((g=K.get(e.apiKey))==null?void 0:g.dispose)===h.dispose&&K.delete(e.apiKey);try{localStorage.removeItem(oe+e.apiKey),localStorage.removeItem(Ge(e.apiKey)),localStorage.removeItem(Ue(e.apiKey))}catch(y){}e.debug&&console.log("[sentient] destroyed")}};if(K.set(e.apiKey,{config:e,upgrade:null,dispose:h.dispose}),B=An(h,e.apiKey,g=>{L.then(()=>{re||St.add(g)})}),e.debug){let g=window;g.__sentient&&(g.__sentient.client=h)}return h}var wt="_snt_graph_edges",On={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function Dn(e){var t;return(t=On[e])!=null?t:[]}function Nn(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function Pn(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var Ln=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function Bn(e){return Ln.has(e)?e:"generic"}function ze(e){try{let t=new URL(e);return`${t.origin}${t.pathname}`}catch(t){return"/"}}function Mn(e,t,n){let i=`${e}:${t}:${n.join(",")}`,u=5381;for(let c=0;c<i.length;c++)u=(u<<5)+u+i.charCodeAt(c)&4294967295;return(u>>>0).toString(16).padStart(8,"0")}function Et(e){let t=new Map,n=new Map,i=`_snt_graph_nodes${ne(e==null?void 0:e.apiKey)}`,u=()=>{typeof window!="undefined"&&Pn(i,[...t.values()])};if(typeof window!="undefined"){let c=Nn(i,[]);for(let a of c)t.set(a.componentId,a);try{localStorage.removeItem(wt)}catch(a){}}return{addPageNode(c){t.set(c.componentId,c),u()},addStructuralEdge(c){let a=`${c.fromComponentId}->${c.toComponentId}`;n.set(a,c)},syncOnce(){var a,l;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let c=[...t.values()];if(c.length!==0)try{let d=new Map;for(let p of c){let m=(a=d.get(p.semanticType))!=null?a:[];m.push(p),d.set(p.semanticType,m)}let r=[],o=new Set;for(let p of c)for(let m of Dn(p.semanticType)){let S=(l=d.get(m))!=null?l:[];for(let E of S){if(E.componentId===p.componentId)continue;let v=`semantic:${p.componentId}->${E.componentId}`;o.has(v)||(o.add(v),r.push({fromComponentId:p.componentId,toComponentId:E.componentId,type:"semantic",weight:.4,confidence:.9}))}}let s=new Set(c.map(p=>p.componentId));for(let p of n.values()){if(!s.has(p.fromComponentId)||!s.has(p.toComponentId))continue;let m=`structural:${p.fromComponentId}->${p.toComponentId}`;o.has(m)||(o.add(m),r.push({fromComponentId:p.fromComponentId,toComponentId:p.toComponentId,type:"structural",weight:p.weight,confidence:1}))}let f=j(w(w({pageUrl:ze(window.location.href)},e.sessionId?{sessionId:e.sessionId}:{}),e.projectId?{projectId:e.projectId}:{}),{nodes:c.map(p=>{let m=Bn(p.semanticType);return{componentId:p.componentId,semanticType:m,answers:p.answers,contentHash:Mn(p.componentId,m,p.answers),prominenceScore:p.prominenceScore,depthInPage:p.depth}}),edges:r});fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:w({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(f)}).catch(()=>{})}catch(d){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},destroy(){if(typeof window!="undefined")try{localStorage.removeItem(i),localStorage.removeItem(wt)}catch(c){}}}}var xt=["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"],Kn=[["pricing",/\b(pricing|price|plans?|subscriptions?|per month|\/mo|tier)\b/i],["faq",/\b(faq|frequently asked|common questions?)\b/i],["comparison",/\b(compare|comparison|versus|vs\.)\b/i],["social_proof",/\b(testimonial|reviews?|trusted by|loved by|customers?|logos|rated|case stud)\b/i],["trust",/\b(security|guarantee|privacy|compliance|secure|gdpr|soc ?2|encrypt)\b/i],["features",/\b(features?|how it works|benefits?|capabilit|what you get)\b/i]],Gn=[["pricing",/(?:[$€£]\s?\d[\d,.]*\s*(?:\/|per\s)\s*(?:mo|month|yr|year|seat|user))|(?:\b(?:starter|basic|pro|growth|premium|enterprise)\b[^.]{0,60}[$€£]\s?\d)/i],["social_proof",/(?:★{2,})|(?:\b\d(?:\.\d)?\s*(?:out of|\/)\s*5\b)|(?:\brated\b)|(?:["“][^"”]{20,160}["”]\s*[—–-]\s*[A-Z][a-z]+)/],["trust",/\b(?:money[- ]back guarantee|refund(?:s)? within|encrypted|soc ?2|iso ?27001|gdpr[- ]compliant|cancel anytime)\b/i],["comparison",/\b(?:vs|versus)\b\.?[^.!?]{0,80}\b(?:compare|comparison|plans?|features?|alternative)\b|\bhow (?:we|it) compares?\b/i]];function Un(e){var n;let t=e.querySelector("h1, h2, h3");return((n=t==null?void 0:t.textContent)!=null?n:"").slice(0,160)}function $n(e){if(e.tag==="nav"||e.tag==="footer")return{type:"navigation",strength:"weak"};let t=`${e.idClass} ${e.headingText}`.toLowerCase();for(let[n,i]of Kn)if(i.test(t))return{type:n,strength:"strong"};for(let[n,i]of Gn)if(i.test(e.bodyText))return{type:n,strength:"strong"};return e.actionCount>=1&&e.textLength>0&&e.textLength<200?{type:"cta",strength:"weak"}:e.tag==="header"?{type:"hero",strength:"weak"}:/\b(hero|headline|banner)\b/i.test(t)?{type:"hero",strength:"weak"}:{type:"generic",strength:"weak"}}function Fn(e){var n,i;let t=((n=e.textContent)!=null?n:"").replace(/\s+/g," ").trim();return{tag:e.tagName.toLowerCase(),idClass:`${e.id} ${String((i=e.className)!=null?i:"")}`,headingText:Un(e),bodyText:t.slice(0,2e3),actionCount:e.querySelectorAll('a, button, [role="button"]').length,textLength:t.length}}function Ct(e){return $n(Fn(e)).type}var jn=new Set(["SECTION","ARTICLE","MAIN","DIV","ASIDE"]),Wn="h1, h2, h3",Hn="[data-sentient-id], section[aria-label], article[aria-label], main[aria-label], aside[aria-label]",It=30,zn=1500,qn={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function kt(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function Qn(e){var t,n,i;try{let u=e;for(let c of Object.keys(u)){if(!c.startsWith("__reactFiber")&&!c.startsWith("__reactInternalInstance"))continue;let a=u[c],l=(i=(t=a==null?void 0:a.type)==null?void 0:t.displayName)!=null?i:(n=a==null?void 0:a.type)==null?void 0:n.name;if(l&&l.length>1)return l}}catch(u){}}function Jn(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}var Tt=new Set(xt);function Vn(e){let t=e.getAttribute("data-sentient-type");if(t&&Tt.has(t))return t;let n=e.getAttribute("role");return n&&Tt.has(n)?n:Ct(e)}function Yn(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)&4294967295;return(t>>>0).toString(16).padStart(8,"0")}function Xn(e){let t=[],n=e;for(;n;){let i=n.parentElement;if(!i){t.push(n.tagName.toLowerCase());break}let u=Array.prototype.indexOf.call(i.children,n);t.push(`${n.tagName.toLowerCase()}[${u}]`),n=i}return t.reverse().join("/")}function Zn(e){var n;let t=(n=e.getAttribute("data-sentient-id"))!=null?n:e.getAttribute("id");return t||`${e.tagName.toLowerCase()}-${Yn(Xn(e))}`}function eo(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function qe(e,t){var i,u,c;let n=e.querySelector(Wn);return{componentId:Zn(e),semanticType:Vn(e),ariaLabel:(i=e.getAttribute("aria-label"))!=null?i:void 0,headingText:(c=(u=n==null?void 0:n.textContent)==null?void 0:u.trim())!=null?c:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:eo(e),reactComponentName:Qn(e),dataAttributes:Jn(e)}}function At(e){var c;let t=[],n=new Set,i="__root__",u=new Map;for(let[a,l]of e){let d=a.parentElement,r=i;for(;d;){if(e.has(d)){r=e.get(d);let s=e.get(a),f=`${r}->${s}`;!n.has(f)&&r!==s&&(n.add(f),t.push({fromComponentId:r,toComponentId:s,weight:.6}));break}d=d.parentElement}let o=(c=u.get(r))!=null?c:[];o.push(a),u.set(r,o)}for(let a of u.values()){if(a.length<2)continue;let l=a.length>It?a.slice(0,It):a;for(let d=0;d<l.length;d++)for(let r=d+1;r<l.length;r++){if(t.length>=zn)return t;let o=e.get(l[d]),s=e.get(l[r]);if(o===s)continue;let f=`${o}->${s}::sib`,p=`${s}->${o}::sib`;n.has(f)||(n.add(f),t.push({fromComponentId:o,toComponentId:s,weight:.3})),n.has(p)||(n.add(p),t.push({fromComponentId:s,toComponentId:o,weight:.3}))}}return t}function to(e){let t=[],n=new Set,i=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(a=>{if(a instanceof Element&&!n.has(a)){n.add(a);let l=qe(a,e);t.push(l),i.set(a,l.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(a=>{if(!(a instanceof Element)||n.has(a))return;let l=a.hasAttribute("aria-label"),d=a.hasAttribute("data-sentient-id");if(!l&&!d)return;n.add(a);let r=qe(a,e);t.push(r),i.set(a,r.componentId)}),{nodes:t,edges:At(i),elementToId:i}}function _t(){if(typeof window=="undefined")return qn;let e=null,t=0,n=null,i=new Map,u=d=>{try{let r=window.getComputedStyle(d),o=parseFloat(r.fontSize)||12,s=parseFloat(r.zIndex)||0,f=d.getBoundingClientRect(),p=Math.max(f.top,0),m=window.innerHeight||1,S=1/(p/m+1),E=kt(o,12,48)*.4+S*.4+kt(s,0,100)*.2;return Math.max(0,Math.min(1,E))}catch(r){return .5}};return{scan:()=>new Promise(d=>{let r=()=>{let{nodes:o,edges:s,elementToId:f}=to(u);i.clear();for(let[p,m]of f)i.set(p,m);d({nodes:o,edges:s,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(r,{timeout:100}):r()}catch(o){r()}}),observe:d=>{n=d;try{e=new MutationObserver(r=>{let o=[],s=new Set;for(let p of r)p.type==="childList"&&p.addedNodes.forEach(m=>{if(!(m instanceof Element))return;let S=[];jn.has(m.tagName)&&(m.hasAttribute("data-sentient-id")||m.hasAttribute("aria-label"))&&S.push(m);try{m.querySelectorAll(Hn).forEach(E=>S.push(E))}catch(E){}for(let E of S){if(i.has(E))continue;let v=qe(E,u);o.push(v),s.add(v.componentId),i.set(E,v.componentId)}});if(o.length===0||!n)return;for(let p of[...i.keys()])p.isConnected||i.delete(p);let f=At(i).filter(p=>s.has(p.fromComponentId)||s.has(p.toComponentId));n({nodes:o,edges:f,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(r){}},getProminenceScore:u,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(d){}t=0,n=null,i.clear()}}}var no="https://api.sentient-ui.com/v1/events";function oo(e){var n;let t=i=>{try{let u=document.cookie.match(new RegExp(`(?:^|; )${i}=([^;]*)`));return u?decodeURIComponent(u[1]):void 0}catch(u){return}};return(n=e?t(ae(e)):void 0)!=null?n:t(we)}var Me=new Map;function Rt(e){var p;let t=He(e),n=e.respectDoNotTrack!==!1&&Ce(),i=e.consent===!1||n,u=typeof e.apiKey=="string"&&e.apiKey.startsWith("pk_"),c=e.localMode===!0||!u;if(!e.graph||c||typeof window=="undefined")return t;if(i)return n||ht(e.apiKey,m=>Rt(m)),t;let a=Me.get(e.apiKey);if(a)try{a()}catch(m){}let l=_t(),d=(p=e.ingestUrl)!=null?p:no,r=Et({syncUrl:d.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:oo(e.apiKey)});l.scan().then(m=>{for(let S of m.nodes)r.addPageNode({id:S.componentId,componentId:S.componentId,semanticType:S.semanticType,answers:e.captureDomText&&S.headingText?[S.headingText]:[],prominenceScore:S.prominenceScore,depth:S.depth});for(let S of m.edges)r.addStructuralEdge(S);r.syncOnce()});let o=null,s=()=>{o!==null&&clearTimeout(o),o=setTimeout(()=>{o=null,r.syncOnce()},500)};l.observe(m=>{for(let S of m.nodes)r.addPageNode({id:S.componentId,componentId:S.componentId,semanticType:S.semanticType,answers:e.captureDomText&&S.headingText?[S.headingText]:[],prominenceScore:S.prominenceScore,depth:S.depth});for(let S of m.edges)r.addStructuralEdge(S);s()});let f=()=>{o!==null&&(clearTimeout(o),o=null),l.destroy(),r.destroy(),Me.get(e.apiKey)===f&&Me.delete(e.apiKey)};return Me.set(e.apiKey,f),j(w({},t),{getGraph:()=>r.snapshot(),dispose:()=>{f(),t.dispose()},destroy:()=>{f(),t.destroy()}})}0&&(module.exports={BLOCK_ALIGNS,BLOCK_EMPHASES,BLOCK_FITS,BLOCK_GAPS,BLOCK_GRID_COLUMNS,BLOCK_HEADING_LEVELS,BLOCK_JUSTIFIES,BLOCK_RATIOS,BLOCK_SIZES,BLOCK_TEXT_ALIGNS,BLOCK_TONES,BLOCK_WEIGHTS,LEGACY_SESSION_COOKIE_NAME,MAX_BLOCK_ARMS,MAX_BLOCK_CHILDREN,MAX_BLOCK_DEPTH,MAX_BLOCK_NODES,MAX_BLOCK_TEXT_LEN,SNAPSHOT_STORAGE_KEY_PREFIX,armOfResult,attachMicroSignalDetectors,baselineResultFor,baselineSlots,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,isDoNotTrackEnabled,readSnapshot,referrerDomainFromReferer,renderPrePaintScript,sanitizePageUrl,sessionCookieName,toWireSlot,writeSnapshot});
2
2
  //# sourceMappingURL=index-graph.js.map