@sensiblestats/widget-react 0.12.0 → 0.13.1

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/StatsWidget.tsx","../src/i18n.ts","../src/config.ts","../src/theme.ts","../src/useChatStream.ts","../src/reducer.ts","../src/model.ts","../src/assets/logo.ts","../src/components/Icons.tsx","../src/components/GreetingBubble.tsx","../src/components/ChatFab.tsx","../src/components/ChatPanel.tsx","../src/components/ChatHeader.tsx","../src/components/MessageList.tsx","../src/components/Markdown.tsx","../src/components/EntityCardList.tsx","../src/components/BettingInsightList.tsx","../src/components/AddToSlipButton.tsx","../src/slip.ts","../src/components/Toast.tsx","../src/components/OddsMovementBadge.tsx","../src/components/MarketOddsCardList.tsx","../src/components/ActionButtons.tsx","../src/components/ChatMessage.tsx","../src/components/IntentChips.tsx","../src/scroll.ts","../src/components/ChatInput.tsx","../src/styles/css.generated.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, type CSSProperties } from 'react'\nimport { StatsWidgetClient, type Conversation } from '@sensiblestats/widget-sdk'\nimport { normalizeUi, toClientOptions, toUserContext, type StatsWidgetConfig } from './config'\nimport type { SlipHandlerProps } from './slip'\nimport { themeAttrs } from './theme'\nimport { useChatStream } from './useChatStream'\nimport { ChatFab } from './components/ChatFab'\nimport { ChatPanel } from './components/ChatPanel'\nimport { WIDGET_CSS } from './styles/css.generated'\n\nexport type StatsWidgetProps =\n | { config: StatsWidgetConfig; client?: never }\n | { client: StatsWidgetClient; config?: Omit<StatsWidgetConfig, 'operatorId' | 'publicKey' | 'baseUrl' | 'userContext'> }\n\nfunction buildClient(props: StatsWidgetProps): { client: StatsWidgetClient; conversation: Conversation } | null {\n try {\n if ('client' in props && props.client) {\n return { client: props.client, conversation: props.client.conversation() }\n }\n const cfg = props.config as StatsWidgetConfig\n const client = new StatsWidgetClient(toClientOptions(cfg))\n return { client, conversation: client.conversation(toUserContext(cfg)) }\n } catch (err) {\n console.error('[StatsWidget] failed to initialize:', err instanceof Error ? err.message : err)\n return null\n }\n}\n\nfunction injectStyles(root: Document | ShadowRoot): void {\n const host: ParentNode = root instanceof ShadowRoot ? root : root.head\n if (host.querySelector('#ss-w-styles')) return\n const el = document.createElement('style')\n el.id = 'ss-w-styles'\n el.textContent = WIDGET_CSS\n host.appendChild(el)\n}\n\nexport function StatsWidget(props: StatsWidgetProps): JSX.Element | null {\n const injectedClient = 'client' in props ? props.client : undefined\n const cfg = props.config as Partial<StatsWidgetConfig> | undefined\n const built = useMemo(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl])\n const ui = useMemo(() => normalizeUi((props.config ?? { operatorId: '', publicKey: '' }) as StatsWidgetConfig), [props.config])\n const rootRef = useRef<HTMLDivElement>(null)\n const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : undefined)\n const slip = useMemo<SlipHandlerProps>(\n () => ({\n onAddToSlip: props.config?.onAddToSlip,\n conversationId: controller.state.conversationId ?? undefined,\n onMarketClicked: (marketName) => {\n // sendSignal throws synchronously with no operatorUserId configured, and its\n // returned promise can reject on a gateway failure. Neither should ever break\n // the add-to-slip flow for a host that never wired signal tracking.\n try {\n void built?.conversation\n .sendSignal({ signalType: 'InsightMarketClicked', entityType: 'Market', entityName: marketName })\n .catch(() => undefined)\n } catch {\n // ignored — see comment above\n }\n },\n }),\n [props.config?.onAddToSlip, controller.state.conversationId, built],\n )\n\n useEffect(() => {\n if (!built || !ui.injectStyles) return\n const node = rootRef.current?.getRootNode()\n if (node) injectStyles(node as Document | ShadowRoot)\n }, [built, ui.injectStyles])\n\n if (!built) return null\n const attrs = themeAttrs(ui)\n return (\n <div ref={rootRef} className=\"ss-w-root\" data-ss-w-theme={attrs['data-ss-w-theme']} data-ss-w-pos={attrs['data-ss-w-pos']} style={attrs.style as CSSProperties}>\n {controller.state.isOpen ? (\n <ChatPanel controller={controller} ui={ui} slip={slip} />\n ) : (\n <ChatFab\n label={ui.launcherLabel}\n greeting={ui.greeting}\n popupText={controller.state.popupText}\n onOpen={controller.open}\n onDismissPopup={controller.dismissPopup}\n dismissLabel={ui.dismissGreeting}\n />\n )}\n </div>\n )\n}\n\n// Hooks must run unconditionally; when the client failed to build we still need a Conversation-shaped stub for the hook.\nfunction emptyConversation(): Conversation {\n return { send: () => { throw new Error('widget not initialized') } } as unknown as Conversation\n}\n","export type Locale = 'en' | 'tr'\n\nexport interface LocaleStrings {\n launcherLabel: string\n placeholder: string\n closeChat: string\n chatDialogLabel: string\n stopResponse: string\n sendMessage: string\n dismissGreeting: string\n somethingWentWrong: string\n retry: string\n showLess: string\n showMore: (n: number) => string\n showStats: string\n hideStats: string\n oddsLabel: string\n liveLabel: string\n addToSlip: string\n marketPrices: string\n moreLines: string\n hideLines: string\n oddsMoved: (was: string, now: string, direction: string) => string\n oddsShortened: string\n oddsDrifted: string\n updatedLabel: string\n inSlip: string\n slipAdded: (n?: number) => string\n slipDuplicate: string\n slipPriceChanged: (from: string, to: string) => string\n slipPriceNotAccepted: (from: string, to: string) => string\n slipLoginRequired: string\n slipSuspended: string\n slipFailed: string\n}\n\nconst STRINGS: Record<Locale, LocaleStrings> = {\n en: {\n launcherLabel: 'Chat with SensibleStats',\n placeholder: 'Ask about a team, player or match…',\n closeChat: 'Close chat',\n chatDialogLabel: 'SensibleStats chat',\n stopResponse: 'Stop response',\n sendMessage: 'Send message',\n dismissGreeting: 'Dismiss',\n somethingWentWrong: 'Something went wrong.',\n retry: 'Retry',\n showLess: 'Show less',\n showMore: (n) => `Show ${n} more`,\n showStats: 'Show stats',\n hideStats: 'Hide stats',\n oddsLabel: 'Odds',\n liveLabel: 'Live',\n addToSlip: 'Add to slip',\n marketPrices: 'Market prices',\n moreLines: 'More lines',\n hideLines: 'Hide lines',\n oddsMoved: (was, now, direction) => `was ${was}, now ${now}, ${direction}`,\n oddsShortened: 'shortened',\n oddsDrifted: 'drifted',\n updatedLabel: 'updated',\n inSlip: 'In slip',\n slipAdded: (n) => (n === undefined ? 'Added to slip' : `Added to slip (${n} selection${n === 1 ? '' : 's'})`),\n slipDuplicate: 'Already in your slip',\n slipPriceChanged: (from, to) => `Added at ${to} (was ${from})`,\n slipPriceNotAccepted: (from, to) => `Price moved to ${to} (was ${from}). Tap to add.`,\n slipLoginRequired: 'Sign in to add to your slip',\n slipSuspended: 'Market suspended',\n slipFailed: \"Couldn't add to slip. Try again.\",\n },\n tr: {\n launcherLabel: 'SensibleStats ile sohbet et',\n placeholder: 'Bir takım, oyuncu veya maç hakkında sor…',\n closeChat: 'Sohbeti kapat',\n chatDialogLabel: 'SensibleStats sohbet',\n stopResponse: 'Yanıtı durdur',\n sendMessage: 'Mesaj gönder',\n dismissGreeting: 'Kapat',\n somethingWentWrong: 'Bir şeyler ters gitti.',\n retry: 'Tekrar dene',\n showLess: 'Daha az göster',\n showMore: (n) => `${n} tane daha göster`,\n showStats: 'İstatistikleri göster',\n hideStats: 'İstatistikleri gizle',\n oddsLabel: 'Oran',\n liveLabel: 'Canlı',\n addToSlip: 'Kupona ekle',\n marketPrices: 'Piyasa fiyatları',\n moreLines: 'Diğer çizgiler',\n hideLines: 'Çizgileri gizle',\n oddsMoved: (was, now, direction) => `önce ${was}, şimdi ${now}, ${direction}`,\n oddsShortened: 'düştü',\n oddsDrifted: 'yükseldi',\n updatedLabel: 'güncellendi',\n inSlip: 'Kuponda',\n slipAdded: (n) => (n === undefined ? 'Kupona eklendi' : `Kupona eklendi (${n} seçim)`),\n slipDuplicate: 'Bu seçim kuponunuzda zaten var',\n slipPriceChanged: (from, to) => `${to} oranıyla eklendi (önceki ${from})`,\n slipPriceNotAccepted: (from, to) => `Oran ${to} oldu (önceki ${from}). Eklemek için dokunun.`,\n slipLoginRequired: 'Kupona eklemek için giriş yapın',\n slipSuspended: 'Bu market askıya alındı',\n slipFailed: 'Kupona eklenemedi. Tekrar deneyin.',\n },\n}\n\nexport function resolveLocaleStrings(locale?: string): LocaleStrings {\n return STRINGS[locale as Locale] ?? STRINGS.en\n}\n","import type { AddToSlipHandler, StatsWidgetClientOptions, UserContext } from '@sensiblestats/widget-sdk'\nimport { resolveLocaleStrings } from './i18n'\n\nexport interface StatsWidgetConfig {\n operatorId: string\n publicKey: string\n baseUrl?: string\n userContext?: UserContext\n theme?: 'light' | 'dark' | 'auto'\n accent?: string\n position?: 'left' | 'right'\n offset?: { x?: number; y?: number }\n radius?: number\n /** BCP-47-ish locale code for the widget's own chrome text (e.g. \"en\", \"tr\"). Defaults to \"en\". */\n locale?: string\n launcherLabel?: string\n greeting?: string\n /** Message auto-sent once on load (e.g. \"hello\"); its response shows as the launcher popup. */\n greetingMessage?: string\n placeholder?: string\n starters?: string[]\n injectStyles?: boolean\n /** Called when the user adds an insight's selection to the operator's slip. */\n onAddToSlip?: AddToSlipHandler\n}\n\ntype UiKeys =\n | 'theme' | 'accent' | 'position' | 'offset' | 'radius' | 'locale'\n | 'launcherLabel' | 'greeting' | 'greetingMessage' | 'placeholder' | 'starters' | 'injectStyles'\n\nexport interface UiConfig {\n theme: 'light' | 'dark' | 'auto'\n accent?: string\n position: 'left' | 'right'\n offset: { x: number; y: number }\n radius: number\n launcherLabel: string\n greeting?: string\n greetingMessage?: string\n placeholder: string\n starters: string[]\n injectStyles: boolean\n closeChat: string\n chatDialogLabel: string\n stopResponse: string\n sendMessage: string\n dismissGreeting: string\n somethingWentWrong: string\n retry: string\n showLess: string\n showMore: (n: number) => string\n showStats: string\n hideStats: string\n oddsLabel: string\n liveLabel: string\n marketPrices: string\n moreLines: string\n hideLines: string\n oddsMoved: (was: string, now: string, direction: string) => string\n oddsShortened: string\n oddsDrifted: string\n updatedLabel: string\n addToSlip: string\n inSlip: string\n slipAdded: (n?: number) => string\n slipDuplicate: string\n slipPriceChanged: (from: string, to: string) => string\n slipPriceNotAccepted: (from: string, to: string) => string\n slipLoginRequired: string\n slipSuspended: string\n slipFailed: string\n}\n\nexport function normalizeUi(cfg: Pick<StatsWidgetConfig, UiKeys>): UiConfig {\n const strings = resolveLocaleStrings(cfg.locale)\n return {\n theme: cfg.theme ?? 'auto',\n accent: cfg.accent,\n position: cfg.position ?? 'right',\n offset: { x: cfg.offset?.x ?? 20, y: cfg.offset?.y ?? 20 },\n radius: cfg.radius ?? 16,\n launcherLabel: cfg.launcherLabel ?? strings.launcherLabel,\n greeting: cfg.greeting,\n greetingMessage: cfg.greetingMessage,\n placeholder: cfg.placeholder ?? strings.placeholder,\n starters: cfg.starters ?? [],\n injectStyles: cfg.injectStyles ?? true,\n closeChat: strings.closeChat,\n chatDialogLabel: strings.chatDialogLabel,\n stopResponse: strings.stopResponse,\n sendMessage: strings.sendMessage,\n dismissGreeting: strings.dismissGreeting,\n somethingWentWrong: strings.somethingWentWrong,\n retry: strings.retry,\n showLess: strings.showLess,\n showMore: strings.showMore,\n showStats: strings.showStats,\n hideStats: strings.hideStats,\n oddsLabel: strings.oddsLabel,\n liveLabel: strings.liveLabel,\n marketPrices: strings.marketPrices,\n moreLines: strings.moreLines,\n hideLines: strings.hideLines,\n oddsMoved: strings.oddsMoved,\n oddsShortened: strings.oddsShortened,\n oddsDrifted: strings.oddsDrifted,\n updatedLabel: strings.updatedLabel,\n addToSlip: strings.addToSlip,\n inSlip: strings.inSlip,\n slipAdded: strings.slipAdded,\n slipDuplicate: strings.slipDuplicate,\n slipPriceChanged: strings.slipPriceChanged,\n slipPriceNotAccepted: strings.slipPriceNotAccepted,\n slipLoginRequired: strings.slipLoginRequired,\n slipSuspended: strings.slipSuspended,\n slipFailed: strings.slipFailed,\n }\n}\n\nexport function toClientOptions(cfg: StatsWidgetConfig): StatsWidgetClientOptions {\n const opts: StatsWidgetClientOptions = { operatorId: cfg.operatorId, publicKey: cfg.publicKey }\n if (cfg.baseUrl !== undefined) opts.baseUrl = cfg.baseUrl\n return opts\n}\n\nexport function toUserContext(cfg: StatsWidgetConfig): UserContext | undefined {\n return cfg.userContext && Object.keys(cfg.userContext).length > 0 ? cfg.userContext : undefined\n}\n","import type { UiConfig } from './config'\n\nexport interface ThemeAttrs {\n 'data-ss-w-theme': string\n 'data-ss-w-pos': string\n style: Record<string, string>\n}\n\nexport function themeAttrs(ui: UiConfig): ThemeAttrs {\n const style: Record<string, string> = {\n '--ss-w-offset-x': `${ui.offset.x}px`,\n '--ss-w-offset-y': `${ui.offset.y}px`,\n '--ss-w-radius': `${ui.radius}px`,\n }\n if (ui.accent) style['--ss-w-accent'] = ui.accent\n return { 'data-ss-w-theme': ui.theme, 'data-ss-w-pos': ui.position, style }\n}\n","import { useCallback, useEffect, useMemo, useReducer, useRef } from 'react'\nimport type { ChatHandle, ChatInput, Conversation } from '@sensiblestats/widget-sdk'\nimport { WidgetSdkError } from '@sensiblestats/widget-sdk'\nimport { reducer, initialState, type WidgetState } from './reducer'\nimport { chipFromText } from './model'\n\nexport interface SendOptions {\n actionId?: string\n /** Text shown in the user bubble when it differs from the message sent upstream (e.g. an action's label). */\n displayText?: string\n}\n\nexport interface ChatController {\n state: WidgetState\n open(): void\n close(): void\n stop(): void\n toggle(): void\n send(text: string, opts?: SendOptions): void\n retry(): void\n dismissPopup(): void\n}\n\nexport function useChatStream(conversation: Conversation, starterTexts: string[], greetingMessage?: string): ChatController {\n const seed = useMemo(() => initialState(starterTexts.map(chipFromText)), [])\n const [state, dispatch] = useReducer(reducer, seed)\n const idRef = useRef(0)\n const handleRef = useRef<ChatHandle | null>(null)\n const stateRef = useRef(state)\n stateRef.current = state\n const greetedRef = useRef(false)\n\n const nextId = () => `m${idRef.current++}`\n\n const consume = useCallback((handle: ChatHandle, onError: (err: WidgetSdkError) => void) => {\n ;(async () => {\n try {\n for await (const event of handle) dispatch({ kind: 'EVENT', event })\n } catch (err) {\n if (err instanceof WidgetSdkError) onError(err)\n else if ((err as { name?: string } | null)?.name === 'AbortError') { /* expected on cancel/close — ignore */ }\n else throw err\n } finally {\n if (handleRef.current === handle) handleRef.current = null\n }\n })()\n }, [])\n\n const run = useCallback((input: ChatInput, displayText?: string) => {\n handleRef.current?.cancel()\n dispatch({ kind: 'USER_SENT', input, userId: nextId(), assistantId: nextId(), displayText })\n const handle = conversation.send(input)\n handleRef.current = handle\n consume(handle, (err) => dispatch({ kind: 'STREAM_ERROR', error: err }))\n }, [conversation, consume])\n\n const send = useCallback((text: string, opts?: SendOptions) => {\n const trimmed = text.trim()\n if (!trimmed) return\n run({ message: trimmed, actionId: opts?.actionId }, opts?.displayText)\n }, [run])\n\n const retry = useCallback(() => {\n const last = stateRef.current.lastUserInput\n if (last) run(last, stateRef.current.lastDisplayText ?? undefined)\n }, [run])\n\n // Auto-greeting: fire once on mount when configured. No user bubble; its response\n // becomes the launcher popup. Fire-and-forget — failures are swallowed (STOP).\n useEffect(() => {\n const message = greetingMessage?.trim()\n if (!message || greetedRef.current) return\n greetedRef.current = true\n try {\n handleRef.current?.cancel()\n dispatch({ kind: 'GREETING_SENT', assistantId: nextId() })\n const handle = conversation.send({ message })\n handleRef.current = handle\n consume(handle, () => dispatch({ kind: 'STOP' }))\n } catch {\n dispatch({ kind: 'STOP' })\n }\n }, [greetingMessage, conversation, consume])\n\n const open = useCallback(() => dispatch({ kind: 'OPEN' }), [])\n const close = useCallback(() => { handleRef.current?.cancel(); handleRef.current = null; dispatch({ kind: 'CLOSE' }) }, [])\n const stop = useCallback(() => { handleRef.current?.cancel(); handleRef.current = null; dispatch({ kind: 'STOP' }) }, [])\n const toggle = useCallback(() => { if (stateRef.current.isOpen) close(); else open() }, [close, open])\n const dismissPopup = useCallback(() => dispatch({ kind: 'DISMISS_POPUP' }), [])\n\n return { state, open, close, stop, toggle, send, retry, dismissPopup }\n}\n","import type { ChatEvent, ChatInput, StreamErrorEventData } from '@sensiblestats/widget-sdk'\nimport { WidgetSdkError } from '@sensiblestats/widget-sdk'\nimport { toActionVM, toCardVM, toChipVM, toInsightVM, toMarketOddsVM, type ActionVM, type CardVM, type ChipVM, type InsightVM, type MarketOddsVM } from './model'\n\nexport interface UserMessage { role: 'user'; id: string; text: string }\nexport interface AssistantTurn { role: 'assistant'; id: string; text: string; cards: CardVM[]; actions: ActionVM[]; insights: InsightVM[]; marketOdds: MarketOddsVM[]; done: boolean; isGreeting?: boolean }\nexport type Message = UserMessage | AssistantTurn\n\nexport interface WidgetState {\n isOpen: boolean\n messages: Message[]\n isStreaming: boolean\n status: string | null\n actionsLoading: boolean\n starters: ChipVM[]\n error: StreamErrorEventData | WidgetSdkError | null\n lastUserInput: ChatInput | null\n lastDisplayText: string | null\n // Launcher popup text (the auto-greeting response). Cleared on open/dismiss.\n popupText: string | null\n conversationId: string | null\n}\n\nexport type Action =\n | { kind: 'OPEN' }\n | { kind: 'CLOSE' }\n | { kind: 'USER_SENT'; input: ChatInput; userId: string; assistantId: string; displayText?: string }\n | { kind: 'GREETING_SENT'; assistantId: string }\n | { kind: 'EVENT'; event: ChatEvent }\n | { kind: 'STREAM_ERROR'; error: WidgetSdkError }\n | { kind: 'STOP' }\n | { kind: 'DISMISS_POPUP' }\n\nconst POPUP_MAX = 160\n\nexport function initialState(starters: ChipVM[]): WidgetState {\n return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null }\n}\n\nfunction activeTurn(state: WidgetState): AssistantTurn | null {\n const last = state.messages[state.messages.length - 1]\n return last && last.role === 'assistant' && !last.done ? last : null\n}\n\nfunction mapActive(state: WidgetState, fn: (t: AssistantTurn) => AssistantTurn): Message[] {\n const last = state.messages[state.messages.length - 1]\n if (!last || last.role !== 'assistant' || last.done) return state.messages\n return [...state.messages.slice(0, -1), fn(last)]\n}\n\nfunction applyEvent(state: WidgetState, event: ChatEvent): WidgetState {\n switch (event.type) {\n case 'progress':\n return { ...state, status: event.data.message }\n case 'answer':\n return { ...state, messages: mapActive(state, (t) => ({ ...t, text: event.data.text })) }\n case 'entity_card': {\n if (event.data.card.isUsed === false) return state\n const card = toCardVM(event.data.card)\n // Generic cards (coach/referee/stadium/competition — anything not team or\n // player) carry no distinct identity and add no user value; drop them until\n // a purpose-built variant exists.\n if (card.kind === 'generic') return state\n return { ...state, messages: mapActive(state, (t) => ({ ...t, cards: [...t.cards, card] })) }\n }\n case 'action_button':\n return { ...state, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, actions: [...t.actions, toActionVM(event.data.action)] })) }\n case 'betting_insight':\n return { ...state, messages: mapActive(state, (t) => ({ ...t, insights: [...t.insights, toInsightVM(event.data.insight)] })) }\n case 'market_odds':\n return { ...state, messages: mapActive(state, (t) => ({ ...t, marketOdds: [...t.marketOdds, toMarketOddsVM(event.data.card)] })) }\n case 'intent_chip': {\n const chip = toChipVM(event.data.intent)\n return chip ? { ...state, starters: [...state.starters, chip] } : state\n }\n case 'actions_loading':\n return { ...state, actionsLoading: true, status: event.data.message }\n case 'turn_complete': {\n const active = activeTurn(state)\n const text = active?.text.trim() ?? ''\n // A completed greeting turn surfaces its answer as the launcher popup (unless already open).\n const popupText = active?.isGreeting && !state.isOpen && text ? text.slice(0, POPUP_MAX) : state.popupText\n return {\n ...state, isStreaming: false, status: null, actionsLoading: false, popupText,\n conversationId: event.data.conversationId ?? state.conversationId,\n messages: mapActive(state, (t) => ({ ...t, done: true })),\n }\n }\n case 'error': {\n // A failed greeting fails silently — it's non-critical background chatter.\n const suppress = activeTurn(state)?.isGreeting === true\n return { ...state, error: suppress ? state.error : event.data, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) }\n }\n }\n // Unknown/unmodelled event type: never return undefined — that would corrupt\n // state and crash the next dispatch. Ignore the event and keep state intact.\n return state\n}\n\nexport function reducer(state: WidgetState, action: Action): WidgetState {\n switch (action.kind) {\n case 'OPEN':\n return { ...state, isOpen: true, popupText: null }\n case 'CLOSE':\n return { ...state, isOpen: false, isStreaming: false, status: null, actionsLoading: false }\n case 'USER_SENT': {\n const user: UserMessage = { role: 'user', id: action.userId, text: action.displayText ?? action.input.message }\n const assistant: AssistantTurn = { role: 'assistant', id: action.assistantId, text: '', cards: [], actions: [], insights: [], marketOdds: [], done: false }\n return { ...state, messages: [...state.messages, user, assistant], isStreaming: true, status: null, actionsLoading: false, starters: [], error: null, lastUserInput: action.input, lastDisplayText: action.displayText ?? null }\n }\n case 'GREETING_SENT': {\n // Auto-greeting: no user bubble; the assistant turn is flagged so its completion sets the popup.\n const assistant: AssistantTurn = { role: 'assistant', id: action.assistantId, text: '', cards: [], actions: [], insights: [], marketOdds: [], done: false, isGreeting: true }\n return { ...state, messages: [...state.messages, assistant], isStreaming: true, status: null, error: null }\n }\n case 'DISMISS_POPUP':\n return { ...state, popupText: null }\n case 'EVENT':\n return applyEvent(state, action.event)\n case 'STREAM_ERROR':\n return { ...state, error: action.error, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) }\n case 'STOP':\n return { ...state, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) }\n }\n}\n","import type { BettingInsight, EntityCard, MarketOddsCard, MarketOddsRow, SlipSelection } from '@sensiblestats/widget-sdk'\n\nexport type CardKind = 'player' | 'team' | 'generic'\nexport interface StatCell { label: string; value: string }\nexport interface CardScope { competitionId: number | null; label: string; image?: string; stats: StatCell[] }\nexport interface CardVM { id: string; kind: CardKind; name: string; image?: string; sub?: string; season?: string; scopes: CardScope[] }\nexport interface ActionVM { label: string; actionId?: string; message: string }\nexport interface ChipVM { text: string }\nexport interface InsightScope { key: string; label: string; stats: StatCell[] }\nexport interface InsightVM {\n id: string\n market: string\n selection?: string\n odds?: string\n bookmaker?: string\n isLive: boolean\n phase?: string\n fixture?: string\n competition?: string\n scopes?: InsightScope[]\n text: string\n stats: StatCell[]\n disclaimer?: string\n matchId: number\n matchOddsId?: number\n addToSlipEnabled: boolean\n oddsDecimal?: number\n quotedAtUtc?: string\n previousOdds?: string\n movementDirection?: 'shortened' | 'drifted'\n}\n\nexport interface MarketOddsRowVM {\n key: string\n selection: string\n odds: string\n oddsDecimal?: number\n matchOddsId?: number\n quotedAtUtc?: string\n isMain: boolean\n previousOdds?: string\n movementDirection?: 'shortened' | 'drifted'\n}\nexport interface MarketOddsVM {\n id: string\n market: string\n fixture?: string\n competition?: string\n bookmaker?: string\n updatedAt?: string\n isLive: boolean\n matchId: number\n mainRows: MarketOddsRowVM[]\n moreRows: MarketOddsRowVM[]\n disclaimer?: string\n addToSlipEnabled: boolean\n}\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined\n}\nfunction num(v: unknown): string | undefined {\n return typeof v === 'number' && Number.isFinite(v) ? String(v) : undefined\n}\n\nfunction readStatCells(raw: unknown): StatCell[] {\n if (!Array.isArray(raw)) return []\n const cells: StatCell[] = []\n for (const entry of raw as Array<Record<string, unknown>>) {\n const label = str(entry.label)\n const value = num(entry.value) ?? str(entry.value)\n if (label !== undefined && value !== undefined) cells.push({ label, value })\n }\n return cells\n}\n\nexport function toCardVM(card: EntityCard): CardVM {\n const entityType = str(card.entityType)?.toLowerCase()\n const kind: CardKind = entityType === 'player' ? 'player' : entityType === 'team' ? 'team' : 'generic'\n const scopes = Array.isArray(card.scopes)\n ? (card.scopes as unknown as Array<Record<string, unknown>>)\n .map((s): CardScope | null => {\n const label = str(s.label)\n if (!label) return null\n return {\n competitionId: typeof s.competitionId === 'number' ? s.competitionId : null,\n label,\n image: str(s.imagePath),\n stats: readStatCells(s.stats),\n }\n })\n .filter((s): s is CardScope => s !== null)\n : []\n return {\n id: String(card.entityId),\n kind,\n name: card.canonicalName,\n image: str(card.imagePath) ?? str(card.imageUrl) ?? str(card.image_url) ?? str(card.logoUrl) ?? str(card.logo),\n sub: str(card.subtitle) ?? str(card.teamName) ?? str(card.leagueName) ?? str(card.position),\n season: str(card.seasonName),\n scopes,\n }\n}\n\nexport function toActionVM(action: Record<string, unknown>): ActionVM {\n const label = str(action.actionLabel) ?? str(action.label) ?? str(action.text) ?? str(action.title) ?? 'Continue'\n const actionId = str(action.actionId) ?? str(action.id)\n const message = str(action.actionValue) ?? str(action.message) ?? str(action.query) ?? label\n return { label, actionId, message }\n}\n\nexport function toChipVM(intent: Record<string, unknown>): ChipVM | null {\n const text = str(intent.text) ?? str(intent.label) ?? str(intent.title)\n return text ? { text } : null\n}\n\nexport function chipFromText(text: string): ChipVM {\n return { text }\n}\n\nexport function toInsightVM(insight: BettingInsight): InsightVM {\n const market = str(insight.marketLabel) ?? str(insight.marketDeveloperName) ?? ''\n const selection = [str(insight.selectionLabel), str(insight.line)].filter(Boolean).join(' ') || undefined\n const value = insight.odds?.value\n const odds = typeof value === 'number' && Number.isFinite(value) ? value.toFixed(2) : undefined\n const oddsValue = insight.odds?.value\n const matchOddsId = typeof insight.odds?.matchOddsId === 'number' ? insight.odds.matchOddsId : undefined\n const home = str(insight.homeTeamName)\n const away = str(insight.awayTeamName)\n const fixture = home && away ? `${home} vs ${away}` : undefined\n const competition = str(insight.competitionName)\n const scopes = Array.isArray(insight.scopes)\n ? (insight.scopes as Array<Record<string, unknown>>)\n .map((s) => ({ key: str(s.key), label: str(s.label), stats: readStatCells(s.stats) }))\n .filter((s): s is InsightScope => !!s.key && !!s.label)\n : undefined\n const previousValue = insight.odds?.previousValue\n const previous =\n typeof previousValue === 'number' && Number.isFinite(previousValue) ? previousValue : undefined\n const direction =\n insight.odds?.movementDirection === 'shortened' || insight.odds?.movementDirection === 'drifted'\n ? insight.odds.movementDirection\n : undefined\n return {\n id: str(insight.insightId) ?? `${str(insight.ruleId) ?? 'insight'}:${num(insight.matchId) ?? ''}`,\n market,\n selection,\n odds,\n // The wire payload carries bookmakerId (not a name); render a name only if one is present.\n bookmaker: str(insight.odds?.bookmakerName),\n isLive: insight.odds?.isLive === true,\n phase: str(insight.phase),\n fixture,\n competition,\n scopes,\n text: str(insight.text) ?? '',\n stats: readStatCells(insight.stats),\n disclaimer: str(insight.disclaimer),\n matchId: typeof insight.matchId === 'number' ? insight.matchId : 0,\n matchOddsId,\n addToSlipEnabled: insight.addToSlipEnabled === true,\n oddsDecimal: typeof oddsValue === 'number' && Number.isFinite(oddsValue) ? oddsValue : undefined,\n quotedAtUtc: str(insight.odds?.quotedAtUtc),\n previousOdds: previous !== undefined && direction !== undefined ? previous.toFixed(2) : undefined,\n movementDirection: previous !== undefined && direction !== undefined ? direction : undefined,\n }\n}\n\nexport function toSlipSelection(vm: InsightVM, conversationId?: string): SlipSelection | null {\n if (vm.matchOddsId === undefined || vm.oddsDecimal === undefined) return null\n const selection: SlipSelection = {\n matchOddsId: vm.matchOddsId,\n matchId: vm.matchId,\n oddsDecimal: vm.oddsDecimal,\n }\n if (vm.quotedAtUtc !== undefined) selection.quotedAtUtc = vm.quotedAtUtc\n if (vm.id !== undefined) selection.insightId = vm.id\n if (conversationId !== undefined) selection.conversationId = conversationId\n return selection\n}\n\nexport function toMarketOddsVM(card: MarketOddsCard): MarketOddsVM {\n const rows = Array.isArray(card.rows) ? card.rows : []\n const toRow = (r: MarketOddsRow, i: number): MarketOddsRowVM => {\n const selection = [str(r.selectionLabel), str(r.line)].filter(Boolean).join(' ')\n const price = typeof r.price === 'number' && Number.isFinite(r.price) ? r.price : undefined\n const previous =\n typeof r.previousPrice === 'number' && Number.isFinite(r.previousPrice) ? r.previousPrice : undefined\n const direction =\n r.movementDirection === 'shortened' || r.movementDirection === 'drifted' ? r.movementDirection : undefined\n return {\n key: `${selection}:${str(r.line) ?? ''}:${i}`,\n selection,\n odds: price !== undefined ? price.toFixed(2) : '',\n oddsDecimal: price,\n matchOddsId: typeof r.matchOddsId === 'number' ? r.matchOddsId : undefined,\n quotedAtUtc: str(r.quotedAtUtc),\n isMain: r.isMainLine !== false,\n previousOdds: previous !== undefined && direction !== undefined ? previous.toFixed(2) : undefined,\n movementDirection: previous !== undefined && direction !== undefined ? direction : undefined,\n }\n }\n const vms = rows.map(toRow).filter((r) => r.selection && r.odds)\n const home = str(card.homeTeamName)\n const away = str(card.awayTeamName)\n const updated = rows.map((r) => str(r.quotedAtUtc)).filter((v): v is string => !!v).sort()\n return {\n id: `${typeof card.matchId === 'number' ? card.matchId : 0}:${str(card.marketDeveloperName) ?? ''}`,\n market: str(card.marketLabel) ?? str(card.marketDeveloperName) ?? '',\n fixture: home && away ? `${home} vs ${away}` : undefined,\n competition: str(card.competitionName),\n bookmaker: rows.map((r) => str(r.bookmakerName)).find(Boolean),\n updatedAt: updated.length > 0 ? updated[updated.length - 1] : undefined,\n isLive: rows.some((r) => r.isLive === true),\n matchId: typeof card.matchId === 'number' ? card.matchId : 0,\n mainRows: vms.filter((r) => r.isMain),\n moreRows: vms.filter((r) => !r.isMain),\n disclaimer: str(card.disclaimer),\n addToSlipEnabled: card.addToSlipEnabled === true,\n }\n}\n\nexport function marketOddsRowToSlipSelection(\n vm: MarketOddsVM, row: MarketOddsRowVM, conversationId?: string,\n): SlipSelection | null {\n if (row.matchOddsId === undefined || row.oddsDecimal === undefined) return null\n const selection: SlipSelection = { matchOddsId: row.matchOddsId, matchId: vm.matchId, oddsDecimal: row.oddsDecimal }\n if (row.quotedAtUtc !== undefined) selection.quotedAtUtc = row.quotedAtUtc\n if (conversationId !== undefined) selection.conversationId = conversationId\n return selection\n}\n","// SensibleStats brand mark, inlined as a data URI so the published widget\n// bundle stays self-contained (no external asset hosting / CORS concerns\n// for third-party embeds).\nexport const SS_LOGO_DATA_URI = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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\"\n","// SensibleStats brand mark, rendered from the official logo asset.\nimport { SS_LOGO_DATA_URI } from '../assets/logo'\n\nexport function SsMark({ className }: { className?: string }): JSX.Element {\n return <img className={className} src={SS_LOGO_DATA_URI} alt=\"\" aria-hidden=\"true\" />\n}\nexport function SendIcon(): JSX.Element {\n return <svg viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M3 20l18-8L3 4v6l12 2-12 2z\" /></svg>\n}\nexport function CloseIcon(): JSX.Element {\n return <svg viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" aria-hidden=\"true\"><path fill=\"none\" d=\"M18 6L6 18M6 6l12 12\" stroke=\"currentColor\" strokeWidth=\"2\" /></svg>\n}\n","export function GreetingBubble({ text, onOpen, onDismiss, dismissLabel = 'Dismiss' }: { text: string; onOpen?: () => void; onDismiss?: () => void; dismissLabel?: string }): JSX.Element {\n return (\n <div className=\"ss-w-greeting\" role=\"note\">\n <button type=\"button\" className=\"ss-w-greeting-body\" onClick={onOpen}>{text}</button>\n {onDismiss ? (\n <button type=\"button\" className=\"ss-w-greeting-x\" aria-label={dismissLabel} onClick={onDismiss}>×</button>\n ) : null}\n </div>\n )\n}\n","import { SsMark } from './Icons'\nimport { GreetingBubble } from './GreetingBubble'\n\n// Only rendered while the panel is closed. The dynamic greeting popup takes\n// precedence over the static greeting and is dismissable; both open the panel.\nexport function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLabel = 'Dismiss' }: { label: string; greeting?: string; popupText?: string | null; onOpen: () => void; onDismissPopup: () => void; dismissLabel?: string }): JSX.Element {\n const bubble = popupText ?? greeting\n return (\n <div className=\"ss-w-fab-wrap\">\n {bubble ? <GreetingBubble text={bubble} onOpen={onOpen} onDismiss={popupText ? onDismissPopup : undefined} dismissLabel={dismissLabel} /> : null}\n <button type=\"button\" className=\"ss-w-fab\" aria-label={label} onClick={onOpen}>\n <SsMark className=\"ss-w-fab-mark\" />\n </button>\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\nimport type { ChatController } from '../useChatStream'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { ChatHeader } from './ChatHeader'\nimport { MessageList } from './MessageList'\nimport { ChatInput } from './ChatInput'\n\n// Mirrors the panel's fullscreen breakpoint in widget.css (@media max-width: 639px).\n// The panel only traps the page — and is thus truly modal — when it fills the viewport.\nconst FULLSCREEN_QUERY = '(max-width: 639px)'\n\nfunction useIsModal(): boolean {\n const [modal, setModal] = useState(false)\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return\n const mql = window.matchMedia(FULLSCREEN_QUERY)\n const sync = (): void => setModal(mql.matches)\n sync()\n mql.addEventListener('change', sync)\n return () => mql.removeEventListener('change', sync)\n }, [])\n return modal\n}\n\nexport function ChatPanel({ controller, ui, slip }: { controller: ChatController; ui: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const { state, close, stop, send } = controller\n const isModal = useIsModal()\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') close() }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [close])\n\n return (\n <div className=\"ss-w-panel\" role=\"dialog\" aria-modal={isModal} aria-label={ui.chatDialogLabel}>\n <ChatHeader onClose={close} closeLabel={ui.closeChat} />\n <MessageList controller={controller} ui={ui} slip={slip} />\n <ChatInput placeholder={ui.placeholder} streaming={state.isStreaming} onSend={(t) => send(t)} onStop={stop} stopLabel={ui.stopResponse} sendLabel={ui.sendMessage} />\n </div>\n )\n}\n","import { SsMark, CloseIcon } from './Icons'\n\nexport function ChatHeader({ onClose, closeLabel = 'Close chat' }: { onClose: () => void; closeLabel?: string }): JSX.Element {\n return (\n <header className=\"ss-w-header\">\n <SsMark className=\"ss-w-header-mark\" />\n <span className=\"ss-w-header-title\">SensibleStats</span>\n <button type=\"button\" className=\"ss-w-close\" aria-label={closeLabel} onClick={onClose}><CloseIcon /></button>\n </header>\n )\n}\n","import { useEffect, useRef } from 'react'\nimport type { ChatController } from '../useChatStream'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { ChatMessage } from './ChatMessage'\nimport { IntentChips } from './IntentChips'\nimport { ActionButtons } from './ActionButtons'\nimport { isPinnedToBottom } from '../scroll'\n\nexport function MessageList({ controller, ui, slip }: { controller: ChatController; ui: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const { state, send } = controller\n const listRef = useRef<HTMLDivElement>(null)\n const endRef = useRef<HTMLDivElement>(null)\n // Follow the stream only while the user is at the bottom. pinnedRef is updated\n // on real scroll events (content growth fires none), so a user who scrolls up\n // stays put when late content — suggested actions, status — arrives.\n const pinnedRef = useRef(true)\n useEffect(() => {\n if (pinnedRef.current) endRef.current?.scrollIntoView({ block: 'end' })\n }, [state.messages, state.status])\n\n const empty = state.messages.length === 0\n return (\n <div\n className=\"ss-w-list\"\n aria-live=\"polite\"\n ref={listRef}\n onScroll={() => { if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current) }}\n >\n {state.messages.map((m) => (\n <ChatMessage\n key={m.id}\n message={m}\n disabled={state.isStreaming}\n onAct={(a) => send(a.message, { actionId: a.actionId, displayText: a.label })}\n ui={ui}\n slip={slip}\n />\n ))}\n {state.isStreaming && state.actionsLoading ? <ActionButtons actions={[]} loading onAct={() => {}} /> : null}\n {state.status ? <div className=\"ss-w-status\">{state.status}</div> : null}\n {state.error ? (\n <div className=\"ss-w-error\" role=\"alert\">\n <span>{'message' in state.error ? state.error.message : ui.somethingWentWrong}</span>\n <button type=\"button\" className=\"ss-w-retry\" onClick={() => controller.retry()}>{ui.retry}</button>\n </div>\n ) : null}\n {empty ? <IntentChips chips={state.starters} onPick={(t) => send(t)} /> : null}\n <div ref={endRef} />\n </div>\n )\n}\n","import ReactMarkdown, { type Components } from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\n\nconst components: Components = {\n a: ({ children, href }) => (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" className=\"ss-w-md-link\">{children}</a>\n ),\n table: ({ children }) => (\n <div className=\"ss-w-table-wrap\"><table className=\"ss-w-md-table\">{children}</table></div>\n ),\n ul: ({ children }) => <ul className=\"ss-w-md-ul\">{children}</ul>,\n ol: ({ children }) => <ol className=\"ss-w-md-ol\">{children}</ol>,\n code: ({ children }) => <code className=\"ss-w-md-code\">{children}</code>,\n}\n\nexport function Markdown({ text }: { text: string }): JSX.Element {\n return (\n <div className=\"ss-w-md\">\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>{text}</ReactMarkdown>\n </div>\n )\n}\n","import { useState } from 'react'\nimport type { CardVM, CardScope, StatCell } from '../model'\n\nconst MAX_VISIBLE = 3\nconst RECORD_RE = /^(\\d+)-(\\d+)-(\\d+)$/\n\nfunction initials(name: string): string {\n return name.split(/\\s+/).slice(0, 2).map((w) => w[0] ?? '').join('').toUpperCase()\n}\n\n// \"2026/2027\" -> \"26/27\", \"2026\" -> \"26\"; leaves any non-4-digit token untouched.\nfunction shortSeason(season: string): string {\n return season.replace(/\\d{4}/g, (year) => year.slice(2))\n}\n\nfunction Crest({ image }: { image: string }): JSX.Element {\n return <span className=\"ss-w-ecard-crest\" style={{ backgroundImage: `url(${image})` }} aria-hidden=\"true\" />\n}\n\n// Proportional win/draw/loss bar. Rendered for any stat value shaped \"w-d-l\".\nfunction FormBar({ w, d, l }: { w: number; d: number; l: number }): JSX.Element | null {\n if (w + d + l === 0) return null\n return (\n <span className=\"ss-w-form\" aria-hidden=\"true\">\n {w > 0 ? <span className=\"ss-w-form-w\" style={{ flexGrow: w }} /> : null}\n {d > 0 ? <span className=\"ss-w-form-d\" style={{ flexGrow: d }} /> : null}\n {l > 0 ? <span className=\"ss-w-form-l\" style={{ flexGrow: l }} /> : null}\n </span>\n )\n}\n\nfunction StatRows({ stats }: { stats: StatCell[] }): JSX.Element {\n return (\n <div className=\"ss-w-ecard-stats\">\n {stats.map((s) => {\n const m = RECORD_RE.exec(s.value)\n return (\n <div key={s.label} className=\"ss-w-ecard-row\">\n <span className=\"ss-w-ecard-rlabel\">{s.label}</span>\n {m ? <FormBar w={Number(m[1])} d={Number(m[2])} l={Number(m[3])} /> : <span />}\n <span className=\"ss-w-ecard-rval\">{s.value}</span>\n </div>\n )\n })}\n </div>\n )\n}\n\n// The right-hand panel: competition tabs (2+ scopes) or a static league label\n// (1 scope), the season pill, and the stat rows for the active scope.\nfunction CardBody({ c }: { c: CardVM }): JSX.Element | null {\n const [active, setActive] = useState(0)\n if (c.scopes.length === 0) return null\n const season = c.season ? <span className=\"ss-w-ecard-season\">{shortSeason(c.season)}</span> : null\n\n if (c.scopes.length === 1) {\n const only = c.scopes[0]!\n return (\n <div className=\"ss-w-ecard-body\">\n <div className=\"ss-w-ecard-tabs ss-w-ecard-tabs-static\">\n <span className=\"ss-w-ecard-lead\" title={only.label}>{only.image ? <Crest image={only.image} /> : null}<span className=\"ss-w-ecard-lead-txt\">{only.label}</span></span>\n {season}\n </div>\n <StatRows stats={only.stats} />\n </div>\n )\n }\n\n const current = c.scopes[active] ?? c.scopes[0]!\n return (\n <div className=\"ss-w-ecard-body\">\n <div className=\"ss-w-ecard-tabs\" role=\"tablist\">\n {c.scopes.map((s, i) => (\n <button\n key={String(s.competitionId ?? 'all')}\n type=\"button\"\n role=\"tab\"\n className=\"ss-w-ecard-tab\"\n aria-selected={i === active}\n aria-label={s.label}\n title={s.label}\n onClick={() => setActive(i)}\n >\n {s.image ? <Crest image={s.image} /> : s.label}\n </button>\n ))}\n {season}\n </div>\n <StatRows key={String(current.competitionId ?? 'all')} stats={current.stats} />\n </div>\n )\n}\n\nfunction EntityCardItem({ c }: { c: CardVM }): JSX.Element {\n const hasBody = c.scopes.length > 0\n return (\n <div className={hasBody ? 'ss-w-ecard' : 'ss-w-ecard ss-w-ecard-bare'} data-kind={c.kind}>\n <div className=\"ss-w-ecard-id\">\n <span\n className={c.kind === 'team' ? 'ss-w-thumb ss-w-team' : 'ss-w-thumb'}\n style={c.image ? { backgroundImage: `url(${c.image})` } : undefined}\n >\n {c.image ? '' : initials(c.name)}\n </span>\n <span className=\"ss-w-ecard-idtext\">\n <span className=\"ss-w-nm\">{c.name}</span>\n {c.sub ? <span className=\"ss-w-sub\">{c.sub}</span> : null}\n </span>\n </div>\n <CardBody c={c} />\n </div>\n )\n}\n\nexport function EntityCardList({ cards, disabled, showLessLabel = 'Show less', showMoreLabel = (n: number) => `Show ${n} more` }: { cards: CardVM[]; disabled?: boolean; showLessLabel?: string; showMoreLabel?: (n: number) => string }): JSX.Element | null {\n const [expanded, setExpanded] = useState(false)\n if (cards.length === 0) return null\n const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE)\n const overflow = cards.length - MAX_VISIBLE\n return (\n <div className=\"ss-w-cards\">\n {visible.map((c) => <EntityCardItem key={c.id} c={c} />)}\n {overflow > 0 ? (\n <button type=\"button\" className=\"ss-w-cards-more\" disabled={disabled} onClick={() => setExpanded((v) => !v)}>\n {expanded ? showLessLabel : showMoreLabel(overflow)}\n </button>\n ) : null}\n </div>\n )\n}\n","import { useState } from 'react'\nimport type { InsightVM, StatCell } from '../model'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { AddToSlipButton } from './AddToSlipButton'\nimport { OddsMovementBadge } from './OddsMovementBadge'\n\nfunction StatRows({ stats }: { stats: StatCell[] }): JSX.Element {\n return (\n <div className=\"ss-w-bi-rows\">\n {stats.map((s) => (\n <div key={`${s.label}:${s.value}`} className=\"ss-w-bi-row\">\n <span className=\"ss-w-bi-row-lbl\">{s.label}</span>\n <span className=\"ss-w-bi-row-num\">{s.value}</span>\n </div>\n ))}\n </div>\n )\n}\n\nfunction ScopedStats({ scopes }: { scopes: NonNullable<InsightVM['scopes']> }): JSX.Element {\n const [active, setActive] = useState(0)\n const current = scopes[active] ?? scopes[0] ?? { key: '', label: '', stats: [] }\n return (\n <div className=\"ss-w-bi-scoped\">\n <div className=\"ss-w-bi-scopes\" role=\"group\">\n {scopes.map((s, i) => (\n <button key={s.key} type=\"button\" className=\"ss-w-bi-chip\" aria-pressed={i === active} onClick={() => setActive(i)}>\n {s.label}\n </button>\n ))}\n </div>\n <StatRows key={current.key} stats={current.stats} />\n </div>\n )\n}\n\n// Stats are collapsed by default — the reason-to-bet prose carries the justification, and the\n// numbers are one tap away for anyone who wants to verify. Only renders when there is something\n// to show.\nfunction StatsDisclosure({ it, ui }: { it: InsightVM; ui?: UiConfig }): JSX.Element | null {\n const [open, setOpen] = useState(false)\n const hasScopes = !!it.scopes && it.scopes.length >= 2\n const hasStats = hasScopes || it.stats.length > 0\n if (!hasStats) return null\n return (\n <div className=\"ss-w-bi-stats\">\n <button\n type=\"button\"\n className=\"ss-w-bi-toggle\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n >\n <span>{open ? ui?.hideStats ?? 'Hide stats' : ui?.showStats ?? 'Show stats'}</span>\n <span className={`ss-w-bi-chev${open ? ' ss-w-bi-chev-up' : ''}`} aria-hidden=\"true\" />\n </button>\n {open\n ? hasScopes\n ? <ScopedStats scopes={it.scopes!} />\n : <StatRows stats={it.stats} />\n : null}\n </div>\n )\n}\n\nfunction InsightCard({ it, ui, slip }: { it: InsightVM; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const live = it.isLive || it.phase === 'live'\n return (\n <div className=\"ss-w-binsight\">\n {live ? (\n <div className=\"ss-w-bi-status\">\n <span className=\"ss-w-bi-live\"><span className=\"ss-w-bi-live-dot\" aria-hidden=\"true\" />{ui?.liveLabel ?? 'Live'}</span>\n </div>\n ) : null}\n <div className=\"ss-w-bi-head\">\n <span className=\"ss-w-bi-mkt\">\n <span className=\"ss-w-bi-market\">{it.market}</span>\n {it.selection ? <span className=\"ss-w-bi-sel\">{it.selection}</span> : null}\n {(it.fixture || it.competition) ? (\n <span className=\"ss-w-bi-match\">\n {it.fixture ? <span className=\"ss-w-bi-fixture\">{it.fixture}</span> : null}\n {it.competition ? <span className=\"ss-w-bi-comp\">{it.competition}</span> : null}\n </span>\n ) : null}\n </span>\n <div className=\"ss-w-bi-action\">\n {it.odds ? (\n <span className=\"ss-w-bi-odds\">\n <span className=\"ss-w-bi-odds-cap\">{ui?.oddsLabel ?? 'Odds'}</span>\n <b>{it.odds}</b>\n <OddsMovementBadge previous={it.previousOdds} current={it.odds} direction={it.movementDirection} ui={ui} />\n {it.bookmaker ? <span className=\"ss-w-bi-book\">{it.bookmaker}</span> : null}\n </span>\n ) : null}\n <AddToSlipButton it={it} slip={slip} ui={ui} />\n </div>\n </div>\n {it.text ? <p className=\"ss-w-bi-text\">{it.text}</p> : null}\n <StatsDisclosure it={it} ui={ui} />\n {it.disclaimer ? <p className=\"ss-w-bi-disc\">{it.disclaimer}</p> : null}\n </div>\n )\n}\n\nexport function BettingInsightList({ insights, ui, slip }: { insights: InsightVM[]; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element | null {\n if (!insights || insights.length === 0) return null\n return (\n <div className=\"ss-w-binsights\">\n {insights.map((it) => <InsightCard key={it.id} it={it} ui={ui} slip={slip} />)}\n </div>\n )\n}\n","import { useCallback, useState } from 'react'\nimport { isAddToSlipResult, type AddToSlipResult, type SlipSelection } from '@sensiblestats/widget-sdk'\nimport type { UiConfig } from '../config'\nimport { toSlipSelection, type InsightVM } from '../model'\nimport { ADD_TO_SLIP_TIMEOUT_MS, isTerminal, resultToToast, wasAdded, type SlipHandlerProps, type SlipToast } from '../slip'\nimport { Toast } from './Toast'\n\nfunction withTimeout(value: Promise<AddToSlipResult | void>): Promise<AddToSlipResult | void> {\n return Promise.race([\n value,\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('add-to-slip timed out')), ADD_TO_SLIP_TIMEOUT_MS)),\n ])\n}\n\nexport function SlipButton(\n { selection, shownOdds, marketName, slip, ui }:\n { selection: SlipSelection | null; shownOdds: string; marketName: string; slip: SlipHandlerProps; ui?: UiConfig },\n): JSX.Element | null {\n const [pending, setPending] = useState(false)\n const [settled, setSettled] = useState(false)\n const [toast, setToast] = useState<SlipToast | null>(null)\n const dismiss = useCallback(() => setToast(null), [])\n\n const handler = slip.onAddToSlip\n if (!ui || !handler || !selection) return null\n\n const onClick = async (): Promise<void> => {\n setPending(true)\n try {\n const raw = await withTimeout(Promise.resolve(handler(selection)))\n // Only a genuine void return means \"assume success\". A non-null value the\n // guard rejects is a broken contract (e.g. an operator forwarding their own\n // backend's reason string, which `any` lets past the compiler) — treating it\n // as void would report a refused bet to the user as added.\n if (raw != null && !isAddToSlipResult(raw)) throw new Error('malformed add-to-slip result')\n const result = raw ?? undefined\n setToast(resultToToast(result, shownOdds || selection.oddsDecimal.toFixed(2), ui))\n setSettled(isTerminal(result))\n if (wasAdded(result) && slip.onMarketClicked) {\n try {\n slip.onMarketClicked(marketName)\n } catch {\n // Telemetry must never change what the user sees.\n }\n }\n } catch {\n setToast({ kind: 'error', text: ui.slipFailed })\n } finally {\n setPending(false)\n }\n }\n\n return (\n <div className=\"ss-w-slip\">\n <button\n type=\"button\"\n className=\"ss-w-slip-btn\"\n disabled={pending || settled}\n onClick={onClick}\n >\n {settled ? ui.inSlip : ui.addToSlip}\n </button>\n <Toast toast={toast} onDismiss={dismiss} />\n </div>\n )\n}\n\nexport function AddToSlipButton(\n { it, slip, ui }: { it: InsightVM; slip: SlipHandlerProps; ui?: UiConfig },\n): JSX.Element | null {\n const selection = it.addToSlipEnabled ? toSlipSelection(it, slip.conversationId) : null\n return <SlipButton selection={selection} shownOdds={it.odds ?? ''} marketName={it.market} slip={slip} ui={ui} />\n}\n","import type { AddToSlipHandler, AddToSlipResult } from '@sensiblestats/widget-sdk'\nimport type { UiConfig } from './config'\n\nexport const ADD_TO_SLIP_TIMEOUT_MS = 10_000\n\nexport interface SlipToast { kind: 'success' | 'error'; text: string }\n\nexport interface SlipHandlerProps {\n onAddToSlip?: AddToSlipHandler\n conversationId?: string\n onMarketClicked?: (marketName: string) => void\n}\n\nexport function wasAdded(result: AddToSlipResult | void): boolean {\n if (!result) return true\n if (result.status === 'price_changed') return result.accepted\n return result.status === 'added'\n}\n\nexport function isTerminal(result: AddToSlipResult | void): boolean {\n if (!result) return true\n if (result.status === 'price_changed') return result.accepted\n return result.status === 'added' || result.status === 'duplicate'\n}\n\nexport function resultToToast(result: AddToSlipResult | void, shownOdds: string, ui: UiConfig): SlipToast {\n if (!result) return { kind: 'success', text: ui.slipAdded(undefined) }\n switch (result.status) {\n case 'added':\n return { kind: 'success', text: ui.slipAdded(result.slip?.selectionCount) }\n case 'duplicate':\n return { kind: 'success', text: ui.slipDuplicate }\n case 'price_changed':\n return result.accepted\n ? { kind: 'success', text: ui.slipPriceChanged(shownOdds, result.newOddsDecimal.toFixed(2)) }\n : { kind: 'error', text: ui.slipPriceNotAccepted(shownOdds, result.newOddsDecimal.toFixed(2)) }\n case 'rejected':\n if (result.reason === 'login_required') return { kind: 'error', text: ui.slipLoginRequired }\n if (result.reason === 'suspended') return { kind: 'error', text: ui.slipSuspended }\n return { kind: 'error', text: result.message ?? ui.slipFailed }\n }\n}\n","import { useEffect } from 'react'\nimport type { SlipToast } from '../slip'\n\nconst DISMISS_MS = 4000\n\nexport function Toast({ toast, onDismiss }: { toast: SlipToast | null; onDismiss: () => void }): JSX.Element | null {\n useEffect(() => {\n if (!toast) return\n const timer = setTimeout(onDismiss, DISMISS_MS)\n return () => clearTimeout(timer)\n }, [toast, onDismiss])\n\n if (!toast) return null\n return (\n <div className={`ss-w-toast ss-w-toast-${toast.kind}`} role=\"status\" aria-live=\"polite\">\n {toast.text}\n </div>\n )\n}\n","import type { UiConfig } from '../config'\n\n// One component for both card types. The market-odds row and the insight card must not drift into\n// two visual languages for the same signal, so there is exactly one place this markup exists.\nexport function OddsMovementBadge({\n previous,\n current,\n direction,\n ui,\n}: {\n previous?: string\n current: string\n direction?: 'shortened' | 'drifted'\n ui?: UiConfig\n}): JSX.Element | null {\n if (previous === undefined || direction === undefined) return null\n const directionWord =\n direction === 'shortened' ? (ui?.oddsShortened ?? 'shortened') : (ui?.oddsDrifted ?? 'drifted')\n const label =\n ui?.oddsMoved?.(previous, current, directionWord) ?? `was ${previous}, now ${current}, ${directionWord}`\n return (\n // Strikethrough is invisible to screen readers, so the whole was/now/direction sentence rides\n // on one aria-label and the visual glyphs are hidden from the accessibility tree.\n <span className=\"ss-w-move\" role=\"img\" aria-label={label}>\n <span className=\"ss-w-move-prev\" aria-hidden=\"true\">{previous}</span>\n <span className=\"ss-w-move-arrow\" aria-hidden=\"true\">{direction === 'shortened' ? '▼' : '▲'}</span>\n </span>\n )\n}\n","import { useState } from 'react'\nimport type { MarketOddsVM, MarketOddsRowVM } from '../model'\nimport { marketOddsRowToSlipSelection } from '../model'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { SlipButton } from './AddToSlipButton'\nimport { OddsMovementBadge } from './OddsMovementBadge'\n\nfunction OddsRow({ vm, row, ui, slip }: { vm: MarketOddsVM; row: MarketOddsRowVM; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null\n return (\n <div className=\"ss-w-mo-row\">\n <span className=\"ss-w-mo-sel\">{row.selection}</span>\n <OddsMovementBadge previous={row.previousOdds} current={row.odds} direction={row.movementDirection} ui={ui} />\n <span className=\"ss-w-mo-price\">{row.odds}</span>\n <SlipButton selection={selection} shownOdds={row.odds} marketName={vm.market} slip={slip} ui={ui} />\n </div>\n )\n}\n\nfunction MarketOddsCard({ vm, ui, slip }: { vm: MarketOddsVM; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const [open, setOpen] = useState(false)\n return (\n <div className=\"ss-w-mocard\">\n <div className=\"ss-w-mo-head\">\n <span className=\"ss-w-mo-market\">{vm.market}</span>\n <span className=\"ss-w-mo-tag\">{ui?.marketPrices ?? 'Market prices'}</span>\n </div>\n {(vm.fixture || vm.competition) ? (\n <div className=\"ss-w-mo-fixture\">\n {vm.fixture ? <span>{vm.fixture}</span> : null}\n {vm.competition ? <span className=\"ss-w-mo-comp\">{vm.competition}</span> : null}\n </div>\n ) : null}\n <div className=\"ss-w-mo-rows\">\n {vm.mainRows.map((row) => <OddsRow key={row.key} vm={vm} row={row} ui={ui} slip={slip} />)}\n {open ? vm.moreRows.map((row) => <OddsRow key={row.key} vm={vm} row={row} ui={ui} slip={slip} />) : null}\n </div>\n {vm.moreRows.length > 0 ? (\n <button type=\"button\" className=\"ss-w-bi-toggle\" aria-expanded={open} onClick={() => setOpen((v) => !v)}>\n <span>{open ? ui?.hideLines ?? 'Hide lines' : `${ui?.moreLines ?? 'More lines'} (${vm.moreRows.length})`}</span>\n <span className={`ss-w-bi-chev${open ? ' ss-w-bi-chev-up' : ''}`} aria-hidden=\"true\" />\n </button>\n ) : null}\n {vm.bookmaker ? (\n <div className=\"ss-w-mo-foot\">\n <span>{vm.bookmaker}</span>\n </div>\n ) : null}\n {vm.disclaimer ? <p className=\"ss-w-bi-disc\">{vm.disclaimer}</p> : null}\n </div>\n )\n}\n\nexport function MarketOddsCardList({ cards, ui, slip }: { cards: MarketOddsVM[]; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element | null {\n if (!cards || cards.length === 0) return null\n return (\n <div className=\"ss-w-mocards\">\n {cards.map((vm) => <MarketOddsCard key={vm.id} vm={vm} ui={ui} slip={slip} />)}\n </div>\n )\n}\n","import type { ActionVM } from '../model'\n\nexport function ActionButtons({ actions, loading, disabled, onAct }: { actions: ActionVM[]; loading: boolean; disabled?: boolean; onAct: (action: ActionVM) => void }): JSX.Element | null {\n if (actions.length === 0 && !loading) return null\n return (\n <div className=\"ss-w-actions\">\n {actions.map((a, i) => (\n <button key={`${a.label}-${i}`} type=\"button\" className=\"ss-w-abtn\" disabled={disabled} onClick={() => onAct(a)}>{a.label}</button>\n ))}\n {actions.length === 0 && loading ? (\n <>\n <span className=\"ss-w-abtn-shimmer\" />\n <span className=\"ss-w-abtn-shimmer\" />\n </>\n ) : null}\n </div>\n )\n}\n","import type { Message } from '../reducer'\nimport type { ActionVM } from '../model'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { Markdown } from './Markdown'\nimport { EntityCardList } from './EntityCardList'\nimport { BettingInsightList } from './BettingInsightList'\nimport { MarketOddsCardList } from './MarketOddsCardList'\nimport { ActionButtons } from './ActionButtons'\n\nexport function ChatMessage({ message, disabled, onAct, ui, slip }: { message: Message; disabled: boolean; onAct: (a: ActionVM) => void; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n if (message.role === 'user') {\n return <div className=\"ss-w-msg ss-w-user\"><div className=\"ss-w-bubble\">{message.text}</div></div>\n }\n return (\n <div className=\"ss-w-msg ss-w-bot\">\n {message.text ? <Markdown text={message.text} /> : null}\n <EntityCardList cards={message.cards} disabled={disabled} showLessLabel={ui?.showLess} showMoreLabel={ui?.showMore} />\n <BettingInsightList insights={message.insights} ui={ui} slip={slip} />\n <MarketOddsCardList cards={message.marketOdds} ui={ui} slip={slip} />\n <ActionButtons actions={message.actions} loading={false} disabled={disabled} onAct={onAct} />\n </div>\n )\n}\n","import type { ChipVM } from '../model'\n\nexport function IntentChips({ chips, onPick }: { chips: ChipVM[]; onPick: (text: string) => void }): JSX.Element | null {\n if (chips.length === 0) return null\n return (\n <div className=\"ss-w-chips\">\n {chips.map((c, i) => (\n <button key={`${c.text}-${i}`} type=\"button\" className=\"ss-w-chip\" onClick={() => onPick(c.text)}>{c.text}</button>\n ))}\n </div>\n )\n}\n","// Distance (px) from the bottom within which the list is still considered\n// \"pinned\" — small enough that a user reading earlier content isn't counted\n// as pinned, large enough to absorb sub-pixel/rounding drift while streaming.\nexport const PIN_THRESHOLD = 48\n\n/**\n * True when the scroll container is at (or within PIN_THRESHOLD of) its bottom.\n * Used to decide whether new content should auto-scroll: we follow the stream\n * only while the user is already at the bottom, so late arrivals (e.g. suggested\n * actions) never yank a user who has scrolled up to read.\n */\nexport function isPinnedToBottom(el: Pick<HTMLElement, 'scrollHeight' | 'scrollTop' | 'clientHeight'>, threshold = PIN_THRESHOLD): boolean {\n return el.scrollHeight - el.scrollTop - el.clientHeight <= threshold\n}\n","import { useState, type KeyboardEvent } from 'react'\nimport { SendIcon } from './Icons'\n\nexport function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = 'Stop response', sendLabel = 'Send message' }: { placeholder: string; streaming: boolean; onSend: (t: string) => void; onStop: () => void; stopLabel?: string; sendLabel?: string }): JSX.Element {\n const [value, setValue] = useState('')\n const submit = () => { const t = value.trim(); if (!t) return; onSend(t); setValue('') }\n const onKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); submit() }\n }\n return (\n <div className=\"ss-w-input\">\n <textarea className=\"ss-w-textarea\" rows={1} placeholder={placeholder} value={value} disabled={streaming} onChange={(e) => setValue(e.target.value)} onKeyDown={onKeyDown} />\n {streaming ? (\n <button type=\"button\" className=\"ss-w-send ss-w-stop\" aria-label={stopLabel} onClick={onStop}><span className=\"ss-w-stop-glyph\" /></button>\n ) : (\n <button type=\"button\" className=\"ss-w-send\" aria-label={sendLabel} onClick={submit}><SendIcon /></button>\n )}\n </div>\n )\n}\n","// AUTO-GENERATED by scripts/gen-css.mjs from widget.css. Do not edit.\nexport const WIDGET_CSS = \".ss-w-root { all: revert; }\\n.ss-w-root, .ss-w-root * { box-sizing: border-box; margin: 0; padding: 0; }\\n.ss-w-root {\\n --ss-w-accent: #17936a;\\n --ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #14181d; --ss-w-faint: #6b7580; --ss-w-line: #e4e8ec;\\n --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\\n --ss-w-pos: #1aa563; --ss-w-neg: #e0524b;\\n --ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;\\n font-family: -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", Roboto, Helvetica, Arial, sans-serif;\\n font-size: 13px; line-height: 1.5; color: var(--ss-w-ink);\\n}\\n@media (prefers-color-scheme: dark) {\\n .ss-w-root[data-ss-w-theme=\\\"auto\\\"] {\\n --ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\\n --ss-w-pos: #37c891; --ss-w-neg: #f0655d;\\n }\\n}\\n.ss-w-root[data-ss-w-theme=\\\"dark\\\"] {\\n --ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\\n --ss-w-pos: #37c891; --ss-w-neg: #f0655d;\\n}\\n.ss-w-root[data-ss-w-theme=\\\"light\\\"] {\\n --ss-w-accent: #17936a; --ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #14181d; --ss-w-faint: #6b7580;\\n --ss-w-line: #e4e8ec; --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\\n}\\n\\n/* launcher */\\n.ss-w-fab-wrap { position: fixed; bottom: var(--ss-w-offset-y); z-index: 2147483000; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }\\n.ss-w-root[data-ss-w-pos=\\\"right\\\"] .ss-w-fab-wrap { right: var(--ss-w-offset-x); }\\n.ss-w-root[data-ss-w-pos=\\\"left\\\"] .ss-w-fab-wrap { left: var(--ss-w-offset-x); align-items: flex-start; }\\n.ss-w-fab { width: 56px; height: 56px; border: none; border-radius: 50%; background: var(--ss-w-nav); color: #fff; cursor: pointer; display: grid; place-items: center; box-shadow: 0 6px 20px rgba(0,0,0,.28); }\\n.ss-w-fab-mark { width: 30px; height: 30px; display: block; }\\n.ss-w-greeting { max-width: 240px; display: flex; align-items: flex-start; background: var(--ss-w-panel); color: var(--ss-w-ink); border: 1px solid var(--ss-w-line); border-radius: 12px; box-shadow: 0 4px 14px rgba(0,0,0,.14); }\\n.ss-w-greeting-body { flex: 1; min-width: 0; text-align: left; background: none; border: none; color: inherit; font: inherit; cursor: pointer; padding: 9px 4px 9px 12px; }\\n.ss-w-greeting-x { flex: none; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 17px; line-height: 1; padding: 7px 9px 0 2px; }\\n\\n/* panel */\\n.ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(400px, calc(100vw - 40px)); height: min(620px, calc(100vh - 120px)); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.24); }\\n.ss-w-root[data-ss-w-pos=\\\"right\\\"] .ss-w-panel { right: var(--ss-w-offset-x); }\\n.ss-w-root[data-ss-w-pos=\\\"left\\\"] .ss-w-panel { left: var(--ss-w-offset-x); }\\n@media (max-width: 639px) {\\n /* Fill via inset with no explicit height (like the site's working panel) so the\\n input stays visible when the mobile keyboard/URL-bar shrinks the viewport. The\\n position-specific selectors override the right/left offsets set above. */\\n .ss-w-root[data-ss-w-pos=\\\"right\\\"] .ss-w-panel,\\n .ss-w-root[data-ss-w-pos=\\\"left\\\"] .ss-w-panel { inset: 0; width: auto; height: auto; border: none; border-radius: 0; }\\n}\\n.ss-w-header { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--ss-w-line); }\\n.ss-w-header-mark { width: 18px; height: 18px; display: block; }\\n.ss-w-header-title { font-weight: 660; }\\n.ss-w-close { margin-left: auto; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 16px; display: grid; place-items: center; }\\n\\n/* messages */\\n.ss-w-list { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 12px; }\\n.ss-w-msg { display: flex; }\\n.ss-w-user { justify-content: flex-end; }\\n.ss-w-user .ss-w-bubble { background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 14px; padding: 8px 12px; max-width: 80%; }\\n.ss-w-bot { flex-direction: column; gap: 8px; }\\n.ss-w-status { font-size: 11px; color: var(--ss-w-faint); font-style: italic; }\\n.ss-w-error { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #c0392b; }\\n.ss-w-retry { background: none; border: 1px solid currentColor; border-radius: 10px; padding: 2px 8px; cursor: pointer; color: inherit; }\\n\\n/* markdown */\\n.ss-w-md { display: flex; flex-direction: column; gap: 8px; }\\n.ss-w-md :where(p, ul, ol, table, pre, blockquote, h1, h2, h3, h4) { margin: 0; }\\n.ss-w-md > *:first-child { margin-top: 0; }\\n.ss-w-md > *:last-child { margin-bottom: 0; }\\n.ss-w-md-ul { list-style: disc outside; padding-left: 18px; }\\n.ss-w-md-ol { list-style: decimal outside; padding-left: 18px; }\\n.ss-w-md-ul li::marker, .ss-w-md-ol li::marker { color: var(--ss-w-accent); }\\n.ss-w-md-link { color: var(--ss-w-accent); text-decoration: underline; }\\n.ss-w-table-wrap { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }\\n.ss-w-md-table { border-collapse: collapse; width: max-content; min-width: 100%; font-variant-numeric: tabular-nums; }\\n.ss-w-md-table td, .ss-w-md-table th { border: 1px solid var(--ss-w-line); padding: 4px 8px; text-align: left; white-space: nowrap; }\\n.ss-w-md-table th { background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); font-weight: 700; }\\n.ss-w-md-table tbody tr:nth-child(even) { background: var(--ss-w-bubble); }\\n.ss-w-md-code { background: var(--ss-w-bubble); border-radius: 5px; padding: 1px 5px; font-family: ui-monospace, monospace; }\\n\\n/* entity cards */\\n.ss-w-cards { display: flex; flex-direction: column; gap: 8px; }\\n\\n/* Identity Hero: crest-led identity block | tabbed stats panel */\\n.ss-w-ecard { display: grid; grid-template-columns: 112px 1fr; align-items: stretch; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; text-align: left; }\\n\\n.ss-w-ecard-id { display: flex; flex-direction: column; align-items: center; gap: 7px; text-align: center; padding: 13px 10px; border-right: 1px solid var(--ss-w-line); background: linear-gradient(158deg, var(--ss-w-bubble), color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-bubble))); }\\n.ss-w-ecard-idtext { display: flex; flex-direction: column; gap: 1px; min-width: 0; max-width: 100%; }\\n.ss-w-thumb { width: 54px; height: 54px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 16px; font-weight: 700; color: #fff; background-color: var(--ss-w-nav); background-size: cover; background-position: center; box-shadow: 0 1px 3px rgba(0,0,0,.14); }\\n.ss-w-thumb.ss-w-team { border-radius: 12px; }\\n.ss-w-ecard[data-kind=\\\"player\\\"] .ss-w-thumb { background-color: var(--ss-w-accent); }\\n.ss-w-nm { font-weight: 680; line-height: 1.15; overflow-wrap: anywhere; }\\n.ss-w-sub { font-size: 11px; color: var(--ss-w-faint); overflow-wrap: anywhere; }\\n\\n/* bare card (no stat scopes): simple avatar + name row */\\n.ss-w-ecard-bare { display: flex; align-items: center; }\\n.ss-w-ecard-bare .ss-w-ecard-id { flex-direction: row; text-align: left; gap: 11px; background: none; border-right: none; padding: 10px 12px; }\\n.ss-w-ecard-bare .ss-w-thumb { width: 40px; height: 40px; font-size: 13px; box-shadow: none; }\\n.ss-w-ecard-bare .ss-w-thumb.ss-w-team { border-radius: 10px; }\\n\\n.ss-w-ecard-body { min-width: 0; padding: 9px 12px 12px; display: flex; flex-direction: column; }\\n\\n/* tab strip seated on the stats panel's top edge; active tab underlined in accent */\\n.ss-w-ecard-tabs { display: flex; align-items: stretch; gap: 3px; border-bottom: 1px solid var(--ss-w-line); margin-bottom: 9px; flex-wrap: wrap; }\\n.ss-w-ecard-tab { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 620; color: var(--ss-w-faint); background: none; border: none; cursor: pointer; padding: 5px 8px 8px; margin-bottom: -1px; border-bottom: 2px solid transparent; }\\n.ss-w-ecard-tab[aria-selected=\\\"true\\\"] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }\\n.ss-w-ecard-tabs-static { align-items: center; flex-wrap: nowrap; }\\n.ss-w-ecard-lead { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 640; color: var(--ss-w-ink); padding: 4px 2px 8px; min-width: 0; flex: 1; }\\n.ss-w-ecard-lead-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.ss-w-ecard-crest { width: 15px; height: 15px; flex: none; display: block; border-radius: 4px; background-size: cover; background-position: center; }\\n.ss-w-ecard-season { flex: none; margin-left: auto; align-self: center; margin-bottom: 5px; font-size: 10.5px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 13%, var(--ss-w-panel)); border-radius: 999px; padding: 3px 9px; white-space: nowrap; }\\n.ss-w-ecard-tabs-static .ss-w-ecard-season { margin-bottom: 4px; }\\n\\n.ss-w-ecard-stats { display: flex; flex-direction: column; gap: 4px; }\\n.ss-w-ecard-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; }\\n.ss-w-ecard-rlabel { font-size: 9.5px; text-transform: uppercase; letter-spacing: .045em; color: var(--ss-w-faint); font-weight: 600; }\\n.ss-w-ecard-rval { justify-self: end; font-size: 15px; font-weight: 720; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }\\n.ss-w-form { justify-self: end; display: flex; height: 6px; width: 48px; border-radius: 4px; overflow: hidden; gap: 2px; }\\n.ss-w-form span { display: block; border-radius: 2px; }\\n.ss-w-form-w { background: var(--ss-w-pos); }\\n.ss-w-form-d { background: var(--ss-w-faint); }\\n.ss-w-form-l { background: var(--ss-w-neg); }\\n\\n.ss-w-cards-more { align-self: flex-start; font-size: 11.5px; font-weight: 560; color: var(--ss-w-accent); background: none; border: none; cursor: pointer; padding: 3px 2px; }\\n.ss-w-cards-more:hover:not(:disabled) { text-decoration: underline; }\\n.ss-w-cards-more:disabled { opacity: .5; cursor: default; }\\n\\n/* betting insights */\\n.ss-w-binsights { display: flex; flex-direction: column; gap: 7px; }\\n.ss-w-binsight { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }\\n.ss-w-bi-status { display: flex; align-items: center; gap: 6px; min-width: 0; }\\n.ss-w-bi-fixture { font-size: 11px; color: var(--ss-w-ink); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\\n.ss-w-bi-comp { font-size: 10.5px; color: var(--ss-w-faint); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\\n.ss-w-bi-live { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #fff; background: #c0392b; border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; gap: 4px; flex: none; }\\n.ss-w-bi-live-dot { width: 5px; height: 5px; border-radius: 50%; background: #fff; }\\n.ss-w-bi-head { display: flex; align-items: flex-start; gap: 10px; }\\n.ss-w-bi-mkt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }\\n.ss-w-bi-market { font-size: 15px; font-weight: 700; line-height: 1.25; color: var(--ss-w-ink); }\\n.ss-w-bi-sel { font-size: 12px; line-height: 1.3; color: var(--ss-w-faint); }\\n.ss-w-bi-match { display: flex; flex-direction: column; gap: 1px; min-width: 0; margin-top: 5px; }\\n.ss-w-bi-action { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: stretch; gap: 6px; }\\n.ss-w-bi-action .ss-w-slip > button { flex: 1; text-align: center; }\\n/* The action column is narrow; let its toast size to its own text and anchor to the card's right edge instead of being clipped to the button width. */\\n.ss-w-bi-action .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }\\n.ss-w-bi-odds { flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 1px; background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 10px; padding: 4px 11px; min-width: 62px; }\\n.ss-w-bi-odds-cap { font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }\\n.ss-w-bi-odds b { font-size: 19px; font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.1; }\\n.ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }\\n.ss-w-bi-text { font-size: 12px; line-height: 1.45; color: var(--ss-w-ink); }\\n.ss-w-bi-stats { display: flex; flex-direction: column; gap: 8px; }\\n.ss-w-bi-toggle { align-self: flex-start; display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 11.5px; font-weight: 600; padding: 2px 0; cursor: pointer; }\\n.ss-w-bi-toggle:hover { text-decoration: underline; }\\n.ss-w-bi-chev { width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s ease; }\\n.ss-w-bi-chev-up { transform: translateY(1px) rotate(-135deg); }\\n.ss-w-bi-rows { display: flex; flex-direction: column; }\\n.ss-w-bi-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 5px 0; border-top: 1px solid var(--ss-w-line); }\\n.ss-w-bi-row:first-child { border-top: none; }\\n.ss-w-bi-row-lbl { font-size: 11.5px; color: var(--ss-w-faint); min-width: 0; }\\n.ss-w-bi-row-num { font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; font-size: 13px; flex: none; color: var(--ss-w-ink); }\\n.ss-w-bi-disc { font-size: 10px; font-style: italic; color: var(--ss-w-faint); }\\n.ss-w-bi-scoped { display: flex; flex-direction: column; gap: 8px; }\\n.ss-w-bi-scopes { display: inline-flex; align-items: center; gap: 2px; flex-wrap: wrap; align-self: flex-start; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 9px; padding: 2px; }\\n.ss-w-bi-chip { font-size: 11px; font-weight: 600; border: none; border-radius: 7px; padding: 4px 10px; color: var(--ss-w-faint); background: none; cursor: pointer; }\\n.ss-w-bi-chip[aria-pressed=\\\"true\\\"] { color: var(--ss-w-ink); background: var(--ss-w-panel); box-shadow: 0 1px 2px rgba(0,0,0,.08); }\\n\\n/* market odds card */\\n.ss-w-mocards { display: flex; flex-direction: column; gap: 7px; }\\n.ss-w-mocard { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }\\n.ss-w-mo-head { display: flex; align-items: center; gap: 8px; }\\n.ss-w-mo-market { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }\\n.ss-w-mo-tag { margin-left: auto; flex: none; font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); border: 1px solid var(--ss-w-line); border-radius: 8px; padding: 2px 7px; }\\n.ss-w-mo-fixture { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ss-w-faint); min-width: 0; }\\n.ss-w-mo-comp { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.ss-w-mo-rows { display: flex; flex-direction: column; gap: 4px; }\\n.ss-w-mo-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--ss-w-line); }\\n.ss-w-mo-row:last-child { border-bottom: none; }\\n.ss-w-mo-sel { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }\\n.ss-w-mo-price { margin-left: auto; font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 700; color: var(--ss-w-accent); }\\n/* Movement: BOTH directions share --ss-w-faint on purpose. Green-good/red-bad would frame a\\n shortening price as a discount, which inverts what it actually means for the bettor. */\\n.ss-w-move { display: inline-flex; align-items: baseline; gap: 4px; color: var(--ss-w-faint); }\\n.ss-w-move-prev { font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 12px; text-decoration: line-through; }\\n.ss-w-move-arrow { font-size: 9px; line-height: 1; }\\n/* margin-left:auto is row layout, not badge styling -- it belongs to the market-odds row, which is\\n a flex row, and must NOT follow the badge into the insight card's odds column. */\\n.ss-w-mo-row .ss-w-move { margin-left: auto; }\\n.ss-w-mo-row .ss-w-move + .ss-w-mo-price { margin-left: 0; }\\n.ss-w-mo-row .ss-w-slip { margin: 0; }\\n.ss-w-mo-foot { display: flex; align-items: center; gap: 8px; font-size: 10.5px; color: var(--ss-w-faint); }\\n\\n/* action buttons */\\n.ss-w-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }\\n.ss-w-abtn { font-size: 12px; font-weight: 560; color: var(--ss-w-accent); background: var(--ss-w-panel); border: 1px solid var(--ss-w-accent); border-radius: 16px; padding: 6px 12px; cursor: pointer; }\\n.ss-w-abtn:disabled { opacity: .5; cursor: default; }\\n.ss-w-abtn-shimmer { width: 140px; height: 30px; border-radius: 16px; background: linear-gradient(90deg, var(--ss-w-bubble), var(--ss-w-line), var(--ss-w-bubble)); background-size: 200% 100%; animation: ss-w-shimmer 1.2s infinite; }\\n@keyframes ss-w-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }\\n\\n/* intent chips */\\n.ss-w-chips { display: flex; flex-wrap: wrap; gap: 6px; }\\n.ss-w-chip { font-size: 11.5px; font-weight: 550; color: var(--ss-w-ink); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 5px 11px; cursor: pointer; }\\n\\n/* input */\\n.ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }\\n.ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }\\n.ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }\\n/* iOS Safari zooms the page when a focused field's font-size is < 16px. Bump it\\n on touch devices only, so the desktop 13px design is unchanged. */\\n@media (pointer: coarse) {\\n .ss-w-textarea { font-size: 16px; }\\n}\\n.ss-w-send { width: 36px; height: 36px; flex: none; border: none; border-radius: 50%; background: var(--ss-w-accent); color: #fff; cursor: pointer; display: grid; place-items: center; font-size: 16px; }\\n.ss-w-stop-glyph { width: 11px; height: 11px; background: currentColor; border-radius: 2px; }\\n\\n/* add to slip */\\n.ss-w-slip { position: relative; display: flex; }\\n.ss-w-slip-btn { font-size: 11.5px; font-weight: 620; color: var(--ss-w-cta-ink); background: var(--ss-w-cta); border: 1px solid var(--ss-w-cta); border-radius: 14px; padding: 5px 12px; cursor: pointer; }\\n.ss-w-slip-btn:disabled { opacity: .6; cursor: default; background: var(--ss-w-bubble); color: var(--ss-w-faint); border-color: var(--ss-w-line); }\\n.ss-w-toast { position: absolute; top: calc(100% + 6px); left: 0; z-index: 1; max-width: 100%; font-size: 11px; font-weight: 560; border-radius: 10px; padding: 5px 10px; overflow-wrap: anywhere; box-shadow: 0 4px 14px rgba(0,0,0,.14); }\\n.ss-w-toast-success { color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); }\\n.ss-w-toast-error { color: #c0392b; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }\\n\\n@media (prefers-reduced-motion: reduce) {\\n .ss-w-abtn-shimmer { animation: none; }\\n}\\n\"\n"],"mappings":"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","names":["useEffect","useMemo","useRef","WidgetSdkError","WidgetSdkError","jsx","jsx","jsxs","useEffect","useState","jsx","jsxs","useEffect","useRef","jsx","jsx","jsxs","useState","useCallback","useState","useEffect","jsx","jsx","jsxs","useState","useCallback","jsx","jsxs","jsx","jsxs","StatRows","useState","useState","jsx","jsxs","useState","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","useRef","useEffect","useState","jsx","jsxs","useState","jsx","jsxs","useState","useEffect","jsx","useMemo","useRef","useEffect"]}
1
+ {"version":3,"sources":["../src/StatsWidget.tsx","../src/i18n.ts","../src/config.ts","../src/theme.ts","../src/useChatStream.ts","../src/reducer.ts","../src/chart.ts","../src/model.ts","../src/assets/logo.ts","../src/components/Icons.tsx","../src/components/GreetingBubble.tsx","../src/components/ChatFab.tsx","../src/components/ChatPanel.tsx","../src/components/ChatHeader.tsx","../src/components/MessageList.tsx","../src/components/Markdown.tsx","../src/components/EntityCardList.tsx","../src/components/BettingInsightList.tsx","../src/components/AddToSlipButton.tsx","../src/slip.ts","../src/components/Toast.tsx","../src/components/OddsMovementBadge.tsx","../src/components/MarketOddsCardList.tsx","../src/components/OddsMovementCard.tsx","../src/components/ActionButtons.tsx","../src/components/ChatMessage.tsx","../src/components/IntentChips.tsx","../src/scroll.ts","../src/components/ChatInput.tsx","../src/styles/css.generated.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, type CSSProperties } from 'react'\nimport { StatsWidgetClient, type Conversation } from '@sensiblestats/widget-sdk'\nimport { normalizeUi, toClientOptions, toUserContext, type StatsWidgetConfig } from './config'\nimport type { SlipHandlerProps } from './slip'\nimport { themeAttrs } from './theme'\nimport { useChatStream } from './useChatStream'\nimport { ChatFab } from './components/ChatFab'\nimport { ChatPanel } from './components/ChatPanel'\nimport { WIDGET_CSS } from './styles/css.generated'\n\nexport type StatsWidgetProps =\n | { config: StatsWidgetConfig; client?: never }\n | { client: StatsWidgetClient; config?: Omit<StatsWidgetConfig, 'operatorId' | 'publicKey' | 'baseUrl' | 'userContext'> }\n\nfunction buildClient(props: StatsWidgetProps): { client: StatsWidgetClient; conversation: Conversation } | null {\n try {\n if ('client' in props && props.client) {\n return { client: props.client, conversation: props.client.conversation() }\n }\n const cfg = props.config as StatsWidgetConfig\n const client = new StatsWidgetClient(toClientOptions(cfg))\n return { client, conversation: client.conversation(toUserContext(cfg)) }\n } catch (err) {\n console.error('[StatsWidget] failed to initialize:', err instanceof Error ? err.message : err)\n return null\n }\n}\n\nfunction injectStyles(root: Document | ShadowRoot): void {\n const host: ParentNode = root instanceof ShadowRoot ? root : root.head\n if (host.querySelector('#ss-w-styles')) return\n const el = document.createElement('style')\n el.id = 'ss-w-styles'\n el.textContent = WIDGET_CSS\n host.appendChild(el)\n}\n\nexport function StatsWidget(props: StatsWidgetProps): JSX.Element | null {\n const injectedClient = 'client' in props ? props.client : undefined\n const cfg = props.config as Partial<StatsWidgetConfig> | undefined\n const built = useMemo(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl])\n const ui = useMemo(() => normalizeUi((props.config ?? { operatorId: '', publicKey: '' }) as StatsWidgetConfig), [props.config])\n const rootRef = useRef<HTMLDivElement>(null)\n const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : undefined)\n const slip = useMemo<SlipHandlerProps>(\n () => ({\n onAddToSlip: props.config?.onAddToSlip,\n conversationId: controller.state.conversationId ?? undefined,\n onMarketClicked: (marketName) => {\n // sendSignal throws synchronously with no operatorUserId configured, and its\n // returned promise can reject on a gateway failure. Neither should ever break\n // the add-to-slip flow for a host that never wired signal tracking.\n try {\n void built?.conversation\n .sendSignal({ signalType: 'InsightMarketClicked', entityType: 'Market', entityName: marketName })\n .catch(() => undefined)\n } catch {\n // ignored — see comment above\n }\n },\n }),\n [props.config?.onAddToSlip, controller.state.conversationId, built],\n )\n\n useEffect(() => {\n if (!built || !ui.injectStyles) return\n const node = rootRef.current?.getRootNode()\n if (node) injectStyles(node as Document | ShadowRoot)\n }, [built, ui.injectStyles])\n\n if (!built) return null\n const attrs = themeAttrs(ui)\n return (\n <div ref={rootRef} className=\"ss-w-root\" data-ss-w-theme={attrs['data-ss-w-theme']} data-ss-w-pos={attrs['data-ss-w-pos']} style={attrs.style as CSSProperties}>\n {controller.state.isOpen ? (\n <ChatPanel controller={controller} ui={ui} slip={slip} />\n ) : (\n <ChatFab\n label={ui.launcherLabel}\n greeting={ui.greeting}\n popupText={controller.state.popupText}\n onOpen={controller.open}\n onDismissPopup={controller.dismissPopup}\n dismissLabel={ui.dismissGreeting}\n />\n )}\n </div>\n )\n}\n\n// Hooks must run unconditionally; when the client failed to build we still need a Conversation-shaped stub for the hook.\nfunction emptyConversation(): Conversation {\n return { send: () => { throw new Error('widget not initialized') } } as unknown as Conversation\n}\n","export type Locale = 'en' | 'tr'\n\nexport interface LocaleStrings {\n launcherLabel: string\n placeholder: string\n closeChat: string\n chatDialogLabel: string\n stopResponse: string\n sendMessage: string\n dismissGreeting: string\n somethingWentWrong: string\n retry: string\n showLess: string\n showMore: (n: number) => string\n showStats: string\n hideStats: string\n oddsLabel: string\n liveLabel: string\n addToSlip: string\n marketPrices: string\n moreLines: string\n hideLines: string\n oddsMoved: (was: string, now: string, direction: string) => string\n oddsShortened: string\n oddsDrifted: string\n updatedLabel: string\n priceMovement: string\n openingLabel: string\n currentLabel: string\n movementWindow: (hours: number) => string\n notEnoughHistory: string\n singlePricePoint: string\n selectionSuspended: string\n excludedSuspended: (n: number) => string\n chartTimeLabel: (ms: number) => string\n chartAria: (opening: string, current: string, direction: string, hours: number) => string\n inSlip: string\n slipAdded: (n?: number) => string\n slipDuplicate: string\n slipPriceChanged: (from: string, to: string) => string\n slipPriceNotAccepted: (from: string, to: string) => string\n slipLoginRequired: string\n slipSuspended: string\n slipFailed: string\n}\n\nconst STRINGS: Record<Locale, LocaleStrings> = {\n en: {\n launcherLabel: 'Chat with SensibleStats',\n placeholder: 'Ask about a team, player or match…',\n closeChat: 'Close chat',\n chatDialogLabel: 'SensibleStats chat',\n stopResponse: 'Stop response',\n sendMessage: 'Send message',\n dismissGreeting: 'Dismiss',\n somethingWentWrong: 'Something went wrong.',\n retry: 'Retry',\n showLess: 'Show less',\n showMore: (n) => `Show ${n} more`,\n showStats: 'Show stats',\n hideStats: 'Hide stats',\n oddsLabel: 'Odds',\n liveLabel: 'Live',\n addToSlip: 'Add to slip',\n marketPrices: 'Market prices',\n moreLines: 'More lines',\n hideLines: 'Hide lines',\n oddsMoved: (was, now, direction) => `was ${was}, now ${now}, ${direction}`,\n oddsShortened: 'shortened',\n oddsDrifted: 'drifted',\n updatedLabel: 'updated',\n priceMovement: 'Price movement',\n openingLabel: 'Opening',\n currentLabel: 'Current',\n movementWindow: (hours) => (hours % 24 === 0 ? `Last ${hours / 24}d` : `Last ${hours}h`),\n notEnoughHistory: 'No price history recorded yet for this selection.',\n singlePricePoint: 'Only one price recorded so far for this selection.',\n selectionSuspended: 'This selection is not currently available to bet.',\n excludedSuspended: (n) => `${n} suspended price${n === 1 ? '' : 's'} excluded from this chart.`,\n chartTimeLabel: (ms) =>\n new Intl.DateTimeFormat('en-GB', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' }).format(new Date(ms)),\n chartAria: (opening, current, direction, hours) => {\n const span = hours % 24 === 0 ? `${hours / 24} day${hours / 24 === 1 ? '' : 's'}` : `${hours} hour${hours === 1 ? '' : 's'}`\n // A flat price has no direction word; appending an empty one leaves \", .\" for a screen reader.\n const drift = direction ? `, ${direction}` : ''\n return `Price movement over the last ${span}: opened at ${opening}, currently ${current}${drift}.`\n },\n inSlip: 'In slip',\n slipAdded: (n) => (n === undefined ? 'Added to slip' : `Added to slip (${n} selection${n === 1 ? '' : 's'})`),\n slipDuplicate: 'Already in your slip',\n slipPriceChanged: (from, to) => `Added at ${to} (was ${from})`,\n slipPriceNotAccepted: (from, to) => `Price moved to ${to} (was ${from}). Tap to add.`,\n slipLoginRequired: 'Sign in to add to your slip',\n slipSuspended: 'Market suspended',\n slipFailed: \"Couldn't add to slip. Try again.\",\n },\n tr: {\n launcherLabel: 'SensibleStats ile sohbet et',\n placeholder: 'Bir takım, oyuncu veya maç hakkında sor…',\n closeChat: 'Sohbeti kapat',\n chatDialogLabel: 'SensibleStats sohbet',\n stopResponse: 'Yanıtı durdur',\n sendMessage: 'Mesaj gönder',\n dismissGreeting: 'Kapat',\n somethingWentWrong: 'Bir şeyler ters gitti.',\n retry: 'Tekrar dene',\n showLess: 'Daha az göster',\n showMore: (n) => `${n} tane daha göster`,\n showStats: 'İstatistikleri göster',\n hideStats: 'İstatistikleri gizle',\n oddsLabel: 'Oran',\n liveLabel: 'Canlı',\n addToSlip: 'Kupona ekle',\n marketPrices: 'Piyasa fiyatları',\n moreLines: 'Diğer çizgiler',\n hideLines: 'Çizgileri gizle',\n oddsMoved: (was, now, direction) => `önce ${was}, şimdi ${now}, ${direction}`,\n oddsShortened: 'düştü',\n oddsDrifted: 'yükseldi',\n updatedLabel: 'güncellendi',\n priceMovement: 'Oran hareketi',\n openingLabel: 'Açılış',\n currentLabel: 'Güncel',\n movementWindow: (hours) => (hours % 24 === 0 ? `Son ${hours / 24} gün` : `Son ${hours} saat`),\n notEnoughHistory: 'Bu seçim için henüz oran geçmişi kaydedilmedi.',\n singlePricePoint: 'Bu seçim için şimdiye kadar yalnızca bir fiyat kaydedildi.',\n selectionSuspended: 'Bu seçim şu anda bahse kapalı.',\n excludedSuspended: (n) => `${n} askıya alınmış fiyat bu grafikten hariç tutuldu.`,\n chartTimeLabel: (ms) =>\n new Intl.DateTimeFormat('tr-TR', { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' }).format(new Date(ms)),\n chartAria: (opening, current, direction, hours) => {\n const span = hours % 24 === 0 ? `${hours / 24} gün` : `${hours} saat`\n const drift = direction ? `, ${direction}` : ''\n return `Son ${span} içindeki oran hareketi: ${opening} ile açıldı, şu anda ${current}${drift}.`\n },\n inSlip: 'Kuponda',\n slipAdded: (n) => (n === undefined ? 'Kupona eklendi' : `Kupona eklendi (${n} seçim)`),\n slipDuplicate: 'Bu seçim kuponunuzda zaten var',\n slipPriceChanged: (from, to) => `${to} oranıyla eklendi (önceki ${from})`,\n slipPriceNotAccepted: (from, to) => `Oran ${to} oldu (önceki ${from}). Eklemek için dokunun.`,\n slipLoginRequired: 'Kupona eklemek için giriş yapın',\n slipSuspended: 'Bu market askıya alındı',\n slipFailed: 'Kupona eklenemedi. Tekrar deneyin.',\n },\n}\n\nexport function resolveLocaleStrings(locale?: string): LocaleStrings {\n return STRINGS[locale as Locale] ?? STRINGS.en\n}\n","import type { AddToSlipHandler, StatsWidgetClientOptions, UserContext } from '@sensiblestats/widget-sdk'\nimport { resolveLocaleStrings } from './i18n'\n\nexport interface StatsWidgetConfig {\n operatorId: string\n publicKey: string\n baseUrl?: string\n userContext?: UserContext\n theme?: 'light' | 'dark' | 'auto'\n accent?: string\n position?: 'left' | 'right'\n offset?: { x?: number; y?: number }\n radius?: number\n /** BCP-47-ish locale code for the widget's own chrome text (e.g. \"en\", \"tr\"). Defaults to \"en\". */\n locale?: string\n launcherLabel?: string\n greeting?: string\n /** Message auto-sent once on load (e.g. \"hello\"); its response shows as the launcher popup. */\n greetingMessage?: string\n placeholder?: string\n starters?: string[]\n injectStyles?: boolean\n /** Called when the user adds an insight's selection to the operator's slip. */\n onAddToSlip?: AddToSlipHandler\n}\n\ntype UiKeys =\n | 'theme' | 'accent' | 'position' | 'offset' | 'radius' | 'locale'\n | 'launcherLabel' | 'greeting' | 'greetingMessage' | 'placeholder' | 'starters' | 'injectStyles'\n\nexport interface UiConfig {\n theme: 'light' | 'dark' | 'auto'\n accent?: string\n position: 'left' | 'right'\n offset: { x: number; y: number }\n radius: number\n launcherLabel: string\n greeting?: string\n greetingMessage?: string\n placeholder: string\n starters: string[]\n injectStyles: boolean\n closeChat: string\n chatDialogLabel: string\n stopResponse: string\n sendMessage: string\n dismissGreeting: string\n somethingWentWrong: string\n retry: string\n showLess: string\n showMore: (n: number) => string\n showStats: string\n hideStats: string\n oddsLabel: string\n liveLabel: string\n marketPrices: string\n moreLines: string\n hideLines: string\n oddsMoved: (was: string, now: string, direction: string) => string\n oddsShortened: string\n oddsDrifted: string\n updatedLabel: string\n priceMovement: string\n openingLabel: string\n currentLabel: string\n movementWindow: (hours: number) => string\n notEnoughHistory: string\n singlePricePoint: string\n selectionSuspended: string\n excludedSuspended: (n: number) => string\n chartTimeLabel: (ms: number) => string\n chartAria: (opening: string, current: string, direction: string, hours: number) => string\n addToSlip: string\n inSlip: string\n slipAdded: (n?: number) => string\n slipDuplicate: string\n slipPriceChanged: (from: string, to: string) => string\n slipPriceNotAccepted: (from: string, to: string) => string\n slipLoginRequired: string\n slipSuspended: string\n slipFailed: string\n}\n\nexport function normalizeUi(cfg: Pick<StatsWidgetConfig, UiKeys>): UiConfig {\n const strings = resolveLocaleStrings(cfg.locale)\n return {\n theme: cfg.theme ?? 'auto',\n accent: cfg.accent,\n position: cfg.position ?? 'right',\n offset: { x: cfg.offset?.x ?? 20, y: cfg.offset?.y ?? 20 },\n radius: cfg.radius ?? 16,\n launcherLabel: cfg.launcherLabel ?? strings.launcherLabel,\n greeting: cfg.greeting,\n greetingMessage: cfg.greetingMessage,\n placeholder: cfg.placeholder ?? strings.placeholder,\n starters: cfg.starters ?? [],\n injectStyles: cfg.injectStyles ?? true,\n closeChat: strings.closeChat,\n chatDialogLabel: strings.chatDialogLabel,\n stopResponse: strings.stopResponse,\n sendMessage: strings.sendMessage,\n dismissGreeting: strings.dismissGreeting,\n somethingWentWrong: strings.somethingWentWrong,\n retry: strings.retry,\n showLess: strings.showLess,\n showMore: strings.showMore,\n showStats: strings.showStats,\n hideStats: strings.hideStats,\n oddsLabel: strings.oddsLabel,\n liveLabel: strings.liveLabel,\n marketPrices: strings.marketPrices,\n moreLines: strings.moreLines,\n hideLines: strings.hideLines,\n oddsMoved: strings.oddsMoved,\n oddsShortened: strings.oddsShortened,\n oddsDrifted: strings.oddsDrifted,\n updatedLabel: strings.updatedLabel,\n priceMovement: strings.priceMovement,\n openingLabel: strings.openingLabel,\n currentLabel: strings.currentLabel,\n movementWindow: strings.movementWindow,\n notEnoughHistory: strings.notEnoughHistory,\n singlePricePoint: strings.singlePricePoint,\n selectionSuspended: strings.selectionSuspended,\n excludedSuspended: strings.excludedSuspended,\n chartTimeLabel: strings.chartTimeLabel,\n chartAria: strings.chartAria,\n addToSlip: strings.addToSlip,\n inSlip: strings.inSlip,\n slipAdded: strings.slipAdded,\n slipDuplicate: strings.slipDuplicate,\n slipPriceChanged: strings.slipPriceChanged,\n slipPriceNotAccepted: strings.slipPriceNotAccepted,\n slipLoginRequired: strings.slipLoginRequired,\n slipSuspended: strings.slipSuspended,\n slipFailed: strings.slipFailed,\n }\n}\n\nexport function toClientOptions(cfg: StatsWidgetConfig): StatsWidgetClientOptions {\n const opts: StatsWidgetClientOptions = { operatorId: cfg.operatorId, publicKey: cfg.publicKey }\n if (cfg.baseUrl !== undefined) opts.baseUrl = cfg.baseUrl\n return opts\n}\n\nexport function toUserContext(cfg: StatsWidgetConfig): UserContext | undefined {\n return cfg.userContext && Object.keys(cfg.userContext).length > 0 ? cfg.userContext : undefined\n}\n","import type { UiConfig } from './config'\n\nexport interface ThemeAttrs {\n 'data-ss-w-theme': string\n 'data-ss-w-pos': string\n style: Record<string, string>\n}\n\nexport function themeAttrs(ui: UiConfig): ThemeAttrs {\n const style: Record<string, string> = {\n '--ss-w-offset-x': `${ui.offset.x}px`,\n '--ss-w-offset-y': `${ui.offset.y}px`,\n '--ss-w-radius': `${ui.radius}px`,\n }\n if (ui.accent) style['--ss-w-accent'] = ui.accent\n return { 'data-ss-w-theme': ui.theme, 'data-ss-w-pos': ui.position, style }\n}\n","import { useCallback, useEffect, useMemo, useReducer, useRef } from 'react'\nimport type { ChatHandle, ChatInput, Conversation } from '@sensiblestats/widget-sdk'\nimport { WidgetSdkError } from '@sensiblestats/widget-sdk'\nimport { reducer, initialState, type WidgetState } from './reducer'\nimport { chipFromText } from './model'\n\nexport interface SendOptions {\n actionId?: string\n /** Text shown in the user bubble when it differs from the message sent upstream (e.g. an action's label). */\n displayText?: string\n}\n\nexport interface ChatController {\n state: WidgetState\n open(): void\n close(): void\n stop(): void\n toggle(): void\n send(text: string, opts?: SendOptions): void\n retry(): void\n dismissPopup(): void\n}\n\nexport function useChatStream(conversation: Conversation, starterTexts: string[], greetingMessage?: string): ChatController {\n const seed = useMemo(() => initialState(starterTexts.map(chipFromText)), [])\n const [state, dispatch] = useReducer(reducer, seed)\n const idRef = useRef(0)\n const handleRef = useRef<ChatHandle | null>(null)\n const stateRef = useRef(state)\n stateRef.current = state\n const greetedRef = useRef(false)\n\n const nextId = () => `m${idRef.current++}`\n\n const consume = useCallback((handle: ChatHandle, onError: (err: WidgetSdkError) => void) => {\n ;(async () => {\n try {\n for await (const event of handle) dispatch({ kind: 'EVENT', event })\n } catch (err) {\n if (err instanceof WidgetSdkError) onError(err)\n else if ((err as { name?: string } | null)?.name === 'AbortError') { /* expected on cancel/close — ignore */ }\n else throw err\n } finally {\n if (handleRef.current === handle) handleRef.current = null\n }\n })()\n }, [])\n\n const run = useCallback((input: ChatInput, displayText?: string) => {\n handleRef.current?.cancel()\n dispatch({ kind: 'USER_SENT', input, userId: nextId(), assistantId: nextId(), displayText })\n const handle = conversation.send(input)\n handleRef.current = handle\n consume(handle, (err) => dispatch({ kind: 'STREAM_ERROR', error: err }))\n }, [conversation, consume])\n\n const send = useCallback((text: string, opts?: SendOptions) => {\n const trimmed = text.trim()\n if (!trimmed) return\n run({ message: trimmed, actionId: opts?.actionId }, opts?.displayText)\n }, [run])\n\n const retry = useCallback(() => {\n const last = stateRef.current.lastUserInput\n if (last) run(last, stateRef.current.lastDisplayText ?? undefined)\n }, [run])\n\n // Auto-greeting: fire once on mount when configured. No user bubble; its response\n // becomes the launcher popup. Fire-and-forget — failures are swallowed (STOP).\n useEffect(() => {\n const message = greetingMessage?.trim()\n if (!message || greetedRef.current) return\n greetedRef.current = true\n try {\n handleRef.current?.cancel()\n dispatch({ kind: 'GREETING_SENT', assistantId: nextId() })\n const handle = conversation.send({ message })\n handleRef.current = handle\n consume(handle, () => dispatch({ kind: 'STOP' }))\n } catch {\n dispatch({ kind: 'STOP' })\n }\n }, [greetingMessage, conversation, consume])\n\n const open = useCallback(() => dispatch({ kind: 'OPEN' }), [])\n const close = useCallback(() => { handleRef.current?.cancel(); handleRef.current = null; dispatch({ kind: 'CLOSE' }) }, [])\n const stop = useCallback(() => { handleRef.current?.cancel(); handleRef.current = null; dispatch({ kind: 'STOP' }) }, [])\n const toggle = useCallback(() => { if (stateRef.current.isOpen) close(); else open() }, [close, open])\n const dismissPopup = useCallback(() => dispatch({ kind: 'DISMISS_POPUP' }), [])\n\n return { state, open, close, stop, toggle, send, retry, dismissPopup }\n}\n","import type { ChatEvent, ChatInput, StreamErrorEventData } from '@sensiblestats/widget-sdk'\nimport { WidgetSdkError } from '@sensiblestats/widget-sdk'\nimport { toActionVM, toCardVM, toChipVM, toInsightVM, toMarketOddsVM, toOddsMovementVM, type ActionVM, type CardVM, type ChipVM, type InsightVM, type MarketOddsVM, type OddsMovementVM } from './model'\n\nexport interface UserMessage { role: 'user'; id: string; text: string }\nexport interface AssistantTurn { role: 'assistant'; id: string; text: string; cards: CardVM[]; actions: ActionVM[]; insights: InsightVM[]; marketOdds: MarketOddsVM[]; oddsMovement: OddsMovementVM[]; done: boolean; isGreeting?: boolean }\nexport type Message = UserMessage | AssistantTurn\n\nexport interface WidgetState {\n isOpen: boolean\n messages: Message[]\n isStreaming: boolean\n status: string | null\n actionsLoading: boolean\n starters: ChipVM[]\n error: StreamErrorEventData | WidgetSdkError | null\n lastUserInput: ChatInput | null\n lastDisplayText: string | null\n // Launcher popup text (the auto-greeting response). Cleared on open/dismiss.\n popupText: string | null\n conversationId: string | null\n}\n\nexport type Action =\n | { kind: 'OPEN' }\n | { kind: 'CLOSE' }\n | { kind: 'USER_SENT'; input: ChatInput; userId: string; assistantId: string; displayText?: string }\n | { kind: 'GREETING_SENT'; assistantId: string }\n | { kind: 'EVENT'; event: ChatEvent }\n | { kind: 'STREAM_ERROR'; error: WidgetSdkError }\n | { kind: 'STOP' }\n | { kind: 'DISMISS_POPUP' }\n\nconst POPUP_MAX = 160\n\nexport function initialState(starters: ChipVM[]): WidgetState {\n return { isOpen: false, messages: [], isStreaming: false, status: null, actionsLoading: false, starters, error: null, lastUserInput: null, lastDisplayText: null, popupText: null, conversationId: null }\n}\n\nfunction activeTurn(state: WidgetState): AssistantTurn | null {\n const last = state.messages[state.messages.length - 1]\n return last && last.role === 'assistant' && !last.done ? last : null\n}\n\nfunction mapActive(state: WidgetState, fn: (t: AssistantTurn) => AssistantTurn): Message[] {\n const last = state.messages[state.messages.length - 1]\n if (!last || last.role !== 'assistant' || last.done) return state.messages\n return [...state.messages.slice(0, -1), fn(last)]\n}\n\nfunction applyEvent(state: WidgetState, event: ChatEvent): WidgetState {\n switch (event.type) {\n case 'progress':\n return { ...state, status: event.data.message }\n case 'answer':\n return { ...state, messages: mapActive(state, (t) => ({ ...t, text: event.data.text })) }\n case 'entity_card': {\n if (event.data.card.isUsed === false) return state\n const card = toCardVM(event.data.card)\n // Generic cards (coach/referee/stadium/competition — anything not team or\n // player) carry no distinct identity and add no user value; drop them until\n // a purpose-built variant exists.\n if (card.kind === 'generic') return state\n return { ...state, messages: mapActive(state, (t) => ({ ...t, cards: [...t.cards, card] })) }\n }\n case 'action_button':\n return { ...state, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, actions: [...t.actions, toActionVM(event.data.action)] })) }\n case 'betting_insight':\n return { ...state, messages: mapActive(state, (t) => ({ ...t, insights: [...t.insights, toInsightVM(event.data.insight)] })) }\n case 'market_odds':\n return { ...state, messages: mapActive(state, (t) => ({ ...t, marketOdds: [...t.marketOdds, toMarketOddsVM(event.data.card)] })) }\n case 'odds_movement':\n return { ...state, messages: mapActive(state, (t) => ({ ...t, oddsMovement: [...t.oddsMovement, toOddsMovementVM(event.data.card)] })) }\n case 'intent_chip': {\n const chip = toChipVM(event.data.intent)\n return chip ? { ...state, starters: [...state.starters, chip] } : state\n }\n case 'actions_loading':\n return { ...state, actionsLoading: true, status: event.data.message }\n case 'turn_complete': {\n const active = activeTurn(state)\n const text = active?.text.trim() ?? ''\n // A completed greeting turn surfaces its answer as the launcher popup (unless already open).\n const popupText = active?.isGreeting && !state.isOpen && text ? text.slice(0, POPUP_MAX) : state.popupText\n return {\n ...state, isStreaming: false, status: null, actionsLoading: false, popupText,\n conversationId: event.data.conversationId ?? state.conversationId,\n messages: mapActive(state, (t) => ({ ...t, done: true })),\n }\n }\n case 'error': {\n // A failed greeting fails silently — it's non-critical background chatter.\n const suppress = activeTurn(state)?.isGreeting === true\n return { ...state, error: suppress ? state.error : event.data, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) }\n }\n }\n // Unknown/unmodelled event type: never return undefined — that would corrupt\n // state and crash the next dispatch. Ignore the event and keep state intact.\n return state\n}\n\nexport function reducer(state: WidgetState, action: Action): WidgetState {\n switch (action.kind) {\n case 'OPEN':\n return { ...state, isOpen: true, popupText: null }\n case 'CLOSE':\n return { ...state, isOpen: false, isStreaming: false, status: null, actionsLoading: false }\n case 'USER_SENT': {\n const user: UserMessage = { role: 'user', id: action.userId, text: action.displayText ?? action.input.message }\n const assistant: AssistantTurn = { role: 'assistant', id: action.assistantId, text: '', cards: [], actions: [], insights: [], marketOdds: [], oddsMovement: [], done: false }\n return { ...state, messages: [...state.messages, user, assistant], isStreaming: true, status: null, actionsLoading: false, starters: [], error: null, lastUserInput: action.input, lastDisplayText: action.displayText ?? null }\n }\n case 'GREETING_SENT': {\n // Auto-greeting: no user bubble; the assistant turn is flagged so its completion sets the popup.\n const assistant: AssistantTurn = { role: 'assistant', id: action.assistantId, text: '', cards: [], actions: [], insights: [], marketOdds: [], oddsMovement: [], done: false, isGreeting: true }\n return { ...state, messages: [...state.messages, assistant], isStreaming: true, status: null, error: null }\n }\n case 'DISMISS_POPUP':\n return { ...state, popupText: null }\n case 'EVENT':\n return applyEvent(state, action.event)\n case 'STREAM_ERROR':\n return { ...state, error: action.error, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) }\n case 'STOP':\n return { ...state, isStreaming: false, status: null, actionsLoading: false, messages: mapActive(state, (t) => ({ ...t, done: true })) }\n }\n}\n","export interface ChartSample { atMs: number; price: number }\nexport interface ChartGeometry {\n path: string\n markers: { x: number; y: number }[]\n gridlines: { y: number; price: number }[]\n viewBox: string\n startMs: number\n endMs: number\n}\n\nexport const CHART_VIEW_W = 320\nexport const CHART_VIEW_H = 140\n\nconst PLOT_X0 = 40\nconst PLOT_X1 = 312\nconst PLOT_Y0 = 10\nconst PLOT_Y1 = 110\n\n// Point markers are drawn only on sparse series. Measured on sandbox1, the median chartable\n// series has TWO points: without markers a two-point chart is one bare diagonal that reads as a\n// rendering glitch rather than as data. Above this count the dots crowd the line and the shape\n// carries itself.\nconst MARKER_MAX_POINTS = 8\n\n// A flat series has no price range to scale against. Widening the domain by a fixed amount keeps\n// the line horizontal through the middle of the plot instead of dividing by zero.\nconst FLAT_DOMAIN_PAD = 0.05\n\nconst round2 = (n: number): number => Math.round(n * 100) / 100\n\nexport function projectSeries(samples: ChartSample[]): ChartGeometry | null {\n if (samples.length < 2) return null\n\n // noUncheckedIndexedAccess can't see that the length check above guarantees these exist.\n const tMin = samples[0]!.atMs\n const tMax = samples[samples.length - 1]!.atMs\n if (tMax <= tMin) return null\n\n const prices = samples.map((s) => s.price)\n const pMin = Math.min(...prices)\n const pMax = Math.max(...prices)\n\n let yMin: number\n let yMax: number\n if (pMax === pMin) {\n yMin = pMin - FLAT_DOMAIN_PAD\n yMax = pMax + FLAT_DOMAIN_PAD\n } else {\n const pad = (pMax - pMin) * 0.1\n yMin = pMin - pad\n yMax = pMax + pad\n }\n\n const x = (atMs: number): number =>\n round2(PLOT_X0 + ((atMs - tMin) / (tMax - tMin)) * (PLOT_X1 - PLOT_X0))\n const y = (price: number): number =>\n round2(PLOT_Y1 - ((price - yMin) / (yMax - yMin)) * (PLOT_Y1 - PLOT_Y0))\n\n const projected = samples.map((s) => ({ x: x(s.atMs), y: y(s.price) }))\n const path = projected.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`).join(' ')\n\n return {\n path,\n markers: samples.length <= MARKER_MAX_POINTS ? projected : [],\n // The real extremes, never the padded bounds: a gridline label is a price, and the padded\n // bounds are prices nobody was ever offered. A flat series has one real extreme, not two —\n // two identical gridlines would collide on both React key and rendered text.\n gridlines: pMax === pMin\n ? [{ y: y(pMax), price: pMax }]\n : [\n { y: y(pMax), price: pMax },\n { y: y(pMin), price: pMin },\n ],\n viewBox: `0 0 ${CHART_VIEW_W} ${CHART_VIEW_H}`,\n startMs: tMin,\n endMs: tMax,\n }\n}\n","import type { BettingInsight, EntityCard, MarketOddsCard, MarketOddsRow, OddsMovementCard, SlipSelection } from '@sensiblestats/widget-sdk'\nimport type { ChartGeometry, ChartSample } from './chart'\nimport { projectSeries } from './chart'\n\nexport type CardKind = 'player' | 'team' | 'generic'\nexport interface StatCell { label: string; value: string }\nexport interface CardScope { competitionId: number | null; label: string; image?: string; stats: StatCell[] }\nexport interface CardVM { id: string; kind: CardKind; name: string; image?: string; sub?: string; season?: string; scopes: CardScope[] }\nexport interface ActionVM { label: string; actionId?: string; message: string }\nexport interface ChipVM { text: string }\nexport interface InsightScope { key: string; label: string; stats: StatCell[] }\nexport interface InsightVM {\n id: string\n market: string\n selection?: string\n odds?: string\n bookmaker?: string\n isLive: boolean\n phase?: string\n fixture?: string\n competition?: string\n scopes?: InsightScope[]\n text: string\n stats: StatCell[]\n disclaimer?: string\n matchId: number\n matchOddsId?: number\n addToSlipEnabled: boolean\n oddsDecimal?: number\n quotedAtUtc?: string\n previousOdds?: string\n movementDirection?: 'shortened' | 'drifted'\n}\n\nexport interface MarketOddsRowVM {\n key: string\n selection: string\n odds: string\n oddsDecimal?: number\n matchOddsId?: number\n quotedAtUtc?: string\n isMain: boolean\n previousOdds?: string\n movementDirection?: 'shortened' | 'drifted'\n}\nexport interface MarketOddsVM {\n id: string\n market: string\n fixture?: string\n competition?: string\n bookmaker?: string\n updatedAt?: string\n isLive: boolean\n matchId: number\n mainRows: MarketOddsRowVM[]\n moreRows: MarketOddsRowVM[]\n disclaimer?: string\n addToSlipEnabled: boolean\n}\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' && v.length > 0 ? v : undefined\n}\nfunction num(v: unknown): string | undefined {\n return typeof v === 'number' && Number.isFinite(v) ? String(v) : undefined\n}\n\nfunction readStatCells(raw: unknown): StatCell[] {\n if (!Array.isArray(raw)) return []\n const cells: StatCell[] = []\n for (const entry of raw as Array<Record<string, unknown>>) {\n const label = str(entry.label)\n const value = num(entry.value) ?? str(entry.value)\n if (label !== undefined && value !== undefined) cells.push({ label, value })\n }\n return cells\n}\n\nexport function toCardVM(card: EntityCard): CardVM {\n const entityType = str(card.entityType)?.toLowerCase()\n const kind: CardKind = entityType === 'player' ? 'player' : entityType === 'team' ? 'team' : 'generic'\n const scopes = Array.isArray(card.scopes)\n ? (card.scopes as unknown as Array<Record<string, unknown>>)\n .map((s): CardScope | null => {\n const label = str(s.label)\n if (!label) return null\n return {\n competitionId: typeof s.competitionId === 'number' ? s.competitionId : null,\n label,\n image: str(s.imagePath),\n stats: readStatCells(s.stats),\n }\n })\n .filter((s): s is CardScope => s !== null)\n : []\n return {\n id: String(card.entityId),\n kind,\n name: card.canonicalName,\n image: str(card.imagePath) ?? str(card.imageUrl) ?? str(card.image_url) ?? str(card.logoUrl) ?? str(card.logo),\n sub: str(card.subtitle) ?? str(card.teamName) ?? str(card.leagueName) ?? str(card.position),\n season: str(card.seasonName),\n scopes,\n }\n}\n\nexport function toActionVM(action: Record<string, unknown>): ActionVM {\n const label = str(action.actionLabel) ?? str(action.label) ?? str(action.text) ?? str(action.title) ?? 'Continue'\n const actionId = str(action.actionId) ?? str(action.id)\n const message = str(action.actionValue) ?? str(action.message) ?? str(action.query) ?? label\n return { label, actionId, message }\n}\n\nexport function toChipVM(intent: Record<string, unknown>): ChipVM | null {\n const text = str(intent.text) ?? str(intent.label) ?? str(intent.title)\n return text ? { text } : null\n}\n\nexport function chipFromText(text: string): ChipVM {\n return { text }\n}\n\nexport function toInsightVM(insight: BettingInsight): InsightVM {\n const market = str(insight.marketLabel) ?? str(insight.marketDeveloperName) ?? ''\n const selection = [str(insight.selectionLabel), str(insight.line)].filter(Boolean).join(' ') || undefined\n const value = insight.odds?.value\n const odds = typeof value === 'number' && Number.isFinite(value) ? value.toFixed(2) : undefined\n const oddsValue = insight.odds?.value\n const matchOddsId = typeof insight.odds?.matchOddsId === 'number' ? insight.odds.matchOddsId : undefined\n const home = str(insight.homeTeamName)\n const away = str(insight.awayTeamName)\n const fixture = home && away ? `${home} vs ${away}` : undefined\n const competition = str(insight.competitionName)\n const scopes = Array.isArray(insight.scopes)\n ? (insight.scopes as Array<Record<string, unknown>>)\n .map((s) => ({ key: str(s.key), label: str(s.label), stats: readStatCells(s.stats) }))\n .filter((s): s is InsightScope => !!s.key && !!s.label)\n : undefined\n const previousValue = insight.odds?.previousValue\n const previous =\n typeof previousValue === 'number' && Number.isFinite(previousValue) ? previousValue : undefined\n const direction =\n insight.odds?.movementDirection === 'shortened' || insight.odds?.movementDirection === 'drifted'\n ? insight.odds.movementDirection\n : undefined\n return {\n id: str(insight.insightId) ?? `${str(insight.ruleId) ?? 'insight'}:${num(insight.matchId) ?? ''}`,\n market,\n selection,\n odds,\n // The wire payload carries bookmakerId (not a name); render a name only if one is present.\n bookmaker: str(insight.odds?.bookmakerName),\n isLive: insight.odds?.isLive === true,\n phase: str(insight.phase),\n fixture,\n competition,\n scopes,\n text: str(insight.text) ?? '',\n stats: readStatCells(insight.stats),\n disclaimer: str(insight.disclaimer),\n matchId: typeof insight.matchId === 'number' ? insight.matchId : 0,\n matchOddsId,\n addToSlipEnabled: insight.addToSlipEnabled === true,\n oddsDecimal: typeof oddsValue === 'number' && Number.isFinite(oddsValue) ? oddsValue : undefined,\n quotedAtUtc: str(insight.odds?.quotedAtUtc),\n previousOdds: previous !== undefined && direction !== undefined ? previous.toFixed(2) : undefined,\n movementDirection: previous !== undefined && direction !== undefined ? direction : undefined,\n }\n}\n\nexport function toSlipSelection(vm: InsightVM, conversationId?: string): SlipSelection | null {\n if (vm.matchOddsId === undefined || vm.oddsDecimal === undefined) return null\n const selection: SlipSelection = {\n matchOddsId: vm.matchOddsId,\n matchId: vm.matchId,\n oddsDecimal: vm.oddsDecimal,\n }\n if (vm.quotedAtUtc !== undefined) selection.quotedAtUtc = vm.quotedAtUtc\n if (vm.id !== undefined) selection.insightId = vm.id\n if (conversationId !== undefined) selection.conversationId = conversationId\n return selection\n}\n\nexport function toMarketOddsVM(card: MarketOddsCard): MarketOddsVM {\n const rows = Array.isArray(card.rows) ? card.rows : []\n const toRow = (r: MarketOddsRow, i: number): MarketOddsRowVM => {\n const selection = [str(r.selectionLabel), str(r.line)].filter(Boolean).join(' ')\n const price = typeof r.price === 'number' && Number.isFinite(r.price) ? r.price : undefined\n const previous =\n typeof r.previousPrice === 'number' && Number.isFinite(r.previousPrice) ? r.previousPrice : undefined\n const direction =\n r.movementDirection === 'shortened' || r.movementDirection === 'drifted' ? r.movementDirection : undefined\n return {\n key: `${selection}:${str(r.line) ?? ''}:${i}`,\n selection,\n odds: price !== undefined ? price.toFixed(2) : '',\n oddsDecimal: price,\n matchOddsId: typeof r.matchOddsId === 'number' ? r.matchOddsId : undefined,\n quotedAtUtc: str(r.quotedAtUtc),\n isMain: r.isMainLine !== false,\n previousOdds: previous !== undefined && direction !== undefined ? previous.toFixed(2) : undefined,\n movementDirection: previous !== undefined && direction !== undefined ? direction : undefined,\n }\n }\n const vms = rows.map(toRow).filter((r) => r.selection && r.odds)\n const home = str(card.homeTeamName)\n const away = str(card.awayTeamName)\n const updated = rows.map((r) => str(r.quotedAtUtc)).filter((v): v is string => !!v).sort()\n return {\n id: `${typeof card.matchId === 'number' ? card.matchId : 0}:${str(card.marketDeveloperName) ?? ''}`,\n market: str(card.marketLabel) ?? str(card.marketDeveloperName) ?? '',\n fixture: home && away ? `${home} vs ${away}` : undefined,\n competition: str(card.competitionName),\n bookmaker: rows.map((r) => str(r.bookmakerName)).find(Boolean),\n updatedAt: updated.length > 0 ? updated[updated.length - 1] : undefined,\n isLive: rows.some((r) => r.isLive === true),\n matchId: typeof card.matchId === 'number' ? card.matchId : 0,\n mainRows: vms.filter((r) => r.isMain),\n moreRows: vms.filter((r) => !r.isMain),\n disclaimer: str(card.disclaimer),\n addToSlipEnabled: card.addToSlipEnabled === true,\n }\n}\n\nexport interface OddsMovementVM {\n id: string\n market: string\n selection: string\n fixture?: string\n competition?: string\n bookmaker?: string\n opening: string\n current: string\n direction?: 'shortened' | 'drifted'\n windowHours: number\n excludedCount: number\n isSuspended: boolean\n disclaimer?: string\n geometry: ChartGeometry | null\n observationCount: number\n}\n\nexport function toOddsMovementVM(card: OddsMovementCard): OddsMovementVM {\n const raw = Array.isArray(card.points) ? card.points : []\n const samples: ChartSample[] = []\n for (const p of raw) {\n const price = typeof p.price === 'number' && Number.isFinite(p.price) ? p.price : undefined\n const atMs = typeof p.atUtc === 'string' ? Date.parse(p.atUtc) : NaN\n if (price === undefined || Number.isNaN(atMs)) continue\n samples.push({ atMs, price })\n }\n // projectSeries trusts sample order as the time domain (samples[0]/samples[^1] become tMin/tMax)\n // without re-checking it; every other field above is already validated, so this is the one\n // property whose violation is otherwise invisible.\n samples.sort((a, b) => a.atMs - b.atMs)\n\n const asNumber = (v: unknown): number | undefined =>\n typeof v === 'number' && Number.isFinite(v) ? v : undefined\n const opening = asNumber(card.openingPrice)\n const current = asNumber(card.currentPrice)\n const home = str(card.homeTeamName)\n const away = str(card.awayTeamName)\n const selection = [str(card.selectionLabel), str(card.line)].filter(Boolean).join(' ')\n const bookmakerId = typeof card.bookmakerId === 'number' ? card.bookmakerId : ''\n\n return {\n id: `${typeof card.matchId === 'number' ? card.matchId : 0}:${str(card.marketDeveloperName) ?? ''}:${selection}:${bookmakerId}`,\n market: str(card.marketLabel) ?? str(card.marketDeveloperName) ?? '',\n selection,\n fixture: home && away ? `${home} vs ${away}` : undefined,\n competition: str(card.competitionName),\n bookmaker: str(card.bookmakerName),\n opening: opening !== undefined ? opening.toFixed(2) : '',\n current: current !== undefined ? current.toFixed(2) : '',\n direction:\n card.movementDirection === 'shortened' || card.movementDirection === 'drifted'\n ? card.movementDirection\n : undefined,\n windowHours: asNumber(card.windowHours) ?? 0,\n excludedCount: asNumber(card.excludedSuspendedCount) ?? 0,\n isSuspended: card.isSuspended === true,\n disclaimer: str(card.disclaimer),\n geometry: projectSeries(samples),\n observationCount: samples.length,\n }\n}\n\nexport function marketOddsRowToSlipSelection(\n vm: MarketOddsVM, row: MarketOddsRowVM, conversationId?: string,\n): SlipSelection | null {\n if (row.matchOddsId === undefined || row.oddsDecimal === undefined) return null\n const selection: SlipSelection = { matchOddsId: row.matchOddsId, matchId: vm.matchId, oddsDecimal: row.oddsDecimal }\n if (row.quotedAtUtc !== undefined) selection.quotedAtUtc = row.quotedAtUtc\n if (conversationId !== undefined) selection.conversationId = conversationId\n return selection\n}\n","// SensibleStats brand mark, inlined as a data URI so the published widget\n// bundle stays self-contained (no external asset hosting / CORS concerns\n// for third-party embeds).\nexport const SS_LOGO_DATA_URI = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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\"\n","// SensibleStats brand mark, rendered from the official logo asset.\nimport { SS_LOGO_DATA_URI } from '../assets/logo'\n\nexport function SsMark({ className }: { className?: string }): JSX.Element {\n return <img className={className} src={SS_LOGO_DATA_URI} alt=\"\" aria-hidden=\"true\" />\n}\nexport function SendIcon(): JSX.Element {\n return <svg viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" aria-hidden=\"true\"><path fill=\"currentColor\" d=\"M3 20l18-8L3 4v6l12 2-12 2z\" /></svg>\n}\nexport function CloseIcon(): JSX.Element {\n return <svg viewBox=\"0 0 24 24\" width=\"1em\" height=\"1em\" aria-hidden=\"true\"><path fill=\"none\" d=\"M18 6L6 18M6 6l12 12\" stroke=\"currentColor\" strokeWidth=\"2\" /></svg>\n}\n","export function GreetingBubble({ text, onOpen, onDismiss, dismissLabel = 'Dismiss' }: { text: string; onOpen?: () => void; onDismiss?: () => void; dismissLabel?: string }): JSX.Element {\n return (\n <div className=\"ss-w-greeting\" role=\"note\">\n <button type=\"button\" className=\"ss-w-greeting-body\" onClick={onOpen}>{text}</button>\n {onDismiss ? (\n <button type=\"button\" className=\"ss-w-greeting-x\" aria-label={dismissLabel} onClick={onDismiss}>×</button>\n ) : null}\n </div>\n )\n}\n","import { SsMark } from './Icons'\nimport { GreetingBubble } from './GreetingBubble'\n\n// Only rendered while the panel is closed. The dynamic greeting popup takes\n// precedence over the static greeting and is dismissable; both open the panel.\nexport function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLabel = 'Dismiss' }: { label: string; greeting?: string; popupText?: string | null; onOpen: () => void; onDismissPopup: () => void; dismissLabel?: string }): JSX.Element {\n const bubble = popupText ?? greeting\n return (\n <div className=\"ss-w-fab-wrap\">\n {bubble ? <GreetingBubble text={bubble} onOpen={onOpen} onDismiss={popupText ? onDismissPopup : undefined} dismissLabel={dismissLabel} /> : null}\n <button type=\"button\" className=\"ss-w-fab\" aria-label={label} onClick={onOpen}>\n <SsMark className=\"ss-w-fab-mark\" />\n </button>\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\nimport type { ChatController } from '../useChatStream'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { ChatHeader } from './ChatHeader'\nimport { MessageList } from './MessageList'\nimport { ChatInput } from './ChatInput'\n\n// Mirrors the panel's fullscreen breakpoint in widget.css (@media max-width: 639px).\n// The panel only traps the page — and is thus truly modal — when it fills the viewport.\nconst FULLSCREEN_QUERY = '(max-width: 639px)'\n\nfunction useIsModal(): boolean {\n const [modal, setModal] = useState(false)\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return\n const mql = window.matchMedia(FULLSCREEN_QUERY)\n const sync = (): void => setModal(mql.matches)\n sync()\n mql.addEventListener('change', sync)\n return () => mql.removeEventListener('change', sync)\n }, [])\n return modal\n}\n\nexport function ChatPanel({ controller, ui, slip }: { controller: ChatController; ui: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const { state, close, stop, send } = controller\n const isModal = useIsModal()\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') close() }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [close])\n\n return (\n <div className=\"ss-w-panel\" role=\"dialog\" aria-modal={isModal} aria-label={ui.chatDialogLabel}>\n <ChatHeader onClose={close} closeLabel={ui.closeChat} />\n <MessageList controller={controller} ui={ui} slip={slip} />\n <ChatInput placeholder={ui.placeholder} streaming={state.isStreaming} onSend={(t) => send(t)} onStop={stop} stopLabel={ui.stopResponse} sendLabel={ui.sendMessage} />\n </div>\n )\n}\n","import { SsMark, CloseIcon } from './Icons'\n\nexport function ChatHeader({ onClose, closeLabel = 'Close chat' }: { onClose: () => void; closeLabel?: string }): JSX.Element {\n return (\n <header className=\"ss-w-header\">\n <SsMark className=\"ss-w-header-mark\" />\n <span className=\"ss-w-header-title\">SensibleStats</span>\n <button type=\"button\" className=\"ss-w-close\" aria-label={closeLabel} onClick={onClose}><CloseIcon /></button>\n </header>\n )\n}\n","import { useEffect, useRef } from 'react'\nimport type { ChatController } from '../useChatStream'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { ChatMessage } from './ChatMessage'\nimport { IntentChips } from './IntentChips'\nimport { ActionButtons } from './ActionButtons'\nimport { isPinnedToBottom } from '../scroll'\n\nexport function MessageList({ controller, ui, slip }: { controller: ChatController; ui: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const { state, send } = controller\n const listRef = useRef<HTMLDivElement>(null)\n const endRef = useRef<HTMLDivElement>(null)\n // Follow the stream only while the user is at the bottom. pinnedRef is updated\n // on real scroll events (content growth fires none), so a user who scrolls up\n // stays put when late content — suggested actions, status — arrives.\n const pinnedRef = useRef(true)\n useEffect(() => {\n if (pinnedRef.current) endRef.current?.scrollIntoView({ block: 'end' })\n }, [state.messages, state.status])\n\n const empty = state.messages.length === 0\n return (\n <div\n className=\"ss-w-list\"\n aria-live=\"polite\"\n ref={listRef}\n onScroll={() => { if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current) }}\n >\n {state.messages.map((m) => (\n <ChatMessage\n key={m.id}\n message={m}\n disabled={state.isStreaming}\n onAct={(a) => send(a.message, { actionId: a.actionId, displayText: a.label })}\n ui={ui}\n slip={slip}\n />\n ))}\n {state.isStreaming && state.actionsLoading ? <ActionButtons actions={[]} loading onAct={() => {}} /> : null}\n {state.status ? <div className=\"ss-w-status\">{state.status}</div> : null}\n {state.error ? (\n <div className=\"ss-w-error\" role=\"alert\">\n <span>{'message' in state.error ? state.error.message : ui.somethingWentWrong}</span>\n <button type=\"button\" className=\"ss-w-retry\" onClick={() => controller.retry()}>{ui.retry}</button>\n </div>\n ) : null}\n {empty ? <IntentChips chips={state.starters} onPick={(t) => send(t)} /> : null}\n <div ref={endRef} />\n </div>\n )\n}\n","import ReactMarkdown, { type Components } from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\n\nconst components: Components = {\n a: ({ children, href }) => (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" className=\"ss-w-md-link\">{children}</a>\n ),\n table: ({ children }) => (\n <div className=\"ss-w-table-wrap\"><table className=\"ss-w-md-table\">{children}</table></div>\n ),\n ul: ({ children }) => <ul className=\"ss-w-md-ul\">{children}</ul>,\n ol: ({ children }) => <ol className=\"ss-w-md-ol\">{children}</ol>,\n code: ({ children }) => <code className=\"ss-w-md-code\">{children}</code>,\n}\n\nexport function Markdown({ text }: { text: string }): JSX.Element {\n return (\n <div className=\"ss-w-md\">\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>{text}</ReactMarkdown>\n </div>\n )\n}\n","import { useState } from 'react'\nimport type { CardVM, CardScope, StatCell } from '../model'\n\nconst MAX_VISIBLE = 3\nconst RECORD_RE = /^(\\d+)-(\\d+)-(\\d+)$/\n\nfunction initials(name: string): string {\n return name.split(/\\s+/).slice(0, 2).map((w) => w[0] ?? '').join('').toUpperCase()\n}\n\n// \"2026/2027\" -> \"26/27\", \"2026\" -> \"26\"; leaves any non-4-digit token untouched.\nfunction shortSeason(season: string): string {\n return season.replace(/\\d{4}/g, (year) => year.slice(2))\n}\n\nfunction Crest({ image }: { image: string }): JSX.Element {\n return <span className=\"ss-w-ecard-crest\" style={{ backgroundImage: `url(${image})` }} aria-hidden=\"true\" />\n}\n\n// Proportional win/draw/loss bar. Rendered for any stat value shaped \"w-d-l\".\nfunction FormBar({ w, d, l }: { w: number; d: number; l: number }): JSX.Element | null {\n if (w + d + l === 0) return null\n return (\n <span className=\"ss-w-form\" aria-hidden=\"true\">\n {w > 0 ? <span className=\"ss-w-form-w\" style={{ flexGrow: w }} /> : null}\n {d > 0 ? <span className=\"ss-w-form-d\" style={{ flexGrow: d }} /> : null}\n {l > 0 ? <span className=\"ss-w-form-l\" style={{ flexGrow: l }} /> : null}\n </span>\n )\n}\n\nfunction StatRows({ stats }: { stats: StatCell[] }): JSX.Element {\n return (\n <div className=\"ss-w-ecard-stats\">\n {stats.map((s) => {\n const m = RECORD_RE.exec(s.value)\n return (\n <div key={s.label} className=\"ss-w-ecard-row\">\n <span className=\"ss-w-ecard-rlabel\">{s.label}</span>\n {m ? <FormBar w={Number(m[1])} d={Number(m[2])} l={Number(m[3])} /> : <span />}\n <span className=\"ss-w-ecard-rval\">{s.value}</span>\n </div>\n )\n })}\n </div>\n )\n}\n\n// The right-hand panel: competition tabs (2+ scopes) or a static league label\n// (1 scope), the season pill, and the stat rows for the active scope.\nfunction CardBody({ c }: { c: CardVM }): JSX.Element | null {\n const [active, setActive] = useState(0)\n if (c.scopes.length === 0) return null\n const season = c.season ? <span className=\"ss-w-ecard-season\">{shortSeason(c.season)}</span> : null\n\n if (c.scopes.length === 1) {\n const only = c.scopes[0]!\n return (\n <div className=\"ss-w-ecard-body\">\n <div className=\"ss-w-ecard-tabs ss-w-ecard-tabs-static\">\n <span className=\"ss-w-ecard-lead\" title={only.label}>{only.image ? <Crest image={only.image} /> : null}<span className=\"ss-w-ecard-lead-txt\">{only.label}</span></span>\n {season}\n </div>\n <StatRows stats={only.stats} />\n </div>\n )\n }\n\n const current = c.scopes[active] ?? c.scopes[0]!\n return (\n <div className=\"ss-w-ecard-body\">\n <div className=\"ss-w-ecard-tabs\" role=\"tablist\">\n {c.scopes.map((s, i) => (\n <button\n key={String(s.competitionId ?? 'all')}\n type=\"button\"\n role=\"tab\"\n className=\"ss-w-ecard-tab\"\n aria-selected={i === active}\n aria-label={s.label}\n title={s.label}\n onClick={() => setActive(i)}\n >\n {s.image ? <Crest image={s.image} /> : s.label}\n </button>\n ))}\n {season}\n </div>\n <StatRows key={String(current.competitionId ?? 'all')} stats={current.stats} />\n </div>\n )\n}\n\nfunction EntityCardItem({ c }: { c: CardVM }): JSX.Element {\n const hasBody = c.scopes.length > 0\n return (\n <div className={hasBody ? 'ss-w-ecard' : 'ss-w-ecard ss-w-ecard-bare'} data-kind={c.kind}>\n <div className=\"ss-w-ecard-id\">\n <span\n className={c.kind === 'team' ? 'ss-w-thumb ss-w-team' : 'ss-w-thumb'}\n style={c.image ? { backgroundImage: `url(${c.image})` } : undefined}\n >\n {c.image ? '' : initials(c.name)}\n </span>\n <span className=\"ss-w-ecard-idtext\">\n <span className=\"ss-w-nm\">{c.name}</span>\n {c.sub ? <span className=\"ss-w-sub\">{c.sub}</span> : null}\n </span>\n </div>\n <CardBody c={c} />\n </div>\n )\n}\n\nexport function EntityCardList({ cards, disabled, showLessLabel = 'Show less', showMoreLabel = (n: number) => `Show ${n} more` }: { cards: CardVM[]; disabled?: boolean; showLessLabel?: string; showMoreLabel?: (n: number) => string }): JSX.Element | null {\n const [expanded, setExpanded] = useState(false)\n if (cards.length === 0) return null\n const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE)\n const overflow = cards.length - MAX_VISIBLE\n return (\n <div className=\"ss-w-cards\">\n {visible.map((c) => <EntityCardItem key={c.id} c={c} />)}\n {overflow > 0 ? (\n <button type=\"button\" className=\"ss-w-cards-more\" disabled={disabled} onClick={() => setExpanded((v) => !v)}>\n {expanded ? showLessLabel : showMoreLabel(overflow)}\n </button>\n ) : null}\n </div>\n )\n}\n","import { useState } from 'react'\nimport type { InsightVM, StatCell } from '../model'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { AddToSlipButton } from './AddToSlipButton'\nimport { OddsMovementBadge } from './OddsMovementBadge'\n\nfunction StatRows({ stats }: { stats: StatCell[] }): JSX.Element {\n return (\n <div className=\"ss-w-bi-rows\">\n {stats.map((s) => (\n <div key={`${s.label}:${s.value}`} className=\"ss-w-bi-row\">\n <span className=\"ss-w-bi-row-lbl\">{s.label}</span>\n <span className=\"ss-w-bi-row-num\">{s.value}</span>\n </div>\n ))}\n </div>\n )\n}\n\nfunction ScopedStats({ scopes }: { scopes: NonNullable<InsightVM['scopes']> }): JSX.Element {\n const [active, setActive] = useState(0)\n const current = scopes[active] ?? scopes[0] ?? { key: '', label: '', stats: [] }\n return (\n <div className=\"ss-w-bi-scoped\">\n <div className=\"ss-w-bi-scopes\" role=\"group\">\n {scopes.map((s, i) => (\n <button key={s.key} type=\"button\" className=\"ss-w-bi-chip\" aria-pressed={i === active} onClick={() => setActive(i)}>\n {s.label}\n </button>\n ))}\n </div>\n <StatRows key={current.key} stats={current.stats} />\n </div>\n )\n}\n\n// Stats are collapsed by default — the reason-to-bet prose carries the justification, and the\n// numbers are one tap away for anyone who wants to verify. Only renders when there is something\n// to show.\nfunction StatsDisclosure({ it, ui }: { it: InsightVM; ui?: UiConfig }): JSX.Element | null {\n const [open, setOpen] = useState(false)\n const hasScopes = !!it.scopes && it.scopes.length >= 2\n const hasStats = hasScopes || it.stats.length > 0\n if (!hasStats) return null\n return (\n <div className=\"ss-w-bi-stats\">\n <button\n type=\"button\"\n className=\"ss-w-bi-toggle\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n >\n <span>{open ? ui?.hideStats ?? 'Hide stats' : ui?.showStats ?? 'Show stats'}</span>\n <span className={`ss-w-bi-chev${open ? ' ss-w-bi-chev-up' : ''}`} aria-hidden=\"true\" />\n </button>\n {open\n ? hasScopes\n ? <ScopedStats scopes={it.scopes!} />\n : <StatRows stats={it.stats} />\n : null}\n </div>\n )\n}\n\nfunction InsightCard({ it, ui, slip }: { it: InsightVM; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const live = it.isLive || it.phase === 'live'\n return (\n <div className=\"ss-w-binsight\">\n {live ? (\n <div className=\"ss-w-bi-status\">\n <span className=\"ss-w-bi-live\"><span className=\"ss-w-bi-live-dot\" aria-hidden=\"true\" />{ui?.liveLabel ?? 'Live'}</span>\n </div>\n ) : null}\n <div className=\"ss-w-bi-head\">\n <span className=\"ss-w-bi-mkt\">\n <span className=\"ss-w-bi-market\">{it.market}</span>\n {it.selection ? <span className=\"ss-w-bi-sel\">{it.selection}</span> : null}\n {(it.fixture || it.competition) ? (\n <span className=\"ss-w-bi-match\">\n {it.fixture ? <span className=\"ss-w-bi-fixture\">{it.fixture}</span> : null}\n {it.competition ? <span className=\"ss-w-bi-comp\">{it.competition}</span> : null}\n </span>\n ) : null}\n </span>\n <div className=\"ss-w-bi-action\">\n {it.odds ? (\n <span className=\"ss-w-bi-odds\">\n <span className=\"ss-w-bi-odds-cap\">{ui?.oddsLabel ?? 'Odds'}</span>\n <b>{it.odds}</b>\n <OddsMovementBadge previous={it.previousOdds} current={it.odds} direction={it.movementDirection} ui={ui} />\n {it.bookmaker ? <span className=\"ss-w-bi-book\">{it.bookmaker}</span> : null}\n </span>\n ) : null}\n <AddToSlipButton it={it} slip={slip} ui={ui} />\n </div>\n </div>\n {it.text ? <p className=\"ss-w-bi-text\">{it.text}</p> : null}\n <StatsDisclosure it={it} ui={ui} />\n {it.disclaimer ? <p className=\"ss-w-bi-disc\">{it.disclaimer}</p> : null}\n </div>\n )\n}\n\nexport function BettingInsightList({ insights, ui, slip }: { insights: InsightVM[]; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element | null {\n if (!insights || insights.length === 0) return null\n return (\n <div className=\"ss-w-binsights\">\n {insights.map((it) => <InsightCard key={it.id} it={it} ui={ui} slip={slip} />)}\n </div>\n )\n}\n","import { useCallback, useState } from 'react'\nimport { isAddToSlipResult, type AddToSlipResult, type SlipSelection } from '@sensiblestats/widget-sdk'\nimport type { UiConfig } from '../config'\nimport { toSlipSelection, type InsightVM } from '../model'\nimport { ADD_TO_SLIP_TIMEOUT_MS, isTerminal, resultToToast, wasAdded, type SlipHandlerProps, type SlipToast } from '../slip'\nimport { Toast } from './Toast'\n\nfunction withTimeout(value: Promise<AddToSlipResult | void>): Promise<AddToSlipResult | void> {\n return Promise.race([\n value,\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('add-to-slip timed out')), ADD_TO_SLIP_TIMEOUT_MS)),\n ])\n}\n\nexport function SlipButton(\n { selection, shownOdds, marketName, slip, ui }:\n { selection: SlipSelection | null; shownOdds: string; marketName: string; slip: SlipHandlerProps; ui?: UiConfig },\n): JSX.Element | null {\n const [pending, setPending] = useState(false)\n const [settled, setSettled] = useState(false)\n const [toast, setToast] = useState<SlipToast | null>(null)\n const dismiss = useCallback(() => setToast(null), [])\n\n const handler = slip.onAddToSlip\n if (!ui || !handler || !selection) return null\n\n const onClick = async (): Promise<void> => {\n setPending(true)\n try {\n const raw = await withTimeout(Promise.resolve(handler(selection)))\n // Only a genuine void return means \"assume success\". A non-null value the\n // guard rejects is a broken contract (e.g. an operator forwarding their own\n // backend's reason string, which `any` lets past the compiler) — treating it\n // as void would report a refused bet to the user as added.\n if (raw != null && !isAddToSlipResult(raw)) throw new Error('malformed add-to-slip result')\n const result = raw ?? undefined\n setToast(resultToToast(result, shownOdds || selection.oddsDecimal.toFixed(2), ui))\n setSettled(isTerminal(result))\n if (wasAdded(result) && slip.onMarketClicked) {\n try {\n slip.onMarketClicked(marketName)\n } catch {\n // Telemetry must never change what the user sees.\n }\n }\n } catch {\n setToast({ kind: 'error', text: ui.slipFailed })\n } finally {\n setPending(false)\n }\n }\n\n return (\n <div className=\"ss-w-slip\">\n <button\n type=\"button\"\n className=\"ss-w-slip-btn\"\n disabled={pending || settled}\n onClick={onClick}\n >\n {settled ? ui.inSlip : ui.addToSlip}\n </button>\n <Toast toast={toast} onDismiss={dismiss} />\n </div>\n )\n}\n\nexport function AddToSlipButton(\n { it, slip, ui }: { it: InsightVM; slip: SlipHandlerProps; ui?: UiConfig },\n): JSX.Element | null {\n const selection = it.addToSlipEnabled ? toSlipSelection(it, slip.conversationId) : null\n return <SlipButton selection={selection} shownOdds={it.odds ?? ''} marketName={it.market} slip={slip} ui={ui} />\n}\n","import type { AddToSlipHandler, AddToSlipResult } from '@sensiblestats/widget-sdk'\nimport type { UiConfig } from './config'\n\nexport const ADD_TO_SLIP_TIMEOUT_MS = 10_000\n\nexport interface SlipToast { kind: 'success' | 'error'; text: string }\n\nexport interface SlipHandlerProps {\n onAddToSlip?: AddToSlipHandler\n conversationId?: string\n onMarketClicked?: (marketName: string) => void\n}\n\nexport function wasAdded(result: AddToSlipResult | void): boolean {\n if (!result) return true\n if (result.status === 'price_changed') return result.accepted\n return result.status === 'added'\n}\n\nexport function isTerminal(result: AddToSlipResult | void): boolean {\n if (!result) return true\n if (result.status === 'price_changed') return result.accepted\n return result.status === 'added' || result.status === 'duplicate'\n}\n\nexport function resultToToast(result: AddToSlipResult | void, shownOdds: string, ui: UiConfig): SlipToast {\n if (!result) return { kind: 'success', text: ui.slipAdded(undefined) }\n switch (result.status) {\n case 'added':\n return { kind: 'success', text: ui.slipAdded(result.slip?.selectionCount) }\n case 'duplicate':\n return { kind: 'success', text: ui.slipDuplicate }\n case 'price_changed':\n return result.accepted\n ? { kind: 'success', text: ui.slipPriceChanged(shownOdds, result.newOddsDecimal.toFixed(2)) }\n : { kind: 'error', text: ui.slipPriceNotAccepted(shownOdds, result.newOddsDecimal.toFixed(2)) }\n case 'rejected':\n if (result.reason === 'login_required') return { kind: 'error', text: ui.slipLoginRequired }\n if (result.reason === 'suspended') return { kind: 'error', text: ui.slipSuspended }\n return { kind: 'error', text: result.message ?? ui.slipFailed }\n }\n}\n","import { useEffect } from 'react'\nimport type { SlipToast } from '../slip'\n\nconst DISMISS_MS = 4000\n\nexport function Toast({ toast, onDismiss }: { toast: SlipToast | null; onDismiss: () => void }): JSX.Element | null {\n useEffect(() => {\n if (!toast) return\n const timer = setTimeout(onDismiss, DISMISS_MS)\n return () => clearTimeout(timer)\n }, [toast, onDismiss])\n\n if (!toast) return null\n return (\n <div className={`ss-w-toast ss-w-toast-${toast.kind}`} role=\"status\" aria-live=\"polite\">\n {toast.text}\n </div>\n )\n}\n","import type { UiConfig } from '../config'\n\n// One component for both card types. The market-odds row and the insight card must not drift into\n// two visual languages for the same signal, so there is exactly one place this markup exists.\nexport function OddsMovementBadge({\n previous,\n current,\n direction,\n ui,\n}: {\n previous?: string\n current: string\n direction?: 'shortened' | 'drifted'\n ui?: UiConfig\n}): JSX.Element | null {\n if (previous === undefined || direction === undefined) return null\n const directionWord =\n direction === 'shortened' ? (ui?.oddsShortened ?? 'shortened') : (ui?.oddsDrifted ?? 'drifted')\n const label =\n ui?.oddsMoved?.(previous, current, directionWord) ?? `was ${previous}, now ${current}, ${directionWord}`\n return (\n // Strikethrough is invisible to screen readers, so the whole was/now/direction sentence rides\n // on one aria-label and the visual glyphs are hidden from the accessibility tree.\n <span className=\"ss-w-move\" role=\"img\" aria-label={label}>\n <span className=\"ss-w-move-prev\" aria-hidden=\"true\">{previous}</span>\n <span className=\"ss-w-move-arrow\" aria-hidden=\"true\">{direction === 'shortened' ? '▼' : '▲'}</span>\n </span>\n )\n}\n","import { useState } from 'react'\nimport type { MarketOddsVM, MarketOddsRowVM } from '../model'\nimport { marketOddsRowToSlipSelection } from '../model'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { SlipButton } from './AddToSlipButton'\nimport { OddsMovementBadge } from './OddsMovementBadge'\n\nfunction OddsRow({ vm, row, ui, slip }: { vm: MarketOddsVM; row: MarketOddsRowVM; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null\n return (\n <div className=\"ss-w-mo-row\">\n <span className=\"ss-w-mo-sel\">{row.selection}</span>\n <OddsMovementBadge previous={row.previousOdds} current={row.odds} direction={row.movementDirection} ui={ui} />\n <span className=\"ss-w-mo-price\">{row.odds}</span>\n <SlipButton selection={selection} shownOdds={row.odds} marketName={vm.market} slip={slip} ui={ui} />\n </div>\n )\n}\n\nfunction MarketOddsCard({ vm, ui, slip }: { vm: MarketOddsVM; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n const [open, setOpen] = useState(false)\n return (\n <div className=\"ss-w-mocard\">\n <div className=\"ss-w-mo-head\">\n <span className=\"ss-w-mo-market\">{vm.market}</span>\n <span className=\"ss-w-mo-tag\">{ui?.marketPrices ?? 'Market prices'}</span>\n </div>\n {(vm.fixture || vm.competition) ? (\n <div className=\"ss-w-mo-fixture\">\n {vm.fixture ? <span>{vm.fixture}</span> : null}\n {vm.competition ? <span className=\"ss-w-mo-comp\">{vm.competition}</span> : null}\n </div>\n ) : null}\n <div className=\"ss-w-mo-rows\">\n {vm.mainRows.map((row) => <OddsRow key={row.key} vm={vm} row={row} ui={ui} slip={slip} />)}\n {open ? vm.moreRows.map((row) => <OddsRow key={row.key} vm={vm} row={row} ui={ui} slip={slip} />) : null}\n </div>\n {vm.moreRows.length > 0 ? (\n <button type=\"button\" className=\"ss-w-bi-toggle\" aria-expanded={open} onClick={() => setOpen((v) => !v)}>\n <span>{open ? ui?.hideLines ?? 'Hide lines' : `${ui?.moreLines ?? 'More lines'} (${vm.moreRows.length})`}</span>\n <span className={`ss-w-bi-chev${open ? ' ss-w-bi-chev-up' : ''}`} aria-hidden=\"true\" />\n </button>\n ) : null}\n {vm.bookmaker ? (\n <div className=\"ss-w-mo-foot\">\n <span>{vm.bookmaker}</span>\n </div>\n ) : null}\n {vm.disclaimer ? <p className=\"ss-w-bi-disc\">{vm.disclaimer}</p> : null}\n </div>\n )\n}\n\nexport function MarketOddsCardList({ cards, ui, slip }: { cards: MarketOddsVM[]; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element | null {\n if (!cards || cards.length === 0) return null\n return (\n <div className=\"ss-w-mocards\">\n {cards.map((vm) => <MarketOddsCard key={vm.id} vm={vm} ui={ui} slip={slip} />)}\n </div>\n )\n}\n","import type { UiConfig } from '../config'\nimport type { OddsMovementVM } from '../model'\nimport { CHART_VIEW_H, CHART_VIEW_W } from '../chart'\nimport { OddsMovementBadge } from './OddsMovementBadge'\n\nfunction directionWord(vm: OddsMovementVM, ui?: UiConfig): string {\n if (vm.direction === 'shortened') return ui?.oddsShortened ?? 'shortened'\n if (vm.direction === 'drifted') return ui?.oddsDrifted ?? 'drifted'\n return ''\n}\n\nfunction OddsMovementCard({ vm, ui }: { vm: OddsMovementVM; ui?: UiConfig }): JSX.Element {\n const word = directionWord(vm, ui)\n const drift = word ? `, ${word}` : ''\n const aria = ui?.chartAria\n ? ui.chartAria(vm.opening, vm.current, word, vm.windowHours)\n : `Price movement over the last ${vm.windowHours} hours: opened at ${vm.opening}, currently ${vm.current}${drift}.`\n\n return (\n <div className=\"ss-w-omcard\">\n <div className=\"ss-w-om-head\">\n <span className=\"ss-w-om-market\">{vm.market}</span>\n <span className=\"ss-w-om-tag\">{ui?.priceMovement ?? 'Price movement'}</span>\n </div>\n {vm.fixture ? (\n <div className=\"ss-w-om-fixture\">\n <span>{vm.fixture}</span>\n {vm.competition ? <span className=\"ss-w-om-comp\">{vm.competition}</span> : null}\n </div>\n ) : null}\n <div className=\"ss-w-om-sel\">{vm.selection}</div>\n <OddsMovementBadge previous={vm.opening} current={vm.current} direction={vm.direction} ui={ui} />\n\n {vm.geometry === null ? (\n <div className=\"ss-w-om-empty\">\n {vm.observationCount === 1\n ? ui?.singlePricePoint ?? 'Only one price recorded so far for this selection.'\n : ui?.notEnoughHistory ?? 'No price history recorded yet for this selection.'}\n </div>\n ) : (\n <svg\n className=\"ss-w-om-chart\"\n viewBox={vm.geometry.viewBox}\n width=\"100%\"\n role=\"img\"\n aria-label={aria}\n >\n {vm.geometry.gridlines.map((g) => (\n <g key={g.price}>\n <line className=\"ss-w-om-grid\" x1={40} y1={g.y} x2={CHART_VIEW_W - 8} y2={g.y} />\n <text className=\"ss-w-om-ylab\" x={34} y={g.y + 3} textAnchor=\"end\">{g.price.toFixed(2)}</text>\n </g>\n ))}\n <path className=\"ss-w-om-line\" d={vm.geometry.path} fill=\"none\" />\n {vm.geometry.markers.map((m, i) => (\n <circle key={i} className=\"ss-w-om-dot\" cx={m.x} cy={m.y} r={2.5} />\n ))}\n {ui?.chartTimeLabel ? (\n <>\n <text className=\"ss-w-om-xlab\" x={40} y={CHART_VIEW_H - 8} textAnchor=\"start\">\n {ui.chartTimeLabel(vm.geometry.startMs)}\n </text>\n <text className=\"ss-w-om-xlab\" x={CHART_VIEW_W - 8} y={CHART_VIEW_H - 8} textAnchor=\"end\">\n {ui.chartTimeLabel(vm.geometry.endMs)}\n </text>\n </>\n ) : (\n <text className=\"ss-w-om-xlab\" x={40} y={CHART_VIEW_H - 8}>\n {ui?.movementWindow ? ui.movementWindow(vm.windowHours) : `Last ${vm.windowHours}h`}\n </text>\n )}\n </svg>\n )}\n\n <div className=\"ss-w-om-foot\">\n <span>{ui?.openingLabel ?? 'Opening'} <b>{vm.opening}</b></span>\n <span>{ui?.currentLabel ?? 'Current'} <b>{vm.current}</b></span>\n </div>\n {vm.bookmaker ? (\n <div className=\"ss-w-om-foot\">\n <span>{vm.bookmaker}</span>\n </div>\n ) : null}\n {vm.excludedCount > 0 ? (\n <div className=\"ss-w-om-excl\">\n {ui?.excludedSuspended ? ui.excludedSuspended(vm.excludedCount) : `${vm.excludedCount} suspended price(s) excluded from this chart.`}\n </div>\n ) : null}\n {vm.isSuspended ? (\n <div className=\"ss-w-om-susp\">{ui?.selectionSuspended ?? 'This selection is not currently available to bet.'}</div>\n ) : null}\n {vm.disclaimer ? <div className=\"ss-w-om-disc\">{vm.disclaimer}</div> : null}\n </div>\n )\n}\n\nexport function OddsMovementCardList({ cards, ui }: { cards: OddsMovementVM[]; ui?: UiConfig }): JSX.Element | null {\n if (!cards || cards.length === 0) return null\n return (\n <div className=\"ss-w-omcards\">\n {cards.map((vm) => <OddsMovementCard key={vm.id} vm={vm} ui={ui} />)}\n </div>\n )\n}\n","import type { ActionVM } from '../model'\n\nexport function ActionButtons({ actions, loading, disabled, onAct }: { actions: ActionVM[]; loading: boolean; disabled?: boolean; onAct: (action: ActionVM) => void }): JSX.Element | null {\n if (actions.length === 0 && !loading) return null\n return (\n <div className=\"ss-w-actions\">\n {actions.map((a, i) => (\n <button key={`${a.label}-${i}`} type=\"button\" className=\"ss-w-abtn\" disabled={disabled} onClick={() => onAct(a)}>{a.label}</button>\n ))}\n {actions.length === 0 && loading ? (\n <>\n <span className=\"ss-w-abtn-shimmer\" />\n <span className=\"ss-w-abtn-shimmer\" />\n </>\n ) : null}\n </div>\n )\n}\n","import type { Message } from '../reducer'\nimport type { ActionVM } from '../model'\nimport type { UiConfig } from '../config'\nimport type { SlipHandlerProps } from '../slip'\nimport { Markdown } from './Markdown'\nimport { EntityCardList } from './EntityCardList'\nimport { BettingInsightList } from './BettingInsightList'\nimport { MarketOddsCardList } from './MarketOddsCardList'\nimport { OddsMovementCardList } from './OddsMovementCard'\nimport { ActionButtons } from './ActionButtons'\n\nexport function ChatMessage({ message, disabled, onAct, ui, slip }: { message: Message; disabled: boolean; onAct: (a: ActionVM) => void; ui?: UiConfig; slip: SlipHandlerProps }): JSX.Element {\n if (message.role === 'user') {\n return <div className=\"ss-w-msg ss-w-user\"><div className=\"ss-w-bubble\">{message.text}</div></div>\n }\n return (\n <div className=\"ss-w-msg ss-w-bot\">\n {message.text ? <Markdown text={message.text} /> : null}\n <EntityCardList cards={message.cards} disabled={disabled} showLessLabel={ui?.showLess} showMoreLabel={ui?.showMore} />\n <BettingInsightList insights={message.insights} ui={ui} slip={slip} />\n <MarketOddsCardList cards={message.marketOdds} ui={ui} slip={slip} />\n <OddsMovementCardList cards={message.oddsMovement} ui={ui} />\n <ActionButtons actions={message.actions} loading={false} disabled={disabled} onAct={onAct} />\n </div>\n )\n}\n","import type { ChipVM } from '../model'\n\nexport function IntentChips({ chips, onPick }: { chips: ChipVM[]; onPick: (text: string) => void }): JSX.Element | null {\n if (chips.length === 0) return null\n return (\n <div className=\"ss-w-chips\">\n {chips.map((c, i) => (\n <button key={`${c.text}-${i}`} type=\"button\" className=\"ss-w-chip\" onClick={() => onPick(c.text)}>{c.text}</button>\n ))}\n </div>\n )\n}\n","// Distance (px) from the bottom within which the list is still considered\n// \"pinned\" — small enough that a user reading earlier content isn't counted\n// as pinned, large enough to absorb sub-pixel/rounding drift while streaming.\nexport const PIN_THRESHOLD = 48\n\n/**\n * True when the scroll container is at (or within PIN_THRESHOLD of) its bottom.\n * Used to decide whether new content should auto-scroll: we follow the stream\n * only while the user is already at the bottom, so late arrivals (e.g. suggested\n * actions) never yank a user who has scrolled up to read.\n */\nexport function isPinnedToBottom(el: Pick<HTMLElement, 'scrollHeight' | 'scrollTop' | 'clientHeight'>, threshold = PIN_THRESHOLD): boolean {\n return el.scrollHeight - el.scrollTop - el.clientHeight <= threshold\n}\n","import { useState, type KeyboardEvent } from 'react'\nimport { SendIcon } from './Icons'\n\nexport function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = 'Stop response', sendLabel = 'Send message' }: { placeholder: string; streaming: boolean; onSend: (t: string) => void; onStop: () => void; stopLabel?: string; sendLabel?: string }): JSX.Element {\n const [value, setValue] = useState('')\n const submit = () => { const t = value.trim(); if (!t) return; onSend(t); setValue('') }\n const onKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); submit() }\n }\n return (\n <div className=\"ss-w-input\">\n <textarea className=\"ss-w-textarea\" rows={1} placeholder={placeholder} value={value} disabled={streaming} onChange={(e) => setValue(e.target.value)} onKeyDown={onKeyDown} />\n {streaming ? (\n <button type=\"button\" className=\"ss-w-send ss-w-stop\" aria-label={stopLabel} onClick={onStop}><span className=\"ss-w-stop-glyph\" /></button>\n ) : (\n <button type=\"button\" className=\"ss-w-send\" aria-label={sendLabel} onClick={submit}><SendIcon /></button>\n )}\n </div>\n )\n}\n","// AUTO-GENERATED by scripts/gen-css.mjs from widget.css. Do not edit.\nexport const WIDGET_CSS = \".ss-w-root { all: revert; }\\n.ss-w-root, .ss-w-root * { box-sizing: border-box; margin: 0; padding: 0; }\\n.ss-w-root {\\n --ss-w-accent: #17936a;\\n --ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #14181d; --ss-w-faint: #6b7580; --ss-w-line: #e4e8ec;\\n --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\\n --ss-w-pos: #1aa563; --ss-w-neg: #e0524b;\\n --ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;\\n font-family: -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", Roboto, Helvetica, Arial, sans-serif;\\n font-size: 13px; line-height: 1.5; color: var(--ss-w-ink);\\n}\\n@media (prefers-color-scheme: dark) {\\n .ss-w-root[data-ss-w-theme=\\\"auto\\\"] {\\n --ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\\n --ss-w-pos: #37c891; --ss-w-neg: #f0655d;\\n }\\n}\\n.ss-w-root[data-ss-w-theme=\\\"dark\\\"] {\\n --ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;\\n --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;\\n --ss-w-pos: #37c891; --ss-w-neg: #f0655d;\\n}\\n.ss-w-root[data-ss-w-theme=\\\"light\\\"] {\\n --ss-w-accent: #17936a; --ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;\\n --ss-w-ink: #14181d; --ss-w-faint: #6b7580;\\n --ss-w-line: #e4e8ec; --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;\\n}\\n\\n/* launcher */\\n.ss-w-fab-wrap { position: fixed; bottom: var(--ss-w-offset-y); z-index: 2147483000; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }\\n.ss-w-root[data-ss-w-pos=\\\"right\\\"] .ss-w-fab-wrap { right: var(--ss-w-offset-x); }\\n.ss-w-root[data-ss-w-pos=\\\"left\\\"] .ss-w-fab-wrap { left: var(--ss-w-offset-x); align-items: flex-start; }\\n.ss-w-fab { width: 56px; height: 56px; border: none; border-radius: 50%; background: var(--ss-w-nav); color: #fff; cursor: pointer; display: grid; place-items: center; box-shadow: 0 6px 20px rgba(0,0,0,.28); }\\n.ss-w-fab-mark { width: 30px; height: 30px; display: block; }\\n.ss-w-greeting { max-width: 240px; display: flex; align-items: flex-start; background: var(--ss-w-panel); color: var(--ss-w-ink); border: 1px solid var(--ss-w-line); border-radius: 12px; box-shadow: 0 4px 14px rgba(0,0,0,.14); }\\n.ss-w-greeting-body { flex: 1; min-width: 0; text-align: left; background: none; border: none; color: inherit; font: inherit; cursor: pointer; padding: 9px 4px 9px 12px; }\\n.ss-w-greeting-x { flex: none; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 17px; line-height: 1; padding: 7px 9px 0 2px; }\\n\\n/* panel */\\n.ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(400px, calc(100vw - 40px)); height: min(620px, calc(100vh - 120px)); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.24); }\\n.ss-w-root[data-ss-w-pos=\\\"right\\\"] .ss-w-panel { right: var(--ss-w-offset-x); }\\n.ss-w-root[data-ss-w-pos=\\\"left\\\"] .ss-w-panel { left: var(--ss-w-offset-x); }\\n@media (max-width: 639px) {\\n /* Fill via inset with no explicit height (like the site's working panel) so the\\n input stays visible when the mobile keyboard/URL-bar shrinks the viewport. The\\n position-specific selectors override the right/left offsets set above. */\\n .ss-w-root[data-ss-w-pos=\\\"right\\\"] .ss-w-panel,\\n .ss-w-root[data-ss-w-pos=\\\"left\\\"] .ss-w-panel { inset: 0; width: auto; height: auto; border: none; border-radius: 0; }\\n}\\n.ss-w-header { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--ss-w-line); }\\n.ss-w-header-mark { width: 18px; height: 18px; display: block; }\\n.ss-w-header-title { font-weight: 660; }\\n.ss-w-close { margin-left: auto; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 16px; display: grid; place-items: center; }\\n\\n/* messages */\\n.ss-w-list { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 12px; }\\n.ss-w-msg { display: flex; }\\n.ss-w-user { justify-content: flex-end; }\\n.ss-w-user .ss-w-bubble { background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 14px; padding: 8px 12px; max-width: 80%; }\\n.ss-w-bot { flex-direction: column; gap: 8px; }\\n.ss-w-status { font-size: 11px; color: var(--ss-w-faint); font-style: italic; }\\n.ss-w-error { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #c0392b; }\\n.ss-w-retry { background: none; border: 1px solid currentColor; border-radius: 10px; padding: 2px 8px; cursor: pointer; color: inherit; }\\n\\n/* markdown */\\n.ss-w-md { display: flex; flex-direction: column; gap: 8px; }\\n.ss-w-md :where(p, ul, ol, table, pre, blockquote, h1, h2, h3, h4) { margin: 0; }\\n.ss-w-md > *:first-child { margin-top: 0; }\\n.ss-w-md > *:last-child { margin-bottom: 0; }\\n.ss-w-md-ul { list-style: disc outside; padding-left: 18px; }\\n.ss-w-md-ol { list-style: decimal outside; padding-left: 18px; }\\n.ss-w-md-ul li::marker, .ss-w-md-ol li::marker { color: var(--ss-w-accent); }\\n.ss-w-md-link { color: var(--ss-w-accent); text-decoration: underline; }\\n.ss-w-table-wrap { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }\\n.ss-w-md-table { border-collapse: collapse; width: max-content; min-width: 100%; font-variant-numeric: tabular-nums; }\\n.ss-w-md-table td, .ss-w-md-table th { border: 1px solid var(--ss-w-line); padding: 4px 8px; text-align: left; white-space: nowrap; }\\n.ss-w-md-table th { background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); font-weight: 700; }\\n.ss-w-md-table tbody tr:nth-child(even) { background: var(--ss-w-bubble); }\\n.ss-w-md-code { background: var(--ss-w-bubble); border-radius: 5px; padding: 1px 5px; font-family: ui-monospace, monospace; }\\n\\n/* entity cards */\\n.ss-w-cards { display: flex; flex-direction: column; gap: 8px; }\\n\\n/* Identity Hero: crest-led identity block | tabbed stats panel */\\n.ss-w-ecard { display: grid; grid-template-columns: 112px 1fr; align-items: stretch; width: 100%; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; text-align: left; }\\n\\n.ss-w-ecard-id { display: flex; flex-direction: column; align-items: center; gap: 7px; text-align: center; padding: 13px 10px; border-right: 1px solid var(--ss-w-line); background: linear-gradient(158deg, var(--ss-w-bubble), color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-bubble))); }\\n.ss-w-ecard-idtext { display: flex; flex-direction: column; gap: 1px; min-width: 0; max-width: 100%; }\\n.ss-w-thumb { width: 54px; height: 54px; flex: none; border-radius: 50%; display: grid; place-items: center; font-size: 16px; font-weight: 700; color: #fff; background-color: var(--ss-w-nav); background-size: cover; background-position: center; box-shadow: 0 1px 3px rgba(0,0,0,.14); }\\n.ss-w-thumb.ss-w-team { border-radius: 12px; }\\n.ss-w-ecard[data-kind=\\\"player\\\"] .ss-w-thumb { background-color: var(--ss-w-accent); }\\n.ss-w-nm { font-weight: 680; line-height: 1.15; overflow-wrap: anywhere; }\\n.ss-w-sub { font-size: 11px; color: var(--ss-w-faint); overflow-wrap: anywhere; }\\n\\n/* bare card (no stat scopes): simple avatar + name row */\\n.ss-w-ecard-bare { display: flex; align-items: center; }\\n.ss-w-ecard-bare .ss-w-ecard-id { flex-direction: row; text-align: left; gap: 11px; background: none; border-right: none; padding: 10px 12px; }\\n.ss-w-ecard-bare .ss-w-thumb { width: 40px; height: 40px; font-size: 13px; box-shadow: none; }\\n.ss-w-ecard-bare .ss-w-thumb.ss-w-team { border-radius: 10px; }\\n\\n.ss-w-ecard-body { min-width: 0; padding: 9px 12px 12px; display: flex; flex-direction: column; }\\n\\n/* tab strip seated on the stats panel's top edge; active tab underlined in accent */\\n.ss-w-ecard-tabs { display: flex; align-items: stretch; gap: 3px; border-bottom: 1px solid var(--ss-w-line); margin-bottom: 9px; flex-wrap: wrap; }\\n.ss-w-ecard-tab { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 620; color: var(--ss-w-faint); background: none; border: none; cursor: pointer; padding: 5px 8px 8px; margin-bottom: -1px; border-bottom: 2px solid transparent; }\\n.ss-w-ecard-tab[aria-selected=\\\"true\\\"] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }\\n.ss-w-ecard-tabs-static { align-items: center; flex-wrap: nowrap; }\\n.ss-w-ecard-lead { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 640; color: var(--ss-w-ink); padding: 4px 2px 8px; min-width: 0; flex: 1; }\\n.ss-w-ecard-lead-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.ss-w-ecard-crest { width: 15px; height: 15px; flex: none; display: block; border-radius: 4px; background-size: cover; background-position: center; }\\n.ss-w-ecard-season { flex: none; margin-left: auto; align-self: center; margin-bottom: 5px; font-size: 10.5px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 13%, var(--ss-w-panel)); border-radius: 999px; padding: 3px 9px; white-space: nowrap; }\\n.ss-w-ecard-tabs-static .ss-w-ecard-season { margin-bottom: 4px; }\\n\\n.ss-w-ecard-stats { display: flex; flex-direction: column; gap: 4px; }\\n.ss-w-ecard-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; }\\n.ss-w-ecard-rlabel { font-size: 9.5px; text-transform: uppercase; letter-spacing: .045em; color: var(--ss-w-faint); font-weight: 600; }\\n.ss-w-ecard-rval { justify-self: end; font-size: 15px; font-weight: 720; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }\\n.ss-w-form { justify-self: end; display: flex; height: 6px; width: 48px; border-radius: 4px; overflow: hidden; gap: 2px; }\\n.ss-w-form span { display: block; border-radius: 2px; }\\n.ss-w-form-w { background: var(--ss-w-pos); }\\n.ss-w-form-d { background: var(--ss-w-faint); }\\n.ss-w-form-l { background: var(--ss-w-neg); }\\n\\n.ss-w-cards-more { align-self: flex-start; font-size: 11.5px; font-weight: 560; color: var(--ss-w-accent); background: none; border: none; cursor: pointer; padding: 3px 2px; }\\n.ss-w-cards-more:hover:not(:disabled) { text-decoration: underline; }\\n.ss-w-cards-more:disabled { opacity: .5; cursor: default; }\\n\\n/* betting insights */\\n.ss-w-binsights { display: flex; flex-direction: column; gap: 7px; }\\n.ss-w-binsight { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }\\n.ss-w-bi-status { display: flex; align-items: center; gap: 6px; min-width: 0; }\\n.ss-w-bi-fixture { font-size: 11px; color: var(--ss-w-ink); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\\n.ss-w-bi-comp { font-size: 10.5px; color: var(--ss-w-faint); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\\n.ss-w-bi-live { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #fff; background: #c0392b; border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; gap: 4px; flex: none; }\\n.ss-w-bi-live-dot { width: 5px; height: 5px; border-radius: 50%; background: #fff; }\\n.ss-w-bi-head { display: flex; align-items: flex-start; gap: 10px; }\\n.ss-w-bi-mkt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }\\n.ss-w-bi-market { font-size: 15px; font-weight: 700; line-height: 1.25; color: var(--ss-w-ink); }\\n.ss-w-bi-sel { font-size: 12px; line-height: 1.3; color: var(--ss-w-faint); }\\n.ss-w-bi-match { display: flex; flex-direction: column; gap: 1px; min-width: 0; margin-top: 5px; }\\n.ss-w-bi-action { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: stretch; gap: 6px; }\\n.ss-w-bi-action .ss-w-slip > button { flex: 1; text-align: center; }\\n/* The action column is narrow; let its toast size to its own text and anchor to the card's right edge instead of being clipped to the button width. */\\n.ss-w-bi-action .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }\\n.ss-w-bi-odds { flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 1px; background: color-mix(in srgb, var(--ss-w-accent) 12%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); border-radius: 10px; padding: 4px 11px; min-width: 62px; }\\n.ss-w-bi-odds-cap { font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }\\n.ss-w-bi-odds b { font-size: 19px; font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.1; }\\n.ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }\\n.ss-w-bi-text { font-size: 12px; line-height: 1.45; color: var(--ss-w-ink); }\\n.ss-w-bi-stats { display: flex; flex-direction: column; gap: 8px; }\\n.ss-w-bi-toggle { align-self: flex-start; display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 11.5px; font-weight: 600; padding: 2px 0; cursor: pointer; }\\n.ss-w-bi-toggle:hover { text-decoration: underline; }\\n.ss-w-bi-chev { width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s ease; }\\n.ss-w-bi-chev-up { transform: translateY(1px) rotate(-135deg); }\\n.ss-w-bi-rows { display: flex; flex-direction: column; }\\n.ss-w-bi-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 5px 0; border-top: 1px solid var(--ss-w-line); }\\n.ss-w-bi-row:first-child { border-top: none; }\\n.ss-w-bi-row-lbl { font-size: 11.5px; color: var(--ss-w-faint); min-width: 0; }\\n.ss-w-bi-row-num { font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; font-size: 13px; flex: none; color: var(--ss-w-ink); }\\n.ss-w-bi-disc { font-size: 10px; font-style: italic; color: var(--ss-w-faint); }\\n.ss-w-bi-scoped { display: flex; flex-direction: column; gap: 8px; }\\n.ss-w-bi-scopes { display: inline-flex; align-items: center; gap: 2px; flex-wrap: wrap; align-self: flex-start; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 9px; padding: 2px; }\\n.ss-w-bi-chip { font-size: 11px; font-weight: 600; border: none; border-radius: 7px; padding: 4px 10px; color: var(--ss-w-faint); background: none; cursor: pointer; }\\n.ss-w-bi-chip[aria-pressed=\\\"true\\\"] { color: var(--ss-w-ink); background: var(--ss-w-panel); box-shadow: 0 1px 2px rgba(0,0,0,.08); }\\n\\n/* market odds card */\\n.ss-w-mocards { display: flex; flex-direction: column; gap: 7px; }\\n.ss-w-mocard { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }\\n.ss-w-mo-head { display: flex; align-items: center; gap: 8px; }\\n.ss-w-mo-market { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }\\n.ss-w-mo-tag { margin-left: auto; flex: none; font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); border: 1px solid var(--ss-w-line); border-radius: 8px; padding: 2px 7px; }\\n.ss-w-mo-fixture { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ss-w-faint); min-width: 0; }\\n.ss-w-mo-comp { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.ss-w-mo-rows { display: flex; flex-direction: column; gap: 4px; }\\n.ss-w-mo-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--ss-w-line); }\\n.ss-w-mo-row:last-child { border-bottom: none; }\\n.ss-w-mo-sel { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }\\n.ss-w-mo-price { margin-left: auto; font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 700; color: var(--ss-w-accent); }\\n/* Movement: BOTH directions share --ss-w-faint on purpose. Green-good/red-bad would frame a\\n shortening price as a discount, which inverts what it actually means for the bettor. */\\n.ss-w-move { display: inline-flex; align-items: baseline; gap: 4px; color: var(--ss-w-faint); }\\n.ss-w-move-prev { font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 12px; text-decoration: line-through; }\\n.ss-w-move-arrow { font-size: 9px; line-height: 1; }\\n/* margin-left:auto is row layout, not badge styling -- it belongs to the market-odds row, which is\\n a flex row, and must NOT follow the badge into the insight card's odds column. */\\n.ss-w-mo-row .ss-w-move { margin-left: auto; }\\n.ss-w-mo-row .ss-w-move + .ss-w-mo-price { margin-left: 0; }\\n.ss-w-mo-row .ss-w-slip { margin: 0; }\\n.ss-w-mo-foot { display: flex; align-items: center; gap: 8px; font-size: 10.5px; color: var(--ss-w-faint); }\\n\\n/* odds movement card */\\n.ss-w-omcards { display: flex; flex-direction: column; gap: 7px; }\\n.ss-w-omcard { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }\\n.ss-w-om-head { display: flex; align-items: center; gap: 8px; }\\n.ss-w-om-market { font-size: 13px; font-weight: 700; color: var(--ss-w-ink); }\\n.ss-w-om-tag { margin-left: auto; flex: none; font-size: 9px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); border: 1px solid var(--ss-w-line); border-radius: 8px; padding: 2px 7px; }\\n.ss-w-om-fixture { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ss-w-faint); min-width: 0; }\\n.ss-w-om-comp { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\\n.ss-w-om-sel { font-size: 12.5px; font-weight: 600; color: var(--ss-w-ink); }\\n.ss-w-om-chart { display: block; width: 100%; height: auto; }\\n/* Single neutral accent in BOTH directions, deliberately. Colouring a shortening price green\\n frames it as a discount, which inverts what it means for the bettor -- the same reason\\n .ss-w-move keeps both directions on --ss-w-faint. */\\n.ss-w-om-line { stroke: var(--ss-w-accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }\\n.ss-w-om-dot { fill: var(--ss-w-accent); }\\n.ss-w-om-grid { stroke: var(--ss-w-line); stroke-width: 1; }\\n.ss-w-om-ylab, .ss-w-om-xlab { fill: var(--ss-w-faint); font-size: 9px; font-family: ui-monospace, monospace; }\\n.ss-w-om-empty { font-size: 11.5px; color: var(--ss-w-faint); padding: 6px 0; }\\n.ss-w-om-foot { display: flex; align-items: center; gap: 14px; font-size: 11.5px; color: var(--ss-w-faint); }\\n.ss-w-om-foot b { font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 13px; color: var(--ss-w-ink); }\\n.ss-w-om-excl { font-size: 10.5px; color: var(--ss-w-faint); }\\n.ss-w-om-susp { font-size: 11px; font-weight: 600; color: #c0392b; }\\n.ss-w-om-disc { font-size: 10px; font-style: italic; color: var(--ss-w-faint); }\\n\\n/* action buttons */\\n.ss-w-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }\\n.ss-w-abtn { font-size: 12px; font-weight: 560; color: var(--ss-w-accent); background: var(--ss-w-panel); border: 1px solid var(--ss-w-accent); border-radius: 16px; padding: 6px 12px; cursor: pointer; }\\n.ss-w-abtn:disabled { opacity: .5; cursor: default; }\\n.ss-w-abtn-shimmer { width: 140px; height: 30px; border-radius: 16px; background: linear-gradient(90deg, var(--ss-w-bubble), var(--ss-w-line), var(--ss-w-bubble)); background-size: 200% 100%; animation: ss-w-shimmer 1.2s infinite; }\\n@keyframes ss-w-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }\\n\\n/* intent chips */\\n.ss-w-chips { display: flex; flex-wrap: wrap; gap: 6px; }\\n.ss-w-chip { font-size: 11.5px; font-weight: 550; color: var(--ss-w-ink); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 14px; padding: 5px 11px; cursor: pointer; }\\n\\n/* input */\\n.ss-w-input { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--ss-w-line); }\\n.ss-w-textarea { flex: 1; resize: none; border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 8px 10px; font: inherit; color: inherit; background: var(--ss-w-panel); max-height: 96px; }\\n.ss-w-textarea:disabled { opacity: .55; cursor: not-allowed; }\\n/* iOS Safari zooms the page when a focused field's font-size is < 16px. Bump it\\n on touch devices only, so the desktop 13px design is unchanged. */\\n@media (pointer: coarse) {\\n .ss-w-textarea { font-size: 16px; }\\n}\\n.ss-w-send { width: 36px; height: 36px; flex: none; border: none; border-radius: 50%; background: var(--ss-w-accent); color: #fff; cursor: pointer; display: grid; place-items: center; font-size: 16px; }\\n.ss-w-stop-glyph { width: 11px; height: 11px; background: currentColor; border-radius: 2px; }\\n\\n/* add to slip */\\n.ss-w-slip { position: relative; display: flex; }\\n.ss-w-slip-btn { font-size: 11.5px; font-weight: 620; color: var(--ss-w-cta-ink); background: var(--ss-w-cta); border: 1px solid var(--ss-w-cta); border-radius: 14px; padding: 5px 12px; cursor: pointer; }\\n.ss-w-slip-btn:disabled { opacity: .6; cursor: default; background: var(--ss-w-bubble); color: var(--ss-w-faint); border-color: var(--ss-w-line); }\\n.ss-w-toast { position: absolute; top: calc(100% + 6px); left: 0; z-index: 1; max-width: 100%; font-size: 11px; font-weight: 560; border-radius: 10px; padding: 5px 10px; overflow-wrap: anywhere; box-shadow: 0 4px 14px rgba(0,0,0,.14); }\\n.ss-w-toast-success { color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); }\\n.ss-w-toast-error { color: #c0392b; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }\\n\\n@media (prefers-reduced-motion: reduce) {\\n .ss-w-abtn-shimmer { animation: none; }\\n}\\n\"\n"],"mappings":"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","names":["useEffect","useMemo","useRef","WidgetSdkError","WidgetSdkError","jsx","jsx","jsxs","useEffect","useState","jsx","jsxs","useEffect","useRef","jsx","jsx","jsxs","useState","useCallback","useState","useEffect","jsx","jsx","jsxs","useState","useCallback","jsx","jsxs","directionWord","jsx","jsxs","StatRows","useState","useState","jsx","jsxs","useState","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","useRef","useEffect","useState","jsx","jsxs","useState","jsx","jsxs","useState","useEffect","jsx","useMemo","useRef","useEffect"]}