@sentientui/react 0.28.0 → 0.29.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.
- package/dist/devtools.js +1 -1
- package/dist/devtools.js.map +1 -1
- package/dist/devtools.mjs +1 -1
- package/dist/devtools.mjs.map +1 -1
- package/dist/index.d.cts +32 -2
- package/dist/index.d.ts +32 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/next/adaptive-root.d.ts +10 -1
- package/dist/next/adaptive-root.js +2 -2
- package/dist/next/adaptive-root.js.map +1 -1
- package/dist/server.d.cts +3 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +1 -1
- package/dist/server.mjs.map +1 -1
- package/dist/testing/msw.d.cts +3 -0
- package/dist/testing/msw.d.ts +3 -0
- package/dist/testing/msw.js +1 -1
- package/dist/testing/msw.js.map +1 -1
- package/dist/testing/msw.mjs +1 -1
- package/dist/testing/msw.mjs.map +1 -1
- package/dist/testing/node.d.cts +3 -0
- package/dist/testing/node.d.ts +3 -0
- package/dist/testing/node.js +1 -1
- package/dist/testing/node.js.map +1 -1
- package/dist/testing/node.mjs +1 -1
- package/dist/testing/node.mjs.map +1 -1
- package/dist/testing/react.d.cts +3 -0
- package/dist/testing/react.d.ts +3 -0
- package/dist/testing/react.js +1 -1
- package/dist/testing/react.js.map +1 -1
- package/dist/testing/react.mjs +1 -1
- package/dist/testing/react.mjs.map +1 -1
- package/dist/testing.d.cts +3 -0
- package/dist/testing.d.ts +3 -0
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/dist/testing.mjs.map +1 -1
- package/package.json +2 -2
package/dist/devtools.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/devtools/index.tsx","../src/devtools-registry.ts","../src/devtools-overrides.ts","../src/devtools-slot-overrides.ts","../src/preview-mode.ts","../src/override-events.ts","../src/devtools-config.ts"],"sourcesContent":["'use client';\n// `type JSX` from react, not the global namespace removed in @types/react@19\n// (peers allow react >=18) — see adaptive-text.tsx.\nimport { useEffect, useReducer, useState, useSyncExternalStore, type CSSProperties, type JSX } from 'react';\nimport { PERSONAS, PERSONA_DISPLAY, confidenceBand } from '@sentientui/policy';\nimport { LEGACY_SESSION_COOKIE_NAME, SNAPSHOT_STORAGE_KEY_PREFIX, sessionCookieName } from '@sentientui/core';\nimport {\n getRegistered,\n getRegisteredSlots,\n getRegisteredSections,\n subscribeRegistry,\n getRegistryVersion,\n type RegisteredSlot,\n} from '../devtools-registry.js';\nimport { setVariantOverride, clearVariantOverride, getOverrides } from '../devtools-overrides.js';\nimport { setSlotOverride, clearSlotOverride, getSlotOverrides } from '../devtools-slot-overrides.js';\nimport { setPreviewMode, getPreviewMode } from '../preview-mode.js';\nimport { notifyOverridesChanged } from '../override-events.js';\nimport { readDevtoolsConfig, type DevtoolsConfig } from '../devtools-config.js';\n\ndeclare const process: { env?: { NODE_ENV?: string } } | undefined;\nconst IS_PROD = typeof process !== 'undefined' && process.env?.NODE_ENV === 'production';\nconst DEFAULT_API_BASE_URL = 'https://api.sentient-ui.com/v1';\n\nexport const LOCAL_MODE_DEVTOOLS_BANNER =\n 'Local mode — decisions are simulated; add a key to learn from real traffic';\n\ntype OutcomeToApply = {\n assignments?: Record<string, string>;\n layoutOrder?: string[] | null;\n slots?: Record<string, string | Record<string, string>>;\n personaAttributes?: { persona: string; confidence: 'low' | 'medium' | 'high' };\n};\n\ntype OverrideWindow = Window & {\n __sentient_layout_override?: string[];\n __sentient_slot_overrides?: Record<string, string | Record<string, string>>;\n};\n\n/** The order the page is rendering: a previewed override, else what was registered. */\nfunction currentLayout(): string[] {\n const forced = (window as unknown as OverrideWindow).__sentient_layout_override;\n const registered = getRegisteredSections();\n if (!forced || forced.length === 0) return registered;\n // Registered ids the override omits still render (useLayoutOrder returns the\n // override verbatim, and the app maps whatever ids it is given), so show them\n // trailing rather than dropping them from the list you are dragging.\n return [...forced, ...registered.filter((id) => !forced.includes(id))];\n}\n\n/**\n * Move `from` to `to` within the current order and preview it.\n *\n * Writes the whole order rather than swapping neighbours: the point is to try an\n * arrangement, not to walk one block up a list one press at a time.\n */\nfunction reorderLayout(from: number, to: number): void {\n const order = currentLayout();\n if (from === to || from < 0 || to < 0 || from >= order.length || to >= order.length) return;\n const next = [...order];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved!);\n (window as unknown as OverrideWindow).__sentient_layout_override = next;\n setPreviewMode(true); // an arrangement you are trying must not train the bandit\n notifyOverridesChanged();\n}\n\nfunction resetLayout(): void {\n delete (window as unknown as OverrideWindow).__sentient_layout_override;\n notifyOverridesChanged();\n}\n\n/** Apply a simulated outcome across every surface: variants, layout, slots/tokens, persona attrs. */\nfunction applyOutcome(result: OutcomeToApply): void {\n for (const [id, variantId] of Object.entries(result.assignments ?? {})) {\n setVariantOverride(id, variantId);\n }\n const w = window as unknown as OverrideWindow;\n if (result.layoutOrder && result.layoutOrder.length > 0) {\n w.__sentient_layout_override = result.layoutOrder;\n }\n if (result.slots) {\n w.__sentient_slot_overrides = { ...(w.__sentient_slot_overrides ?? {}), ...result.slots };\n }\n if (result.personaAttributes) {\n document.documentElement.dataset.sentientPersona = result.personaAttributes.persona;\n document.documentElement.dataset.sentientConfidence = result.personaAttributes.confidence;\n }\n setPreviewMode(true); // suppress events while previewing\n notifyOverridesChanged(); // re-render layout/slot consumers\n}\n\n// Reads the SDK's own session cookie — the per-project SUFFIXED name first\n// (that is what the client writes since namespacing; the bare `_snt_uid` this\n// used to read is only written in keyless/local mode), then the bare name as\n// the legacy/local fallback.\nfunction readSessionId(apiKey?: string): string {\n const read = (name: string): string | null => {\n try {\n const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));\n return match ? decodeURIComponent(match[1]!) : null;\n } catch {\n return null;\n }\n };\n return (apiKey ? read(sessionCookieName(apiKey)) : null) ?? read(LEGACY_SESSION_COOKIE_NAME) ?? 'devtools-preview';\n}\n\nfunction slotDecls(): Array<{ id: string; arms?: string[]; dims?: RegisteredSlot['dims'] }> {\n return getRegisteredSlots().map((s) => ({\n id: s.id,\n ...(s.arms ? { arms: s.arms } : {}),\n ...(s.dims ? { dims: s.dims } : {}),\n }));\n}\n\n/** One member of the project's persona vocabulary, as /v1/personas serves it. */\ntype VocabMember = { key: string; displayName: string };\n\nconst DEFAULT_PERSONA_CHOICES: VocabMember[] = PERSONAS.map((key) => ({\n key,\n displayName: PERSONA_DISPLAY[key],\n}));\n\n/**\n * Keyed mode: the project's ACTIVE vocabulary from /v1/personas. Personas are\n * per-project (persona_sets, migration 113) — discovery can promote new ones\n * and retire the pinned four — so hardcoding PERSONAS here offered buttons\n * that silently simulated the default experience on any project whose\n * vocabulary differs. null on any failure → the caller keeps the pinned-four\n * fallback (an old API without the endpoint degrades to today's behavior).\n */\nasync function fetchPersonaVocabulary(\n apiKey: string,\n apiBaseUrl: string,\n): Promise<{ personas: VocabMember[]; discovered: VocabMember[] } | null> {\n try {\n const res = await fetch(`${apiBaseUrl}/personas`, {\n headers: { authorization: `Bearer ${apiKey}` },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { personas?: VocabMember[]; discovered?: VocabMember[] };\n const valid = (list: VocabMember[] | undefined): VocabMember[] =>\n Array.isArray(list)\n ? list.filter((p) => p && typeof p.key === 'string' && typeof p.displayName === 'string')\n : [];\n const personas = valid(data.personas);\n return personas.length > 0 ? { personas, discovered: valid(data.discovered) } : null;\n } catch {\n return null;\n }\n}\n\n/** Keyed mode: simulate via /v1/explain (read-only, event-free). Returns how\n * the persona RESOLVED so the panel can say when the project didn't\n * recognize it — the page then shows the default experience, and a silently\n * highlighted button claiming otherwise was the old lie. */\nasync function forcePersonaKeyed(\n apiKey: string,\n apiBaseUrl: string,\n persona: string,\n): Promise<{ recognized: boolean; resolvedDisplay: string } | null> {\n const res = await fetch(`${apiBaseUrl}/explain`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n persona,\n sections: getRegisteredSections().map((id) => ({ id })),\n components: getRegistered().map((c) => ({ id: c.id, variantIds: c.variantIds })),\n slots: slotDecls(),\n }),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as OutcomeToApply & {\n recognized?: boolean;\n persona?: string;\n personaDisplay?: string;\n };\n applyOutcome({\n ...data,\n personaAttributes: data.personaAttributes ?? { persona, confidence: 'high' },\n });\n return {\n // An older API omits the field — treat as recognized (no basis to warn).\n recognized: data.recognized !== false,\n resolvedDisplay: data.personaDisplay ?? data.persona ?? persona,\n };\n}\n\n/** Local mode: simulate via the deterministic local engine — zero network. */\nasync function forcePersonaLocal(persona: string, apiKey?: string): Promise<void> {\n const mod = await import('@sentientui/core/local');\n if (!mod.LOCAL_ENGINE_AVAILABLE) return;\n const outcome = mod\n .createLocalEngine({ sessionId: readSessionId(apiKey), forcedPersona: persona })\n .decide({\n sections: getRegisteredSections(),\n components: getRegistered().map((c) => ({ id: c.id, variantIds: c.variantIds })),\n slots: slotDecls(),\n });\n applyOutcome({\n assignments: outcome.assignments,\n layoutOrder: outcome.layoutOrder,\n slots: outcome.slots,\n personaAttributes: {\n persona: outcome.persona,\n confidence: confidenceBand(outcome.confidence),\n },\n });\n}\n\n/** Reset: clear the decision snapshot + every override, then reload to re-decide. */\nfunction resetAll(): void {\n for (const id of Object.keys(getOverrides())) clearVariantOverride(id);\n const w = window as unknown as OverrideWindow;\n delete w.__sentient_layout_override;\n delete w.__sentient_slot_overrides;\n delete document.documentElement.dataset.sentientPersona;\n delete document.documentElement.dataset.sentientConfidence;\n try {\n const stale: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && key.startsWith(SNAPSHOT_STORAGE_KEY_PREFIX)) stale.push(key);\n }\n for (const key of stale) localStorage.removeItem(key);\n } catch {\n /* ignore */\n }\n setPreviewMode(false);\n notifyOverridesChanged();\n try {\n window.location.reload();\n } catch {\n /* jsdom */\n }\n}\n\nconst btn = (active: boolean): CSSProperties => ({\n padding: '2px 8px',\n borderRadius: 4,\n border: '1px solid #444',\n background: active ? '#3b82f6' : '#222',\n color: '#eee',\n cursor: 'pointer',\n});\n\n/** Sentient \"S.\" wordmark, monoline — white strokes for the black launcher button. */\nfunction SentientMark({ size = 26 }: { size?: number } = {}): JSX.Element {\n return (\n <svg width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M21 9H14C11.2 9 9.8 10.8 9.8 13C9.8 15.4 11.6 16.6 14.5 16.6H18.5C20.5 16.6 20.7 18.2 20.4 19.6\"\n stroke=\"#fff\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M10 22H17\" stroke=\"#fff\" strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <circle cx=\"20.6\" cy=\"22\" r=\"2.1\" fill=\"#fff\" />\n </svg>\n );\n}\n\nexport function AdaptiveDevtools({ apiKey }: { apiKey?: string } = {}): JSX.Element | null {\n const [open, setOpen] = useState(false);\n const [activePersona, setActivePersona] = useState<string | null>(null);\n // The project's vocabulary (keyed mode); null = not loaded → pinned-four\n // fallback. Local mode never fetches: the local engine only knows the\n // pinned four, and its banner already frames everything as simulated.\n const [vocab, setVocab] = useState<VocabMember[] | null>(null);\n // Discovered SHADOW personas — display-only. They never serve until\n // promotion, so there is no button: forcing one would simulate a persona\n // that cannot occur on this project.\n const [discovered, setDiscovered] = useState<VocabMember[]>([]);\n // Set when a forced persona did NOT resolve against the project's\n // vocabulary — the page is showing the default experience and the panel\n // must say so instead of highlighting the button as if the preview worked.\n const [personaNote, setPersonaNote] = useState<string | null>(null);\n const [dragFrom, setDragFrom] = useState<number | null>(null);\n const [mounted, setMounted] = useState(false);\n const [, force] = useReducer((n: number) => n + 1, 0);\n // Re-render when the component/slot registry changes. useSyncExternalStore\n // (not a manual useEffect subscription) so the subscription can't go stale\n // across Next Fast Refresh — a stale listener was why the panel needed a hard\n // refresh to pick up a renamed id.\n useSyncExternalStore(subscribeRegistry, getRegistryVersion, () => 0);\n // Client-mount gate: render nothing during SSR / the first paint so the widget\n // never reads `window` on the server. Lets consumers drop `<AdaptiveDevtools/>`\n // straight into a tree without a `dynamic(..., { ssr: false })` wrapper.\n useEffect(() => setMounted(true), []);\n // Load the project's persona vocabulary once (keyed mode only).\n useEffect(() => {\n if (IS_PROD) return;\n const cfg = readDevtoolsConfig() ?? { apiKey: apiKey ?? '', apiBaseUrl: DEFAULT_API_BASE_URL, isLocal: false };\n if (cfg.isLocal || !cfg.apiKey) return;\n let cancelled = false;\n void fetchPersonaVocabulary(cfg.apiKey, cfg.apiBaseUrl).then((v) => {\n if (cancelled || !v) return;\n setVocab(v.personas);\n setDiscovered(v.discovered);\n });\n return () => { cancelled = true; };\n }, [apiKey]);\n\n // Never render in production, even if imported by mistake. (Hooks run first\n // so the rules of hooks hold regardless of these early returns.)\n if (IS_PROD) return null;\n if (!mounted) return null;\n\n const config: DevtoolsConfig = readDevtoolsConfig() ?? {\n apiKey: apiKey ?? '',\n apiBaseUrl: DEFAULT_API_BASE_URL,\n isLocal: false,\n };\n const useLocalEngine = config.isLocal || !config.apiKey;\n const components = getRegistered();\n const slots = getRegisteredSlots();\n const overrides = getOverrides();\n const slotOverrides = getSlotOverrides();\n const sections = currentLayout();\n const layoutForced = (window as unknown as OverrideWindow).__sentient_layout_override !== undefined;\n\n function onReorder(from: number, to: number): void {\n reorderLayout(from, to);\n force();\n }\n function onResetLayout(): void {\n resetLayout();\n maybeExitPreview();\n force();\n }\n\n // Preview mode stays on while ANY override (variant, slot or layout) is\n // active. Omitting layout here let clearing the last variant re-enable event\n // recording while a previewed section order was still on screen.\n function maybeExitPreview(): void {\n if (\n Object.keys(getOverrides()).length === 0 &&\n Object.keys(getSlotOverrides()).length === 0 &&\n (window as unknown as OverrideWindow).__sentient_layout_override === undefined\n ) {\n setPreviewMode(false);\n }\n }\n\n function choose(id: string, variantId: string): void {\n setVariantOverride(id, variantId);\n setPreviewMode(true);\n notifyOverridesChanged();\n force();\n }\n function resetVariant(id: string): void {\n clearVariantOverride(id);\n maybeExitPreview();\n notifyOverridesChanged();\n force();\n }\n function chooseSlotArm(id: string, arm: string): void {\n setSlotOverride(id, arm);\n setPreviewMode(true);\n notifyOverridesChanged();\n force();\n }\n function chooseSlotDim(id: string, dim: string, value: string, dims: RegisteredSlot['dims']): void {\n const current = getSlotOverrides()[id];\n // Merge onto the existing forced object, or seed from each dim's baseline\n // (first value) so unset dims stay at baseline instead of vanishing.\n const next: Record<string, string> =\n current && typeof current === 'object'\n ? { ...current }\n : Object.fromEntries(Object.entries(dims ?? {}).map(([d, values]) => [d, values[0]!]));\n next[dim] = value;\n setSlotOverride(id, next);\n setPreviewMode(true);\n notifyOverridesChanged();\n force();\n }\n function resetSlot(id: string): void {\n clearSlotOverride(id);\n maybeExitPreview();\n notifyOverridesChanged();\n force();\n }\n function choosePersona(member: VocabMember): void {\n setActivePersona(member.key);\n setPersonaNote(null);\n // .catch: a failed simulate (offline /v1/explain, bad key, failed local\n // dynamic import) is a preview no-op — without the handler it surfaced as\n // an unhandled promise rejection in the console.\n if (useLocalEngine) {\n forcePersonaLocal(member.key, config.apiKey).then(force).catch(() => {});\n return;\n }\n forcePersonaKeyed(config.apiKey, config.apiBaseUrl, member.key)\n .then((r) => {\n if (r && !r.recognized) {\n setPersonaNote(\n `“${member.displayName}” isn’t in this project’s personas — the page is showing the default experience.`,\n );\n }\n force();\n })\n .catch(() => {});\n }\n\n return (\n <div style={{ position: 'fixed', bottom: 16, right: 16, zIndex: 2147483647, fontFamily: 'system-ui' }}>\n {/* Panel stays mounted and animates in/out from the button's corner, so the\n launcher below never shifts. transform-origin is the button (bottom-right). */}\n <div\n aria-hidden={!open}\n style={{\n position: 'absolute',\n bottom: 52,\n right: 0,\n transformOrigin: 'bottom right',\n transition: 'opacity .18s ease, transform .2s cubic-bezier(.16,1,.3,1)',\n opacity: open ? 1 : 0,\n transform: open ? 'translateY(0) scale(1)' : 'translateY(6px) scale(.96)',\n pointerEvents: open ? 'auto' : 'none',\n }}\n >\n <div style={{ width: 300, maxHeight: 460, overflowY: 'auto', background: '#111', color: '#eee',\n borderRadius: 8, padding: 12, boxShadow: '0 8px 30px rgba(0,0,0,.4)', fontSize: 12 }}>\n {config.isLocal && (\n <div style={{ background: '#1e293b', border: '1px solid #334155', borderRadius: 4,\n padding: '6px 8px', marginBottom: 8 }}>\n {LOCAL_MODE_DEVTOOLS_BANNER}\n </div>\n )}\n <div style={{ opacity: .7, marginBottom: 8 }}>\n {components.length} component{components.length === 1 ? '' : 's'} · {getPreviewMode() ? 'preview — writing nothing' : 'live'}\n </div>\n <div style={{ borderBottom: '1px solid #333', paddingBottom: 8, marginBottom: 8 }}>\n <div style={{ opacity: .7, marginBottom: 4 }}>Preview persona</div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {/* Keyed mode renders the project's OWN vocabulary (falling back\n to the pinned four until /v1/personas answers); local mode\n keeps the pinned four the local engine simulates. */}\n {(useLocalEngine ? DEFAULT_PERSONA_CHOICES : vocab ?? DEFAULT_PERSONA_CHOICES).map((p) => (\n <button key={p.key} onClick={() => choosePersona(p)} style={btn(activePersona === p.key)}>\n {p.displayName}\n </button>\n ))}\n {(activePersona !== null || Object.keys(overrides).length > 0 || Object.keys(slotOverrides).length > 0) && (\n <button onClick={resetAll} style={{ ...btn(false), color: '#aaa' }}>\n Reset\n </button>\n )}\n </div>\n {personaNote && (\n <div style={{ marginTop: 6, fontSize: 11, color: '#fbbf24' }}>{personaNote}</div>\n )}\n {!useLocalEngine && discovered.length > 0 && (\n <div style={{ marginTop: 8 }}>\n <div style={{ opacity: .5, fontSize: 11, marginBottom: 4 }}>\n Discovered — not serving yet (promote from the dashboard)\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {discovered.map((p) => (\n <span\n key={p.key}\n title=\"Found by clustering your traffic; it starts serving only after promotion.\"\n style={{ ...btn(false), opacity: .45, cursor: 'default', display: 'inline-block' }}\n >\n {p.displayName}\n </span>\n ))}\n </div>\n </div>\n )}\n </div>\n {sections.length > 0 && (\n <div style={{ borderBottom: '1px solid #333', paddingBottom: 8, marginBottom: 8 }}>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 4 }}>\n <span style={{ opacity: .7 }}>Layout — drag to reorder</span>\n {layoutForced && (\n // Distinct accessible name: the per-variant and per-slot resets\n // below are also labelled \"reset\", and three identical buttons\n // in one panel is ambiguous to a screen reader and to tests.\n <button\n aria-label=\"Reset section order\"\n onClick={onResetLayout}\n style={{ ...btn(false), color: '#aaa' }}\n >\n reset\n </button>\n )}\n </div>\n {/* Drop-on-row inserts at that row's position, so any block can go\n anywhere in one gesture. The whole order is written on each\n drop — see reorderLayout. */}\n <ul aria-label=\"Section order\" style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {sections.map((id, i) => (\n <li\n key={id}\n draggable\n onDragStart={() => setDragFrom(i)}\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => {\n e.preventDefault();\n if (dragFrom !== null) onReorder(dragFrom, i);\n setDragFrom(null);\n }}\n onDragEnd={() => setDragFrom(null)}\n style={{\n display: 'flex', alignItems: 'center', gap: 6, padding: '4px 6px', marginBottom: 2,\n borderRadius: 4, border: '1px solid #262626', cursor: 'grab',\n background: dragFrom === i ? '#1e293b' : '#181818',\n opacity: dragFrom !== null && dragFrom !== i ? .6 : 1,\n }}\n >\n <span style={{ opacity: .4, minWidth: 10, fontVariantNumeric: 'tabular-nums' }}>{i + 1}</span>\n <span aria-hidden=\"true\" style={{ opacity: .35 }}>⠿</span>\n <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {id}\n </span>\n </li>\n ))}\n </ul>\n </div>\n )}\n {components.length === 0 && slots.length === 0 && sections.length === 0 && (\n <div style={{ opacity: .6 }}>No components, sections or slots on this page yet.</div>\n )}\n {components.map((c) => (\n <div key={c.id} style={{ borderTop: '1px solid #333', padding: '8px 0' }}>\n <div style={{ fontWeight: 600 }}>{c.id}{c.goal ? ` · goal: ${c.goal}` : ''}</div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 4 }}>\n {c.variantIds.map((v) => (\n <button key={v} onClick={() => choose(c.id, v)} style={btn(overrides[c.id] === v)}>\n {v}\n </button>\n ))}\n {overrides[c.id] && (\n <button onClick={() => resetVariant(c.id)} style={{ ...btn(false), color: '#aaa' }}>\n reset\n </button>\n )}\n </div>\n </div>\n ))}\n {slots.length > 0 && (\n <div style={{ borderTop: '1px solid #333', paddingTop: 8, marginTop: 4 }}>\n <div style={{ opacity: .7, marginBottom: 4 }}>Slots</div>\n {slots.map((s) => {\n const ov = slotOverrides[s.id];\n return (\n <div key={s.id} style={{ padding: '6px 0' }}>\n <div style={{ fontWeight: 600 }}>{s.id}</div>\n {s.arms && (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 4 }}>\n {s.arms.map((arm) => (\n <button key={arm} onClick={() => chooseSlotArm(s.id, arm)} style={btn(ov === arm)}>\n {arm}\n </button>\n ))}\n </div>\n )}\n {s.dims && Object.entries(s.dims).map(([dim, values]) => (\n <div key={dim} style={{ marginTop: 4 }}>\n <div style={{ opacity: .6, fontSize: 11 }}>{dim}</div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {values.map((v) => (\n <button\n key={v}\n onClick={() => chooseSlotDim(s.id, dim, v, s.dims)}\n style={btn(!!ov && typeof ov === 'object' && ov[dim] === v)}\n >\n {v}\n </button>\n ))}\n </div>\n </div>\n ))}\n {ov !== undefined && (\n <button onClick={() => resetSlot(s.id)} style={{ ...btn(false), color: '#aaa', marginTop: 4 }}>\n reset\n </button>\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n <button\n aria-label=\"Sentient DevTools\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n style={{ width: 44, height: 44, borderRadius: 12, border: '1px solid #2a2a2a', background: '#000',\n display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 0,\n cursor: 'pointer', boxShadow: '0 6px 18px rgba(0,0,0,.4)' }}\n >\n <SentientMark />\n </button>\n </div>\n );\n}\n","import { isDevBuild } from './adaptive-shared.js';\n\nexport type RegisteredComponent = { id: string; variantIds: string[]; goal?: string };\nexport type RegisteredSlot = {\n id: string;\n arms?: string[];\n dims?: Record<string, readonly string[]>;\n};\n\ntype RegistryState = {\n components: Map<string, RegisteredComponent>;\n slots: Map<string, RegisteredSlot>;\n sections: string[];\n listeners: Set<() => void>;\n /** Bumped on every mutation so `useSyncExternalStore` can read a stable, comparable snapshot. */\n version: number;\n};\n\n// Shared through a window global: the main entry and the /devtools entry are\n// separate bundles, each with its own copy of this module — module-local\n// state would give the devtools an always-empty registry in published apps.\nconst ssrFallback: RegistryState = {\n components: new Map(),\n slots: new Map(),\n sections: [],\n listeners: new Set(),\n version: 0,\n};\n\nfunction state(): RegistryState {\n if (typeof window === 'undefined') return ssrFallback;\n const w = window as unknown as { __sentient_registry?: RegistryState };\n if (!w.__sentient_registry) {\n w.__sentient_registry = {\n components: new Map(),\n slots: new Map(),\n sections: [],\n listeners: new Set(),\n version: 0,\n };\n }\n return w.__sentient_registry;\n}\n\nfunction emit(): void {\n // Bump BEFORE notifying so a useSyncExternalStore consumer re-reading its\n // snapshot inside the notification sees the new value and re-renders.\n state().version += 1;\n for (const fn of state().listeners) fn();\n}\n\n// The registry exists solely to feed the opt-in devtools panel, which is a\n// dev-only surface. In a production build there is no panel reading it, so\n// every register call is dead work plus a `window.__sentient_registry`\n// footprint on the customer's page. Short-circuit to a noop in production —\n// every <Adaptive>/useAdaptive/slot mount calls one of these.\nconst NOOP_UNREGISTER = (): void => undefined;\n\n/** Register (or re-register) a component. Returns an unregister function. */\nexport function registerComponent(c: RegisteredComponent): () => void {\n if (!isDevBuild()) return NOOP_UNREGISTER;\n state().components.set(c.id, c);\n emit();\n return () => {\n state().components.delete(c.id);\n emit();\n };\n}\n\n/** Register (or re-register) a slot declaration. Returns an unregister function. */\nexport function registerSlot(s: RegisteredSlot): () => void {\n if (!isDevBuild()) return NOOP_UNREGISTER;\n state().slots.set(s.id, s);\n emit();\n return () => {\n state().slots.delete(s.id);\n emit();\n };\n}\n\n/** Register the page's declared section ids (from AdaptiveRoot/provider). */\nexport function registerSections(sections: string[]): void {\n if (!isDevBuild()) return;\n state().sections = [...sections];\n emit();\n}\n\nexport function getRegistered(): RegisteredComponent[] {\n return [...state().components.values()];\n}\n\nexport function getRegisteredSlots(): RegisteredSlot[] {\n return [...state().slots.values()];\n}\n\nexport function getRegisteredSections(): string[] {\n return [...state().sections];\n}\n\nexport function subscribeRegistry(fn: () => void): () => void {\n const listeners = state().listeners;\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n\n/** Monotonic snapshot for `useSyncExternalStore` — changes on every registry mutation. */\nexport function getRegistryVersion(): number {\n return state().version;\n}\n","function store(): Record<string, string> {\n const w = window as unknown as { __sentient_overrides?: Record<string, string> };\n if (!w.__sentient_overrides) w.__sentient_overrides = {};\n return w.__sentient_overrides;\n}\n\n/** Force `componentId` to render `variantId` — read by `useAssignment`. */\nexport function setVariantOverride(componentId: string, variantId: string): void {\n store()[componentId] = variantId;\n}\n\nexport function clearVariantOverride(componentId: string): void {\n delete store()[componentId];\n}\n\nexport function getOverrides(): Record<string, string> {\n return { ...store() };\n}\n","import type { SlotResult } from '@sentientui/core';\n\n/**\n * Slot-override store — the channel `useSlotResult` reads (`useAdaptiveTokens` /\n * `AdaptiveGroup`). Separate from `__sentient_overrides` (variant components):\n * a slot result is a token object (`{ tone: 'urgent' }`) or an arm string\n * (`'social_first'`), never a bare variant id. Window-backed so the /devtools\n * bundle and the main bundle share one store.\n */\nfunction store(): Record<string, SlotResult> {\n const w = window as unknown as { __sentient_slot_overrides?: Record<string, SlotResult> };\n if (!w.__sentient_slot_overrides) w.__sentient_slot_overrides = {};\n return w.__sentient_slot_overrides;\n}\n\n/** Force `slotId` to resolve to `result` — read by `useSlotResult`. */\nexport function setSlotOverride(slotId: string, result: SlotResult): void {\n store()[slotId] = result;\n}\n\nexport function clearSlotOverride(slotId: string): void {\n delete store()[slotId];\n}\n\nexport function getSlotOverrides(): Record<string, SlotResult> {\n return { ...store() };\n}\n","import type { SentientClient } from '@sentientui/core';\n\ntype PreviewState = { on: boolean; listeners: Set<() => void> };\nconst ssrFallback: PreviewState = { on: false, listeners: new Set() };\n\n// Window-backed: the /devtools entry (a separate bundle) toggles preview mode\n// and the provider (main bundle) must observe it.\nfunction state(): PreviewState {\n if (typeof window === 'undefined') return ssrFallback;\n const w = window as unknown as { __sentient_preview?: PreviewState };\n if (!w.__sentient_preview) w.__sentient_preview = { on: false, listeners: new Set() };\n return w.__sentient_preview;\n}\n\nexport function setPreviewMode(on: boolean): void {\n const s = state();\n if (s.on === on) return;\n s.on = on;\n for (const fn of s.listeners) fn();\n}\n\nexport function getPreviewMode(): boolean {\n return state().on;\n}\n\nexport function subscribePreview(fn: () => void): () => void {\n const listeners = state().listeners;\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n\n/**\n * Wraps a client so it writes nothing: reads pass through, all emitters no-op.\n * Used while previewing variants/personas so no `variant_assigned`, goal, or\n * session events are sent.\n */\nexport function createPreviewClient(inner: SentientClient): SentientClient {\n return {\n isLocal: inner.isLocal,\n track: () => undefined,\n goal: () => undefined,\n componentGoal: () => undefined,\n identify: () => undefined,\n fetchWeights: () => Promise.resolve([]),\n getAssignment: (componentId, segment) => inner.getAssignment(componentId, segment),\n assign: (componentId, variantIds, agentData, agentDataByVariant) =>\n inner.assign(componentId, variantIds, agentData, agentDataByVariant),\n // Reads pass through; decide is a write (slot decisions persist server-side)\n // so preview mode never issues it.\n decide: () => Promise.resolve(null),\n getSlotResult: (slotId) => inner.getSlotResult(slotId),\n getPersona: () => inner.getPersona(),\n getGraph: () => inner.getGraph(),\n dispose: () => inner.dispose(),\n destroy: () => inner.destroy(),\n };\n}\n","/**\n * Cross-bundle re-render bus for devtools overrides. The main entry and the\n * /devtools entry are separate bundles, so state and notifications go through\n * window (a version counter + a DOM event) — never module-local state.\n */\nconst EVENT = 'sentient:overrides-changed';\n\ntype VersionWindow = Window & { __sentient_overrides_version?: number };\n\nexport function getOverridesVersion(): number {\n if (typeof window === 'undefined') return 0;\n return (window as VersionWindow).__sentient_overrides_version ?? 0;\n}\n\nexport function notifyOverridesChanged(): void {\n if (typeof window === 'undefined') return;\n const w = window as VersionWindow;\n w.__sentient_overrides_version = (w.__sentient_overrides_version ?? 0) + 1;\n window.dispatchEvent(new Event(EVENT));\n}\n\nexport function subscribeOverridesChanged(fn: () => void): () => void {\n if (typeof window === 'undefined') return () => undefined;\n window.addEventListener(EVENT, fn);\n return () => window.removeEventListener(EVENT, fn);\n}\n","/** Provider → devtools config handoff. Window-backed: the /devtools entry is a\n * separate bundle and cannot share the provider's React context instance. */\nexport type DevtoolsConfig = {\n apiKey: string;\n apiBaseUrl: string;\n isLocal: boolean;\n};\n\ntype ConfigWindow = Window & { __sentient_devtools_config?: DevtoolsConfig };\n\nexport function publishDevtoolsConfig(config: DevtoolsConfig): void {\n if (typeof window === 'undefined') return;\n (window as ConfigWindow).__sentient_devtools_config = config;\n}\n\nexport function readDevtoolsConfig(): DevtoolsConfig | null {\n if (typeof window === 'undefined') return null;\n return (window as ConfigWindow).__sentient_devtools_config ?? null;\n}\n"],"mappings":"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","names":["useEffect","useReducer","useState","useSyncExternalStore","PERSONAS","PERSONA_DISPLAY","confidenceBand","LEGACY_SESSION_COOKIE_NAME","SNAPSHOT_STORAGE_KEY_PREFIX","sessionCookieName","ssrFallback","state","w","getRegistered","state","getRegisteredSlots","getRegisteredSections","subscribeRegistry","fn","listeners","getRegistryVersion","store","w","setVariantOverride","componentId","variantId","clearVariantOverride","getOverrides","__spreadValues","store","w","setSlotOverride","slotId","result","clearSlotOverride","getSlotOverrides","__spreadValues","ssrFallback","state","w","setPreviewMode","on","s","fn","getPreviewMode","EVENT","notifyOverridesChanged","_a","w","EVENT","readDevtoolsConfig","_a","jsx","jsxs","_a","IS_PROD","DEFAULT_API_BASE_URL","LOCAL_MODE_DEVTOOLS_BANNER","currentLayout","forced","registered","getRegisteredSections","id","reorderLayout","from","to","order","next","moved","setPreviewMode","notifyOverridesChanged","resetLayout","applyOutcome","result","_b","variantId","setVariantOverride","w","__spreadValues","readSessionId","apiKey","read","name","match","e","sessionCookieName","LEGACY_SESSION_COOKIE_NAME","slotDecls","getRegisteredSlots","s","DEFAULT_PERSONA_CHOICES","PERSONAS","key","PERSONA_DISPLAY","fetchPersonaVocabulary","apiBaseUrl","res","data","valid","list","p","personas","forcePersonaKeyed","persona","_c","getRegistered","c","__spreadProps","forcePersonaLocal","mod","outcome","confidenceBand","resetAll","getOverrides","clearVariantOverride","stale","i","SNAPSHOT_STORAGE_KEY_PREFIX","btn","active","SentientMark","size","AdaptiveDevtools","open","setOpen","useState","activePersona","setActivePersona","vocab","setVocab","discovered","setDiscovered","personaNote","setPersonaNote","dragFrom","setDragFrom","mounted","setMounted","force","useReducer","useSyncExternalStore","subscribeRegistry","getRegistryVersion","useEffect","cfg","readDevtoolsConfig","cancelled","config","useLocalEngine","components","slots","overrides","slotOverrides","getSlotOverrides","sections","layoutForced","onReorder","onResetLayout","maybeExitPreview","choose","resetVariant","chooseSlotArm","arm","setSlotOverride","chooseSlotDim","dim","value","dims","current","d","values","resetSlot","clearSlotOverride","choosePersona","member","getPreviewMode","v","ov","o"]}
|
|
1
|
+
{"version":3,"sources":["../src/devtools/index.tsx","../src/devtools-registry.ts","../src/devtools-overrides.ts","../src/devtools-slot-overrides.ts","../src/preview-mode.ts","../src/override-events.ts","../src/devtools-config.ts"],"sourcesContent":["'use client';\n// `type JSX` from react, not the global namespace removed in @types/react@19\n// (peers allow react >=18) — see adaptive-text.tsx.\nimport { useEffect, useReducer, useState, useSyncExternalStore, type CSSProperties, type JSX } from 'react';\nimport { PERSONAS, PERSONA_DISPLAY, confidenceBand } from '@sentientui/policy';\nimport { LEGACY_SESSION_COOKIE_NAME, SNAPSHOT_STORAGE_KEY_PREFIX, sessionCookieName } from '@sentientui/core';\nimport {\n getRegistered,\n getRegisteredSlots,\n getRegisteredSections,\n subscribeRegistry,\n getRegistryVersion,\n type RegisteredSlot,\n} from '../devtools-registry.js';\nimport { setVariantOverride, clearVariantOverride, getOverrides } from '../devtools-overrides.js';\nimport { setSlotOverride, clearSlotOverride, getSlotOverrides } from '../devtools-slot-overrides.js';\nimport { setPreviewMode, getPreviewMode } from '../preview-mode.js';\nimport { notifyOverridesChanged } from '../override-events.js';\nimport { readDevtoolsConfig, type DevtoolsConfig } from '../devtools-config.js';\n\ndeclare const process: { env?: { NODE_ENV?: string } } | undefined;\nconst IS_PROD = typeof process !== 'undefined' && process.env?.NODE_ENV === 'production';\nconst DEFAULT_API_BASE_URL = 'https://api.sentient-ui.com/v1';\n\nexport const LOCAL_MODE_DEVTOOLS_BANNER =\n 'Local mode — decisions are simulated; add a key to learn from real traffic';\n\ntype OutcomeToApply = {\n assignments?: Record<string, string>;\n layoutOrder?: string[] | null;\n slots?: Record<string, string | Record<string, string>>;\n personaAttributes?: { persona: string; confidence: 'low' | 'medium' | 'high' };\n};\n\ntype OverrideWindow = Window & {\n __sentient_layout_override?: string[];\n __sentient_slot_overrides?: Record<string, string | Record<string, string>>;\n};\n\n/** The order the page is rendering: a previewed override, else what was registered. */\nfunction currentLayout(): string[] {\n const forced = (window as unknown as OverrideWindow).__sentient_layout_override;\n const registered = getRegisteredSections();\n if (!forced || forced.length === 0) return registered;\n // Registered ids the override omits still render (useLayoutOrder returns the\n // override verbatim, and the app maps whatever ids it is given), so show them\n // trailing rather than dropping them from the list you are dragging.\n return [...forced, ...registered.filter((id) => !forced.includes(id))];\n}\n\n/**\n * Move `from` to `to` within the current order and preview it.\n *\n * Writes the whole order rather than swapping neighbours: the point is to try an\n * arrangement, not to walk one block up a list one press at a time.\n */\nfunction reorderLayout(from: number, to: number): void {\n const order = currentLayout();\n if (from === to || from < 0 || to < 0 || from >= order.length || to >= order.length) return;\n const next = [...order];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved!);\n (window as unknown as OverrideWindow).__sentient_layout_override = next;\n setPreviewMode(true); // an arrangement you are trying must not train the bandit\n notifyOverridesChanged();\n}\n\nfunction resetLayout(): void {\n delete (window as unknown as OverrideWindow).__sentient_layout_override;\n notifyOverridesChanged();\n}\n\n/** Apply a simulated outcome across every surface: variants, layout, slots/tokens, persona attrs. */\nfunction applyOutcome(result: OutcomeToApply): void {\n for (const [id, variantId] of Object.entries(result.assignments ?? {})) {\n setVariantOverride(id, variantId);\n }\n const w = window as unknown as OverrideWindow;\n if (result.layoutOrder && result.layoutOrder.length > 0) {\n w.__sentient_layout_override = result.layoutOrder;\n }\n if (result.slots) {\n w.__sentient_slot_overrides = { ...(w.__sentient_slot_overrides ?? {}), ...result.slots };\n }\n if (result.personaAttributes) {\n document.documentElement.dataset.sentientPersona = result.personaAttributes.persona;\n document.documentElement.dataset.sentientConfidence = result.personaAttributes.confidence;\n }\n setPreviewMode(true); // suppress events while previewing\n notifyOverridesChanged(); // re-render layout/slot consumers\n}\n\n// Reads the SDK's own session cookie — the per-project SUFFIXED name first\n// (that is what the client writes since namespacing; the bare `_snt_uid` this\n// used to read is only written in keyless/local mode), then the bare name as\n// the legacy/local fallback.\nfunction readSessionId(apiKey?: string): string {\n const read = (name: string): string | null => {\n try {\n const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));\n return match ? decodeURIComponent(match[1]!) : null;\n } catch {\n return null;\n }\n };\n return (apiKey ? read(sessionCookieName(apiKey)) : null) ?? read(LEGACY_SESSION_COOKIE_NAME) ?? 'devtools-preview';\n}\n\nfunction slotDecls(): Array<{ id: string; arms?: string[]; dims?: RegisteredSlot['dims'] }> {\n return getRegisteredSlots().map((s) => ({\n id: s.id,\n ...(s.arms ? { arms: s.arms } : {}),\n ...(s.dims ? { dims: s.dims } : {}),\n }));\n}\n\n/** One member of the project's persona vocabulary, as /v1/personas serves it. */\ntype VocabMember = { key: string; displayName: string };\n\nconst DEFAULT_PERSONA_CHOICES: VocabMember[] = PERSONAS.map((key) => ({\n key,\n displayName: PERSONA_DISPLAY[key],\n}));\n\n/**\n * Keyed mode: the project's ACTIVE vocabulary from /v1/personas. Personas are\n * per-project (persona_sets, migration 113) — discovery can promote new ones\n * and retire the pinned four — so hardcoding PERSONAS here offered buttons\n * that silently simulated the default experience on any project whose\n * vocabulary differs. null on any failure → the caller keeps the pinned-four\n * fallback (an old API without the endpoint degrades to today's behavior).\n */\nasync function fetchPersonaVocabulary(\n apiKey: string,\n apiBaseUrl: string,\n): Promise<{ personas: VocabMember[]; discovered: VocabMember[] } | null> {\n try {\n const res = await fetch(`${apiBaseUrl}/personas`, {\n headers: { authorization: `Bearer ${apiKey}` },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as { personas?: VocabMember[]; discovered?: VocabMember[] };\n const valid = (list: VocabMember[] | undefined): VocabMember[] =>\n Array.isArray(list)\n ? list.filter((p) => p && typeof p.key === 'string' && typeof p.displayName === 'string')\n : [];\n const personas = valid(data.personas);\n return personas.length > 0 ? { personas, discovered: valid(data.discovered) } : null;\n } catch {\n return null;\n }\n}\n\n/** Keyed mode: simulate via /v1/explain (read-only, event-free). Returns how\n * the persona RESOLVED so the panel can say when the project didn't\n * recognize it — the page then shows the default experience, and a silently\n * highlighted button claiming otherwise was the old lie. */\nasync function forcePersonaKeyed(\n apiKey: string,\n apiBaseUrl: string,\n persona: string,\n): Promise<{ recognized: boolean; resolvedDisplay: string } | null> {\n const res = await fetch(`${apiBaseUrl}/explain`, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n persona,\n sections: getRegisteredSections().map((id) => ({ id })),\n components: getRegistered().map((c) => ({ id: c.id, variantIds: c.variantIds })),\n slots: slotDecls(),\n }),\n });\n if (!res.ok) return null;\n const data = (await res.json()) as OutcomeToApply & {\n recognized?: boolean;\n persona?: string;\n personaDisplay?: string;\n };\n applyOutcome({\n ...data,\n personaAttributes: data.personaAttributes ?? { persona, confidence: 'high' },\n });\n return {\n // An older API omits the field — treat as recognized (no basis to warn).\n recognized: data.recognized !== false,\n resolvedDisplay: data.personaDisplay ?? data.persona ?? persona,\n };\n}\n\n/** Local mode: simulate via the deterministic local engine — zero network. */\nasync function forcePersonaLocal(persona: string, apiKey?: string): Promise<void> {\n const mod = await import('@sentientui/core/local');\n if (!mod.LOCAL_ENGINE_AVAILABLE) return;\n const outcome = mod\n .createLocalEngine({ sessionId: readSessionId(apiKey), forcedPersona: persona })\n .decide({\n sections: getRegisteredSections(),\n components: getRegistered().map((c) => ({ id: c.id, variantIds: c.variantIds })),\n slots: slotDecls(),\n });\n applyOutcome({\n assignments: outcome.assignments,\n layoutOrder: outcome.layoutOrder,\n slots: outcome.slots,\n personaAttributes: {\n persona: outcome.persona,\n confidence: confidenceBand(outcome.confidence),\n },\n });\n}\n\n/** Reset: clear the decision snapshot + every override, then reload to re-decide. */\nfunction resetAll(): void {\n for (const id of Object.keys(getOverrides())) clearVariantOverride(id);\n const w = window as unknown as OverrideWindow;\n delete w.__sentient_layout_override;\n delete w.__sentient_slot_overrides;\n delete document.documentElement.dataset.sentientPersona;\n delete document.documentElement.dataset.sentientConfidence;\n try {\n const stale: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && key.startsWith(SNAPSHOT_STORAGE_KEY_PREFIX)) stale.push(key);\n }\n for (const key of stale) localStorage.removeItem(key);\n } catch {\n /* ignore */\n }\n setPreviewMode(false);\n notifyOverridesChanged();\n try {\n window.location.reload();\n } catch {\n /* jsdom */\n }\n}\n\nconst btn = (active: boolean): CSSProperties => ({\n padding: '2px 8px',\n borderRadius: 4,\n border: '1px solid #444',\n background: active ? '#3b82f6' : '#222',\n color: '#eee',\n cursor: 'pointer',\n});\n\n/** Sentient \"S.\" wordmark, monoline — white strokes for the black launcher button. */\nfunction SentientMark({ size = 26 }: { size?: number } = {}): JSX.Element {\n return (\n <svg width={size} height={size} viewBox=\"0 0 32 32\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M21 9H14C11.2 9 9.8 10.8 9.8 13C9.8 15.4 11.6 16.6 14.5 16.6H18.5C20.5 16.6 20.7 18.2 20.4 19.6\"\n stroke=\"#fff\"\n strokeWidth=\"2.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M10 22H17\" stroke=\"#fff\" strokeWidth=\"2.2\" strokeLinecap=\"round\" />\n <circle cx=\"20.6\" cy=\"22\" r=\"2.1\" fill=\"#fff\" />\n </svg>\n );\n}\n\nexport function AdaptiveDevtools({ apiKey }: { apiKey?: string } = {}): JSX.Element | null {\n const [open, setOpen] = useState(false);\n const [activePersona, setActivePersona] = useState<string | null>(null);\n // The project's vocabulary (keyed mode); null = not loaded → pinned-four\n // fallback. Local mode never fetches: the local engine only knows the\n // pinned four, and its banner already frames everything as simulated.\n const [vocab, setVocab] = useState<VocabMember[] | null>(null);\n // Discovered SHADOW personas — display-only. They never serve until\n // promotion, so there is no button: forcing one would simulate a persona\n // that cannot occur on this project.\n const [discovered, setDiscovered] = useState<VocabMember[]>([]);\n // Set when a forced persona did NOT resolve against the project's\n // vocabulary — the page is showing the default experience and the panel\n // must say so instead of highlighting the button as if the preview worked.\n const [personaNote, setPersonaNote] = useState<string | null>(null);\n const [dragFrom, setDragFrom] = useState<number | null>(null);\n const [mounted, setMounted] = useState(false);\n const [, force] = useReducer((n: number) => n + 1, 0);\n // Re-render when the component/slot registry changes. useSyncExternalStore\n // (not a manual useEffect subscription) so the subscription can't go stale\n // across Next Fast Refresh — a stale listener was why the panel needed a hard\n // refresh to pick up a renamed id.\n useSyncExternalStore(subscribeRegistry, getRegistryVersion, () => 0);\n // Client-mount gate: render nothing during SSR / the first paint so the widget\n // never reads `window` on the server. Lets consumers drop `<AdaptiveDevtools/>`\n // straight into a tree without a `dynamic(..., { ssr: false })` wrapper.\n useEffect(() => setMounted(true), []);\n // Load the project's persona vocabulary once (keyed mode only).\n useEffect(() => {\n if (IS_PROD) return;\n const cfg = readDevtoolsConfig() ?? { apiKey: apiKey ?? '', apiBaseUrl: DEFAULT_API_BASE_URL, isLocal: false };\n if (cfg.isLocal || !cfg.apiKey) return;\n let cancelled = false;\n void fetchPersonaVocabulary(cfg.apiKey, cfg.apiBaseUrl).then((v) => {\n if (cancelled || !v) return;\n setVocab(v.personas);\n setDiscovered(v.discovered);\n });\n return () => { cancelled = true; };\n }, [apiKey]);\n\n // Never render in production, even if imported by mistake. (Hooks run first\n // so the rules of hooks hold regardless of these early returns.)\n if (IS_PROD) return null;\n if (!mounted) return null;\n\n const config: DevtoolsConfig = readDevtoolsConfig() ?? {\n apiKey: apiKey ?? '',\n apiBaseUrl: DEFAULT_API_BASE_URL,\n isLocal: false,\n };\n const useLocalEngine = config.isLocal || !config.apiKey;\n const components = getRegistered();\n const slots = getRegisteredSlots();\n const overrides = getOverrides();\n const slotOverrides = getSlotOverrides();\n const sections = currentLayout();\n const layoutForced = (window as unknown as OverrideWindow).__sentient_layout_override !== undefined;\n\n function onReorder(from: number, to: number): void {\n reorderLayout(from, to);\n force();\n }\n function onResetLayout(): void {\n resetLayout();\n maybeExitPreview();\n force();\n }\n\n // Preview mode stays on while ANY override (variant, slot or layout) is\n // active. Omitting layout here let clearing the last variant re-enable event\n // recording while a previewed section order was still on screen.\n function maybeExitPreview(): void {\n if (\n Object.keys(getOverrides()).length === 0 &&\n Object.keys(getSlotOverrides()).length === 0 &&\n (window as unknown as OverrideWindow).__sentient_layout_override === undefined\n ) {\n setPreviewMode(false);\n }\n }\n\n function choose(id: string, variantId: string): void {\n setVariantOverride(id, variantId);\n setPreviewMode(true);\n notifyOverridesChanged();\n force();\n }\n function resetVariant(id: string): void {\n clearVariantOverride(id);\n maybeExitPreview();\n notifyOverridesChanged();\n force();\n }\n function chooseSlotArm(id: string, arm: string): void {\n setSlotOverride(id, arm);\n setPreviewMode(true);\n notifyOverridesChanged();\n force();\n }\n function chooseSlotDim(id: string, dim: string, value: string, dims: RegisteredSlot['dims']): void {\n const current = getSlotOverrides()[id];\n // Merge onto the existing forced object, or seed from each dim's baseline\n // (first value) so unset dims stay at baseline instead of vanishing.\n const next: Record<string, string> =\n current && typeof current === 'object'\n ? { ...current }\n : Object.fromEntries(Object.entries(dims ?? {}).map(([d, values]) => [d, values[0]!]));\n next[dim] = value;\n setSlotOverride(id, next);\n setPreviewMode(true);\n notifyOverridesChanged();\n force();\n }\n function resetSlot(id: string): void {\n clearSlotOverride(id);\n maybeExitPreview();\n notifyOverridesChanged();\n force();\n }\n function choosePersona(member: VocabMember): void {\n setActivePersona(member.key);\n setPersonaNote(null);\n // .catch: a failed simulate (offline /v1/explain, bad key, failed local\n // dynamic import) is a preview no-op — without the handler it surfaced as\n // an unhandled promise rejection in the console.\n if (useLocalEngine) {\n forcePersonaLocal(member.key, config.apiKey).then(force).catch(() => {});\n return;\n }\n forcePersonaKeyed(config.apiKey, config.apiBaseUrl, member.key)\n .then((r) => {\n if (r && !r.recognized) {\n setPersonaNote(\n `“${member.displayName}” isn’t in this project’s personas — the page is showing the default experience.`,\n );\n }\n force();\n })\n .catch(() => {});\n }\n\n return (\n <div style={{ position: 'fixed', bottom: 16, right: 16, zIndex: 2147483647, fontFamily: 'system-ui' }}>\n {/* Panel stays mounted and animates in/out from the button's corner, so the\n launcher below never shifts. transform-origin is the button (bottom-right). */}\n <div\n aria-hidden={!open}\n style={{\n position: 'absolute',\n bottom: 52,\n right: 0,\n transformOrigin: 'bottom right',\n transition: 'opacity .18s ease, transform .2s cubic-bezier(.16,1,.3,1)',\n opacity: open ? 1 : 0,\n transform: open ? 'translateY(0) scale(1)' : 'translateY(6px) scale(.96)',\n pointerEvents: open ? 'auto' : 'none',\n }}\n >\n <div style={{ width: 300, maxHeight: 460, overflowY: 'auto', background: '#111', color: '#eee',\n borderRadius: 8, padding: 12, boxShadow: '0 8px 30px rgba(0,0,0,.4)', fontSize: 12 }}>\n {config.isLocal && (\n <div style={{ background: '#1e293b', border: '1px solid #334155', borderRadius: 4,\n padding: '6px 8px', marginBottom: 8 }}>\n {LOCAL_MODE_DEVTOOLS_BANNER}\n </div>\n )}\n <div style={{ opacity: .7, marginBottom: 8 }}>\n {components.length} component{components.length === 1 ? '' : 's'} · {getPreviewMode() ? 'preview — writing nothing' : 'live'}\n </div>\n <div style={{ borderBottom: '1px solid #333', paddingBottom: 8, marginBottom: 8 }}>\n <div style={{ opacity: .7, marginBottom: 4 }}>Preview persona</div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {/* Keyed mode renders the project's OWN vocabulary (falling back\n to the pinned four until /v1/personas answers); local mode\n keeps the pinned four the local engine simulates. */}\n {(useLocalEngine ? DEFAULT_PERSONA_CHOICES : vocab ?? DEFAULT_PERSONA_CHOICES).map((p) => (\n <button key={p.key} onClick={() => choosePersona(p)} style={btn(activePersona === p.key)}>\n {p.displayName}\n </button>\n ))}\n {(activePersona !== null || Object.keys(overrides).length > 0 || Object.keys(slotOverrides).length > 0) && (\n <button onClick={resetAll} style={{ ...btn(false), color: '#aaa' }}>\n Reset\n </button>\n )}\n </div>\n {personaNote && (\n <div style={{ marginTop: 6, fontSize: 11, color: '#fbbf24' }}>{personaNote}</div>\n )}\n {!useLocalEngine && discovered.length > 0 && (\n <div style={{ marginTop: 8 }}>\n <div style={{ opacity: .5, fontSize: 11, marginBottom: 4 }}>\n Discovered — not serving yet (promote from the dashboard)\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {discovered.map((p) => (\n <span\n key={p.key}\n title=\"Found by clustering your traffic; it starts serving only after promotion.\"\n style={{ ...btn(false), opacity: .45, cursor: 'default', display: 'inline-block' }}\n >\n {p.displayName}\n </span>\n ))}\n </div>\n </div>\n )}\n </div>\n {sections.length > 0 && (\n <div style={{ borderBottom: '1px solid #333', paddingBottom: 8, marginBottom: 8 }}>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 4 }}>\n <span style={{ opacity: .7 }}>Layout — drag to reorder</span>\n {layoutForced && (\n // Distinct accessible name: the per-variant and per-slot resets\n // below are also labelled \"reset\", and three identical buttons\n // in one panel is ambiguous to a screen reader and to tests.\n <button\n aria-label=\"Reset section order\"\n onClick={onResetLayout}\n style={{ ...btn(false), color: '#aaa' }}\n >\n reset\n </button>\n )}\n </div>\n {/* Drop-on-row inserts at that row's position, so any block can go\n anywhere in one gesture. The whole order is written on each\n drop — see reorderLayout. */}\n <ul aria-label=\"Section order\" style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {sections.map((id, i) => (\n <li\n key={id}\n draggable\n onDragStart={() => setDragFrom(i)}\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => {\n e.preventDefault();\n if (dragFrom !== null) onReorder(dragFrom, i);\n setDragFrom(null);\n }}\n onDragEnd={() => setDragFrom(null)}\n style={{\n display: 'flex', alignItems: 'center', gap: 6, padding: '4px 6px', marginBottom: 2,\n borderRadius: 4, border: '1px solid #262626', cursor: 'grab',\n background: dragFrom === i ? '#1e293b' : '#181818',\n opacity: dragFrom !== null && dragFrom !== i ? .6 : 1,\n }}\n >\n <span style={{ opacity: .4, minWidth: 10, fontVariantNumeric: 'tabular-nums' }}>{i + 1}</span>\n <span aria-hidden=\"true\" style={{ opacity: .35 }}>⠿</span>\n <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>\n {id}\n </span>\n </li>\n ))}\n </ul>\n </div>\n )}\n {components.length === 0 && slots.length === 0 && sections.length === 0 && (\n <div style={{ opacity: .6 }}>No components, sections or slots on this page yet.</div>\n )}\n {components.map((c) => (\n <div key={c.id} style={{ borderTop: '1px solid #333', padding: '8px 0' }}>\n <div style={{ fontWeight: 600 }}>{c.id}{c.goal ? ` · goal: ${c.goal}` : ''}</div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 4 }}>\n {c.variantIds.map((v) => (\n <button key={v} onClick={() => choose(c.id, v)} style={btn(overrides[c.id] === v)}>\n {v}\n </button>\n ))}\n {overrides[c.id] && (\n <button onClick={() => resetVariant(c.id)} style={{ ...btn(false), color: '#aaa' }}>\n reset\n </button>\n )}\n </div>\n </div>\n ))}\n {slots.length > 0 && (\n <div style={{ borderTop: '1px solid #333', paddingTop: 8, marginTop: 4 }}>\n <div style={{ opacity: .7, marginBottom: 4 }}>Slots</div>\n {slots.map((s) => {\n const ov = slotOverrides[s.id];\n return (\n <div key={s.id} style={{ padding: '6px 0' }}>\n <div style={{ fontWeight: 600 }}>{s.id}</div>\n {s.arms && (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 4 }}>\n {s.arms.map((arm) => (\n <button key={arm} onClick={() => chooseSlotArm(s.id, arm)} style={btn(ov === arm)}>\n {arm}\n </button>\n ))}\n </div>\n )}\n {s.dims && Object.entries(s.dims).map(([dim, values]) => (\n <div key={dim} style={{ marginTop: 4 }}>\n <div style={{ opacity: .6, fontSize: 11 }}>{dim}</div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n {values.map((v) => (\n <button\n key={v}\n onClick={() => chooseSlotDim(s.id, dim, v, s.dims)}\n style={btn(!!ov && typeof ov === 'object' && ov[dim] === v)}\n >\n {v}\n </button>\n ))}\n </div>\n </div>\n ))}\n {ov !== undefined && (\n <button onClick={() => resetSlot(s.id)} style={{ ...btn(false), color: '#aaa', marginTop: 4 }}>\n reset\n </button>\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n <button\n aria-label=\"Sentient DevTools\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n style={{ width: 44, height: 44, borderRadius: 12, border: '1px solid #2a2a2a', background: '#000',\n display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 0,\n cursor: 'pointer', boxShadow: '0 6px 18px rgba(0,0,0,.4)' }}\n >\n <SentientMark />\n </button>\n </div>\n );\n}\n","import { isDevBuild } from './adaptive-shared.js';\n\nexport type RegisteredComponent = { id: string; variantIds: string[]; goal?: string };\nexport type RegisteredSlot = {\n id: string;\n arms?: string[];\n dims?: Record<string, readonly string[]>;\n};\n\ntype RegistryState = {\n components: Map<string, RegisteredComponent>;\n slots: Map<string, RegisteredSlot>;\n sections: string[];\n listeners: Set<() => void>;\n /** Bumped on every mutation so `useSyncExternalStore` can read a stable, comparable snapshot. */\n version: number;\n};\n\n// Shared through a window global: the main entry and the /devtools entry are\n// separate bundles, each with its own copy of this module — module-local\n// state would give the devtools an always-empty registry in published apps.\nconst ssrFallback: RegistryState = {\n components: new Map(),\n slots: new Map(),\n sections: [],\n listeners: new Set(),\n version: 0,\n};\n\nfunction state(): RegistryState {\n if (typeof window === 'undefined') return ssrFallback;\n const w = window as unknown as { __sentient_registry?: RegistryState };\n if (!w.__sentient_registry) {\n w.__sentient_registry = {\n components: new Map(),\n slots: new Map(),\n sections: [],\n listeners: new Set(),\n version: 0,\n };\n }\n return w.__sentient_registry;\n}\n\nfunction emit(): void {\n // Bump BEFORE notifying so a useSyncExternalStore consumer re-reading its\n // snapshot inside the notification sees the new value and re-renders.\n state().version += 1;\n for (const fn of state().listeners) fn();\n}\n\n// The registry exists solely to feed the opt-in devtools panel, which is a\n// dev-only surface. In a production build there is no panel reading it, so\n// every register call is dead work plus a `window.__sentient_registry`\n// footprint on the customer's page. Short-circuit to a noop in production —\n// every <Adaptive>/useAdaptive/slot mount calls one of these.\nconst NOOP_UNREGISTER = (): void => undefined;\n\n/** Register (or re-register) a component. Returns an unregister function. */\nexport function registerComponent(c: RegisteredComponent): () => void {\n if (!isDevBuild()) return NOOP_UNREGISTER;\n state().components.set(c.id, c);\n emit();\n return () => {\n state().components.delete(c.id);\n emit();\n };\n}\n\n/** Register (or re-register) a slot declaration. Returns an unregister function. */\nexport function registerSlot(s: RegisteredSlot): () => void {\n if (!isDevBuild()) return NOOP_UNREGISTER;\n state().slots.set(s.id, s);\n emit();\n return () => {\n state().slots.delete(s.id);\n emit();\n };\n}\n\n/** Register the page's declared section ids (from AdaptiveRoot/provider). */\nexport function registerSections(sections: string[]): void {\n if (!isDevBuild()) return;\n state().sections = [...sections];\n emit();\n}\n\nexport function getRegistered(): RegisteredComponent[] {\n return [...state().components.values()];\n}\n\nexport function getRegisteredSlots(): RegisteredSlot[] {\n return [...state().slots.values()];\n}\n\nexport function getRegisteredSections(): string[] {\n return [...state().sections];\n}\n\nexport function subscribeRegistry(fn: () => void): () => void {\n const listeners = state().listeners;\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n\n/** Monotonic snapshot for `useSyncExternalStore` — changes on every registry mutation. */\nexport function getRegistryVersion(): number {\n return state().version;\n}\n","function store(): Record<string, string> {\n const w = window as unknown as { __sentient_overrides?: Record<string, string> };\n if (!w.__sentient_overrides) w.__sentient_overrides = {};\n return w.__sentient_overrides;\n}\n\n/** Force `componentId` to render `variantId` — read by `useAssignment`. */\nexport function setVariantOverride(componentId: string, variantId: string): void {\n store()[componentId] = variantId;\n}\n\nexport function clearVariantOverride(componentId: string): void {\n delete store()[componentId];\n}\n\nexport function getOverrides(): Record<string, string> {\n return { ...store() };\n}\n","import type { SlotResult } from '@sentientui/core';\n\n/**\n * Slot-override store — the channel `useSlotResult` reads (`useAdaptiveTokens` /\n * `AdaptiveGroup`). Separate from `__sentient_overrides` (variant components):\n * a slot result is a token object (`{ tone: 'urgent' }`) or an arm string\n * (`'social_first'`), never a bare variant id. Window-backed so the /devtools\n * bundle and the main bundle share one store.\n */\nfunction store(): Record<string, SlotResult> {\n const w = window as unknown as { __sentient_slot_overrides?: Record<string, SlotResult> };\n if (!w.__sentient_slot_overrides) w.__sentient_slot_overrides = {};\n return w.__sentient_slot_overrides;\n}\n\n/** Force `slotId` to resolve to `result` — read by `useSlotResult`. */\nexport function setSlotOverride(slotId: string, result: SlotResult): void {\n store()[slotId] = result;\n}\n\nexport function clearSlotOverride(slotId: string): void {\n delete store()[slotId];\n}\n\nexport function getSlotOverrides(): Record<string, SlotResult> {\n return { ...store() };\n}\n","import type { SentientClient } from '@sentientui/core';\n\ntype PreviewState = { on: boolean; listeners: Set<() => void> };\nconst ssrFallback: PreviewState = { on: false, listeners: new Set() };\n\n// Window-backed: the /devtools entry (a separate bundle) toggles preview mode\n// and the provider (main bundle) must observe it.\nfunction state(): PreviewState {\n if (typeof window === 'undefined') return ssrFallback;\n const w = window as unknown as { __sentient_preview?: PreviewState };\n if (!w.__sentient_preview) w.__sentient_preview = { on: false, listeners: new Set() };\n return w.__sentient_preview;\n}\n\nexport function setPreviewMode(on: boolean): void {\n const s = state();\n if (s.on === on) return;\n s.on = on;\n for (const fn of s.listeners) fn();\n}\n\nexport function getPreviewMode(): boolean {\n return state().on;\n}\n\nexport function subscribePreview(fn: () => void): () => void {\n const listeners = state().listeners;\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n\n/**\n * Wraps a client so it writes nothing: reads pass through, all emitters no-op.\n * Used while previewing variants/personas so no `variant_assigned`, goal, or\n * session events are sent.\n */\nexport function createPreviewClient(inner: SentientClient): SentientClient {\n return {\n isLocal: inner.isLocal,\n track: () => undefined,\n goal: () => undefined,\n componentGoal: () => undefined,\n identify: () => undefined,\n fetchWeights: () => Promise.resolve([]),\n getAssignment: (componentId, segment) => inner.getAssignment(componentId, segment),\n assign: (componentId, variantIds, agentData, agentDataByVariant) =>\n inner.assign(componentId, variantIds, agentData, agentDataByVariant),\n // Reads pass through; decide is a write (slot decisions persist server-side)\n // so preview mode never issues it.\n decide: () => Promise.resolve(null),\n getSlotResult: (slotId) => inner.getSlotResult(slotId),\n getSlotConfig: (slotId) => inner.getSlotConfig(slotId),\n getSitePalette: () => inner.getSitePalette(),\n reportSlots: (ids) => inner.reportSlots(ids),\n getPersona: () => inner.getPersona(),\n getGraph: () => inner.getGraph(),\n dispose: () => inner.dispose(),\n destroy: () => inner.destroy(),\n };\n}\n","/**\n * Cross-bundle re-render bus for devtools overrides. The main entry and the\n * /devtools entry are separate bundles, so state and notifications go through\n * window (a version counter + a DOM event) — never module-local state.\n */\nconst EVENT = 'sentient:overrides-changed';\n\ntype VersionWindow = Window & { __sentient_overrides_version?: number };\n\nexport function getOverridesVersion(): number {\n if (typeof window === 'undefined') return 0;\n return (window as VersionWindow).__sentient_overrides_version ?? 0;\n}\n\nexport function notifyOverridesChanged(): void {\n if (typeof window === 'undefined') return;\n const w = window as VersionWindow;\n w.__sentient_overrides_version = (w.__sentient_overrides_version ?? 0) + 1;\n window.dispatchEvent(new Event(EVENT));\n}\n\nexport function subscribeOverridesChanged(fn: () => void): () => void {\n if (typeof window === 'undefined') return () => undefined;\n window.addEventListener(EVENT, fn);\n return () => window.removeEventListener(EVENT, fn);\n}\n","/** Provider → devtools config handoff. Window-backed: the /devtools entry is a\n * separate bundle and cannot share the provider's React context instance. */\nexport type DevtoolsConfig = {\n apiKey: string;\n apiBaseUrl: string;\n isLocal: boolean;\n};\n\ntype ConfigWindow = Window & { __sentient_devtools_config?: DevtoolsConfig };\n\nexport function publishDevtoolsConfig(config: DevtoolsConfig): void {\n if (typeof window === 'undefined') return;\n (window as ConfigWindow).__sentient_devtools_config = config;\n}\n\nexport function readDevtoolsConfig(): DevtoolsConfig | null {\n if (typeof window === 'undefined') return null;\n return (window as ConfigWindow).__sentient_devtools_config ?? null;\n}\n"],"mappings":"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","names":["useEffect","useReducer","useState","useSyncExternalStore","PERSONAS","PERSONA_DISPLAY","confidenceBand","LEGACY_SESSION_COOKIE_NAME","SNAPSHOT_STORAGE_KEY_PREFIX","sessionCookieName","ssrFallback","state","w","getRegistered","state","getRegisteredSlots","getRegisteredSections","subscribeRegistry","fn","listeners","getRegistryVersion","store","w","setVariantOverride","componentId","variantId","clearVariantOverride","getOverrides","__spreadValues","store","w","setSlotOverride","slotId","result","clearSlotOverride","getSlotOverrides","__spreadValues","ssrFallback","state","w","setPreviewMode","on","s","fn","getPreviewMode","EVENT","notifyOverridesChanged","_a","w","EVENT","readDevtoolsConfig","_a","jsx","jsxs","_a","IS_PROD","DEFAULT_API_BASE_URL","LOCAL_MODE_DEVTOOLS_BANNER","currentLayout","forced","registered","getRegisteredSections","id","reorderLayout","from","to","order","next","moved","setPreviewMode","notifyOverridesChanged","resetLayout","applyOutcome","result","_b","variantId","setVariantOverride","w","__spreadValues","readSessionId","apiKey","read","name","match","e","sessionCookieName","LEGACY_SESSION_COOKIE_NAME","slotDecls","getRegisteredSlots","s","DEFAULT_PERSONA_CHOICES","PERSONAS","key","PERSONA_DISPLAY","fetchPersonaVocabulary","apiBaseUrl","res","data","valid","list","p","personas","forcePersonaKeyed","persona","_c","getRegistered","c","__spreadProps","forcePersonaLocal","mod","outcome","confidenceBand","resetAll","getOverrides","clearVariantOverride","stale","i","SNAPSHOT_STORAGE_KEY_PREFIX","btn","active","SentientMark","size","AdaptiveDevtools","open","setOpen","useState","activePersona","setActivePersona","vocab","setVocab","discovered","setDiscovered","personaNote","setPersonaNote","dragFrom","setDragFrom","mounted","setMounted","force","useReducer","useSyncExternalStore","subscribeRegistry","getRegistryVersion","useEffect","cfg","readDevtoolsConfig","cancelled","config","useLocalEngine","components","slots","overrides","slotOverrides","getSlotOverrides","sections","layoutForced","onReorder","onResetLayout","maybeExitPreview","choose","resetVariant","chooseSlotArm","arm","setSlotOverride","chooseSlotDim","dim","value","dims","current","d","values","resetSlot","clearSlotOverride","choosePersona","member","getPreviewMode","v","ov","o"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, JSX } from 'react';
|
|
3
|
-
import { SentientConfig, SlotResult, SentientClient, MicroSignalType, ComponentGoalOptions } from '@sentientui/core';
|
|
3
|
+
import { SentientConfig, SlotResult, SlotConfigEntry, SitePalette, SentientClient, MicroSignalType, ComponentGoalOptions } from '@sentientui/core';
|
|
4
4
|
export { deriveSessionSegment as detectSegment, grantConsent } from '@sentientui/core';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -107,6 +107,15 @@ type AdaptiveProviderProps = {
|
|
|
107
107
|
* render the decided arm in server HTML — zero flicker, hydration-safe.
|
|
108
108
|
*/
|
|
109
109
|
initialSlots?: Record<string, SlotResult>;
|
|
110
|
+
/**
|
|
111
|
+
* SSR-preloaded registry slot config from `loadAdaptiveDecision()` (the
|
|
112
|
+
* `slotConfig` field of its result, registry mode). Lets `AdaptiveSlot`
|
|
113
|
+
* render server-authored content/blocks in server HTML — zero flicker.
|
|
114
|
+
*/
|
|
115
|
+
initialSlotConfig?: Record<string, SlotConfigEntry>;
|
|
116
|
+
/** SSR-preloaded site palette (`palette` field of `loadAdaptiveDecision()`'s
|
|
117
|
+
* registry-mode result) for block rendering. */
|
|
118
|
+
initialPalette?: SitePalette;
|
|
110
119
|
/**
|
|
111
120
|
* Persona decided during SSR (`persona` + `confidence` fields of
|
|
112
121
|
* `loadAdaptiveDecision()`'s result). Adopted by the core client;
|
|
@@ -485,6 +494,27 @@ type UseAdaptiveTokensResult = {
|
|
|
485
494
|
*/
|
|
486
495
|
declare function useAdaptiveTokens(id: string, dims: Record<string, readonly string[]>, opts?: UseAdaptiveTokensOptions): UseAdaptiveTokensResult;
|
|
487
496
|
|
|
497
|
+
type AdaptiveSlotProps = {
|
|
498
|
+
id: string;
|
|
499
|
+
/** Baseline JSX — holdout, unknown personas, empty cells, every error path. */
|
|
500
|
+
children: ReactNode;
|
|
501
|
+
/** Receives form values when a generated form arm submits. Without it, form
|
|
502
|
+
* arms fall back to children entirely. Values never reach Sentient. */
|
|
503
|
+
onFormSubmit?: (values: Record<string, string>) => void;
|
|
504
|
+
/** Optional goal attached to the container (click/scroll/composite), same
|
|
505
|
+
* shape as AdaptiveGroup's. Form arms fire their own submitGoal regardless. */
|
|
506
|
+
goal?: string | GoalConfig;
|
|
507
|
+
className?: string;
|
|
508
|
+
};
|
|
509
|
+
/**
|
|
510
|
+
* A region whose content the server may replace with a named arm — a copy
|
|
511
|
+
* string or a validated Composition Block tree (registry slot config). The
|
|
512
|
+
* children are the founder's baseline: they render untouched for holdout
|
|
513
|
+
* traffic, unserved slots, and every error path, so the worst case is always
|
|
514
|
+
* "nothing changed" (spec 2026-09-08 empty-cell-generation §3).
|
|
515
|
+
*/
|
|
516
|
+
declare function AdaptiveSlot({ id, children, onFormSubmit, goal, className }: AdaptiveSlotProps): JSX.Element;
|
|
517
|
+
|
|
488
518
|
type UseAdaptiveBind = {
|
|
489
519
|
ref: (el: HTMLElement | null) => void;
|
|
490
520
|
'data-sentient-id': string;
|
|
@@ -644,4 +674,4 @@ declare function renderAgentJsonLdBody(feed: AgentFeed): string;
|
|
|
644
674
|
/** Render the feed as Markdown for agents that negotiate `text/markdown`. */
|
|
645
675
|
declare function renderAgentMarkdown(feed: AgentFeed): string;
|
|
646
676
|
|
|
647
|
-
export { Adaptive, AdaptiveGroup, type AdaptiveGroupProps, type AdaptivePersona, type AdaptiveProps, AdaptiveProvider, type AdaptiveProviderProps, AdaptiveText, type AdaptiveTextProps, type AgentBlock, type AgentFeed, type AssignmentState, type ClickGoal, type ComponentWeights, type CompositeGoal, type FireGoal, type FormSubmitGoal, type GoalConfig, type MicroSignalGoalConfig, type MicroSignalGoals, type PageGoalOptions, type ScrollDepthGoal, SentientPersonaScript, type SentientPersonaScriptProps, type SsrFallback, type UseAdaptiveBind, type UseAdaptiveResult, type UseAdaptiveTokensOptions, type UseAdaptiveTokensResult, type VariantWeight, type WeightedCompositeGoal, type WeightedStep, buildAgentFeed, defineAgentContent, getAgentContent, renderAgentJsonLd, renderAgentJsonLdBody, renderAgentMarkdown, useAdaptive, useAdaptiveApiBaseUrl, useAdaptiveGoal, useAdaptivePersona, useAdaptiveTokens, useAssignment, useInitialAssignments, useLayoutOrder, usePageGoal, useSentient };
|
|
677
|
+
export { Adaptive, AdaptiveGroup, type AdaptiveGroupProps, type AdaptivePersona, type AdaptiveProps, AdaptiveProvider, type AdaptiveProviderProps, AdaptiveSlot, type AdaptiveSlotProps, AdaptiveText, type AdaptiveTextProps, type AgentBlock, type AgentFeed, type AssignmentState, type ClickGoal, type ComponentWeights, type CompositeGoal, type FireGoal, type FormSubmitGoal, type GoalConfig, type MicroSignalGoalConfig, type MicroSignalGoals, type PageGoalOptions, type ScrollDepthGoal, SentientPersonaScript, type SentientPersonaScriptProps, type SsrFallback, type UseAdaptiveBind, type UseAdaptiveResult, type UseAdaptiveTokensOptions, type UseAdaptiveTokensResult, type VariantWeight, type WeightedCompositeGoal, type WeightedStep, buildAgentFeed, defineAgentContent, getAgentContent, renderAgentJsonLd, renderAgentJsonLdBody, renderAgentMarkdown, useAdaptive, useAdaptiveApiBaseUrl, useAdaptiveGoal, useAdaptivePersona, useAdaptiveTokens, useAssignment, useInitialAssignments, useLayoutOrder, usePageGoal, useSentient };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, JSX } from 'react';
|
|
3
|
-
import { SentientConfig, SlotResult, SentientClient, MicroSignalType, ComponentGoalOptions } from '@sentientui/core';
|
|
3
|
+
import { SentientConfig, SlotResult, SlotConfigEntry, SitePalette, SentientClient, MicroSignalType, ComponentGoalOptions } from '@sentientui/core';
|
|
4
4
|
export { deriveSessionSegment as detectSegment, grantConsent } from '@sentientui/core';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -107,6 +107,15 @@ type AdaptiveProviderProps = {
|
|
|
107
107
|
* render the decided arm in server HTML — zero flicker, hydration-safe.
|
|
108
108
|
*/
|
|
109
109
|
initialSlots?: Record<string, SlotResult>;
|
|
110
|
+
/**
|
|
111
|
+
* SSR-preloaded registry slot config from `loadAdaptiveDecision()` (the
|
|
112
|
+
* `slotConfig` field of its result, registry mode). Lets `AdaptiveSlot`
|
|
113
|
+
* render server-authored content/blocks in server HTML — zero flicker.
|
|
114
|
+
*/
|
|
115
|
+
initialSlotConfig?: Record<string, SlotConfigEntry>;
|
|
116
|
+
/** SSR-preloaded site palette (`palette` field of `loadAdaptiveDecision()`'s
|
|
117
|
+
* registry-mode result) for block rendering. */
|
|
118
|
+
initialPalette?: SitePalette;
|
|
110
119
|
/**
|
|
111
120
|
* Persona decided during SSR (`persona` + `confidence` fields of
|
|
112
121
|
* `loadAdaptiveDecision()`'s result). Adopted by the core client;
|
|
@@ -485,6 +494,27 @@ type UseAdaptiveTokensResult = {
|
|
|
485
494
|
*/
|
|
486
495
|
declare function useAdaptiveTokens(id: string, dims: Record<string, readonly string[]>, opts?: UseAdaptiveTokensOptions): UseAdaptiveTokensResult;
|
|
487
496
|
|
|
497
|
+
type AdaptiveSlotProps = {
|
|
498
|
+
id: string;
|
|
499
|
+
/** Baseline JSX — holdout, unknown personas, empty cells, every error path. */
|
|
500
|
+
children: ReactNode;
|
|
501
|
+
/** Receives form values when a generated form arm submits. Without it, form
|
|
502
|
+
* arms fall back to children entirely. Values never reach Sentient. */
|
|
503
|
+
onFormSubmit?: (values: Record<string, string>) => void;
|
|
504
|
+
/** Optional goal attached to the container (click/scroll/composite), same
|
|
505
|
+
* shape as AdaptiveGroup's. Form arms fire their own submitGoal regardless. */
|
|
506
|
+
goal?: string | GoalConfig;
|
|
507
|
+
className?: string;
|
|
508
|
+
};
|
|
509
|
+
/**
|
|
510
|
+
* A region whose content the server may replace with a named arm — a copy
|
|
511
|
+
* string or a validated Composition Block tree (registry slot config). The
|
|
512
|
+
* children are the founder's baseline: they render untouched for holdout
|
|
513
|
+
* traffic, unserved slots, and every error path, so the worst case is always
|
|
514
|
+
* "nothing changed" (spec 2026-09-08 empty-cell-generation §3).
|
|
515
|
+
*/
|
|
516
|
+
declare function AdaptiveSlot({ id, children, onFormSubmit, goal, className }: AdaptiveSlotProps): JSX.Element;
|
|
517
|
+
|
|
488
518
|
type UseAdaptiveBind = {
|
|
489
519
|
ref: (el: HTMLElement | null) => void;
|
|
490
520
|
'data-sentient-id': string;
|
|
@@ -644,4 +674,4 @@ declare function renderAgentJsonLdBody(feed: AgentFeed): string;
|
|
|
644
674
|
/** Render the feed as Markdown for agents that negotiate `text/markdown`. */
|
|
645
675
|
declare function renderAgentMarkdown(feed: AgentFeed): string;
|
|
646
676
|
|
|
647
|
-
export { Adaptive, AdaptiveGroup, type AdaptiveGroupProps, type AdaptivePersona, type AdaptiveProps, AdaptiveProvider, type AdaptiveProviderProps, AdaptiveText, type AdaptiveTextProps, type AgentBlock, type AgentFeed, type AssignmentState, type ClickGoal, type ComponentWeights, type CompositeGoal, type FireGoal, type FormSubmitGoal, type GoalConfig, type MicroSignalGoalConfig, type MicroSignalGoals, type PageGoalOptions, type ScrollDepthGoal, SentientPersonaScript, type SentientPersonaScriptProps, type SsrFallback, type UseAdaptiveBind, type UseAdaptiveResult, type UseAdaptiveTokensOptions, type UseAdaptiveTokensResult, type VariantWeight, type WeightedCompositeGoal, type WeightedStep, buildAgentFeed, defineAgentContent, getAgentContent, renderAgentJsonLd, renderAgentJsonLdBody, renderAgentMarkdown, useAdaptive, useAdaptiveApiBaseUrl, useAdaptiveGoal, useAdaptivePersona, useAdaptiveTokens, useAssignment, useInitialAssignments, useLayoutOrder, usePageGoal, useSentient };
|
|
677
|
+
export { Adaptive, AdaptiveGroup, type AdaptiveGroupProps, type AdaptivePersona, type AdaptiveProps, AdaptiveProvider, type AdaptiveProviderProps, AdaptiveSlot, type AdaptiveSlotProps, AdaptiveText, type AdaptiveTextProps, type AgentBlock, type AgentFeed, type AssignmentState, type ClickGoal, type ComponentWeights, type CompositeGoal, type FireGoal, type FormSubmitGoal, type GoalConfig, type MicroSignalGoalConfig, type MicroSignalGoals, type PageGoalOptions, type ScrollDepthGoal, SentientPersonaScript, type SentientPersonaScriptProps, type SsrFallback, type UseAdaptiveBind, type UseAdaptiveResult, type UseAdaptiveTokensOptions, type UseAdaptiveTokensResult, type VariantWeight, type WeightedCompositeGoal, type WeightedStep, buildAgentFeed, defineAgentContent, getAgentContent, renderAgentJsonLd, renderAgentJsonLdBody, renderAgentMarkdown, useAdaptive, useAdaptiveApiBaseUrl, useAdaptiveGoal, useAdaptivePersona, useAdaptiveTokens, useAssignment, useInitialAssignments, useLayoutOrder, usePageGoal, useSentient };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
"use strict";var Lt=Object.create;var Y=Object.defineProperty,Dt=Object.defineProperties,Tt=Object.getOwnPropertyDescriptor,Pt=Object.getOwnPropertyDescriptors,Ft=Object.getOwnPropertyNames,ne=Object.getOwnPropertySymbols,Mt=Object.getPrototypeOf,ve=Object.prototype.hasOwnProperty,Ee=Object.prototype.propertyIsEnumerable;var Oe=(e,t,n)=>t in e?Y(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,k=(e,t)=>{for(var n in t||(t={}))ve.call(t,n)&&Oe(e,n,t[n]);if(ne)for(var n of ne(t))Ee.call(t,n)&&Oe(e,n,t[n]);return e},re=(e,t)=>Dt(e,Pt(t));var Ie=(e,t)=>{var n={};for(var r in e)ve.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&ne)for(var r of ne(e))t.indexOf(r)<0&&Ee.call(e,r)&&(n[r]=e[r]);return n};var Kt=(e,t)=>{for(var n in t)Y(e,n,{get:t[n],enumerable:!0})},Le=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Ft(t))!ve.call(e,i)&&i!==n&&Y(e,i,{get:()=>t[i],enumerable:!(r=Tt(t,i))||r.enumerable});return e};var De=(e,t,n)=>(n=e!=null?Lt(Mt(e)):{},Le(t||!e||!e.__esModule?Y(n,"default",{value:e,enumerable:!0}):n,e)),Bt=e=>Le(Y({},"__esModule",{value:!0}),e);var qt={};Kt(qt,{Adaptive:()=>ot,AdaptiveGroup:()=>_t,AdaptiveProvider:()=>qe,AdaptiveText:()=>at,SentientPersonaScript:()=>gt,buildAgentFeed:()=>Rt,defineAgentContent:()=>Gt,detectSegment:()=>xe.deriveSessionSegment,getAgentContent:()=>_e,grantConsent:()=>It.grantConsent,renderAgentJsonLd:()=>Ot,renderAgentJsonLdBody:()=>ke,renderAgentMarkdown:()=>Et,useAdaptive:()=>xt,useAdaptiveApiBaseUrl:()=>nt,useAdaptiveGoal:()=>ge,useAdaptivePersona:()=>yt,useAdaptiveTokens:()=>bt,useAssignment:()=>Q,useInitialAssignments:()=>le,useLayoutOrder:()=>Ze,usePageGoal:()=>ut,useSentient:()=>O});module.exports=Bt(qt);var A=require("react"),ae=require("@sentientui/core");var Te=new Map,ie=new Map;function Pe(e,t){let n=ie.get(e);return n||(n=new Set,ie.set(e,n)),n.add(t),()=>{n.delete(t),n.size===0&&ie.delete(e)}}function Fe(e,t){Te.set(e,t);let n=ie.get(e);if(n)for(let r of n)try{r(t)}catch(i){}}function ye(e){var t;return(t=Te.get(e))!=null?t:null}var jt={on:!1,listeners:new Set};function Me(){if(typeof window=="undefined")return jt;let e=window;return e.__sentient_preview||(e.__sentient_preview={on:!1,listeners:new Set}),e.__sentient_preview}function Se(){return Me().on}function Ke(e){let t=Me().listeners;return t.add(e),()=>{t.delete(e)}}function Be(e){return{isLocal:e.isLocal,track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},fetchWeights:()=>Promise.resolve([]),getAssignment:(t,n)=>e.getAssignment(t,n),assign:(t,n,r,i)=>e.assign(t,n,r,i),decide:()=>Promise.resolve(null),getSlotResult:t=>e.getSlotResult(t),getPersona:()=>e.getPersona(),getGraph:()=>e.getGraph(),dispose:()=>e.dispose(),destroy:()=>e.destroy()}}var je="sentient:overrides-changed";function $e(){var e;return typeof window=="undefined"?0:(e=window.__sentient_overrides_version)!=null?e:0}function N(e){return typeof window=="undefined"?()=>{}:(window.addEventListener(je,e),()=>window.removeEventListener(je,e))}function Ve(e){typeof window!="undefined"&&(window.__sentient_devtools_config=e)}function R(){var e;return typeof process=="undefined"||((e=process.env)==null?void 0:e.NODE_ENV)!=="production"}function P(e){return typeof e=="string"?{type:"click"}:e}function X(e){return typeof e=="string"?e:e.type}function j(e){if(typeof e!="string"&&(e.type==="click"||e.type==="form_submit"||e.type==="scroll_depth"))return e.value}var he=new Set,be=!1;function Ne(e){if(he.has(e))return!0;if(he.add(e),!be){be=!0;let t=()=>{be=!1,he.clear()};if(typeof MessageChannel=="function"){let n=new MessageChannel;n.port1.onmessage=()=>{n.port1.close(),n.port2.close(),t()},n.port2.postMessage(0)}else setTimeout(t,0)}return!1}function $t(e){if(!(e instanceof Element))return!1;let t=e.tagName.toLowerCase();return t==="a"||t==="button"?!0:e.getAttribute("role")==="button"}function We(e,t,n){if(n){try{let i=e;for(;i&&i!==t;){if(i.matches(n))return!0;i=i.parentElement}}catch(i){}return!1}let r=e;for(;r&&r!==t;){if($t(r))return!0;r=r.parentElement}return!1}function $(e,t,n,r){if(t.type==="weighted_composite"){let c=new Set,m=[];return t.steps.forEach(({goal:g,name:v,weight:C},w)=>{let x=(u=!1)=>{c.has(w)||u&&r!==void 0&&Ne(`step\0${v}\0${C}\0${w}`)||(c.add(w),n.fireStep(v,C,w))};if(g.type==="click"){let u=s=>{let a=s.target;a instanceof Element&&We(a,e,g.selector)&&x()};e.addEventListener("click",u),m.push(()=>e.removeEventListener("click",u));return}if(g.type==="form_submit"){let u=s=>{s.target instanceof HTMLFormElement&&e.contains(s.target)&&x()};e.addEventListener("submit",u),m.push(()=>e.removeEventListener("submit",u));return}if(g.type==="scroll_depth"){let u=Math.max(0,Math.min(1,g.threshold)),s=new IntersectionObserver(a=>{for(let p of a)if(p.intersectionRatio>=u){x(!0),s.disconnect();break}},{threshold:[u]});s.observe(e),m.push(()=>s.disconnect())}}),()=>{for(let g of m)g()}}let i=t.type==="composite"?t.all:[t],o=new Set(i.map((c,m)=>m)),f=()=>{r!==void 0&&Ne(r)||n.fireGoal()},l=(c,m=!1)=>{o.delete(c),o.size===0&&(m?f():n.fireGoal())},d=[];return i.forEach((c,m)=>{if(c.type==="click"){let g=v=>{let C=v.target;C instanceof Element&&We(C,e,c.selector)&&(t.type==="composite"?l(m):n.fireGoal())};e.addEventListener("click",g),d.push(()=>e.removeEventListener("click",g));return}if(c.type==="form_submit"){let g=v=>{v.target instanceof HTMLFormElement&&e.contains(v.target)&&(t.type==="composite"?l(m):n.fireGoal())};e.addEventListener("submit",g),d.push(()=>e.removeEventListener("submit",g));return}if(c.type==="scroll_depth"){let g=Math.max(0,Math.min(1,c.threshold)),v=new IntersectionObserver(C=>{for(let w of C)if(w.intersectionRatio>=g){t.type==="composite"?l(m,!0):f(),v.disconnect();break}},{threshold:[g]});v.observe(e),d.push(()=>v.disconnect());return}}),()=>{for(let c of d)c()}}var Ue=new Set,Je=new Set;function U(e,t,n,r,i){let o=`${r}|${n}`;if(Je.has(o))return;Je.add(o);let f=i.type==="weighted_composite"&&!Ue.has(r);f&&Ue.add(r),e.track({projectId:t,componentId:n,eventType:"funnel_declared",payload:f?{funnelId:r,steps:i.steps.map(l=>({goalId:l.name,weight:l.weight}))}:{funnelId:r}})}function J(e,t,n,r){e.track({projectId:t,componentId:n,variantId:r,eventType:"variant_assigned",payload:{}})}var Vt={components:new Map,slots:new Map,sections:[],listeners:new Set,version:0};function H(){if(typeof window=="undefined")return Vt;let e=window;return e.__sentient_registry||(e.__sentient_registry={components:new Map,slots:new Map,sections:[],listeners:new Set,version:0}),e.__sentient_registry}function Z(){H().version+=1;for(let e of H().listeners)e()}var He=()=>{};function oe(e){return R()?(H().components.set(e.id,e),Z(),()=>{H().components.delete(e.id),Z()}):He}function se(e){return R()?(H().slots.set(e.id,e),Z(),()=>{H().slots.delete(e.id),Z()}):He}function we(e){R()&&(H().sections=[...e],Z())}var ze="0.28.0",Ae=ze!=="0.0.0-dev"?{name:"react",version:ze}:void 0;var rt=require("react/jsx-runtime");function Nt(){var e,t;if(typeof window=="undefined")return"desktop:direct";try{return(0,ae.deriveSessionSegment)({userAgent:(e=navigator.userAgent)!=null?e:"",referer:(t=document.referrer)!=null?t:"",appOrigin:window.location.origin})}catch(n){return"desktop:direct"}}var Xe="https://api.sentient-ui.com/v1",F=(0,A.createContext)({client:null,apiKey:"",initialAssignments:{},sessionSegment:"desktop:direct",ssrFallback:"first",onAssignment:void 0,initialLayoutOrder:null,initialSlots:{},initialPersona:null,apiBaseUrl:Xe,debug:!1});function Wt(e){let[t,n]=(0,A.useState)(!1),r=(0,A.useRef)(e);r.current=e;let{cookie:i,value:o,event:f}=e!=null?e:{},l=typeof(e==null?void 0:e.check)=="function";return(0,A.useEffect)(()=>{let d=()=>{var v;let m=r.current;if(!m)return!1;if(m.check)return m.check()===!0;if(!m.cookie||typeof document=="undefined")return!1;let g=`${m.cookie}=${(v=m.value)!=null?v:"accepted"}`;return document.cookie.split("; ").some(C=>C.trim()===g)};if(n(d()),!f)return;let c=()=>{n(d())};return window.addEventListener(f,c),()=>window.removeEventListener(f,c)},[i,o,f,l]),t}function qe(e){var w,x;let[t,n]=(0,A.useState)(null),[r]=(0,A.useState)(()=>{var u;return(u=e.sessionSegment)!=null?u:Nt()}),[i,o]=(0,A.useState)(Se());(0,A.useEffect)(()=>Ke(()=>o(Se())),[]);let f=Wt(e.consentFrom),l=e.consentFrom?e.consent===!0||f:e.consent,d=(0,A.useRef)(null);(0,A.useEffect)(()=>{var _;if(l===!1&&!e.preConsentBehavior){(_=d.current)==null||_.destroy(),d.current=null,n(null);return}let u=k({apiKey:e.apiKey,context:e.context,debug:e.debug,initialAssignments:e.initialAssignments,sessionSegment:r,consent:l,preConsentBehavior:e.preConsentBehavior,respectDoNotTrack:e.respectDoNotTrack,ssrSessionId:e.ssrSessionId,country:e.country,persona:e.persona,localMode:e.localMode,initialSlots:e.initialSlots,initialPersona:e.initialPersona,ingestUrl:e.apiBaseUrl?`${e.apiBaseUrl.replace(/\/$/,"")}/events`:void 0},Ae?{sdk:Ae}:{}),s=!1,a=null,p=null,h=G=>{e.engagement!==!1&&import("@sentientui/core/engagement").then(({startEngagementCapture:S})=>{s||(p=S(G,{apiKey:e.apiKey,apiBase:e.apiBaseUrl?e.apiBaseUrl.replace(/\/$/,""):void 0}))})};return e.enableGraph!==!1?import("@sentientui/core/graph").then(({init:G})=>{s||(a=G(re(k({},u),{graph:!0,captureDomText:e.captureDomText===!0})),d.current=a,n(a),h(a))}):(a=(0,ae.init)(u),d.current=a,n(a),h(a)),()=>{s=!0,p==null||p(),a==null||a.dispose()}},[l]),(0,A.useEffect)(()=>{if(!t)return;let u=!1,s=async()=>{if(u)return;let p;try{p=await t.fetchWeights()}catch(h){return}if(!u)for(let h of p){let _={componentId:h.componentId,updatedAt:h.updatedAt,variants:h.variants.map(G=>{var S;return{variantId:G.variantId,pulls:G.pulls,avgReward:(S=G.avgReward)!=null?S:0}})};Fe(h.componentId,_)}};s();let a=setInterval(()=>{s()},6e4);return()=>{u=!0,clearInterval(a)}},[t]);let c=(w=e.ssrFallback)!=null?w:"first",m=((x=e.apiBaseUrl)!=null?x:Xe).replace(/\/$/,""),g=(0,A.useRef)(null);(0,A.useEffect)(()=>{var a;if(typeof process!="undefined"&&((a=process.env)==null?void 0:a.NODE_ENV)==="production")return;let u={apiKey:e.apiKey,context:e.context,country:e.country,persona:e.persona,apiBaseUrl:m},s=g.current;if(g.current=u,s!==null)for(let p of["apiKey","context","country","persona","apiBaseUrl"])Object.is(s[p],u[p])||console.warn(`[sentient] AdaptiveProvider: \`${p}\` changed after initialisation, but the SDK client is stable for the session and only re-inits on \`consent\` \u2014 the new value is ignored. Remount the provider (e.g. via a changing \`key\` prop) to apply it.`)},[e.apiKey,e.context,e.country,e.persona,m]),(0,A.useEffect)(()=>{var u;typeof process!="undefined"&&((u=process.env)==null?void 0:u.NODE_ENV)==="production"||Ve({apiKey:e.apiKey,apiBaseUrl:m,isLocal:(t==null?void 0:t.isLocal)===!0})},[t,e.apiKey,m]),(0,A.useEffect)(()=>{let u=e.initialLayoutOrder;if(u&&u.length>0){we(u);return}e.declaredSections&&e.declaredSections.length>0&&we(e.declaredSections)},[e.initialLayoutOrder,e.declaredSections]),(0,A.useEffect)(()=>{if(!R())return;let u=e.declaredSections;if(!u||u.length===0||typeof document=="undefined")return;let s=new Set(Array.from(document.querySelectorAll("[data-sentient-id]"),p=>p.getAttribute("data-sentient-id"))),a=u.filter(p=>!s.has(p));a.length>0&&console.warn(`[SentientUI] Declared section${a.length>1?"s":""} ${a.map(p=>`"${p}"`).join(", ")} ${a.length>1?"have":"has"} no matching data-sentient-id element, so the layout engine cannot learn what they are and will serve the same order to every persona. Add data-sentient-id="<sectionId>" (plus optional data-sentient-type) to each section's element.`)},[e.declaredSections]);let v=(0,A.useMemo)(()=>t&&i?Be(t):t,[t,i]),C=(0,A.useMemo)(()=>{var u,s,a,p,h;return{client:v,apiKey:e.apiKey,initialAssignments:(u=e.initialAssignments)!=null?u:{},sessionSegment:r,ssrFallback:c,onAssignment:e.onAssignment,initialLayoutOrder:(s=e.initialLayoutOrder)!=null?s:null,initialSlots:(a=e.initialSlots)!=null?a:{},initialPersona:(p=e.initialPersona)!=null?p:null,apiBaseUrl:m,debug:(h=e.debug)!=null?h:!1}},[v,e.apiKey,e.initialAssignments,r,c,e.onAssignment,e.initialLayoutOrder,e.initialSlots,e.initialPersona,m,e.debug]);return(0,rt.jsx)(F.Provider,{value:C,children:e.children})}function O(){return(0,A.useContext)(F).client}function V(){return(0,A.useContext)(F).apiKey}function le(){return(0,A.useContext)(F).initialAssignments}function ue(){return(0,A.useContext)(F).sessionSegment}function Qe(){return(0,A.useContext)(F).ssrFallback}function ce(){return(0,A.useContext)(F).onAssignment}function Ye(){return(0,A.useContext)(F).debug}function Ze(){let e=(0,A.useContext)(F).initialLayoutOrder,t=(0,A.useSyncExternalStore)(N,()=>{var n;return typeof window=="undefined"?null:(n=window.__sentient_layout_override)!=null?n:null},()=>null);return t!=null?t:e}function et(){return(0,A.useContext)(F).initialSlots}function tt(){return(0,A.useContext)(F).initialPersona}function nt(){return(0,A.useContext)(F).apiBaseUrl}var E=require("react"),it=require("@sentientui/core");var M=require("react"),de=require("@sentientui/policy");function q(e){var n;if(typeof window=="undefined")return null;let t=(n=window.__sentient_overrides)==null?void 0:n[e];if(t)return t;if(!window.location.search)return null;try{let r=new URLSearchParams(window.location.search);for(let i of r.getAll("sentient_variant")){let o=i.indexOf(":");if(o!==-1&&i.slice(0,o)===e)return i.slice(o+1)}}catch(r){}return null}function Q(e,t,n,r){let i=le(),o=Qe(),f=O(),l=ue(),d=ce(),c=Ye(),m=(0,M.useRef)(null),g=(0,M.useSyncExternalStore)(N,()=>q(e),()=>null),v=g&&t.includes(g)?g:null,C=(0,M.useRef)(null);(0,M.useEffect)(()=>{c&&v&&C.current!==v&&(C.current=v,console.info(`[sentient] override active: ${e} -> ${v}`))},[c,v,e]);let[w,x]=(0,M.useState)(()=>{var p,h;if(v)return{variantId:v,content:null,isLoading:!1,settled:!0};if(!f){let _=i[e];return _&&t.includes(_)?{variantId:_,content:null,isLoading:!1,settled:!0}:o==="first"&&t.length>0?{variantId:t[0],content:null,isLoading:!1,settled:!1}:{variantId:null,content:null,isLoading:!0,settled:!1}}let s=f.getAssignment(e,l);if(s&&(t.includes(s.variantId)||s.content))return{variantId:s.variantId,content:(p=s.content)!=null?p:null,isLoading:!1,settled:!0};let a=ye(e);if(a){let _=(0,de.pickFromWeights)(a.variants,t);if(_)return{variantId:_,content:null,isLoading:!1,settled:!0}}return{variantId:(h=t[0])!=null?h:null,content:null,isLoading:!1,settled:!1}}),u=s=>{d&&m.current!==s&&(m.current=s,d(e,s))};return(0,M.useEffect)(()=>{var p;if(v||!f)return;let s=f.getAssignment(e,l);if(s&&(t.includes(s.variantId)||s.content)){x({variantId:s.variantId,content:(p=s.content)!=null?p:null,isLoading:!1,settled:!0}),u(s.variantId);return}let a=ye(e);if(a&&w.settled&&w.variantId&&w.variantId===(0,de.pickFromWeights)(a.variants,t)){u(w.variantId);return}x(h=>{var _;return h.variantId?h:{variantId:(_=t[0])!=null?_:null,content:null,isLoading:!1,settled:!1}})},[v,f,e,l]),(0,M.useEffect)(()=>{if(v||!f)return;let s=f.getAssignment(e,l);if(s&&t.includes(s.variantId))return;let a=!1;return f.assign(e,t,n,r).then(p=>{var h;a||p&&(!t.includes(p.variantId)&&!p.content||(x({variantId:p.variantId,content:(h=p.content)!=null?h:null,isLoading:!1,settled:!0}),u(p.variantId)))}),()=>{a=!0}},[v,f,e,l]),(0,M.useEffect)(()=>{if(!v&&f)return Pe(e,s=>{var h;let a=f.getAssignment(e,l);if(a&&(t.includes(a.variantId)||a.content)){x({variantId:a.variantId,content:(h=a.content)!=null?h:null,isLoading:!1,settled:!0}),u(a.variantId);return}let p=(0,de.pickFromWeights)(s.variants,t);p&&(x({variantId:p,content:null,isLoading:!1,settled:!0}),u(p))})},[v,f,e,l]),v?{variantId:v,content:null,isLoading:!1,settled:!0,isOverride:!0}:w}var st=require("react/jsx-runtime");function Ut(e){var h;let t=O(),n=V(),r=Object.keys(e.variants).join("\0"),i=(0,E.useMemo)(()=>Object.keys(e.variants),[r]),{variantId:o,content:f,isOverride:l,settled:d}=Q(e.id,i,e.agentData,e.agentDataByVariant),c=(0,E.useRef)(null),[m,g]=(0,E.useState)(!1);(0,E.useEffect)(()=>{g(!0)},[]);let v=(0,E.useRef)(!1),C=(0,E.useRef)(new Set),w=(0,E.useRef)(null),x=typeof e.goal=="string"?e.goal:JSON.stringify(e.goal),u=(0,E.useMemo)(()=>P(e.goal),[x]),s=typeof e.goal=="string"?e.goal:u.type;if((0,E.useEffect)(()=>oe({id:e.id,variantIds:i,goal:s}),[e.id,i,s]),(0,E.useEffect)(()=>{l||d&&(!t||!o||!n||w.current!==o&&(w.current=o,J(t,n,e.id,o)))},[t,o,n,e.id,l,d]),(0,E.useEffect)(()=>{v.current=!1,C.current=new Set},[o,u]),(0,E.useEffect)(()=>{l||!d||!t||!e.funnel||U(t,n,e.id,e.funnel,u)},[t,n,e.id,e.funnel,u,l,d]),(0,E.useEffect)(()=>{if(l||!d||!t||!o)return;let _=c.current;if(!_)return;let G=null,S=0,b=()=>{S=Date.now(),G=setTimeout(()=>{t.track({projectId:n,componentId:e.id,variantId:o,eventType:"cursor_signal",payload:{hoverDuration:Date.now()-S}}),G=null},800)},y=()=>{G!==null&&(clearTimeout(G),G=null)};return _.addEventListener("mouseenter",b),_.addEventListener("mouseleave",y),()=>{_.removeEventListener("mouseenter",b),_.removeEventListener("mouseleave",y),G!==null&&clearTimeout(G)}},[t,o,n,e.id,l,d]),(0,E.useEffect)(()=>{if(l||!d||!t||!o)return;let _=c.current;if(!_)return;let G=Date.now();return(0,it.attachMicroSignalDetectors)((S,b={})=>{var Ce,Ge,Re;t.track({projectId:n,componentId:e.id,variantId:o,eventType:"micro_signal",payload:k({signalType:S},b)});let y=(Ce=e.microSignalGoals)==null?void 0:Ce[S];if(!y||C.current.has(S))return;C.current.add(S);let T=typeof y=="string"?y:y.name,W=typeof y=="string"?1:(Ge=y.weight)!=null?Ge:1,te=typeof y=="string"?0:(Re=y.stepIndex)!=null?Re:0;t.goal(T,{metadata:k({signalType:S},b),weight:W,stepIndex:te})},_,G)},[t,o,n,e.id,e.microSignalGoals,l,d]),(0,E.useEffect)(()=>{if(l||!d||!t||!o)return;let _=c.current;if(!_)return;let G=j(u);return $(_,u,{fireGoal:()=>{v.current||(v.current=!0,t.track({projectId:n,componentId:e.id,variantId:o,eventType:"goal_achieved",goalType:s,payload:k({reward:1},G!==void 0?{goalValue:G}:{})}),t.goal(s,k({metadata:{componentId:e.id,variantId:o},weight:1,stepIndex:0},G!==void 0?{value:G}:{})))},fireStep:(S,b,y)=>{t.track({projectId:n,componentId:e.id,variantId:o,eventType:"goal_achieved",goalType:S,payload:{reward:b}}),t.goal(S,{metadata:{},weight:b,stepIndex:y})}},s)},[t,o,n,e.id,u,s,l,d]),e.clientOnly&&(!m||!t)||!o)return null;let a=(h=e.variants[o])!=null?h:null,p=a===null?f:null;return R()&&a===null&&p===null&&console.warn(`[sentient] <Adaptive id="${e.id}"> was assigned variant "${o}" but no matching key exists in props.variants. If this is a dashboard-managed text variant, use <AdaptiveText id="${e.id}"> instead.`),(0,st.jsx)("div",{ref:c,"data-sentient-id":e.id,"data-sentient-variant":o,children:a!=null?a:p})}var ot=(0,E.memo)(Ut,(e,t)=>{if(e.id!==t.id||e.goal!==t.goal&&JSON.stringify(e.goal)!==JSON.stringify(t.goal)||e.microSignalGoals!==t.microSignalGoals||e.funnel!==t.funnel||e.clientOnly!==t.clientOnly||e.agentData!==t.agentData||e.agentDataByVariant!==t.agentDataByVariant)return!1;if(e.variants===t.variants)return!0;let n=Object.keys(e.variants),r=Object.keys(t.variants);return n.length!==r.length?!1:n.every(i=>i in t.variants&&Object.is(e.variants[i],t.variants[i]))});var L=require("react");var lt=require("react/jsx-runtime");function at({id:e,default:t,component:n="span",className:r,goal:i}){var G;let o=O(),f=V(),l=ce(),d=ue(),c=(0,L.useRef)(null),m=(0,L.useRef)(null),g=(0,L.useSyncExternalStore)(N,()=>q(e),()=>null),[v,C]=(0,L.useState)(()=>{var S,b;return(b=(S=o==null?void 0:o.getAssignment(e,d))==null?void 0:S.content)!=null?b:null}),[w,x]=(0,L.useState)(()=>{var S,b;return(b=(S=o==null?void 0:o.getAssignment(e,d))==null?void 0:S.variantId)!=null?b:null});(0,L.useEffect)(()=>{if(g||!o)return;let S=o.getAssignment(e,d);if((S==null?void 0:S.content)!==void 0){x(S.variantId),C(S.content);return}let b=!1;return o.assign(e).then(y=>{if(!b){if(!y){R()&&console.warn(`[sentient] <AdaptiveText id="${e}"> assignment failed \u2014 showing default text.`);return}x(y.variantId),y.content&&C(y.content)}}),()=>{b=!0}},[o,e,d,g]),(0,L.useEffect)(()=>{g||!o||!w||!f||c.current!==w&&(c.current=w,o.track({projectId:f,componentId:e,variantId:w,eventType:"variant_assigned",payload:{}}),l==null||l(e,w))},[o,w,f,e,l,g]);let u=i===void 0?"":typeof i=="string"?i:JSON.stringify(i),s=(0,L.useMemo)(()=>i===void 0?null:P(i),[u]),a=i===void 0?null:typeof i=="string"?i:s.type,p=(0,L.useRef)(!1);(0,L.useEffect)(()=>{p.current=!1},[w,u]),(0,L.useEffect)(()=>{if(g||!o||!w||!f||!s||!a)return;let S=m.current;if(!S)return;let b=j(s);return $(S,s,{fireGoal:()=>{p.current||(p.current=!0,o.track({projectId:f,componentId:e,variantId:w,eventType:"goal_achieved",goalType:a,payload:k({reward:1},b!==void 0?{goalValue:b}:{})}),o.goal(a,k({metadata:{componentId:e,variantId:w},weight:1,stepIndex:0},b!==void 0?{value:b}:{})))},fireStep:(y,T,W)=>{o.track({projectId:f,componentId:e,variantId:w,eventType:"goal_achieved",goalType:y,payload:{reward:T}}),o.goal(y,{metadata:{},weight:T,stepIndex:W})}})},[o,w,f,e,s,a,g]);let h=v!=null?v:t;if(g){let S=o==null?void 0:o.getAssignment(e,d);h=S&&S.variantId===g&&(G=S.content)!=null?G:t}return(0,lt.jsx)(n,{ref:S=>{m.current=S},className:r,children:h})}var fe=require("react");function ge(e){let t=O(),n=(0,fe.useRef)(new Set);return(0,fe.useCallback)((r,i)=>{var o,f;if(!q(e)){if(i!=null&&i.once){if(n.current.has(r))return;n.current.add(r)}t==null||t.componentGoal(e,r,i),t==null||t.goal(r,k(k(k({metadata:(o=i==null?void 0:i.metadata)!=null?o:{},weight:(f=i==null?void 0:i.reward)!=null?f:1,stepIndex:0},(i==null?void 0:i.value)!==void 0?{value:i.value}:{}),(i==null?void 0:i.currency)!==void 0?{currency:i.currency}:{}),(i==null?void 0:i.externalId)!==void 0?{externalId:i.externalId}:{}))}},[t,e])}var ee=require("react");function ut(e,t={}){let d=t,{componentId:n}=d,r=Ie(d,["componentId"]),i=O(),o=ge(n!=null?n:""),f=(0,ee.useRef)(!1),l=(0,ee.useRef)(r);l.current=r,(0,ee.useEffect)(()=>{if(!i||f.current)return;f.current=!0;let{metadata:c,reward:m,value:g,currency:v,externalId:C}=l.current;if(n){o(e,l.current);return}i.goal(e,k(k(k({metadata:c!=null?c:{},weight:m!=null?m:1,stepIndex:0},g!==void 0?{value:g}:{}),v!==void 0?{currency:v}:{}),C!==void 0?{externalId:C}:{}))},[i,n,e,o])}var dt=require("@sentientui/core"),ft=require("@sentientui/policy"),mt=require("react/jsx-runtime");function ct(e){return JSON.stringify(e).replace(/</g,"\\u003c")}function Jt(e){return e.persona?'(function(){try{var d=document.documentElement;if(d.hasAttribute("data-sentient-persona"))return;d.setAttribute("data-sentient-persona",'+ct(e.persona.persona)+');d.setAttribute("data-sentient-confidence",'+ct((0,ft.confidenceBand)(e.persona.confidence))+");}catch(e){}})();":(0,dt.renderPrePaintScript)(e.apiKey)}function gt(e){return(0,mt.jsx)("script",{"data-sentient-persona-script":"",nonce:e.nonce,dangerouslySetInnerHTML:{__html:Jt(e)}})}var B=require("react"),ht=require("@sentientui/policy");var K=require("react"),z=require("@sentientui/core"),vt=require("@sentientui/policy");var pt=new Set;function me(e,t){let n=O(),r=et(),[,i]=(0,K.useReducer)(m=>m+1,0),o=(0,K.useSyncExternalStore)(N,()=>{var m;return typeof window!="undefined"?(m=window.__sentient_slot_overrides)==null?void 0:m[e]:void 0},()=>{}),f=o===void 0?r[e]:void 0,l=o===void 0&&f===void 0&&n?n.getSlotResult(e):null,d=(n==null?void 0:n.isLocal)===!0&&o===void 0&&f===void 0&&l===null;(0,K.useEffect)(()=>{if(!d||!n)return;let m=!1;return n.decide({slots:[t]}).then(g=>{!m&&g&&i()}),()=>{m=!0}},[n,e,d]);let c=(()=>{if(o!==void 0)return{result:o,arm:(0,z.armOfResult)(o),source:"override"};if(f!==void 0)return{result:f,arm:(0,z.armOfResult)(f),source:"preloaded"};if(l!==null)return{result:l,arm:(0,z.armOfResult)(l),source:"client"};let m=(0,z.baselineResultFor)(t);return{result:m,arm:(0,z.armOfResult)(m),source:"baseline"}})();return(0,K.useEffect)(()=>{R()&&(!n||n.isLocal===!0||c.source==="baseline"&&(pt.has(e)||(pt.add(e),console.warn(`[sentient] slot "${e}" resolved to its baseline \u2014 no SSR-preloaded or decided result. Keyed clients decide slots server-side, so this slot serves baseline for the whole session and records no exposure. Preload it via loadAdaptiveDecision()/initialSlots so it can serve a decided arm and learn.`))))},[n,c.source,e]),c}function Ht(){var t;if(typeof window=="undefined")return null;let e=window.__sentient_persona_override;if(e!=null&&e.persona)return{persona:e.persona,confidence:(t=e.confidence)!=null?t:1};try{let n=new URLSearchParams(window.location.search).get("sentient_persona");if(n)return{persona:n,confidence:1}}catch(n){}return null}function yt(){let e=O(),t=tt();(0,K.useSyncExternalStore)(N,$e,()=>0);let[n,r]=(0,K.useState)(!1);(0,K.useEffect)(()=>r(!0),[]);let i=l=>({persona:l.persona,confidence:l.confidence,band:(0,vt.confidenceBand)(l.confidence)});if(!n)return t?i(t):null;let o=Ht();if(o)return i(o);if(t)return i(t);let f=e?e.getPersona():null;return f?i(f):null}var St=new Set;function zt(e){return typeof CSS!="undefined"&&typeof CSS.escape=="function"?CSS.escape(e):e.replace(/[\\"]/g,"\\$&")}function bt(e,t,n){let r=O(),i=V(),o=JSON.stringify(t),f=(0,B.useMemo)(()=>({id:e,dims:t}),[e,o]),{result:l,arm:d,source:c}=me(e,f),m=(0,B.useMemo)(()=>typeof l=="string"?{}:l,[d]);if(R()&&!St.has(e)){St.add(e);let x=(0,ht.validateSlotDecl)({id:e,dims:Object.fromEntries(Object.entries(t).map(([s,a])=>[s,[...a]]))}),u=Object.values(t).reduce((s,a)=>s*a.length,1);x.ok?u>4&&console.warn(`[sentient] useAdaptiveTokens("${e}") declares ${u} combinations \u2014 more than the recommended 4. Each extra combination needs more traffic to learn; consider fewer dims/values.`):console.warn(`[sentient] useAdaptiveTokens("${e}"): invalid declaration \u2014 ${x.reason}. Serving baseline.`)}let g=(n==null?void 0:n.goal)===void 0?null:typeof n.goal=="string"?n.goal:JSON.stringify(n.goal);(0,B.useEffect)(()=>se({id:e,dims:t}),[e]);let v=(0,B.useRef)(null);(0,B.useEffect)(()=>{!r||c==="baseline"||c==="override"||v.current===d||(v.current=d,J(r,i,e,d))},[r,i,e,d,c]);let C=n==null?void 0:n.funnel;(0,B.useEffect)(()=>{var x;!r||!C||c==="override"||U(r,i,e,C,P((x=n==null?void 0:n.goal)!=null?x:"click"))},[r,i,e,C,g,c]),(0,B.useEffect)(()=>{if(!r||!(n!=null&&n.goal)||c==="override"||c==="baseline")return;let x=document.querySelector(`[data-sentient-slot="${zt(e)}"]`);if(!x){R()&&console.warn(`[sentient] useAdaptiveTokens("${e}"): a goal is declared but no element carries the returned props \u2014 spread {...props} on the slot's element.`);return}let u=X(n.goal),s=j(n.goal),a=!1;return $(x,P(n.goal),{fireGoal:()=>{a||(a=!0,s!==void 0?r.componentGoal(e,u,{value:s}):r.componentGoal(e,u),r.goal(u,k({metadata:{componentId:e,arm:d},weight:1,stepIndex:0},s!==void 0?{value:s}:{})))},fireStep:(p,h,_)=>{r.componentGoal(e,p,{reward:h}),r.goal(p,{metadata:{componentId:e,arm:d},weight:h,stepIndex:_})}},u)},[r,e,g,d,c]);let w=(0,B.useMemo)(()=>{let x={"data-sentient-slot":e};for(let[u,s]of Object.entries(m))x[`data-${u}`]=s;return x},[e,m]);return{tokens:m,props:w}}var I=require("react"),At=require("@sentientui/core");var wt=new Set;function xt(e,t){var S;if(R()&&!t.goal)throw new Error(`[sentient] useAdaptive("${e}"): a goal is required \u2014 without one the optimizer accumulates exposures with no rewards and cannot learn. Pass e.g. goal: 'buy_click'.`);let n=O(),r=V(),i=Object.keys(t.variants).join(" "),o=(0,I.useMemo)(()=>Object.keys(t.variants),[i]),{variantId:f,isOverride:l,settled:d}=Q(e,o),c=(S=f!=null?f:o[0])!=null?S:"",m=t.variants[c],[g,v]=(0,I.useState)(null),C=(0,I.useRef)(null),w=(0,I.useCallback)(b=>{C.current=b,v(b)},[]),x=typeof t.goal=="string"?t.goal:JSON.stringify(t.goal),u=(0,I.useMemo)(()=>t.goal?P(t.goal):null,[x]),s=t.goal?X(t.goal):"";(0,I.useEffect)(()=>oe({id:e,variantIds:o,goal:s}),[e,o,s]);let a=(0,I.useRef)(null);(0,I.useEffect)(()=>{l||d&&(!n||!c||!g||a.current!==c&&(a.current=c,J(n,r,e,c)))},[n,r,e,c,g,l,d]);let p=t.funnel;(0,I.useEffect)(()=>{l||!d||!n||!p||!u||U(n,r,e,p,u)},[n,r,e,p,u,l,d]);let h=(0,I.useRef)(!1);(0,I.useEffect)(()=>{h.current=!1},[c,x]),(0,I.useEffect)(()=>{if(l||!d||!n||!c||!g||!u)return;let b=j(u);return $(g,u,{fireGoal:()=>{h.current||(h.current=!0,n.track({projectId:r,componentId:e,variantId:c,eventType:"goal_achieved",goalType:s,payload:k({reward:1},b!==void 0?{goalValue:b}:{})}),n.goal(s,k({metadata:{componentId:e,variantId:c},weight:1,stepIndex:0},b!==void 0?{value:b}:{})))},fireStep:(y,T,W)=>{n.track({projectId:r,componentId:e,variantId:c,eventType:"goal_achieved",goalType:y,payload:{reward:T}}),n.goal(y,{metadata:{},weight:T,stepIndex:W})}},s)},[n,g,c,r,e,u,s,l,d]),(0,I.useEffect)(()=>{if(l||!n||!c||!g)return;let b=Date.now();return(0,At.attachMicroSignalDetectors)((y,T={})=>{n.track({projectId:r,componentId:e,variantId:c,eventType:"micro_signal",payload:k({signalType:y},T)})},g,b)},[n,g,c,r,e,l]),(0,I.useEffect)(()=>{if(!R()||!n)return;let b=setTimeout(()=>{!C.current&&!wt.has(e)&&(wt.add(e),console.warn(`[sentient] useAdaptive("${e}"): bind was never attached \u2014 spread {...bind} on the rendered element, otherwise exposure and goal tracking cannot work and the optimizer learns nothing.`))},0);return()=>clearTimeout(b)},[n,e]);let _=(0,I.useCallback)((b,y)=>{var W,te;if(l)return;let T=b!=null?b:s;T&&(n==null||n.componentGoal(e,T,y),n==null||n.goal(T,k(k(k({metadata:(W=y==null?void 0:y.metadata)!=null?W:{},weight:(te=y==null?void 0:y.reward)!=null?te:1,stepIndex:0},(y==null?void 0:y.value)!==void 0?{value:y.value}:{}),(y==null?void 0:y.currency)!==void 0?{currency:y.currency}:{}),(y==null?void 0:y.externalId)!==void 0?{externalId:y.externalId}:{})))},[n,e,s,l]),G=(0,I.useMemo)(()=>({ref:w,"data-sentient-id":e,"data-sentient-variant":c}),[w,e,c]);return{variant:c,value:m,bind:G,fireGoal:_}}var D=require("react");var kt=require("react/jsx-runtime"),pe=new Set;function _t(e){var s;let t=O(),n=V(),r=(0,D.useRef)(null),i=Object.keys(e.arrangements).join(" "),o=(0,D.useMemo)(()=>Object.keys(e.arrangements),[i]),f=(0,D.useMemo)(()=>k({id:e.id,arms:o},e.baseline!==void 0?{baseline:e.baseline}:{}),[e.id,o,e.baseline]),{arm:l,source:d}=me(e.id,f);R()&&e.baseline!==void 0&&e.baseline!==o[0]&&!pe.has(e.id+":baseline")&&(pe.add(e.id+":baseline"),console.warn(`[sentient] <AdaptiveGroup id="${e.id}">: baseline "${e.baseline}" is not the first-declared arrangement ("${o[0]}"). The first arrangement should usually be the page's real incumbent (the holdout sees it).`));let c=D.Children.toArray(e.children).filter(D.isValidElement),m=new Map;for(let a of c)m.set(String((s=a.key)!=null?s:"").replace(/^\.\$/,""),a);let g=e.arrangements[l],v=g!==void 0&&g.length===c.length&&g.every(a=>m.has(a));R()&&g!==void 0&&!v&&!pe.has(e.id+":keys")&&(pe.add(e.id+":keys"),console.warn(`[sentient] <AdaptiveGroup id="${e.id}">: arrangement "${l}" [${g.join(", ")}] does not match the children's keys \u2014 rendering declaration order (fail-safe).`));let C=v?g.map(a=>m.get(a)):c;(0,D.useEffect)(()=>se({id:e.id,arms:Object.keys(e.arrangements)}),[e.id]);let w=(0,D.useRef)(null);(0,D.useEffect)(()=>{!t||d==="baseline"||d==="override"||w.current===l||(w.current=l,J(t,n,e.id,l))},[t,n,e.id,l,d]);let x=e.funnel;(0,D.useEffect)(()=>{var a;!t||!x||d==="override"||U(t,n,e.id,x,P((a=e.goal)!=null?a:"click"))},[t,n,e.id,x,d]);let u=e.goal===void 0?null:typeof e.goal=="string"?e.goal:JSON.stringify(e.goal);return(0,D.useEffect)(()=>{if(!t||e.goal===void 0||d==="override"||d==="baseline")return;let a=r.current;if(!a)return;let p=X(e.goal),h=j(e.goal),_=!1;return $(a,P(e.goal),{fireGoal:()=>{_||(_=!0,h!==void 0?t.componentGoal(e.id,p,{value:h}):t.componentGoal(e.id,p),t.goal(p,k({metadata:{componentId:e.id,arm:l},weight:1,stepIndex:0},h!==void 0?{value:h}:{})))},fireStep:(G,S,b)=>{t.componentGoal(e.id,G,{reward:S}),t.goal(G,{metadata:{componentId:e.id,arm:l},weight:S,stepIndex:b})}},p)},[t,e.id,u,l,d]),(0,kt.jsx)("div",{ref:r,"data-sentient-id":e.id,"data-sentient-variant":l,children:C})}var xe=require("@sentientui/core");var Xt=["page","blocks","layoutOrder"],Ct=new Map;function Gt(e,t){Ct.set(e,t)}function _e(e){return Ct.get(e)}function Rt(e){var i,o;let t=(o=(i=e.content)!=null?i:_e(e.page))!=null?o:{},n={};for(let[f,l]of Object.entries(t))Xt.includes(f)||(n[f]=l);let r=re(k({},n),{page:e.page,blocks:e.blocks});return e.layoutOrder&&(r.layoutOrder=e.layoutOrder),r}function Ot(e){return`<script type="application/ld+json">${ke(e)}</script>`}function ke(e){return JSON.stringify(k({"@context":"https://schema.org","@type":"WebPage"},e)).replace(/</g,"\\u003c")}function Et(e){let t=[];e.title&&t.push(`# ${e.title}`,""),e.summary&&t.push(String(e.summary),"");for(let[n,r]of Object.entries(e))["page","title","summary","blocks","layoutOrder"].includes(n)||t.push(`## ${n}`,"","```json",JSON.stringify(r,null,2),"```","");if(e.blocks.length>0){t.push("## blocks","");for(let n of e.blocks)t.push(`- **${n.id}** \u2192 variant \`${n.variant}\``),n.content!==void 0&&t.push(""," ```json",JSON.stringify(n.content,null,2)," ```");t.push("")}return t.join(`
|
|
2
|
+
"use strict";var Yt=Object.create;var ie=Object.defineProperty,en=Object.defineProperties,tn=Object.getOwnPropertyDescriptor,nn=Object.getOwnPropertyDescriptors,rn=Object.getOwnPropertyNames,ae=Object.getOwnPropertySymbols,on=Object.getPrototypeOf,xe=Object.prototype.hasOwnProperty,Me=Object.prototype.propertyIsEnumerable;var Be=(e,t,n)=>t in e?ie(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,S=(e,t)=>{for(var n in t||(t={}))xe.call(t,n)&&Be(e,n,t[n]);if(ae)for(var n of ae(t))Me.call(t,n)&&Be(e,n,t[n]);return e},J=(e,t)=>en(e,nn(t));var Ke=(e,t)=>{var n={};for(var r in e)xe.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&ae)for(var r of ae(e))t.indexOf(r)<0&&Me.call(e,r)&&(n[r]=e[r]);return n};var sn=(e,t)=>{for(var n in t)ie(e,n,{get:t[n],enumerable:!0})},je=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of rn(t))!xe.call(e,o)&&o!==n&&ie(e,o,{get:()=>t[o],enumerable:!(r=tn(t,o))||r.enumerable});return e};var Ne=(e,t,n)=>(n=e!=null?Yt(on(e)):{},je(t||!e||!e.__esModule?ie(n,"default",{value:e,enumerable:!0}):n,e)),an=e=>je(ie({},"__esModule",{value:!0}),e);var xn={};sn(xn,{Adaptive:()=>mt,AdaptiveGroup:()=>Ut,AdaptiveProvider:()=>it,AdaptiveSlot:()=>jt,AdaptiveText:()=>vt,SentientPersonaScript:()=>xt,buildAgentFeed:()=>zt,defineAgentContent:()=>Xt,detectSegment:()=>Pe.deriveSessionSegment,getAgentContent:()=>Ie,grantConsent:()=>Qt.grantConsent,renderAgentJsonLd:()=>qt,renderAgentJsonLdBody:()=>Le,renderAgentMarkdown:()=>Zt,useAdaptive:()=>Wt,useAdaptiveApiBaseUrl:()=>dt,useAdaptiveGoal:()=>ye,useAdaptivePersona:()=>Rt,useAdaptiveTokens:()=>Ot,useAssignment:()=>re,useInitialAssignments:()=>de,useLayoutOrder:()=>at,usePageGoal:()=>St,useSentient:()=>O});module.exports=an(xn);var _=require("react"),ce=require("@sentientui/core");var $e=new Map,le=new Map;function Ve(e,t){let n=le.get(e);return n||(n=new Set,le.set(e,n)),n.add(t),()=>{n.delete(t),n.size===0&&le.delete(e)}}function We(e,t){$e.set(e,t);let n=le.get(e);if(n)for(let r of n)try{r(t)}catch(o){}}function Ae(e){var t;return(t=$e.get(e))!=null?t:null}var ln={on:!1,listeners:new Set};function Ue(){if(typeof window=="undefined")return ln;let e=window;return e.__sentient_preview||(e.__sentient_preview={on:!1,listeners:new Set}),e.__sentient_preview}function Ce(){return Ue().on}function Je(e){let t=Ue().listeners;return t.add(e),()=>{t.delete(e)}}function He(e){return{isLocal:e.isLocal,track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},fetchWeights:()=>Promise.resolve([]),getAssignment:(t,n)=>e.getAssignment(t,n),assign:(t,n,r,o)=>e.assign(t,n,r,o),decide:()=>Promise.resolve(null),getSlotResult:t=>e.getSlotResult(t),getSlotConfig:t=>e.getSlotConfig(t),getSitePalette:()=>e.getSitePalette(),reportSlots:t=>e.reportSlots(t),getPersona:()=>e.getPersona(),getGraph:()=>e.getGraph(),dispose:()=>e.dispose(),destroy:()=>e.destroy()}}var Xe="sentient:overrides-changed";function ze(){var e;return typeof window=="undefined"?0:(e=window.__sentient_overrides_version)!=null?e:0}function M(e){return typeof window=="undefined"?()=>{}:(window.addEventListener(Xe,e),()=>window.removeEventListener(Xe,e))}function qe(e){typeof window!="undefined"&&(window.__sentient_devtools_config=e)}function G(){var e;return typeof process=="undefined"||((e=process.env)==null?void 0:e.NODE_ENV)!=="production"}function F(e){return typeof e=="string"?{type:"click"}:e}function q(e){return typeof e=="string"?e:e.type}function K(e){if(typeof e!="string"&&(e.type==="click"||e.type==="form_submit"||e.type==="scroll_depth"))return e.value}var ke=new Set,Re=!1;function Ze(e){if(ke.has(e))return!0;if(ke.add(e),!Re){Re=!0;let t=()=>{Re=!1,ke.clear()};if(typeof MessageChannel=="function"){let n=new MessageChannel;n.port1.onmessage=()=>{n.port1.close(),n.port2.close(),t()},n.port2.postMessage(0)}else setTimeout(t,0)}return!1}function un(e){if(!(e instanceof Element))return!1;let t=e.tagName.toLowerCase();return t==="a"||t==="button"?!0:e.getAttribute("role")==="button"}function Qe(e,t,n){if(n){try{let o=e;for(;o&&o!==t;){if(o.matches(n))return!0;o=o.parentElement}}catch(o){}return!1}let r=e;for(;r&&r!==t;){if(un(r))return!0;r=r.parentElement}return!1}function j(e,t,n,r){if(t.type==="weighted_composite"){let l=new Set,d=[];return t.steps.forEach(({goal:f,name:p,weight:h},b)=>{let y=(c=!1)=>{l.has(b)||c&&r!==void 0&&Ze(`step\0${p}\0${h}\0${b}`)||(l.add(b),n.fireStep(p,h,b))};if(f.type==="click"){let c=u=>{let g=u.target;g instanceof Element&&Qe(g,e,f.selector)&&y()};e.addEventListener("click",c),d.push(()=>e.removeEventListener("click",c));return}if(f.type==="form_submit"){let c=u=>{u.target instanceof HTMLFormElement&&e.contains(u.target)&&y()};e.addEventListener("submit",c),d.push(()=>e.removeEventListener("submit",c));return}if(f.type==="scroll_depth"){let c=Math.max(0,Math.min(1,f.threshold)),u=new IntersectionObserver(g=>{for(let v of g)if(v.intersectionRatio>=c){y(!0),u.disconnect();break}},{threshold:[c]});u.observe(e),d.push(()=>u.disconnect())}}),()=>{for(let f of d)f()}}let o=t.type==="composite"?t.all:[t],i=new Set(o.map((l,d)=>d)),m=()=>{r!==void 0&&Ze(r)||n.fireGoal()},s=(l,d=!1)=>{i.delete(l),i.size===0&&(d?m():n.fireGoal())},a=[];return o.forEach((l,d)=>{if(l.type==="click"){let f=p=>{let h=p.target;h instanceof Element&&Qe(h,e,l.selector)&&(t.type==="composite"?s(d):n.fireGoal())};e.addEventListener("click",f),a.push(()=>e.removeEventListener("click",f));return}if(l.type==="form_submit"){let f=p=>{p.target instanceof HTMLFormElement&&e.contains(p.target)&&(t.type==="composite"?s(d):n.fireGoal())};e.addEventListener("submit",f),a.push(()=>e.removeEventListener("submit",f));return}if(l.type==="scroll_depth"){let f=Math.max(0,Math.min(1,l.threshold)),p=new IntersectionObserver(h=>{for(let b of h)if(b.intersectionRatio>=f){t.type==="composite"?s(d,!0):m(),p.disconnect();break}},{threshold:[f]});p.observe(e),a.push(()=>p.disconnect());return}}),()=>{for(let l of a)l()}}var Ye=new Set,et=new Set;function Z(e,t,n,r,o){let i=`${r}|${n}`;if(et.has(i))return;et.add(i);let m=o.type==="weighted_composite"&&!Ye.has(r);m&&Ye.add(r),e.track({projectId:t,componentId:n,eventType:"funnel_declared",payload:m?{funnelId:r,steps:o.steps.map(s=>({goalId:s.name,weight:s.weight}))}:{funnelId:r}})}function H(e,t,n,r){e.track({projectId:t,componentId:n,variantId:r,eventType:"variant_assigned",payload:{}})}var cn={components:new Map,slots:new Map,sections:[],listeners:new Set,version:0};function Q(){if(typeof window=="undefined")return cn;let e=window;return e.__sentient_registry||(e.__sentient_registry={components:new Map,slots:new Map,sections:[],listeners:new Set,version:0}),e.__sentient_registry}function oe(){Q().version+=1;for(let e of Q().listeners)e()}var tt=()=>{};function ue(e){return G()?(Q().components.set(e.id,e),oe(),()=>{Q().components.delete(e.id),oe()}):tt}function te(e){return G()?(Q().slots.set(e.id,e),oe(),()=>{Q().slots.delete(e.id),oe()}):tt}function _e(e){G()&&(Q().sections=[...e],oe())}var nt="0.29.0",Ge=nt!=="0.0.0-dev"?{name:"react",version:nt}:void 0;var ft=require("react/jsx-runtime");function dn(){var e,t;if(typeof window=="undefined")return"desktop:direct";try{return(0,ce.deriveSessionSegment)({userAgent:(e=navigator.userAgent)!=null?e:"",referer:(t=document.referrer)!=null?t:"",appOrigin:window.location.origin})}catch(n){return"desktop:direct"}}var rt="https://api.sentient-ui.com/v1",B=(0,_.createContext)({client:null,apiKey:"",initialAssignments:{},sessionSegment:"desktop:direct",ssrFallback:"first",onAssignment:void 0,initialLayoutOrder:null,initialSlots:{},initialSlotConfig:{},initialPalette:null,initialPersona:null,apiBaseUrl:rt,debug:!1});function fn(e){let[t,n]=(0,_.useState)(!1),r=(0,_.useRef)(e);r.current=e;let{cookie:o,value:i,event:m}=e!=null?e:{},s=typeof(e==null?void 0:e.check)=="function";return(0,_.useEffect)(()=>{let a=()=>{var p;let d=r.current;if(!d)return!1;if(d.check)return d.check()===!0;if(!d.cookie||typeof document=="undefined")return!1;let f=`${d.cookie}=${(p=d.value)!=null?p:"accepted"}`;return document.cookie.split("; ").some(h=>h.trim()===f)};if(n(a()),!m)return;let l=()=>{n(a())};return window.addEventListener(m,l),()=>window.removeEventListener(m,l)},[o,i,m,s]),t}function it(e){var b,y;let[t,n]=(0,_.useState)(null),[r]=(0,_.useState)(()=>{var c;return(c=e.sessionSegment)!=null?c:dn()}),[o,i]=(0,_.useState)(Ce());(0,_.useEffect)(()=>Je(()=>i(Ce())),[]);let m=fn(e.consentFrom),s=e.consentFrom?e.consent===!0||m:e.consent,a=(0,_.useRef)(null);(0,_.useEffect)(()=>{var k;if(s===!1&&!e.preConsentBehavior){(k=a.current)==null||k.destroy(),a.current=null,n(null);return}let c=S({apiKey:e.apiKey,context:e.context,debug:e.debug,initialAssignments:e.initialAssignments,sessionSegment:r,consent:s,preConsentBehavior:e.preConsentBehavior,respectDoNotTrack:e.respectDoNotTrack,ssrSessionId:e.ssrSessionId,country:e.country,persona:e.persona,localMode:e.localMode,initialSlots:e.initialSlots,initialSlotConfig:e.initialSlotConfig,initialPalette:e.initialPalette,initialPersona:e.initialPersona,ingestUrl:e.apiBaseUrl?`${e.apiBaseUrl.replace(/\/$/,"")}/events`:void 0},Ge?{sdk:Ge}:{}),u=!1,g=null,v=null,C=R=>{e.engagement!==!1&&import("@sentientui/core/engagement").then(({startEngagementCapture:x})=>{u||(v=x(R,{apiKey:e.apiKey,apiBase:e.apiBaseUrl?e.apiBaseUrl.replace(/\/$/,""):void 0}))})};return e.enableGraph!==!1?import("@sentientui/core/graph").then(({init:R})=>{u||(g=R(J(S({},c),{graph:!0,captureDomText:e.captureDomText===!0})),a.current=g,n(g),C(g))}):(g=(0,ce.init)(c),a.current=g,n(g),C(g)),()=>{u=!0,v==null||v(),g==null||g.dispose()}},[s]),(0,_.useEffect)(()=>{if(!t)return;let c=!1,u=async()=>{if(c)return;let v;try{v=await t.fetchWeights()}catch(C){return}if(!c)for(let C of v){let k={componentId:C.componentId,updatedAt:C.updatedAt,variants:C.variants.map(R=>{var x;return{variantId:R.variantId,pulls:R.pulls,avgReward:(x=R.avgReward)!=null?x:0}})};We(C.componentId,k)}};u();let g=setInterval(()=>{u()},6e4);return()=>{c=!0,clearInterval(g)}},[t]);let l=(b=e.ssrFallback)!=null?b:"first",d=((y=e.apiBaseUrl)!=null?y:rt).replace(/\/$/,""),f=(0,_.useRef)(null);(0,_.useEffect)(()=>{var g;if(typeof process!="undefined"&&((g=process.env)==null?void 0:g.NODE_ENV)==="production")return;let c={apiKey:e.apiKey,context:e.context,country:e.country,persona:e.persona,apiBaseUrl:d},u=f.current;if(f.current=c,u!==null)for(let v of["apiKey","context","country","persona","apiBaseUrl"])Object.is(u[v],c[v])||console.warn(`[sentient] AdaptiveProvider: \`${v}\` changed after initialisation, but the SDK client is stable for the session and only re-inits on \`consent\` \u2014 the new value is ignored. Remount the provider (e.g. via a changing \`key\` prop) to apply it.`)},[e.apiKey,e.context,e.country,e.persona,d]),(0,_.useEffect)(()=>{var c;typeof process!="undefined"&&((c=process.env)==null?void 0:c.NODE_ENV)==="production"||qe({apiKey:e.apiKey,apiBaseUrl:d,isLocal:(t==null?void 0:t.isLocal)===!0})},[t,e.apiKey,d]),(0,_.useEffect)(()=>{let c=e.initialLayoutOrder;if(c&&c.length>0){_e(c);return}e.declaredSections&&e.declaredSections.length>0&&_e(e.declaredSections)},[e.initialLayoutOrder,e.declaredSections]),(0,_.useEffect)(()=>{if(!G())return;let c=e.declaredSections;if(!c||c.length===0||typeof document=="undefined")return;let u=new Set(Array.from(document.querySelectorAll("[data-sentient-id]"),v=>v.getAttribute("data-sentient-id"))),g=c.filter(v=>!u.has(v));g.length>0&&console.warn(`[SentientUI] Declared section${g.length>1?"s":""} ${g.map(v=>`"${v}"`).join(", ")} ${g.length>1?"have":"has"} no matching data-sentient-id element, so the layout engine cannot learn what they are and will serve the same order to every persona. Add data-sentient-id="<sectionId>" (plus optional data-sentient-type) to each section's element.`)},[e.declaredSections]);let p=(0,_.useMemo)(()=>t&&o?He(t):t,[t,o]),h=(0,_.useMemo)(()=>{var c,u,g,v,C,k,R;return{client:p,apiKey:e.apiKey,initialAssignments:(c=e.initialAssignments)!=null?c:{},sessionSegment:r,ssrFallback:l,onAssignment:e.onAssignment,initialLayoutOrder:(u=e.initialLayoutOrder)!=null?u:null,initialSlots:(g=e.initialSlots)!=null?g:{},initialSlotConfig:(v=e.initialSlotConfig)!=null?v:{},initialPalette:(C=e.initialPalette)!=null?C:null,initialPersona:(k=e.initialPersona)!=null?k:null,apiBaseUrl:d,debug:(R=e.debug)!=null?R:!1}},[p,e.apiKey,e.initialAssignments,r,l,e.onAssignment,e.initialLayoutOrder,e.initialSlots,e.initialSlotConfig,e.initialPalette,e.initialPersona,d,e.debug]);return(0,ft.jsx)(B.Provider,{value:h,children:e.children})}function O(){return(0,_.useContext)(B).client}function N(){return(0,_.useContext)(B).apiKey}function de(){return(0,_.useContext)(B).initialAssignments}function fe(){return(0,_.useContext)(B).sessionSegment}function ot(){return(0,_.useContext)(B).ssrFallback}function ge(){return(0,_.useContext)(B).onAssignment}function st(){return(0,_.useContext)(B).debug}function at(){let e=(0,_.useContext)(B).initialLayoutOrder,t=(0,_.useSyncExternalStore)(M,()=>{var n;return typeof window=="undefined"?null:(n=window.__sentient_layout_override)!=null?n:null},()=>null);return t!=null?t:e}function me(){return(0,_.useContext)(B).initialSlots}function lt(){return(0,_.useContext)(B).initialPersona}function ut(){return(0,_.useContext)(B).initialSlotConfig}function ct(){return(0,_.useContext)(B).initialPalette}function dt(){return(0,_.useContext)(B).apiBaseUrl}var E=require("react"),gt=require("@sentientui/core");var $=require("react"),pe=require("@sentientui/policy");function ne(e){var n;if(typeof window=="undefined")return null;let t=(n=window.__sentient_overrides)==null?void 0:n[e];if(t)return t;if(!window.location.search)return null;try{let r=new URLSearchParams(window.location.search);for(let o of r.getAll("sentient_variant")){let i=o.indexOf(":");if(i!==-1&&o.slice(0,i)===e)return o.slice(i+1)}}catch(r){}return null}function re(e,t,n,r){let o=de(),i=ot(),m=O(),s=fe(),a=ge(),l=st(),d=(0,$.useRef)(null),f=(0,$.useSyncExternalStore)(M,()=>ne(e),()=>null),p=f&&t.includes(f)?f:null,h=(0,$.useRef)(null);(0,$.useEffect)(()=>{l&&p&&h.current!==p&&(h.current=p,console.info(`[sentient] override active: ${e} -> ${p}`))},[l,p,e]);let[b,y]=(0,$.useState)(()=>{var v,C;if(p)return{variantId:p,content:null,isLoading:!1,settled:!0};if(!m){let k=o[e];return k&&t.includes(k)?{variantId:k,content:null,isLoading:!1,settled:!0}:i==="first"&&t.length>0?{variantId:t[0],content:null,isLoading:!1,settled:!1}:{variantId:null,content:null,isLoading:!0,settled:!1}}let u=m.getAssignment(e,s);if(u&&(t.includes(u.variantId)||u.content))return{variantId:u.variantId,content:(v=u.content)!=null?v:null,isLoading:!1,settled:!0};let g=Ae(e);if(g){let k=(0,pe.pickFromWeights)(g.variants,t);if(k)return{variantId:k,content:null,isLoading:!1,settled:!0}}return{variantId:(C=t[0])!=null?C:null,content:null,isLoading:!1,settled:!1}}),c=u=>{a&&d.current!==u&&(d.current=u,a(e,u))};return(0,$.useEffect)(()=>{var v;if(p||!m)return;let u=m.getAssignment(e,s);if(u&&(t.includes(u.variantId)||u.content)){y({variantId:u.variantId,content:(v=u.content)!=null?v:null,isLoading:!1,settled:!0}),c(u.variantId);return}let g=Ae(e);if(g&&b.settled&&b.variantId&&b.variantId===(0,pe.pickFromWeights)(g.variants,t)){c(b.variantId);return}y(C=>{var k;return C.variantId?C:{variantId:(k=t[0])!=null?k:null,content:null,isLoading:!1,settled:!1}})},[p,m,e,s]),(0,$.useEffect)(()=>{if(p||!m)return;let u=m.getAssignment(e,s);if(u&&t.includes(u.variantId))return;let g=!1;return m.assign(e,t,n,r).then(v=>{var C;g||v&&(!t.includes(v.variantId)&&!v.content||(y({variantId:v.variantId,content:(C=v.content)!=null?C:null,isLoading:!1,settled:!0}),c(v.variantId)))}),()=>{g=!0}},[p,m,e,s]),(0,$.useEffect)(()=>{if(!p&&m)return Ve(e,u=>{var C;let g=m.getAssignment(e,s);if(g&&(t.includes(g.variantId)||g.content)){y({variantId:g.variantId,content:(C=g.content)!=null?C:null,isLoading:!1,settled:!0}),c(g.variantId);return}let v=(0,pe.pickFromWeights)(u.variants,t);v&&(y({variantId:v,content:null,isLoading:!1,settled:!0}),c(v))})},[p,m,e,s]),p?{variantId:p,content:null,isLoading:!1,settled:!0,isOverride:!0}:b}var pt=require("react/jsx-runtime");function gn(e){var C;let t=O(),n=N(),r=Object.keys(e.variants).join("\0"),o=(0,E.useMemo)(()=>Object.keys(e.variants),[r]),{variantId:i,content:m,isOverride:s,settled:a}=re(e.id,o,e.agentData,e.agentDataByVariant),l=(0,E.useRef)(null),[d,f]=(0,E.useState)(!1);(0,E.useEffect)(()=>{f(!0)},[]);let p=(0,E.useRef)(!1),h=(0,E.useRef)(new Set),b=(0,E.useRef)(null),y=typeof e.goal=="string"?e.goal:JSON.stringify(e.goal),c=(0,E.useMemo)(()=>F(e.goal),[y]),u=typeof e.goal=="string"?e.goal:c.type;if((0,E.useEffect)(()=>ue({id:e.id,variantIds:o,goal:u}),[e.id,o,u]),(0,E.useEffect)(()=>{s||a&&(!t||!i||!n||b.current!==i&&(b.current=i,H(t,n,e.id,i)))},[t,i,n,e.id,s,a]),(0,E.useEffect)(()=>{p.current=!1,h.current=new Set},[i,c]),(0,E.useEffect)(()=>{s||!a||!t||!e.funnel||Z(t,n,e.id,e.funnel,c)},[t,n,e.id,e.funnel,c,s,a]),(0,E.useEffect)(()=>{if(s||!a||!t||!i)return;let k=l.current;if(!k)return;let R=null,x=0,A=()=>{x=Date.now(),R=setTimeout(()=>{t.track({projectId:n,componentId:e.id,variantId:i,eventType:"cursor_signal",payload:{hoverDuration:Date.now()-x}}),R=null},800)},w=()=>{R!==null&&(clearTimeout(R),R=null)};return k.addEventListener("mouseenter",A),k.addEventListener("mouseleave",w),()=>{k.removeEventListener("mouseenter",A),k.removeEventListener("mouseleave",w),R!==null&&clearTimeout(R)}},[t,i,n,e.id,s,a]),(0,E.useEffect)(()=>{if(s||!a||!t||!i)return;let k=l.current;if(!k)return;let R=Date.now();return(0,gt.attachMicroSignalDetectors)((x,A={})=>{var De,Te,Fe;t.track({projectId:n,componentId:e.id,variantId:i,eventType:"micro_signal",payload:S({signalType:x},A)});let w=(De=e.microSignalGoals)==null?void 0:De[x];if(!w||h.current.has(x))return;h.current.add(x);let L=typeof w=="string"?w:w.name,V=typeof w=="string"?1:(Te=w.weight)!=null?Te:1,ee=typeof w=="string"?0:(Fe=w.stepIndex)!=null?Fe:0;t.goal(L,{metadata:S({signalType:x},A),weight:V,stepIndex:ee})},k,R)},[t,i,n,e.id,e.microSignalGoals,s,a]),(0,E.useEffect)(()=>{if(s||!a||!t||!i)return;let k=l.current;if(!k)return;let R=K(c);return j(k,c,{fireGoal:()=>{p.current||(p.current=!0,t.track({projectId:n,componentId:e.id,variantId:i,eventType:"goal_achieved",goalType:u,payload:S({reward:1},R!==void 0?{goalValue:R}:{})}),t.goal(u,S({metadata:{componentId:e.id,variantId:i},weight:1,stepIndex:0},R!==void 0?{value:R}:{})))},fireStep:(x,A,w)=>{t.track({projectId:n,componentId:e.id,variantId:i,eventType:"goal_achieved",goalType:x,payload:{reward:A}}),t.goal(x,{metadata:{},weight:A,stepIndex:w})}},u)},[t,i,n,e.id,c,u,s,a]),e.clientOnly&&(!d||!t)||!i)return null;let g=(C=e.variants[i])!=null?C:null,v=g===null?m:null;return G()&&g===null&&v===null&&console.warn(`[sentient] <Adaptive id="${e.id}"> was assigned variant "${i}" but no matching key exists in props.variants. If this is a dashboard-managed text variant, use <AdaptiveText id="${e.id}"> instead.`),(0,pt.jsx)("div",{ref:l,"data-sentient-id":e.id,"data-sentient-variant":i,children:g!=null?g:v})}var mt=(0,E.memo)(gn,(e,t)=>{if(e.id!==t.id||e.goal!==t.goal&&JSON.stringify(e.goal)!==JSON.stringify(t.goal)||e.microSignalGoals!==t.microSignalGoals||e.funnel!==t.funnel||e.clientOnly!==t.clientOnly||e.agentData!==t.agentData||e.agentDataByVariant!==t.agentDataByVariant)return!1;if(e.variants===t.variants)return!0;let n=Object.keys(e.variants),r=Object.keys(t.variants);return n.length!==r.length?!1:n.every(o=>o in t.variants&&Object.is(e.variants[o],t.variants[o]))});var D=require("react");var yt=require("react/jsx-runtime");function vt({id:e,default:t,component:n="span",className:r,goal:o}){var R;let i=O(),m=N(),s=ge(),a=fe(),l=(0,D.useRef)(null),d=(0,D.useRef)(null),f=(0,D.useSyncExternalStore)(M,()=>ne(e),()=>null),[p,h]=(0,D.useState)(()=>{var x,A;return(A=(x=i==null?void 0:i.getAssignment(e,a))==null?void 0:x.content)!=null?A:null}),[b,y]=(0,D.useState)(()=>{var x,A;return(A=(x=i==null?void 0:i.getAssignment(e,a))==null?void 0:x.variantId)!=null?A:null});(0,D.useEffect)(()=>{if(f||!i)return;let x=i.getAssignment(e,a);if((x==null?void 0:x.content)!==void 0){y(x.variantId),h(x.content);return}let A=!1;return i.assign(e).then(w=>{if(!A){if(!w){G()&&console.warn(`[sentient] <AdaptiveText id="${e}"> assignment failed \u2014 showing default text.`);return}y(w.variantId),w.content&&h(w.content)}}),()=>{A=!0}},[i,e,a,f]),(0,D.useEffect)(()=>{f||!i||!b||!m||l.current!==b&&(l.current=b,i.track({projectId:m,componentId:e,variantId:b,eventType:"variant_assigned",payload:{}}),s==null||s(e,b))},[i,b,m,e,s,f]);let c=o===void 0?"":typeof o=="string"?o:JSON.stringify(o),u=(0,D.useMemo)(()=>o===void 0?null:F(o),[c]),g=o===void 0?null:typeof o=="string"?o:u.type,v=(0,D.useRef)(!1);(0,D.useEffect)(()=>{v.current=!1},[b,c]),(0,D.useEffect)(()=>{if(f||!i||!b||!m||!u||!g)return;let x=d.current;if(!x)return;let A=K(u);return j(x,u,{fireGoal:()=>{v.current||(v.current=!0,i.track({projectId:m,componentId:e,variantId:b,eventType:"goal_achieved",goalType:g,payload:S({reward:1},A!==void 0?{goalValue:A}:{})}),i.goal(g,S({metadata:{componentId:e,variantId:b},weight:1,stepIndex:0},A!==void 0?{value:A}:{})))},fireStep:(w,L,V)=>{i.track({projectId:m,componentId:e,variantId:b,eventType:"goal_achieved",goalType:w,payload:{reward:L}}),i.goal(w,{metadata:{},weight:L,stepIndex:V})}})},[i,b,m,e,u,g,f]);let C=p!=null?p:t;if(f){let x=i==null?void 0:i.getAssignment(e,a);C=x&&x.variantId===f&&(R=x.content)!=null?R:t}return(0,yt.jsx)(n,{ref:x=>{d.current=x},className:r,children:C})}var ve=require("react");function ye(e){let t=O(),n=(0,ve.useRef)(new Set);return(0,ve.useCallback)((r,o)=>{var i,m;if(!ne(e)){if(o!=null&&o.once){if(n.current.has(r))return;n.current.add(r)}t==null||t.componentGoal(e,r,o),t==null||t.goal(r,S(S(S({metadata:(i=o==null?void 0:o.metadata)!=null?i:{},weight:(m=o==null?void 0:o.reward)!=null?m:1,stepIndex:0},(o==null?void 0:o.value)!==void 0?{value:o.value}:{}),(o==null?void 0:o.currency)!==void 0?{currency:o.currency}:{}),(o==null?void 0:o.externalId)!==void 0?{externalId:o.externalId}:{}))}},[t,e])}var se=require("react");function St(e,t={}){let a=t,{componentId:n}=a,r=Ke(a,["componentId"]),o=O(),i=ye(n!=null?n:""),m=(0,se.useRef)(!1),s=(0,se.useRef)(r);s.current=r,(0,se.useEffect)(()=>{if(!o||m.current)return;m.current=!0;let{metadata:l,reward:d,value:f,currency:p,externalId:h}=s.current;if(n){i(e,s.current);return}o.goal(e,S(S(S({metadata:l!=null?l:{},weight:d!=null?d:1,stepIndex:0},f!==void 0?{value:f}:{}),p!==void 0?{currency:p}:{}),h!==void 0?{externalId:h}:{}))},[o,n,e,i])}var bt=require("@sentientui/core"),wt=require("@sentientui/policy"),At=require("react/jsx-runtime");function ht(e){return JSON.stringify(e).replace(/</g,"\\u003c")}function mn(e){return e.persona?'(function(){try{var d=document.documentElement;if(d.hasAttribute("data-sentient-persona"))return;d.setAttribute("data-sentient-persona",'+ht(e.persona.persona)+');d.setAttribute("data-sentient-confidence",'+ht((0,wt.confidenceBand)(e.persona.confidence))+");}catch(e){}})();":(0,bt.renderPrePaintScript)(e.apiKey)}function xt(e){return(0,At.jsx)("script",{"data-sentient-persona-script":"",nonce:e.nonce,dangerouslySetInnerHTML:{__html:mn(e)}})}var U=require("react"),Gt=require("@sentientui/policy");var W=require("react"),Y=require("@sentientui/core"),kt=require("@sentientui/policy");var Ct=new Set;function Se(e,t){let n=O(),r=me(),[,o]=(0,W.useReducer)(d=>d+1,0),i=(0,W.useSyncExternalStore)(M,()=>{var d;return typeof window!="undefined"?(d=window.__sentient_slot_overrides)==null?void 0:d[e]:void 0},()=>{}),m=i===void 0?r[e]:void 0,s=i===void 0&&m===void 0&&n?n.getSlotResult(e):null,a=(n==null?void 0:n.isLocal)===!0&&i===void 0&&m===void 0&&s===null;(0,W.useEffect)(()=>{if(!a||!n)return;let d=!1;return n.decide({slots:[t]}).then(f=>{!d&&f&&o()}),()=>{d=!0}},[n,e,a]);let l=(()=>{if(i!==void 0)return{result:i,arm:(0,Y.armOfResult)(i),source:"override"};if(m!==void 0)return{result:m,arm:(0,Y.armOfResult)(m),source:"preloaded"};if(s!==null)return{result:s,arm:(0,Y.armOfResult)(s),source:"client"};let d=(0,Y.baselineResultFor)(t);return{result:d,arm:(0,Y.armOfResult)(d),source:"baseline"}})();return(0,W.useEffect)(()=>{G()&&(!n||n.isLocal===!0||l.source==="baseline"&&(Ct.has(e)||(Ct.add(e),console.warn(`[sentient] slot "${e}" resolved to its baseline \u2014 no SSR-preloaded or decided result. Keyed clients decide slots server-side, so this slot serves baseline for the whole session and records no exposure. Preload it via loadAdaptiveDecision()/initialSlots so it can serve a decided arm and learn.`))))},[n,l.source,e]),l}function pn(){var t;if(typeof window=="undefined")return null;let e=window.__sentient_persona_override;if(e!=null&&e.persona)return{persona:e.persona,confidence:(t=e.confidence)!=null?t:1};try{let n=new URLSearchParams(window.location.search).get("sentient_persona");if(n)return{persona:n,confidence:1}}catch(n){}return null}function Rt(){let e=O(),t=lt();(0,W.useSyncExternalStore)(M,ze,()=>0);let[n,r]=(0,W.useState)(!1);(0,W.useEffect)(()=>r(!0),[]);let o=s=>({persona:s.persona,confidence:s.confidence,band:(0,kt.confidenceBand)(s.confidence)});if(!n)return t?o(t):null;let i=pn();if(i)return o(i);if(t)return o(t);let m=e?e.getPersona():null;return m?o(m):null}var _t=new Set;function vn(e){return typeof CSS!="undefined"&&typeof CSS.escape=="function"?CSS.escape(e):e.replace(/[\\"]/g,"\\$&")}function Ot(e,t,n){let r=O(),o=N(),i=JSON.stringify(t),m=(0,U.useMemo)(()=>({id:e,dims:t}),[e,i]),{result:s,arm:a,source:l}=Se(e,m),d=(0,U.useMemo)(()=>typeof s=="string"?{}:s,[a]);if(G()&&!_t.has(e)){_t.add(e);let y=(0,Gt.validateSlotDecl)({id:e,dims:Object.fromEntries(Object.entries(t).map(([u,g])=>[u,[...g]]))}),c=Object.values(t).reduce((u,g)=>u*g.length,1);y.ok?c>4&&console.warn(`[sentient] useAdaptiveTokens("${e}") declares ${c} combinations \u2014 more than the recommended 4. Each extra combination needs more traffic to learn; consider fewer dims/values.`):console.warn(`[sentient] useAdaptiveTokens("${e}"): invalid declaration \u2014 ${y.reason}. Serving baseline.`)}let f=(n==null?void 0:n.goal)===void 0?null:typeof n.goal=="string"?n.goal:JSON.stringify(n.goal);(0,U.useEffect)(()=>te({id:e,dims:t}),[e]);let p=(0,U.useRef)(null);(0,U.useEffect)(()=>{!r||l==="baseline"||l==="override"||p.current===a||(p.current=a,H(r,o,e,a))},[r,o,e,a,l]);let h=n==null?void 0:n.funnel;(0,U.useEffect)(()=>{var y;!r||!h||l==="override"||Z(r,o,e,h,F((y=n==null?void 0:n.goal)!=null?y:"click"))},[r,o,e,h,f,l]),(0,U.useEffect)(()=>{if(!r||!(n!=null&&n.goal)||l==="override"||l==="baseline")return;let y=document.querySelector(`[data-sentient-slot="${vn(e)}"]`);if(!y){G()&&console.warn(`[sentient] useAdaptiveTokens("${e}"): a goal is declared but no element carries the returned props \u2014 spread {...props} on the slot's element.`);return}let c=q(n.goal),u=K(n.goal),g=!1;return j(y,F(n.goal),{fireGoal:()=>{g||(g=!0,u!==void 0?r.componentGoal(e,c,{value:u}):r.componentGoal(e,c),r.goal(c,S({metadata:{componentId:e,arm:a},weight:1,stepIndex:0},u!==void 0?{value:u}:{})))},fireStep:(v,C,k)=>{r.componentGoal(e,v,{reward:C}),r.goal(v,{metadata:{componentId:e,arm:a},weight:C,stepIndex:k})}},c)},[r,e,f,a,l]);let b=(0,U.useMemo)(()=>{let y={"data-sentient-slot":e};for(let[c,u]of Object.entries(d))y[`data-${c}`]=u;return y},[e,d]);return{tokens:d,props:b}}var X=require("react"),Kt=require("@sentientui/core");var z=require("react"),Pt=require("@sentientui/core");var Et=new Set;function It(e){var b;let t=O(),n=me(),r=ut(),o=ct(),[,i]=(0,z.useReducer)(y=>y+1,0),m=(0,z.useSyncExternalStore)(M,()=>{var y;return typeof window!="undefined"?(y=window.__sentient_slot_config_overrides)==null?void 0:y[e]:void 0},()=>{}),s=(0,z.useSyncExternalStore)(M,()=>{var y;return typeof window!="undefined"?(y=window.__sentient_slot_overrides)==null?void 0:y[e]:void 0},()=>{}),a=m===void 0?r[e]:void 0,l=m===void 0&&a===void 0&&t?t.getSlotConfig(e):null,d=y=>y==null?"":(0,Pt.armOfResult)(y),f=(b=o!=null?o:t==null?void 0:t.getSitePalette())!=null?b:null,p=(t==null?void 0:t.isLocal)===!0&&m===void 0&&a===void 0&&l===null;(0,z.useEffect)(()=>{if(!p||!t)return;let y=!1;return t.decide({slotsFrom:"registry"}).then(c=>{!y&&c&&i()}),()=>{y=!0}},[t,e,p]);let h=(()=>{var y,c;return m!==void 0?{config:m,arm:d(s),palette:f,source:"override"}:a!==void 0?{config:a,arm:d((y=n[e])!=null?y:t==null?void 0:t.getSlotResult(e)),palette:f,source:"preloaded"}:l!==null?{config:l,arm:d((c=t==null?void 0:t.getSlotResult(e))!=null?c:n[e]),palette:f,source:"client"}:{config:null,arm:"",palette:f,source:"none"}})();return(0,z.useEffect)(()=>{!t||t.isLocal===!0||h.source!=="none"||t.reportSlots([e])},[t,h.source,e]),(0,z.useEffect)(()=>{G()&&(!t||t.isLocal===!0||h.source==="none"&&(Et.has(e)||(Et.add(e),console.warn(`[sentient] AdaptiveSlot "${e}" has no server config \u2014 rendering its baseline children. Preload it via loadAdaptiveDecision({ slotsFrom: 'registry' }) and pass initialSlotConfig/initialSlots to <AdaptiveProvider> so it can serve a decided arm and learn.`))))},[t,h.source,e]),h}var Ee=require("react");var P=require("react/jsx-runtime"),he={none:"0",sm:"8px",md:"16px",lg:"24px"},Oe={start:"flex-start",center:"center",end:"flex-end",stretch:"stretch",between:"space-between"},Ft={sm:"0.875em",md:"1em",lg:"1.25em"},yn={sm:"1.25em",md:"1.5em",lg:"2em"},Lt={sm:"6px 14px",md:"10px 20px",lg:"14px 28px"},Dt={sm:"8px",md:"16px",lg:"32px"},Sn={square:"1 / 1",landscape:"4 / 3",wide:"16 / 9"},hn={normal:"400",medium:"500",bold:"700"};function Tt(e){return S(S({},e==="muted"?{opacity:.7}:{}),e==="accent"?{fontWeight:600}:{})}function Bt(e,t,n){var r,o,i,m;return J(S({display:"inline-block",padding:(r=Lt[n!=null?n:"md"])!=null?r:Lt.md,borderRadius:(o=t==null?void 0:t.radius)!=null?o:"8px",font:"inherit"},n?{fontSize:Ft[n]}:{}),{textDecoration:e==="ghost"?"underline":"none",cursor:"pointer",background:e==="primary"?(i=t==null?void 0:t.primaryBg)!=null?i:"#111827":"transparent",color:e==="primary"?(m=t==null?void 0:t.primaryText)!=null?m:"#ffffff":"inherit",border:e==="secondary"?"1px solid currentColor":"none"})}function bn({node:e,opts:t}){var o,i,m;let n=(o=e.emphasis)!=null?o:"primary",r={padding:"8px 10px",font:"inherit",border:"1px solid currentColor",borderRadius:(m=(i=t.palette)==null?void 0:i.radius)!=null?m:"8px"};return(0,P.jsxs)("form",{onSubmit:s=>{var d,f,p;s.preventDefault();let a=new FormData(s.currentTarget),l={};for(let h of e.fields)l[h.name]=String((d=a.get(h.name))!=null?d:"");(f=t.onFormGoal)==null||f.call(t,e.submitGoal);try{(p=t.onFormSubmit)==null||p.call(t,l)}catch(h){}},style:{display:"flex",flexDirection:"column",gap:"12px"},children:[e.fields.map(s=>{var a,l;return(0,P.jsxs)("label",{style:{display:"flex",flexDirection:"column",gap:"4px",font:"inherit"},children:[s.label,s.kind==="textarea"?(0,P.jsx)("textarea",{name:s.name,required:s.required,placeholder:s.placeholder,rows:3,style:r}):s.kind==="select"?(0,P.jsx)("select",{name:s.name,required:s.required,style:r,children:((a=s.options)!=null?a:[]).map(d=>(0,P.jsx)("option",{value:d,children:d},d))}):(0,P.jsx)("input",{name:s.name,type:(l=s.inputType)!=null?l:"text",required:s.required,placeholder:s.placeholder,style:r})]},s.name)}),(0,P.jsx)("button",{type:"submit",style:Bt(n,t.palette),children:e.submitLabel})]})}function be(e,t){var n,r,o,i,m,s,a,l,d;try{switch(e.type){case"stack":{let f=(r=he[(n=e.gap)!=null?n:"md"])!=null?r:he.md;return(0,P.jsx)("div",{style:S(S(S({display:"flex",flexDirection:e.direction,gap:f},e.align?{alignItems:Oe[e.align]}:{}),e.justify?{justifyContent:Oe[e.justify]}:{}),e.wrap?{flexWrap:"wrap"}:{}),children:((o=e.children)!=null?o:[]).map((p,h)=>{let b=be(p,t);return b===null?null:(0,P.jsx)(Ee.Fragment,{children:b},h)})})}case"grid":{let f=(m=he[(i=e.gap)!=null?i:"md"])!=null?m:he.md;return(0,P.jsx)("div",{style:S({display:"grid",gridTemplateColumns:`repeat(auto-fit, minmax(max(200px, calc((100% - ${e.columns-1} * ${f}) / ${e.columns})), 1fr))`,gap:f},e.align?{alignItems:Oe[e.align]}:{}),children:((s=e.children)!=null?s:[]).map((p,h)=>{let b=be(p,t);return b===null?null:(0,P.jsx)(Ee.Fragment,{children:b},h)})})}case"text":return(0,P.jsx)("p",{style:S(S(S(S({margin:0},e.size?{fontSize:Ft[e.size]}:{}),e.weight?{fontWeight:hn[e.weight]}:{}),e.align?{textAlign:e.align}:{}),Tt(e.tone)),children:e.value});case"heading":{let f=`h${e.level}`;return(0,P.jsx)(f,{style:S({margin:0,fontSize:yn[(a=e.size)!=null?a:"md"]},e.align?{textAlign:e.align}:{}),children:e.value})}case"button":{let f=(l=e.emphasis)!=null?l:"primary";return(0,P.jsx)("a",J(S({href:e.href},e.tag?{"data-sentient-tag":e.tag}:{}),{style:Bt(f,t.palette,e.size),children:e.label}))}case"link":return(0,P.jsx)("a",J(S({href:e.href},e.tag?{"data-sentient-tag":e.tag}:{}),{style:{color:"inherit",textDecoration:"underline"},children:e.label}));case"image":return(0,P.jsx)("img",{src:e.src,alt:e.alt,style:S(S({display:"block",maxWidth:"100%"},e.ratio&&e.ratio!=="auto"?{aspectRatio:Sn[e.ratio],width:"100%"}:{}),e.fit?{objectFit:e.fit}:{})});case"badge":return(0,P.jsx)("span",{style:S({display:"inline-block",padding:"2px 10px",borderRadius:"999px",fontSize:"0.75em",border:"1px solid currentColor"},Tt(e.tone)),children:e.value});case"spacer":return(0,P.jsx)("div",{style:{height:(d=Dt[e.size])!=null?d:Dt.md}});case"form":return(0,P.jsx)(bn,{node:e,opts:t});default:return null}}catch(f){return null}}var Nt=require("react/jsx-runtime"),Mt=new Set;function jt({id:e,children:t,onFormSubmit:n,goal:r,className:o}){var C,k;let i=O(),m=N(),{config:s,arm:a,palette:l,source:d}=It(e),f=(0,X.useRef)(null),p=a!==""?(C=s==null?void 0:s.blocks)==null?void 0:C[a]:void 0,h=p!==void 0&&(0,Kt.containsFormBlock)(p)&&!n;(0,X.useEffect)(()=>{!h||!G()||Mt.has(e)||(Mt.add(e),console.warn(`[sentient] AdaptiveSlot "${e}" was served a form arm but has no onFormSubmit handler \u2014 rendering its baseline children instead. Pass onFormSubmit to render generated forms.`))},[h,e]);let b=R=>{!i||d==="override"||(i.componentGoal(e,R),i.goal(R,{metadata:{componentId:e,arm:a},weight:1,stepIndex:0}))},y=t;p!==void 0&&!h?y=(k=be(p,{palette:l,onFormSubmit:n,onFormGoal:b}))!=null?k:t:(s==null?void 0:s.content)!==void 0&&d!=="none"&&(y=s.content);let c=s!=null&&s.blocks?Object.keys(s.blocks).sort().join("|"):"";(0,X.useEffect)(()=>te({id:e,arms:c===""?void 0:c.split("|")}),[e,c]);let u=(0,X.useRef)(null);(0,X.useEffect)(()=>{!i||d==="none"||d==="override"||a===""||u.current===a||(u.current=a,H(i,m,e,a))},[i,m,e,a,d]);let g=r===void 0?null:typeof r=="string"?r:JSON.stringify(r);(0,X.useEffect)(()=>{if(!i||!r||d==="override"||d==="none")return;let R=f.current;if(!R)return;let x=q(r),A=K(r),w=!1;return j(R,F(r),{fireGoal:()=>{w||(w=!0,A!==void 0?i.componentGoal(e,x,{value:A}):i.componentGoal(e,x),i.goal(x,S({metadata:{componentId:e,arm:a},weight:1,stepIndex:0},A!==void 0?{value:A}:{})))},fireStep:(L,V,ee)=>{i.componentGoal(e,L,{reward:V}),i.goal(L,{metadata:{componentId:e,arm:a},weight:V,stepIndex:ee})}},x)},[i,e,g,a,d]);let v=(0,X.useMemo)(()=>S({"data-sentient-slot":e},a!==""?{"data-sentient-arm":a}:{}),[e,a]);return(0,Nt.jsx)("div",J(S({ref:f,className:o},v),{children:y}))}var I=require("react"),Vt=require("@sentientui/core");var $t=new Set;function Wt(e,t){var x;if(G()&&!t.goal)throw new Error(`[sentient] useAdaptive("${e}"): a goal is required \u2014 without one the optimizer accumulates exposures with no rewards and cannot learn. Pass e.g. goal: 'buy_click'.`);let n=O(),r=N(),o=Object.keys(t.variants).join(" "),i=(0,I.useMemo)(()=>Object.keys(t.variants),[o]),{variantId:m,isOverride:s,settled:a}=re(e,i),l=(x=m!=null?m:i[0])!=null?x:"",d=t.variants[l],[f,p]=(0,I.useState)(null),h=(0,I.useRef)(null),b=(0,I.useCallback)(A=>{h.current=A,p(A)},[]),y=typeof t.goal=="string"?t.goal:JSON.stringify(t.goal),c=(0,I.useMemo)(()=>t.goal?F(t.goal):null,[y]),u=t.goal?q(t.goal):"";(0,I.useEffect)(()=>ue({id:e,variantIds:i,goal:u}),[e,i,u]);let g=(0,I.useRef)(null);(0,I.useEffect)(()=>{s||a&&(!n||!l||!f||g.current!==l&&(g.current=l,H(n,r,e,l)))},[n,r,e,l,f,s,a]);let v=t.funnel;(0,I.useEffect)(()=>{s||!a||!n||!v||!c||Z(n,r,e,v,c)},[n,r,e,v,c,s,a]);let C=(0,I.useRef)(!1);(0,I.useEffect)(()=>{C.current=!1},[l,y]),(0,I.useEffect)(()=>{if(s||!a||!n||!l||!f||!c)return;let A=K(c);return j(f,c,{fireGoal:()=>{C.current||(C.current=!0,n.track({projectId:r,componentId:e,variantId:l,eventType:"goal_achieved",goalType:u,payload:S({reward:1},A!==void 0?{goalValue:A}:{})}),n.goal(u,S({metadata:{componentId:e,variantId:l},weight:1,stepIndex:0},A!==void 0?{value:A}:{})))},fireStep:(w,L,V)=>{n.track({projectId:r,componentId:e,variantId:l,eventType:"goal_achieved",goalType:w,payload:{reward:L}}),n.goal(w,{metadata:{},weight:L,stepIndex:V})}},u)},[n,f,l,r,e,c,u,s,a]),(0,I.useEffect)(()=>{if(s||!n||!l||!f)return;let A=Date.now();return(0,Vt.attachMicroSignalDetectors)((w,L={})=>{n.track({projectId:r,componentId:e,variantId:l,eventType:"micro_signal",payload:S({signalType:w},L)})},f,A)},[n,f,l,r,e,s]),(0,I.useEffect)(()=>{if(!G()||!n)return;let A=setTimeout(()=>{!h.current&&!$t.has(e)&&($t.add(e),console.warn(`[sentient] useAdaptive("${e}"): bind was never attached \u2014 spread {...bind} on the rendered element, otherwise exposure and goal tracking cannot work and the optimizer learns nothing.`))},0);return()=>clearTimeout(A)},[n,e]);let k=(0,I.useCallback)((A,w)=>{var V,ee;if(s)return;let L=A!=null?A:u;L&&(n==null||n.componentGoal(e,L,w),n==null||n.goal(L,S(S(S({metadata:(V=w==null?void 0:w.metadata)!=null?V:{},weight:(ee=w==null?void 0:w.reward)!=null?ee:1,stepIndex:0},(w==null?void 0:w.value)!==void 0?{value:w.value}:{}),(w==null?void 0:w.currency)!==void 0?{currency:w.currency}:{}),(w==null?void 0:w.externalId)!==void 0?{externalId:w.externalId}:{})))},[n,e,u,s]),R=(0,I.useMemo)(()=>({ref:b,"data-sentient-id":e,"data-sentient-variant":l}),[b,e,l]);return{variant:l,value:d,bind:R,fireGoal:k}}var T=require("react");var Jt=require("react/jsx-runtime"),we=new Set;function Ut(e){var u;let t=O(),n=N(),r=(0,T.useRef)(null),o=Object.keys(e.arrangements).join(" "),i=(0,T.useMemo)(()=>Object.keys(e.arrangements),[o]),m=(0,T.useMemo)(()=>S({id:e.id,arms:i},e.baseline!==void 0?{baseline:e.baseline}:{}),[e.id,i,e.baseline]),{arm:s,source:a}=Se(e.id,m);G()&&e.baseline!==void 0&&e.baseline!==i[0]&&!we.has(e.id+":baseline")&&(we.add(e.id+":baseline"),console.warn(`[sentient] <AdaptiveGroup id="${e.id}">: baseline "${e.baseline}" is not the first-declared arrangement ("${i[0]}"). The first arrangement should usually be the page's real incumbent (the holdout sees it).`));let l=T.Children.toArray(e.children).filter(T.isValidElement),d=new Map;for(let g of l)d.set(String((u=g.key)!=null?u:"").replace(/^\.\$/,""),g);let f=e.arrangements[s],p=f!==void 0&&f.length===l.length&&f.every(g=>d.has(g));G()&&f!==void 0&&!p&&!we.has(e.id+":keys")&&(we.add(e.id+":keys"),console.warn(`[sentient] <AdaptiveGroup id="${e.id}">: arrangement "${s}" [${f.join(", ")}] does not match the children's keys \u2014 rendering declaration order (fail-safe).`));let h=p?f.map(g=>d.get(g)):l;(0,T.useEffect)(()=>te({id:e.id,arms:Object.keys(e.arrangements)}),[e.id]);let b=(0,T.useRef)(null);(0,T.useEffect)(()=>{!t||a==="baseline"||a==="override"||b.current===s||(b.current=s,H(t,n,e.id,s))},[t,n,e.id,s,a]);let y=e.funnel;(0,T.useEffect)(()=>{var g;!t||!y||a==="override"||Z(t,n,e.id,y,F((g=e.goal)!=null?g:"click"))},[t,n,e.id,y,a]);let c=e.goal===void 0?null:typeof e.goal=="string"?e.goal:JSON.stringify(e.goal);return(0,T.useEffect)(()=>{if(!t||e.goal===void 0||a==="override"||a==="baseline")return;let g=r.current;if(!g)return;let v=q(e.goal),C=K(e.goal),k=!1;return j(g,F(e.goal),{fireGoal:()=>{k||(k=!0,C!==void 0?t.componentGoal(e.id,v,{value:C}):t.componentGoal(e.id,v),t.goal(v,S({metadata:{componentId:e.id,arm:s},weight:1,stepIndex:0},C!==void 0?{value:C}:{})))},fireStep:(R,x,A)=>{t.componentGoal(e.id,R,{reward:x}),t.goal(R,{metadata:{componentId:e.id,arm:s},weight:x,stepIndex:A})}},v)},[t,e.id,c,s,a]),(0,Jt.jsx)("div",{ref:r,"data-sentient-id":e.id,"data-sentient-variant":s,children:h})}var Pe=require("@sentientui/core");var wn=["page","blocks","layoutOrder"],Ht=new Map;function Xt(e,t){Ht.set(e,t)}function Ie(e){return Ht.get(e)}function zt(e){var o,i;let t=(i=(o=e.content)!=null?o:Ie(e.page))!=null?i:{},n={};for(let[m,s]of Object.entries(t))wn.includes(m)||(n[m]=s);let r=J(S({},n),{page:e.page,blocks:e.blocks});return e.layoutOrder&&(r.layoutOrder=e.layoutOrder),r}function qt(e){return`<script type="application/ld+json">${Le(e)}</script>`}function Le(e){return JSON.stringify(S({"@context":"https://schema.org","@type":"WebPage"},e)).replace(/</g,"\\u003c")}function Zt(e){let t=[];e.title&&t.push(`# ${e.title}`,""),e.summary&&t.push(String(e.summary),"");for(let[n,r]of Object.entries(e))["page","title","summary","blocks","layoutOrder"].includes(n)||t.push(`## ${n}`,"","```json",JSON.stringify(r,null,2),"```","");if(e.blocks.length>0){t.push("## blocks","");for(let n of e.blocks)t.push(`- **${n.id}** \u2192 variant \`${n.variant}\``),n.content!==void 0&&t.push(""," ```json",JSON.stringify(n.content,null,2)," ```");t.push("")}return t.join(`
|
|
3
3
|
`).trimEnd()+`
|
|
4
|
-
`}var
|
|
4
|
+
`}var Qt=require("@sentientui/core");0&&(module.exports={Adaptive,AdaptiveGroup,AdaptiveProvider,AdaptiveSlot,AdaptiveText,SentientPersonaScript,buildAgentFeed,defineAgentContent,detectSegment,getAgentContent,grantConsent,renderAgentJsonLd,renderAgentJsonLdBody,renderAgentMarkdown,useAdaptive,useAdaptiveApiBaseUrl,useAdaptiveGoal,useAdaptivePersona,useAdaptiveTokens,useAssignment,useInitialAssignments,useLayoutOrder,usePageGoal,useSentient});
|
|
5
5
|
//# sourceMappingURL=index.js.map
|