@flytedan/flytebot-design-system 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/actions/Button.tsx","../src/components/actions/IconButton.tsx","../src/components/actions/Popover.tsx","../src/components/actions/SegmentedControl.tsx","../src/components/surfaces/Card.tsx","../src/components/surfaces/Collapsible.tsx","../src/components/surfaces/Drawer.tsx","../src/components/surfaces/Modal.tsx","../src/components/loading/LoadingRegion.tsx","../src/components/loading/ProgressBar.tsx","../src/components/loading/Skeleton.tsx","../src/components/loading/Spinner.tsx","../src/components/navigation/SidebarNav.tsx","../src/components/navigation/FlytedeskBrand.tsx","../src/components/navigation/Tabs.tsx","../src/components/navigation/Topbar.tsx","../src/components/feedback/Avatar.tsx","../src/components/feedback/Badge.tsx","../src/components/feedback/EmptyState.tsx","../src/components/feedback/Flag.tsx","../src/components/feedback/KeyHint.tsx","../src/components/feedback/Tag.tsx","../src/components/feedback/Toast.tsx","../src/components/feedback/Tooltip.tsx","../src/components/data/Clamp.tsx","../src/components/data/CsiBadge.tsx","../src/components/data/DataTable.tsx","../src/components/data/FilterBar.tsx","../src/components/data/StatTile.tsx","../src/components/data/CodeBlock.tsx","../src/components/data/Markdown.tsx","../src/components/data/Meter.tsx","../src/components/data/Pagination.tsx","../src/components/data/RelativeTime.tsx","../src/components/data/SegmentedMeter.tsx","../src/kits/files.ts","../src/components/data/SortMenu.tsx","../src/components/data/StepList.tsx","../src/components/data/VirtualList.tsx","../src/components/data/EntityRow.tsx","../src/components/data/TransferList.tsx","../src/components/forms/Input.tsx","../src/components/forms/SearchField.tsx","../src/components/forms/Checkbox.tsx","../src/components/forms/Radio.tsx","../src/components/forms/Switch.tsx","../src/components/forms/Textarea.tsx","../src/components/forms/NumberInput.tsx","../src/components/forms/Select.tsx","../src/components/forms/DatePicker.tsx","../src/components/forms/TimePicker.tsx","../src/components/forms/Slider.tsx","../src/components/forms/RangeSlider.tsx","../src/components/forms/Dropzone.tsx","../src/components/forms/FileGrid.tsx","../src/components/forms/MarkdownEditor.tsx","../src/components/platform/AccountMenu.tsx","../src/kits/session.ts","../src/components/platform/ApiSpecBrowser.tsx","../src/components/platform/ProfilePage.tsx","../src/components/platform/RoadmapTimeline.tsx","../src/kits/runtime.ts","../src/components/platform/ComingSoon.tsx","../src/components/platform/Gate.tsx","../src/components/platform/ModeSwitch.tsx","../src/components/planner/ChannelMeta.tsx","../src/components/planner/SaturationDistribution.tsx","../src/components/planner/MixGap.tsx","../src/components/planner/ChannelContribution.tsx","../src/components/planner/BudgetReallocator.tsx","../src/components/planner/SurroundSound.tsx","../src/components/chat/AgentChatPanel.tsx","../src/components/chat/chatEngine.ts","../src/components/chat/ChatTranscript.tsx","../src/components/chat/ChatTurn.tsx","../src/components/chat/ChatComposer.tsx","../src/components/chat/ChatSessionBar.tsx","../src/kits/query.ts","../src/kits/mockJobs.ts","../src/kits/versions.ts"],"sourcesContent":["export * from \"./components/actions\";\nexport * from \"./components/surfaces\";\nexport * from \"./components/loading\";\nexport * from \"./components/navigation\";\nexport * from \"./components/feedback\";\nexport * from \"./components/data\";\nexport * from \"./components/forms\";\nexport * from \"./components/platform\";\nexport * from \"./components/planner\";\nexport * from \"./components/chat\";\n\nexport * from \"./kits\";\n\n// \"Flag\" is exported by both components/feedback (the callout UI component) and\n// kits/session (the feature-flag record interface) — an explicit export of the\n// component here resolves the `export *` ambiguity in the component's favor, and\n// the kit's type is still reachable under a distinct name.\nexport { Flag } from \"./components/feedback\";\nexport type { Flag as SessionFlag } from \"./kits/session\";\n","import * as React from \"react\";\n\nconst VARIANTS: Record<string, string> = {\n primary: \"fd-btn-primary\",\n brandSoft: \"fd-btn-brandsoft\",\n secondary: \"fd-btn-secondary\",\n ghost: \"fd-btn-ghost\",\n danger: \"fd-btn-danger\",\n link: \"fd-btn-link\",\n};\n\n/**\n * The one action primitive. Primary is a gradient; everything else is flat.\n * Never more than one primary per view.\n */\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children?: React.ReactNode;\n /** primary = the one action. brandSoft = marketing CTA at >=19px/700 only (AA large-text). */\n variant?: \"primary\" | \"brandSoft\" | \"secondary\" | \"ghost\" | \"danger\" | \"link\";\n size?: \"sm\" | \"md\" | \"lg\";\n /** Phosphor icon name, leading, e.g. \"plus\" */\n icon?: string;\n /** Phosphor icon name, trailing */\n trailingIcon?: string;\n /** The site's signature inset-circle arrow. Use on hero CTAs only. */\n arrow?: boolean;\n /** Label stays put; a spinner replaces the leading icon. */\n loading?: boolean;\n block?: boolean;\n as?: \"button\" | \"a\";\n}\n\nexport function Button({\n children,\n variant = \"primary\",\n size = \"md\",\n icon,\n trailingIcon,\n arrow = false,\n loading = false,\n disabled = false,\n block = false,\n as = \"button\",\n className = \"\",\n ...rest\n}: ButtonProps) {\n const Tag = as as React.ElementType;\n const cls = [\n \"fd-btn\",\n VARIANTS[variant] || VARIANTS.primary,\n size === \"sm\" ? \"fd-btn-sm\" : size === \"lg\" ? \"fd-btn-lg\" : \"\",\n block ? \"fd-btn-block\" : \"\",\n loading ? \"fd-btn-loading\" : \"\",\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <Tag\n className={cls}\n disabled={Tag === \"button\" ? disabled || loading : undefined}\n aria-disabled={disabled || loading ? \"true\" : undefined}\n aria-busy={loading ? \"true\" : undefined}\n {...rest}\n >\n {icon && !loading ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {loading ? <span className=\"fd-spinner\" aria-hidden=\"true\" /> : null}\n <span>{children}</span>\n {trailingIcon && !arrow ? <i className={\"ph ph-\" + trailingIcon} aria-hidden=\"true\" /> : null}\n {arrow ? (\n <span className=\"fd-btn-arrow\" aria-hidden=\"true\">\n <i className=\"ph ph-arrow-right\" />\n </span>\n ) : null}\n </Tag>\n );\n}\n","import * as React from \"react\";\n\n/** A square action carrying only a Phosphor glyph. Always needs a label for a11y. */\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Phosphor icon name, e.g. \"dots-three-vertical\" */\n icon: string;\n /** Accessible name, also the title tooltip. Required. */\n label: string;\n size?: \"sm\" | \"md\" | \"lg\";\n variant?: \"ghost\" | \"outline\";\n round?: boolean;\n disabled?: boolean;\n className?: string;\n}\n\nexport function IconButton({\n icon,\n label,\n size = \"md\",\n variant = \"ghost\",\n round = false,\n disabled = false,\n className = \"\",\n ...rest\n}: IconButtonProps) {\n const cls = [\n \"fd-btn-icon\",\n variant === \"outline\" ? \"fd-btn-icon-outline\" : \"\",\n size === \"sm\" ? \"fd-btn-icon-sm\" : size === \"lg\" ? \"fd-btn-icon-lg\" : \"\",\n round ? \"fd-btn-icon-round\" : \"\",\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <button type=\"button\" className={cls} aria-label={label} title={label} disabled={disabled} {...rest}>\n <i className={\"ph ph-\" + icon} aria-hidden=\"true\" />\n </button>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport type Placement = \"bottom-start\" | \"bottom-end\" | \"bottom-center\" | \"top-start\" | \"top-end\" | \"top-center\";\n\nexport interface PopoverProps {\n open?: boolean;\n anchorRef: React.RefObject<HTMLElement>;\n onClose?: () => void;\n placement?: Placement;\n offset?: number;\n matchWidth?: boolean;\n width?: number;\n minWidth?: number;\n maxHeight?: number;\n padded?: boolean;\n role?: string;\n label?: string;\n closeOnOutside?: boolean;\n closeOnEscape?: boolean;\n returnFocus?: boolean;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n}\n\ninterface PopoverPosition {\n left: number;\n width: number | undefined;\n minWidth: number | undefined;\n top: number | null;\n bottom: number | null;\n maxH: number;\n side: \"top\" | \"bottom\";\n anchorWidth: number;\n}\n\nconst MARGIN = 8;\nconst parsePlacement = (p?: string): { side: \"top\" | \"bottom\"; align: string } => {\n const [side, align = \"start\"] = String(p || \"bottom-start\").split(\"-\");\n return { side: side === \"top\" ? \"top\" : \"bottom\", align };\n};\n\n/**\n * Fixed-position layer geometry for an anchored surface. Flips side when the\n * preferred one doesn't fit, clamps to the viewport, and re-measures on scroll\n * and resize (capture phase, so it tracks inside scrolling panels too).\n */\nexport function usePopoverPosition(\n open: boolean,\n anchorRef: React.RefObject<HTMLElement>,\n opts?: Partial<PopoverProps> & { estHeight?: number; estWidth?: number }\n): PopoverPosition | null {\n const o = opts || {};\n const { side: wantSide, align } = parsePlacement(o.placement);\n const [pos, setPos] = React.useState<PopoverPosition | null>(null);\n\n React.useLayoutEffect(() => {\n if (!open || !anchorRef || !anchorRef.current) { setPos(null); return; }\n const calc = () => {\n const el = anchorRef.current;\n if (!el) return;\n const r = el.getBoundingClientRect();\n const offset = o.offset == null ? 8 : o.offset;\n const estH = o.estHeight || 300;\n const below = window.innerHeight - r.bottom - offset - MARGIN;\n const above = r.top - offset - MARGIN;\n let side = wantSide;\n if (side === \"bottom\" && below < Math.min(estH, 180) && above > below) side = \"top\";\n else if (side === \"top\" && above < Math.min(estH, 180) && below > above) side = \"bottom\";\n const width = o.matchWidth ? r.width : Math.max(o.width || 0, o.minWidth || 0);\n const w = width || o.estWidth || 260;\n let left = align === \"end\" ? r.right - w : align === \"center\" ? r.left + r.width / 2 - w / 2 : r.left;\n left = Math.max(MARGIN, Math.min(left, window.innerWidth - w - MARGIN));\n const maxH = Math.max(140, (side === \"top\" ? above : below));\n setPos({\n left, width: o.matchWidth ? r.width : undefined, minWidth: o.minWidth,\n top: side === \"bottom\" ? r.bottom + offset : null,\n bottom: side === \"top\" ? window.innerHeight - r.top + offset : null,\n maxH, side, anchorWidth: r.width,\n });\n };\n calc();\n window.addEventListener(\"scroll\", calc, true);\n window.addEventListener(\"resize\", calc);\n return () => { window.removeEventListener(\"scroll\", calc, true); window.removeEventListener(\"resize\", calc); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, o.placement, o.offset, o.matchWidth, o.width, o.minWidth, o.estHeight]);\n\n return pos;\n}\n\nconst portal = (node: React.ReactElement): React.ReactElement => {\n if (typeof document !== \"undefined\") return createPortal(node, document.body);\n return node;\n};\n\n/**\n * An anchored floating surface: menus, pickers, disclosure panels, meters.\n * Owns nothing but placement, dismissal and focus return — the content is yours.\n */\nexport function Popover({\n open, anchorRef, onClose, placement = \"bottom-start\", offset = 8,\n matchWidth = false, width, minWidth, maxHeight, padded = false,\n role = \"dialog\", label, closeOnOutside = true, closeOnEscape = true,\n returnFocus = true, className = \"\", style, children,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement>(null);\n const pos = usePopoverPosition(!!open, anchorRef, { placement, offset, matchWidth, width, minWidth, estHeight: maxHeight || 320 });\n const restore = React.useRef<HTMLElement | null>(null);\n\n React.useEffect(() => {\n if (!open) return;\n restore.current = typeof document !== \"undefined\" ? (document.activeElement as HTMLElement | null) : null;\n return () => {\n if (returnFocus && restore.current && restore.current.focus) {\n try { restore.current.focus({ preventScroll: true }); } catch { /* noop */ }\n }\n };\n }, [open, returnFocus]);\n\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (!closeOnOutside) return;\n const target = e.target as Node;\n if (ref.current && ref.current.contains(target)) return;\n if (anchorRef && anchorRef.current && anchorRef.current.contains(target)) return;\n if ((e.target as Element).closest && (e.target as Element).closest(\".fd-pop\")) return; // nested layers\n onClose && onClose();\n };\n const key = (e: KeyboardEvent) => { if (closeOnEscape && e.key === \"Escape\") { e.stopPropagation(); onClose && onClose(); } };\n document.addEventListener(\"pointerdown\", away, true);\n document.addEventListener(\"keydown\", key);\n return () => { document.removeEventListener(\"pointerdown\", away, true); document.removeEventListener(\"keydown\", key); };\n }, [open, closeOnOutside, closeOnEscape, onClose, anchorRef]);\n\n if (!open || !pos) return null;\n return portal(\n <div\n ref={ref}\n role={role}\n aria-label={label}\n className={[\"fd-pop\", pos.side === \"top\" ? \"is-up\" : \"\", padded ? \"fd-pop-padded\" : \"\", className].filter(Boolean).join(\" \")}\n style={{\n position: \"fixed\", left: pos.left,\n top: pos.top == null ? \"auto\" : pos.top,\n bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n width: matchWidth ? pos.width : width,\n minWidth: minWidth || (matchWidth ? undefined : 200),\n // Size to content by default — cap only at real available room between the\n // anchor and the viewport edge (pos.maxH, computed by usePopoverPosition).\n // A caller-supplied `maxHeight` narrows that further (e.g. a long menu that\n // should scroll well before it reaches the viewport edge); it must never\n // widen past pos.maxH, which is why it's still Math.min'd against it. There\n // is intentionally no arbitrary default here — an unrequested cap would clip\n // ordinary content that simply happens to be taller than some fixed number.\n maxHeight: maxHeight != null ? Math.min(maxHeight, pos.maxH) : pos.maxH,\n transformOrigin: pos.side === \"top\" ? \"bottom center\" : \"top center\",\n zIndex: 140,\n ...style,\n } as React.CSSProperties}\n >\n {children}\n </div>\n );\n}\n\nexport interface MenuItem {\n id?: string;\n label?: React.ReactNode;\n icon?: string;\n description?: React.ReactNode;\n meta?: React.ReactNode;\n /** A key HINT. Renders a cap, binds nothing. */\n shortcut?: React.ReactNode;\n /** Present (true/false) makes the row a menuitemradio with a check column. */\n checked?: boolean;\n disabled?: boolean;\n submenu?: MenuItem[];\n /** A secondary action pinned to the row (e.g. delete). Rendered as a sibling button, so it is keyboard-reachable and does not nest inside the row button. */\n trailingAction?: { icon?: string; label: string; danger?: boolean; closeOnSelect?: boolean; onSelect?: (item: MenuItem) => void };\n onSelect?: (item: MenuItem) => void;\n kind?: \"separator\" | \"section\" | \"custom\";\n render?: () => React.ReactNode;\n}\n\nexport interface MenuProps {\n items: MenuItem[];\n onSelect?: (item: MenuItem) => void;\n onClose?: () => void;\n autoFocus?: boolean;\n header?: React.ReactNode;\n footer?: React.ReactNode;\n className?: string;\n}\n\nconst isItem = (it: MenuItem | null | undefined): boolean =>\n !!it && it.kind !== \"separator\" && it.kind !== \"section\" && it.kind !== \"custom\" && !it.disabled;\n\n/**\n * A keyboard-complete menu list. Items may be:\n * {id,label,icon,description,meta,shortcut,checked,disabled,submenu,onSelect}\n * {kind:\"separator\"} · {kind:\"section\",label} · {kind:\"custom\",render}\n * `shortcut` is a HINT — it renders a cap and binds nothing.\n */\nexport function Menu({ items = [], onSelect, onClose, autoFocus = true, className = \"\", footer, header }: MenuProps) {\n const listRef = React.useRef<HTMLDivElement>(null);\n const [active, setActive] = React.useState(() => items.findIndex(isItem));\n const [openSub, setOpenSub] = React.useState<number | null>(null);\n const subAnchor = React.useRef<HTMLElement | null>(null);\n const typed = React.useRef<{ s: string; t: number }>({ s: \"\", t: 0 });\n\n React.useEffect(() => { if (autoFocus && listRef.current) listRef.current.focus({ preventScroll: true }); }, [autoFocus]);\n\n const move = (dir: number) => {\n setActive((a) => {\n let i = a;\n for (let n = 0; n < items.length; n++) {\n i = (i + dir + items.length) % items.length;\n if (isItem(items[i])) return i;\n }\n return a;\n });\n };\n\n const choose = (it: MenuItem | null | undefined, i: number) => {\n if (!it || it.disabled) return;\n if (it.submenu && it.submenu.length) {\n subAnchor.current = (listRef.current && listRef.current.querySelector('[data-i=\"' + i + '\"]')) as HTMLElement | null;\n setOpenSub(i);\n return;\n }\n it.onSelect && it.onSelect(it);\n onSelect && onSelect(it);\n onClose && onClose();\n };\n\n const onKey = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"ArrowDown\") { e.preventDefault(); move(1); }\n else if (e.key === \"ArrowUp\") { e.preventDefault(); move(-1); }\n else if (e.key === \"Home\") { e.preventDefault(); setActive(items.findIndex(isItem)); }\n else if (e.key === \"End\") { e.preventDefault(); for (let i = items.length - 1; i >= 0; i--) if (isItem(items[i])) { setActive(i); break; } }\n else if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); choose(items[active], active); }\n else if (e.key === \"ArrowRight\") { const it = items[active]; if (it && it.submenu) { e.preventDefault(); choose(it, active); } }\n else if (e.key === \"ArrowLeft\") { if (openSub != null) { e.preventDefault(); setOpenSub(null); } }\n else if (e.key.length === 1 && /\\S/.test(e.key)) {\n const now = Date.now();\n typed.current = { s: (now - typed.current.t < 700 ? typed.current.s : \"\") + e.key.toLowerCase(), t: now };\n const hit = items.findIndex((it) => isItem(it) && String(it.label || \"\").toLowerCase().startsWith(typed.current.s));\n if (hit >= 0) setActive(hit);\n }\n };\n\n const sub = openSub != null ? items[openSub] : null;\n\n return (\n <React.Fragment>\n {header}\n <div\n ref={listRef} tabIndex={-1} role=\"menu\" onKeyDown={onKey}\n className={[\"fd-pop-list\", \"fd-menu\", className].filter(Boolean).join(\" \")}\n >\n {items.map((it, i) => {\n if (!it) return null;\n if (it.kind === \"separator\") return <div key={\"s\" + i} className=\"fd-menu-sep\" role=\"separator\" />;\n if (it.kind === \"section\") return <div key={\"h\" + i} className=\"fd-pop-group\" role=\"presentation\">{it.label}</div>;\n if (it.kind === \"custom\") return <div key={\"c\" + i} className=\"fd-menu-custom\">{it.render ? it.render() : null}</div>;\n const on = !!it.checked;\n const row = (\n <button\n type=\"button\" key={it.id || (it.label as React.Key) || i} data-i={i}\n role={it.checked != null ? \"menuitemradio\" : \"menuitem\"}\n aria-checked={it.checked != null ? on : undefined}\n aria-haspopup={it.submenu ? \"menu\" : undefined}\n aria-expanded={it.submenu ? openSub === i : undefined}\n aria-disabled={it.disabled || undefined}\n className={[\"fd-opt\", \"fd-menu-item\", i === active ? \"is-active\" : \"\", on ? \"is-selected\" : \"\"].filter(Boolean).join(\" \")}\n onMouseEnter={() => { setActive(i); if (openSub != null && openSub !== i) setOpenSub(null); }}\n onClick={() => choose(it, i)}\n >\n {it.icon ? <span className=\"fd-menu-icon\"><i className={\"ph ph-\" + it.icon} aria-hidden=\"true\" /></span> : null}\n <span className=\"fd-menu-text\">\n <span className=\"fd-opt-label\">{it.label}</span>\n {it.description ? <span className=\"fd-opt-desc\">{it.description}</span> : null}\n </span>\n {it.meta ? <span className=\"fd-opt-meta\">{it.meta}</span> : null}\n {it.shortcut ? <span className=\"fd-menu-shortcut\" aria-hidden=\"true\">{it.shortcut}</span> : null}\n {it.submenu ? <i className=\"ph ph-caret-right fd-menu-more\" aria-hidden=\"true\" /> : null}\n {it.checked != null ? <span className=\"fd-opt-check\">{on ? <i className=\"ph ph-check\" aria-hidden=\"true\" /> : null}</span> : null}\n </button>\n );\n const ta = it.trailingAction;\n if (!ta) return row;\n return (\n <div key={it.id || (it.label as React.Key) || i} className=\"fd-menu-row\" onMouseEnter={() => setActive(i)}>\n {row}\n <button\n type=\"button\" className={[\"fd-menu-row-act\", ta.danger ? \"is-danger\" : \"\"].filter(Boolean).join(\" \")}\n aria-label={ta.label} title={ta.label}\n onClick={(e) => { e.stopPropagation(); ta.onSelect && ta.onSelect(it); if (ta.closeOnSelect !== false) { onClose && onClose(); } }}\n >\n <i className={\"ph ph-\" + (ta.icon || \"trash\")} aria-hidden=\"true\" />\n </button>\n </div>\n );\n })}\n </div>\n {footer}\n {sub && sub.submenu ? (\n <Popover\n open anchorRef={{ current: subAnchor.current }} placement=\"bottom-start\" offset={-6}\n minWidth={200} maxHeight={320} label={sub.label as string | undefined} onClose={() => setOpenSub(null)}\n className=\"fd-menu-sub\"\n >\n <Menu items={sub.submenu} onSelect={(it) => { onSelect && onSelect(it); onClose && onClose(); }} onClose={() => setOpenSub(null)} />\n </Popover>\n ) : null}\n </React.Fragment>\n );\n}\n\nexport interface MenuButtonProps extends Omit<MenuProps, \"onClose\" | \"autoFocus\"> {\n label?: React.ReactNode;\n icon?: string;\n trailingIcon?: string | null;\n placement?: Placement;\n variant?: \"chip\" | \"ghost\";\n size?: \"sm\" | \"md\";\n disabled?: boolean;\n title?: string;\n ariaLabel?: string;\n width?: number;\n minWidth?: number;\n maxHeight?: number;\n children?: React.ReactNode;\n}\n\n/**\n * Trigger + menu in one: a compact chip that opens an anchored Menu.\n * Used for model pickers, row overflow actions, view switchers.\n */\nexport function MenuButton({\n label, icon, trailingIcon = \"caret-down\", items = [], onSelect, placement = \"top-end\",\n variant = \"chip\", size = \"sm\", disabled, title, ariaLabel, width, minWidth = 220, maxHeight = 380,\n className = \"\", children, header, footer,\n}: MenuButtonProps) {\n const [open, setOpen] = React.useState(false);\n const ref = React.useRef<HTMLButtonElement>(null);\n return (\n <React.Fragment>\n <button\n type=\"button\" ref={ref} disabled={disabled} title={title}\n aria-label={ariaLabel} aria-haspopup=\"menu\" aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n className={[\"fd-menubtn\", \"fd-menubtn-\" + variant, size === \"md\" ? \"is-md\" : \"\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")}\n >\n {icon ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {children != null ? children : <span className=\"fd-menubtn-label\">{label}</span>}\n {trailingIcon ? <i className={\"ph ph-\" + trailingIcon + \" fd-menubtn-caret\"} aria-hidden=\"true\" /> : null}\n </button>\n <Popover\n open={open} anchorRef={ref} placement={placement} onClose={() => setOpen(false)}\n width={width} minWidth={minWidth} maxHeight={maxHeight} role=\"menu\" label={(ariaLabel || label) as string | undefined}\n >\n <Menu items={items} header={header} footer={footer} onSelect={onSelect} onClose={() => setOpen(false)} />\n </Popover>\n </React.Fragment>\n );\n}\n","\n/** Two to four mutually exclusive views — density, date range, light/dark. */\nexport interface SegmentedControlProps {\n options: Array<string | { value: string; label: string }>;\n value?: string;\n onChange?: (value: string) => void;\n className?: string;\n}\n\nexport function SegmentedControl({ options = [], value, onChange, className = \"\", ...rest }: SegmentedControlProps) {\n return (\n <div className={[\"fd-seg\", className].filter(Boolean).join(\" \")} role=\"group\" {...rest}>\n {options.map((o) => {\n const v = typeof o === \"string\" ? o : o.value;\n const label = typeof o === \"string\" ? o : o.label;\n return (\n <button key={v} type=\"button\" aria-pressed={v === value}\n onClick={onChange ? () => onChange(v) : undefined}>\n {label}\n </button>\n );\n })}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The container. White, 12px radius, hairline border, low soft shadow, and a\n * divider under the header — that divider is the signature detail on flytedesk.com.\n */\nexport interface CardProps {\n title?: React.ReactNode;\n /** Right-aligned control in the header — usually an IconButton or a link Button. */\n action?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n elevation?: \"flat\" | \"rest\" | \"raised\";\n hoverable?: boolean;\n /** Set false to let children run edge to edge (tables, images). */\n padded?: boolean;\n className?: string;\n}\n\nexport function Card({\n title,\n action,\n footer,\n children,\n elevation = \"rest\",\n hoverable = false,\n padded = true,\n className = \"\",\n ...rest\n}: CardProps) {\n const cls = [\n \"fd-card\",\n elevation === \"flat\" ? \"fd-card-flat\" : elevation === \"raised\" ? \"fd-card-raised\" : \"\",\n hoverable ? \"fd-card-hoverable\" : \"\",\n className,\n ].filter(Boolean).join(\" \");\n return (\n <div className={cls} {...rest}>\n {title ? (\n <div className=\"fd-card-head\">\n <span className=\"fd-card-head-title\">{title}</span>\n {action}\n </div>\n ) : null}\n {padded ? <div className=\"fd-card-body\">{children}</div> : children}\n {footer ? <div className=\"fd-card-foot\">{footer}</div> : null}\n </div>\n );\n}\n\nexport interface CardRowProps {\n label: React.ReactNode;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function CardRow({ label, children, className = \"\" }: CardRowProps) {\n return (\n <div className={[\"fd-card-row\", className].filter(Boolean).join(\" \")}>\n <span className=\"fd-card-row-label\">{label}</span>\n <span className=\"fd-card-row-value\">{children}</span>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The system's main density valve: a large, calm trigger row that opens a panel.\n * Prefer this over tabs or a second page when a screen has more than it can show.\n */\nexport interface CollapsibleProps {\n title: React.ReactNode;\n subtitle?: React.ReactNode;\n /** Right-aligned status — a Badge or CsiBadge. */\n badge?: React.ReactNode;\n /** Phosphor icon name shown in a soft brand chip on the left. */\n icon?: string;\n defaultOpen?: boolean;\n /** Pass with onToggle for controlled use. */\n open?: boolean;\n onToggle?: (open: boolean) => void;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Collapsible({\n title,\n subtitle,\n badge,\n icon,\n defaultOpen = false,\n open,\n onToggle,\n children,\n className = \"\",\n ...rest\n}: CollapsibleProps) {\n const [internal, setInternal] = React.useState(defaultOpen);\n const isOpen = open === undefined ? internal : open;\n const toggle = () => {\n if (open === undefined) setInternal(!isOpen);\n if (onToggle) onToggle(!isOpen);\n };\n return (\n <div className={[\"fd-coll\", className].filter(Boolean).join(\" \")} data-open={isOpen ? \"true\" : \"false\"} {...rest}>\n <button type=\"button\" className=\"fd-coll-trigger\" aria-expanded={isOpen} onClick={toggle}>\n {icon ? (\n <span className=\"fd-coll-caret\" style={{ background: \"var(--brand-soft)\", color: \"var(--brand)\", transform: \"none\" }}>\n <i className={\"ph ph-\" + icon} aria-hidden=\"true\" />\n </span>\n ) : null}\n <span style={{ flex: 1, minWidth: 0 }}>\n <span className=\"fd-coll-title\" style={{ display: \"block\" }}>{title}</span>\n {subtitle ? <span className=\"fd-coll-sub\" style={{ display: \"block\" }}>{subtitle}</span> : null}\n </span>\n {badge}\n <span className=\"fd-coll-caret\"><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>\n </button>\n <div className=\"fd-coll-panel\"><div><div className=\"fd-coll-content\">{children}</div></div></div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/** A right-side panel for detail and editing without losing the list behind it. */\nexport interface DrawerProps {\n open?: boolean;\n title?: React.ReactNode;\n onClose?: () => void;\n /** Plain content, or a render function receiving `close` — call it to trigger the closing animation before onClose fires. */\n footer?: React.ReactNode | ((close: () => void) => React.ReactNode);\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Drawer({ open = true, title, onClose, footer, children, className = \"\", ...rest }: DrawerProps) {\n const [closing, setClosing] = React.useState(false);\n const close = React.useCallback(() => {\n if (!onClose) return;\n setClosing(true);\n setTimeout(onClose, 210);\n }, [onClose]);\n React.useEffect(() => {\n if (!open || !onClose) return;\n const h = (e: KeyboardEvent) => { if (e.key === \"Escape\") close(); };\n document.addEventListener(\"keydown\", h);\n return () => document.removeEventListener(\"keydown\", h);\n }, [open, onClose, close]);\n if (!open) return null;\n /* Portalled to <body> on purpose. Rendered inline, the drawer's position:fixed resolves\n against the nearest transformed ancestor — the animated screen wrapper — so it stretched\n to the full scroll height of the page (5000px+) instead of the viewport. */\n return createPortal(\n <>\n <div className={\"fd-scrim\" + (closing ? \" is-closing\" : \"\")} style={{ display: \"block\" }} onClick={close} />\n <aside className={[\"fd-drawer\", closing ? \"is-closing\" : \"\", className].filter(Boolean).join(\" \")} role=\"dialog\" aria-modal=\"true\" {...rest}>\n <div className=\"fd-card-head\" style={{ flex: \"none\" }}>\n <span className=\"fd-card-head-title\">{title}</span>\n {onClose ? <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Close\" onClick={close}><i className=\"ph ph-x\" /></button> : null}\n </div>\n <div style={{ flex: \"1 1 auto\", minHeight: 0, overflow: \"auto\", padding: 20 }}>{children}</div>\n {footer ? <div className=\"fd-card-foot\" style={{ flex: \"none\" }}>{typeof footer === \"function\" ? footer(close) : footer}</div> : null}\n </aside>\n </>,\n document.body\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/** A focused decision on a scrim. Max 560px, 760 with `wide` for data. Escape closes. */\nexport interface ModalProps {\n open?: boolean;\n title?: React.ReactNode;\n description?: React.ReactNode;\n onClose?: () => void;\n /** Plain content, or a render function receiving `close` — call it to trigger the closing animation before onClose fires. */\n footer?: React.ReactNode | ((close: () => void) => React.ReactNode);\n /** 760px — for tables and side-by-side comparisons. */\n wide?: boolean;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Modal({ open = true, title, description, onClose, footer, wide = false, children, className = \"\", ...rest }: ModalProps) {\n const [closing, setClosing] = React.useState(false);\n const close = React.useCallback(() => {\n if (!onClose) return;\n setClosing(true);\n setTimeout(onClose, 190);\n }, [onClose]);\n React.useEffect(() => {\n if (!open || !onClose) return;\n const h = (e: KeyboardEvent) => { if (e.key === \"Escape\") close(); };\n document.addEventListener(\"keydown\", h);\n return () => document.removeEventListener(\"keydown\", h);\n }, [open, onClose, close]);\n if (!open) return null;\n /* Portalled for the same reason as Drawer: inline, the fixed-position scrim resolves\n against the nearest transformed ancestor rather than the viewport. */\n return createPortal(\n <div\n className={\"fd-scrim\" + (closing ? \" is-closing\" : \"\")}\n onClick={onClose ? (e: React.MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) close(); } : undefined}\n >\n <div\n className={[\"fd-modal\", closing ? \"is-closing\" : \"\", wide ? \"fd-modal-wide\" : \"\", className].filter(Boolean).join(\" \")}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n {...rest}\n >\n {title ? (\n <div className=\"fd-modal-head\">\n <span style={{ flex: 1, minWidth: 0 }}>\n <span className=\"fd-modal-title\" style={{ display: \"block\" }}>{title}</span>\n {description ? <span className=\"fd-body-sm fd-secondary\" style={{ display: \"block\", marginTop: 6 }}>{description}</span> : null}\n </span>\n {onClose ? <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Close\" onClick={close}><i className=\"ph ph-x\" /></button> : null}\n </div>\n ) : null}\n <div className=\"fd-modal-body\">{children}</div>\n {footer ? <div className=\"fd-modal-foot\">{typeof footer === \"function\" ? footer(close) : footer}</div> : null}\n </div>\n </div>,\n document.body\n );\n}\n","import * as React from \"react\";\n\n/**\n * The async contract for one region of a screen. Four states, one component:\n * loading (skeleton), refreshing (previous data stays visible, dimmed and inert),\n * ready, empty/error.\n */\nexport interface LoadingRegionProps {\n state?: \"loading\" | \"refreshing\" | \"ready\" | \"empty\" | \"error\";\n /** What to show before first data. Mirror the ready layout. */\n skeleton?: React.ReactNode;\n children?: React.ReactNode;\n /** Announced to screen readers while busy. */\n label?: string;\n error?: string;\n onRetry?: () => void;\n className?: string;\n}\n\nexport function LoadingRegion({\n state = \"ready\",\n skeleton,\n children,\n label = \"Loading\",\n error,\n onRetry,\n className = \"\",\n ...rest\n}: LoadingRegionProps) {\n if (state === \"empty\" || state === \"error\") {\n return (\n <div className={[\"fd-empty\", className].filter(Boolean).join(\" \")} {...rest}>\n <span className=\"fd-empty-icon\">\n <i className={state === \"error\" ? \"ph ph-warning\" : \"ph ph-tray\"} aria-hidden=\"true\" />\n </span>\n <span className=\"fd-empty-title\">{state === \"error\" ? \"That didn't load\" : \"Nothing here yet\"}</span>\n <span className=\"fd-empty-body\">{error || \"Data will appear here once it exists.\"}</span>\n {onRetry ? <button type=\"button\" className=\"fd-btn fd-btn-secondary\" onClick={onRetry}>Try again</button> : null}\n </div>\n );\n }\n if (state === \"loading\") {\n return (\n <div className={className} role=\"status\" aria-busy=\"true\" aria-label={label} {...rest}>\n <span className=\"fd-sr\">{label}</span>\n {skeleton}\n </div>\n );\n }\n const stale = state === \"refreshing\";\n return (\n <div className={[stale ? \"fd-stale-region\" : \"\", className].filter(Boolean).join(\" \")}\n aria-busy={stale ? \"true\" : undefined} {...rest}>\n <div className={stale ? \"fd-stale\" : \"fd-arrived\"}>{children}</div>\n </div>\n );\n}\n","/** Determinate or indeterminate bar for a known long job — uploads, exports, plan builds. */\nexport interface ProgressBarProps {\n /** 0-100. Omit for indeterminate. */\n value?: number;\n label?: string;\n showValue?: boolean;\n className?: string;\n}\n\nexport function ProgressBar({ value, label, showValue = false, className = \"\", ...rest }: ProgressBarProps) {\n const indeterminate = value === undefined || value === null;\n const pct = indeterminate ? 0 : Math.max(0, Math.min(100, value));\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 8 }}>\n {label || showValue ? (\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n {label ? <span className=\"fd-label-lg\">{label}</span> : <span />}\n {showValue && !indeterminate ? <span className=\"fd-num fd-secondary\">{pct}%</span> : null}\n </div>\n ) : null}\n <div className={[\"fd-progress\", indeterminate ? \"fd-progress-indeterminate\" : \"\"].filter(Boolean).join(\" \")}\n role=\"progressbar\" aria-valuenow={indeterminate ? undefined : pct}\n aria-valuemin={0} aria-valuemax={100} aria-label={label} {...rest}>\n <div className=\"fd-progress-fill\" style={indeterminate ? undefined : { width: pct + \"%\" }} />\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The shape data will occupy, shown before the first payload lands.\n * Skeletons mirror the real layout so nothing shifts on arrival.\n */\nexport interface SkeletonProps {\n w?: number | string;\n h?: number | string;\n shape?: \"block\" | \"text\" | \"circle\" | \"card\";\n radius?: string;\n style?: React.CSSProperties;\n className?: string;\n}\n\nexport function Skeleton({ w = \"100%\", h = 16, shape = \"block\", radius, style, className = \"\", ...rest }: SkeletonProps) {\n const cls = [\n \"fd-skel\",\n shape === \"circle\" ? \"fd-skel-circle\" : shape === \"text\" ? \"fd-skel-text\" : shape === \"card\" ? \"fd-skel-card\" : \"fd-skel-block\",\n className\n ].filter(Boolean).join(\" \");\n return <span aria-hidden=\"true\" className={cls}\n style={{ display: \"block\", width: w, height: typeof h === \"number\" ? h + \"px\" : h, borderRadius: radius, ...style }} {...rest} />;\n}\n\nexport interface SkeletonTextProps {\n lines?: number;\n /** Per-line widths, cycled. Ragged widths read as text; equal widths read as a bug. */\n width?: string[];\n size?: number;\n gap?: number;\n className?: string;\n}\n\nexport function SkeletonText({ lines = 3, width = [\"100%\", \"92%\", \"64%\"], size = 15, gap = 8, className = \"\" }: SkeletonTextProps) {\n return (\n <span aria-hidden=\"true\" className={className} style={{ display: \"flex\", flexDirection: \"column\", gap: gap + \"px\" }}>\n {Array.from({ length: lines }).map((_, i) => (\n <span key={i} className=\"fd-skel fd-skel-text\"\n style={{ display: \"block\", height: size + \"px\", width: width[i % width.length] }} />\n ))}\n </span>\n );\n}\n","import * as React from \"react\";\n\n/** A small indeterminate indicator. For inline waits only — never over a whole page. */\nexport interface SpinnerProps {\n size?: \"sm\" | \"md\" | \"lg\";\n label?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport function Spinner({ size = \"md\", label = \"Loading\", className = \"\", style, ...rest }: SpinnerProps) {\n return (\n <span role=\"status\" aria-label={label}\n className={[\"fd-spinner\", size === \"lg\" ? \"fd-spinner-lg\" : \"\", className].filter(Boolean).join(\" \")}\n style={style} {...rest} />\n );\n}\n","import * as React from \"react\";\n\n/**\n * The app's 264px left rail. Grouped items under overline headers; the active item\n * takes a soft blue fill and deep blue label. Collapses off-canvas below 1024px.\n */\nexport interface SidebarNavItem {\n value: string;\n label: string;\n /** Phosphor icon name */\n icon: string;\n count?: number;\n /** Count still loading — shows a small skeleton instead of a number. */\n loading?: boolean;\n /** Member lacks the permission — shows a lock marker. Still navigable; the screen explains. */\n locked?: boolean;\n /** Designed but the backend is not wired — shows a construction marker. Still navigable;\n * the screen renders inert behind a coming-soon banner. */\n preview?: boolean;\n}\n\nexport interface SidebarNavProps {\n brand?: React.ReactNode;\n groups: Array<{ label?: string; items: SidebarNavItem[] }>;\n current?: string;\n onNavigate?: (value: string) => void;\n footer?: React.ReactNode;\n /** Mobile: slides the off-canvas rail in. */\n open?: boolean;\n className?: string;\n}\n\n/* Title-attribute tip rather than the Tooltip component: these sit inside a button, and a\n focusable tooltip trigger nested in a button is invalid and steals the click. */\nfunction Tip({ label, children }: { label: string; children?: React.ReactNode }) {\n return <span title={label} style={{ display: \"inline-flex\", flex: \"none\" }}>{children}</span>;\n}\n\nexport function SidebarNav({ brand, groups = [], current, onNavigate, footer, open = false, className = \"\", ...rest }: SidebarNavProps) {\n return (\n <nav className={[\"fd-side\", className].filter(Boolean).join(\" \")} data-open={open ? \"true\" : \"false\"} {...rest}>\n {brand ? <div style={{ height: \"var(--topbar-h)\", display: \"flex\", alignItems: \"center\", padding: \"0 18px\", borderBottom: \"1px solid var(--border)\", flex: \"none\", overflow: \"hidden\" }}>{brand}</div> : null}\n <div style={{ flex: 1, overflow: \"auto\", padding: \"4px 10px 18px\" }}>\n {groups.map((g, gi) => (\n <div key={gi}>\n {g.label ? <div className=\"fd-side-group\">{g.label}</div> : null}\n <div className=\"fd-stack\" style={{ gap: 2 }}>\n {g.items.map((it) => (\n <button key={it.value} type=\"button\" className=\"fd-side-item\"\n aria-current={current === it.value ? \"page\" : undefined}\n onClick={onNavigate ? () => onNavigate(it.value) : undefined}>\n <span className=\"fd-side-item-icon\"><i className={\"ph ph-\" + it.icon} aria-hidden=\"true\" /></span>\n <span style={{ flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{it.label}</span>\n {/* A preview item is navigable — the screen renders inert behind a banner — so it\n gets a marker rather than being hidden or disabled. */}\n {it.preview ? <Tip label=\"Designed, backend not wired yet\"><i className=\"ph ph-traffic-cone\" style={{ fontSize: 13, color: \"var(--warn-solid)\", flex: \"none\" }} /></Tip> : null}\n {it.locked ? <Tip label=\"You do not have permission for this\"><i className=\"ph ph-lock-simple\" style={{ fontSize: 13, color: \"var(--text-muted)\", flex: \"none\" }} /></Tip> : null}\n {it.count !== undefined ? <span className=\"fd-side-item-count\">{it.count}</span> : null}\n {it.loading ? <span className=\"fd-skel fd-skel-text\" style={{ width: 22, height: 11, marginLeft: \"auto\" }} /> : null}\n </button>\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div style={{ borderTop: \"1px solid var(--border)\", padding: 14, flex: \"none\" }}>{footer}</div> : null}\n </nav>\n );\n}\n","/** The real flytedesk wordmark. A genuinely transparent-background SVG (verified —\n * every non-ink pixel is alpha:0, not painted white; the old PNG's \"white-bg\"\n * filename was misleading, it was transparent too) drawn in a fixed dark navy\n * (#052E4A) — it has no light/white colorway of its own. SVG over the old PNG for\n * real infinite scalability, not a fixed-resolution raster stretched or downsampled\n * per size variant. Dark-theme visibility is handled in CSS (.fd-brand-mark),\n * not by shipping a second asset — see that rule's comment. */\nconst LOGO_SRC =\n \"https://cdn.prod.website-files.com/69a96def413819b7db64de8c/69ac8ec2ed84b986a5fb76dc_Logo%20(dark)%202.svg\";\n\nexport interface FlytedeskMarkProps {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Just the flytedesk logo, no label — for contexts too small for a stacked brand\n * (a collapsed rail, a favicon-sized corner mark). */\nexport function FlytedeskMark({ size = \"md\", className = \"\", ...rest }: FlytedeskMarkProps) {\n return (\n <span className={[\"fd-brand-mark\", size !== \"md\" ? \"fd-brand-mark-\" + size : \"\", className].filter(Boolean).join(\" \")} {...rest}>\n <img src={LOGO_SRC} alt=\"flytedesk\" />\n </span>\n );\n}\n\nexport interface FlytedeskBrandProps {\n /** The consuming app's name, shown under the logo — e.g. \"Media Planner\", \"Admin\". */\n appName: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** The flytedesk logo stacked over the app's name — meant to drop straight into\n * SidebarNav's `brand` slot in every flytedesk app. */\nexport function FlytedeskBrand({ appName, size = \"md\", className = \"\", ...rest }: FlytedeskBrandProps) {\n return (\n <span className={[\"fd-brand\", size !== \"md\" ? \"fd-brand-\" + size : \"\", className].filter(Boolean).join(\" \")} {...rest}>\n <FlytedeskMark size={size} />\n <span className=\"fd-overline fd-muted\">{appName}</span>\n </span>\n );\n}\n","\n/**\n * Places within one screen. Underline only — no pill tabs in the product.\n */\nexport interface TabsProps {\n tabs: Array<string | { value: string; label: string; count?: number }>;\n value?: string;\n onChange?: (value: string) => void;\n className?: string;\n}\n\nexport function Tabs({ tabs = [], value, onChange, className = \"\", ...rest }: TabsProps) {\n return (\n <div className={[\"fd-tabs\", className].filter(Boolean).join(\" \")} role=\"tablist\" {...rest}>\n {tabs.map((t) => {\n const v = typeof t === \"string\" ? t : t.value;\n const label = typeof t === \"string\" ? t : t.label;\n const count = typeof t === \"string\" ? undefined : t.count;\n return (\n <button key={v} type=\"button\" role=\"tab\" className=\"fd-tab\" aria-selected={v === value}\n onClick={onChange ? () => onChange(v) : undefined}>\n {label}\n {count !== undefined ? <span className=\"fd-badge fd-badge-neutral\" style={{ height: 20, padding: \"0 7px\" }}>{count}</span> : null}\n </button>\n );\n })}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** 60px app header: breadcrumb left, actions right, and a 2px route loader along its top edge. */\nexport interface TopbarProps {\n /** A non-last crumb with `onClick` calls it (via `preventDefault`) instead of following\n * `href` — for a crumb that needs to run a side effect (e.g. clearing some selection)\n * before/instead of navigating. `href` still works on its own for a plain link crumb;\n * the two aren't mutually exclusive, but `onClick` wins when both are present. */\n crumbs?: Array<{ label: string; href?: string; onClick?: () => void }>;\n actions?: React.ReactNode;\n /** Shows the indeterminate route loader on the top edge. */\n loading?: boolean;\n /** Mobile menu handler — renders the hamburger. */\n onMenu?: () => void;\n className?: string;\n}\n\nexport function Topbar({ crumbs = [], actions, loading = false, onMenu, className = \"\", ...rest }: TopbarProps) {\n return (\n <header className={[\"fd-topbar\", className].filter(Boolean).join(\" \")} {...rest}>\n {onMenu ? <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Menu\" onClick={onMenu}><i className=\"ph ph-list\" /></button> : null}\n <nav className=\"fd-crumb\" aria-label=\"Breadcrumb\">\n {crumbs.map((c, i) => (\n <React.Fragment key={i}>\n {i > 0 ? <i className=\"ph ph-caret-right\" style={{ fontSize: 11, opacity: .6 }} aria-hidden=\"true\" /> : null}\n {i === crumbs.length - 1 ? (\n <span className=\"fd-crumb-current\">{c.label}</span>\n ) : (\n <a\n href={c.href || \"#\"}\n onClick={\n c.onClick\n ? (e) => {\n e.preventDefault();\n c.onClick!();\n }\n : undefined\n }\n >\n {c.label}\n </a>\n )}\n </React.Fragment>\n ))}\n </nav>\n <span style={{ flex: 1 }} />\n {actions}\n {loading ? <span className=\"fd-topload\" aria-hidden=\"true\" /> : null}\n </header>\n );\n}\n","\n/** A person or organisation mark. Initials on a soft brand tint when no image exists. */\nexport interface AvatarProps {\n name?: string;\n src?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nexport function Avatar({ name = \"\", src, size = \"md\", className = \"\", ...rest }: AvatarProps) {\n const initials = name.split(/\\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join(\"\").toUpperCase();\n return (\n <span className={[\"fd-avatar\", size === \"sm\" ? \"fd-avatar-sm\" : size === \"lg\" ? \"fd-avatar-lg\" : \"\", className].filter(Boolean).join(\" \")}\n title={name || undefined} {...rest}>\n {src ? <img src={src} alt={name} /> : initials || <i className=\"ph ph-user\" aria-hidden=\"true\" />}\n </span>\n );\n}\n\nexport interface AvatarStackProps {\n people: Array<string | { name: string; src?: string }>;\n size?: \"sm\" | \"md\" | \"lg\";\n max?: number;\n className?: string;\n}\n\nexport function AvatarStack({ people = [], size = \"sm\", max = 4, className = \"\" }: AvatarStackProps) {\n const shown = people.slice(0, max);\n const rest = people.length - shown.length;\n return (\n <span className={[\"fd-avatar-stack\", className].filter(Boolean).join(\" \")}>\n {shown.map((p, i) => <Avatar key={i} name={typeof p === \"string\" ? p : p.name} src={typeof p === \"string\" ? undefined : p.src} size={size} />)}\n {rest > 0 ? <Avatar name={\"+\" + rest} size={size} /> : null}\n </span>\n );\n}\n","import * as React from \"react\";\n\nconst TONES: Record<string, string> = { neutral: \"fd-badge-neutral\", info: \"fd-badge-info\", success: \"fd-badge-success\", warning: \"fd-badge-warning\", danger: \"fd-badge-danger\", live: \"fd-badge-live\", approved: \"fd-badge-approved\", count: \"fd-badge-count\" };\n\n/**\n * A pill of state. Badges never carry actions — if it is clickable it is a Tag.\n */\nexport interface BadgeProps {\n children?: React.ReactNode;\n /** live = the site's blue gradient \"Active\". approved = its mint pill. count = the blue number chip. */\n tone?: \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\" | \"live\" | \"approved\" | \"count\";\n dot?: boolean;\n /** Phosphor icon name */\n icon?: string;\n className?: string;\n}\n\nexport function Badge({ children, tone = \"neutral\", dot = false, icon, className = \"\", ...rest }: BadgeProps) {\n return (\n <span className={[\"fd-badge\", TONES[tone] || TONES.neutral, className].filter(Boolean).join(\" \")} {...rest}>\n {dot ? <span className=\"fd-badge-dot\" aria-hidden=\"true\" /> : null}\n {icon ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {children}\n </span>\n );\n}\n","import * as React from \"react\";\n\n/** Says what will appear here, and offers exactly one button. */\nexport interface EmptyStateProps {\n /** Phosphor icon name */\n icon?: string;\n title: React.ReactNode;\n children?: React.ReactNode;\n action?: React.ReactNode;\n className?: string;\n}\n\nexport function EmptyState({ icon = \"tray\", title, children, action, className = \"\", ...rest }: EmptyStateProps) {\n return (\n <div className={[\"fd-empty\", className].filter(Boolean).join(\" \")} {...rest}>\n <span className=\"fd-empty-icon\"><i className={\"ph ph-\" + icon} aria-hidden=\"true\" /></span>\n <span className=\"fd-empty-title\">{title}</span>\n {children ? <span className=\"fd-empty-body\">{children}</span> : null}\n {action}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * A callout with a fixed structure: statement, then cost, then two actions.\n * A flag without a number and a choice is not a flag — use plain body copy.\n */\nexport interface FlagProps {\n /** What is true. \"Ohio State is Weak.\" */\n statement: React.ReactNode;\n /** What it costs to fix. \"+$4,200 reaches Adequate.\" Rendered bold. */\n cost?: React.ReactNode;\n /** Two Buttons — the fix and the dismissal. */\n actions?: React.ReactNode;\n tone?: \"info\" | \"success\" | \"warning\" | \"danger\";\n className?: string;\n}\n\nexport function Flag({ statement, cost, actions, tone = \"warning\", className = \"\", ...rest }: FlagProps) {\n return (\n <div className={[\"fd-flag\", \"fd-flag-\" + tone, className].filter(Boolean).join(\" \")} role=\"status\" {...rest}>\n <span className=\"fd-flag-text\">\n {statement}\n {cost ? <> <span className=\"fd-flag-cost\">{cost}</span></> : null}\n </span>\n {actions ? <span className=\"fd-flag-actions\">{actions}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\nconst IS_MAC = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || \"\");\n\nconst GLYPH: Record<string, string> = {\n mod: IS_MAC ? \"⌘\" : \"Ctrl\", cmd: \"⌘\", meta: \"⌘\", ctrl: IS_MAC ? \"⌃\" : \"Ctrl\",\n alt: IS_MAC ? \"⌥\" : \"Alt\", opt: \"⌥\", option: \"⌥\", shift: \"⇧\",\n enter: \"↵\", return: \"↵\", esc: \"Esc\", escape: \"Esc\", tab: \"⇥\", space: \"Space\",\n backspace: \"⌫\", delete: \"⌦\", up: \"↑\", down: \"↓\", left: \"←\", right: \"→\", slash: \"/\",\n};\n\n/** A key hint that binds NOTHING — register the real shortcut separately. */\nexport interface KeyHintProps { keys: string; size?: \"sm\" | \"md\"; tone?: \"quiet\" | \"solid\"; className?: string }\n\n/**\n * A key hint. Renders a label and binds NOTHING — register the real shortcut\n * separately, or the cap and the binding drift apart.\n */\nexport function KeyHint({ keys, size = \"md\", tone = \"quiet\", className = \"\", ...rest }: KeyHintProps) {\n const parts = String(keys || \"\").split(\"+\").map((p) => p.trim()).filter(Boolean);\n const cls = [\"fd-keyhint\", size === \"sm\" ? \"fd-keyhint-sm\" : \"\", tone === \"solid\" ? \"fd-keyhint-solid\" : \"\", className].filter(Boolean).join(\" \");\n return (\n <span className={cls} aria-hidden=\"true\" {...rest}>\n {parts.map((p, i) => {\n const k = p.toLowerCase();\n const glyph = GLYPH[k] || (p.length === 1 ? p.toUpperCase() : p);\n return <kbd key={i}>{glyph}</kbd>;\n })}\n </span>\n );\n}\n\n/** The platform modifier as text, for prose: \"⌘\" or \"Ctrl\". */\nexport function modifierLabel(): string { return GLYPH.mod; }\n/** True when the event carries the platform's primary modifier. */\nexport function hasModifier(e: KeyboardEvent | React.KeyboardEvent): boolean { return IS_MAC ? e.metaKey : e.ctrlKey; }\n","import * as React from \"react\";\n\n// Badge's \"live\" / \"approved\" / \"count\" tones carry their own gradients and bespoke\n// height/padding, not just color — that's a pill treatment, not a toggle-chip one, so\n// Tag only takes the flat, token-only tones that drop in as background/border/color.\nconst TONES: Record<string, string> = { info: \"fd-tag-info\", success: \"fd-tag-success\", warning: \"fd-tag-warning\", danger: \"fd-tag-danger\" };\n\n/** A clickable chip — filters, selected campuses, applied channels. */\nexport interface TagProps {\n children?: React.ReactNode;\n icon?: string;\n selected?: boolean;\n /** Colors the chip once selected — e.g. a favoured (\"success\") or excluded (\"danger\") toggle. No effect while unselected. */\n tone?: \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\";\n onRemove?: () => void;\n onClick?: () => void;\n className?: string;\n}\n\nexport function Tag({ children, icon, selected = false, tone = \"neutral\", onRemove, onClick, className = \"\", ...rest }: TagProps) {\n return (\n <button type=\"button\" className={[\"fd-tag\", selected ? TONES[tone] : null, className].filter(Boolean).join(\" \")}\n aria-pressed={selected} onClick={onClick} {...rest}>\n {icon ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {children}\n {onRemove ? (\n <span className=\"fd-tag-remove\" role=\"button\" aria-label=\"Remove\"\n onClick={(e) => { e.stopPropagation(); onRemove(); }}><i className=\"ph ph-x\" /></span>\n ) : null}\n </button>\n );\n}\n","import * as React from \"react\";\n\nconst ICON: Record<string, { i: string; bg: string }> = {\n success: { i: \"check\", bg: \"var(--ok-solid)\" },\n error: { i: \"x\", bg: \"var(--danger-solid)\" },\n info: { i: \"info\", bg: \"var(--info-solid)\" },\n loading: { i: \"\", bg: \"var(--n-500)\" },\n};\n\n/** Confirmation of something that already happened. Bottom-right, 5s, undo where reversible. */\nexport interface ToastProps {\n title: React.ReactNode;\n children?: React.ReactNode;\n tone?: \"success\" | \"error\" | \"info\" | \"loading\";\n onUndo?: () => void;\n onDismiss?: () => void;\n className?: string;\n}\n\nexport function Toast({ title, children, tone = \"success\", onUndo, onDismiss, className = \"\", ...rest }: ToastProps) {\n const ic = ICON[tone] || ICON.info;\n return (\n <div className={[\"fd-toast\", className].filter(Boolean).join(\" \")} role=\"status\" {...rest}>\n <span className=\"fd-toast-icon\" style={{ background: ic.bg }} aria-hidden=\"true\">\n {tone === \"loading\" ? <span className=\"fd-spinner\" style={{ width: 12, height: 12, borderWidth: 2, color: \"#fff\" }} /> : <i className={\"ph ph-\" + ic.i} />}\n </span>\n <span className=\"fd-toast-body\">\n <span className=\"fd-toast-title\" style={{ display: \"block\" }}>{title}</span>\n {children ? <span className=\"fd-secondary\" style={{ display: \"block\", marginTop: 2 }}>{children}</span> : null}\n {onUndo ? <button type=\"button\" className=\"fd-btn fd-btn-link\" style={{ marginTop: 8 }} onClick={onUndo}>Undo</button> : null}\n </span>\n {onDismiss ? <button type=\"button\" className=\"fd-btn-icon fd-btn-icon-sm\" aria-label=\"Dismiss\" onClick={onDismiss}><i className=\"ph ph-x\" /></button> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** A short clarification on hover or focus. Never the only place information lives. */\nexport interface TooltipProps {\n label: React.ReactNode;\n placement?: \"top\" | \"bottom\";\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Tooltip({ label, placement = \"top\", children, className = \"\" }: TooltipProps) {\n const [show, setShow] = React.useState(false);\n const pos = placement === \"bottom\"\n ? { top: \"calc(100% + 8px)\", left: \"50%\", transform: \"translateX(-50%)\" }\n : { bottom: \"calc(100% + 8px)\", left: \"50%\", transform: \"translateX(-50%)\" };\n return (\n <span style={{ position: \"relative\", display: \"inline-flex\" }}\n onMouseEnter={() => setShow(true)} onMouseLeave={() => setShow(false)}\n onFocus={() => setShow(true)} onBlur={() => setShow(false)}>\n {children}\n {show ? <span className={[\"fd-tooltip\", className].filter(Boolean).join(\" \")} role=\"tooltip\" style={pos}>{label}</span> : null}\n </span>\n );\n}\n","import * as React from \"react\";\n\nexport interface ClampProps {\n children?: React.ReactNode;\n /** With maxChars, pass the raw string instead of children. */\n text?: string;\n maxChars?: number;\n maxHeight?: number;\n moreLabel?: string;\n lessLabel?: string;\n onToggle?: (open: boolean) => void;\n className?: string;\n}\n\n/**\n * Height- or character-clamped content with a Show more control.\n * The control is a real button, always in the DOM when the content overflows.\n */\nexport function Clamp({\n children, text, maxChars, maxHeight = 320,\n moreLabel = \"Show more\", lessLabel = \"Show less\",\n onToggle, className = \"\",\n}: ClampProps) {\n const [open, setOpen] = React.useState(false);\n const [overflows, setOverflows] = React.useState(false);\n const bodyRef = React.useRef<HTMLDivElement>(null);\n\n const charClamped = React.useMemo(() => {\n if (open || !maxChars || typeof text !== \"string\" || text.length <= maxChars) return null;\n const cut = text.slice(0, maxChars);\n const at = cut.lastIndexOf(\" \");\n return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + \"…\";\n }, [text, maxChars, open]);\n\n React.useLayoutEffect(() => {\n const node = bodyRef.current;\n if (maxChars || !node || !maxHeight) return;\n const measure = () => {\n const el = bodyRef.current;\n if (el) setOverflows(el.scrollHeight > maxHeight + 24);\n };\n measure();\n const RO = typeof ResizeObserver !== \"undefined\" ? ResizeObserver : null;\n if (!RO) return;\n const ro = new RO(measure);\n ro.observe(node);\n return () => ro.disconnect();\n }, [maxHeight, maxChars, children, text]);\n\n const clamped = maxChars ? !!charClamped : overflows && !open;\n const toggle = () => { setOpen((v) => { onToggle && onToggle(!v); return !v; }); };\n\n return (\n <div className={[\"fd-clamp\", clamped ? \"is-clamped\" : \"\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-clamp-body\" ref={bodyRef} style={!maxChars && clamped ? { maxHeight } : undefined}>\n {maxChars ? (charClamped != null ? charClamped : (text != null ? text : children)) : children}\n </div>\n {(maxChars ? (charClamped != null || open) : overflows) ? (\n <button type=\"button\" className=\"fd-clamp-more\" onClick={toggle} aria-expanded={open}>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n {open ? lessLabel : moreLabel}\n </button>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\nconst BANDS: Record<string, { n: number; label: string }> = {\n weak: { n: 1, label: \"Weak\" },\n adequate: { n: 2, label: \"Adequate\" },\n strong: { n: 3, label: \"Strong\" },\n dominant: { n: 4, label: \"Dominant\" },\n};\n\n/** CRP is a derived float (e.g. 151.63707315984357) — never render it raw. One decimal\n * matches every other CRP display in this library (BudgetReallocator, ChannelContribution). */\nfunction formatCrp(crp: number): string {\n return crp.toFixed(1);\n}\n\nexport interface CsiMeterProps {\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n size?: number;\n width?: number;\n gap?: number;\n}\n\nexport function CsiMeter({ band = \"weak\", size = 4, width = 5, gap = 2 }: CsiMeterProps) {\n const n = (BANDS[band] || BANDS.weak).n;\n return (\n <span className=\"fd-meter\" style={{ gap: gap + \"px\" }} aria-hidden=\"true\">\n {[1, 2, 3, 4].map((i) => (\n <span\n key={i}\n className={\"fd-meter-seg\" + (i <= n ? \" is-on\" : \"\")}\n style={{ width: width + \"px\", height: size + \"px\" }}\n />\n ))}\n </span>\n );\n}\n\n/**\n * Campus Saturation Index — the product's signature encoding. Four ordered bands\n * in a reserved teal ramp that appears nowhere else: blue is interaction, teal is\n * saturation. Never color-only — the band name and a 4-segment meter always ship\n * with the fill.\n */\nexport interface CsiBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n /** Cost per reachable person. Internal surfaces only — never client-facing. */\n crp?: number;\n size?: \"compact\" | \"medium\";\n /** The \"will become\" state while a reallocation is being dragged: 70% opacity, dashed edge. */\n preview?: boolean;\n /** Amber dot marking a Weak campus that can be fixed. */\n alert?: boolean;\n}\n\nexport function CsiBadge({ band = \"weak\", crp, size = \"compact\", preview = false, alert = false, className = \"\", ...rest }: CsiBadgeProps) {\n const b = BANDS[band] || BANDS.weak;\n return (\n <span\n className={[\"fd-csi\", \"fd-csi-\" + b.n, size === \"medium\" ? \"fd-csi-medium\" : \"fd-csi-compact\", preview ? \"fd-csi-preview\" : \"\", className].filter(Boolean).join(\" \")}\n {...rest}\n >\n {alert ? <span className=\"fd-badge-dot\" style={{ background: \"var(--csi-alert)\" }} aria-label=\"Fixable\" /> : null}\n <CsiMeter band={band} size={size === \"medium\" ? 11 : 9} width={size === \"medium\" ? 4 : 3} />\n {b.label}\n {crp !== undefined && crp !== null ? <span className=\"fd-csi-crp\">{formatCrp(crp)}</span> : null}\n </span>\n );\n}\n\nexport interface CsiHeroProps {\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n crp?: number;\n label?: string;\n className?: string;\n}\n\nexport function CsiHero({ band = \"weak\", crp, label, className = \"\" }: CsiHeroProps) {\n const b = BANDS[band] || BANDS.weak;\n const mark = \"var(--csi-\" + b.n + \"-mark)\";\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 10 }}>\n <span className=\"fd-csi-hero-num\" style={{ color: mark }}>\n {crp !== undefined && crp !== null ? formatCrp(crp) : \"\"}\n </span>\n <span className=\"fd-label-lg\" style={{ color: \"var(--text-2)\" }}>{label || b.label}</span>\n <span className=\"fd-meter\" style={{ gap: 3, color: mark, width: 120 } as React.CSSProperties}>\n {[1, 2, 3, 4].map((i) => (\n <span key={i} className={\"fd-meter-seg\" + (i <= b.n ? \" is-on\" : \"\")} style={{ height: 6, flex: 1 }} />\n ))}\n </span>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The product's dense read surface. Sticky overline header, hairline rows, no zebra,\n * numbers right-aligned and tabular. Renders its own skeleton rows so the table\n * never collapses while data is in flight.\n */\nexport interface DataTableColumn {\n key: string;\n label: string;\n /** Right-aligned tabular figures. Never center a number. */\n numeric?: boolean;\n /** Set widths explicitly; auto layout shifts as data arrives. */\n width?: string;\n sortable?: boolean;\n render?: (row: any) => React.ReactNode;\n}\nexport interface DataTableProps {\n columns: DataTableColumn[];\n rows: any[];\n compact?: boolean;\n selectedId?: string | number;\n onRowClick?: (row: any) => void;\n rowKey?: string;\n /** First load: nothing on screen yet, so skeleton rows are drawn. */\n loading?: boolean;\n /** A re-query (sort, filter, page) while the PREVIOUS rows are still rendered. Dims them,\n * makes them inert and shows an \"Updating…\" pill, so nobody acts on superseded data. */\n refreshing?: boolean;\n skeletonRows?: number;\n sort?: { key: string; dir: \"asc\" | \"desc\" };\n onSort?: (key: string) => void;\n className?: string;\n}\n\nexport function DataTable({\n columns = [], rows = [], compact = false, selectedId, onRowClick, rowKey = \"id\",\n loading = false, refreshing = false, skeletonRows = 6, sort, onSort, className = \"\", ...rest\n}: DataTableProps) {\n /* `loading` is the first load: no rows exist, so draw skeletons.\n `refreshing` is a re-query (sort, filter, page) where the OLD rows are still on screen —\n they must read as not-current, or the user acts on data the server has already superseded.\n Reuses the design system's documented stale tier (skeleton.css: fd-stale-region + fd-stale,\n dimmed, inert, with a sheen) and adds only the explicit label that tier lacks. */\n const stale = refreshing && !loading;\n /* The overlay lives in a host OUTSIDE .fd-table-wrap on purpose. The wrap carries\n overflow:auto for wide tables, which makes it the nearest scrollport — so a sticky pill\n inside it can never stick to the page's real scroller and scrolled straight off screen.\n The host has no overflow, so sticky resolves against .fd-scroll as intended.\n Rendered unconditionally so toggling stale causes no layout shift. */\n return (\n <div className=\"fd-table-host\">\n <div className={[\"fd-table-wrap\", className].filter(Boolean).join(\" \")}\n aria-busy={loading || refreshing ? \"true\" : undefined} {...rest}>\n <table className={[\"fd-table\", compact ? \"fd-table-compact\" : \"\"].filter(Boolean).join(\" \")}>\n <thead>\n <tr>\n {columns.map((c) => (\n <th key={c.key} scope=\"col\" style={{ width: c.width }}\n className={[c.numeric ? \"is-num\" : \"\", sort && sort.key === c.key ? \"is-sorted\" : \"\"].filter(Boolean).join(\" \")}\n aria-sort={sort && sort.key === c.key ? (sort.dir === \"asc\" ? \"ascending\" : \"descending\") : undefined}>\n {c.sortable && onSort ? (\n <button type=\"button\" onClick={() => onSort(c.key)}>\n {c.label}\n {sort && sort.key === c.key ? <i className={\"ph fd-caret ph-caret-\" + (sort.dir === \"asc\" ? \"up\" : \"down\")} /> : null}\n </button>\n ) : c.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className={stale ? \"fd-stale\" : undefined}>\n {loading\n ? Array.from({ length: skeletonRows }).map((_, i) => (\n <tr key={i}>\n {columns.map((c) => (\n <td key={c.key} className={c.numeric ? \"is-num\" : \"\"}>\n <span className=\"fd-skel fd-skel-text\" style={{ display: \"inline-block\", height: 13, width: c.numeric ? 52 : (i % 3 === 0 ? \"72%\" : \"88%\") }} />\n </td>\n ))}\n </tr>\n ))\n : rows.map((r) => (\n <tr key={r[rowKey]} aria-selected={selectedId === r[rowKey] ? \"true\" : undefined}\n onClick={onRowClick ? () => onRowClick(r) : undefined}\n style={onRowClick ? { cursor: \"pointer\" } : undefined}>\n {columns.map((c) => (\n <td key={c.key} className={c.numeric ? \"is-num\" : \"\"}>\n {c.render ? c.render(r) : r[c.key]}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {stale ? (\n <div className=\"fd-table-stale\">\n <span className=\"fd-table-stale-pill\" role=\"status\"><span className=\"fd-spinner\" aria-hidden=\"true\" /> Updating…</span>\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Button } from \"../actions/Button\";\nimport { Tag } from \"../feedback/Tag\";\n\nexport interface FilterFieldOption {\n value: string;\n label: string;\n}\n\ninterface FilterFieldBase {\n /** Filter id — the key this field reads/writes in `filters` and reports through\n * onFilterChange/onFilterRemove. Matches useServerTable's setFilter(id, value). */\n key: string;\n /** Human label shown in the \"add filter\" list and on the field's chip. */\n label: string;\n}\n\nexport interface FilterFieldText extends FilterFieldBase {\n type: \"text\";\n placeholder?: string;\n}\n\nexport interface FilterFieldSelect extends FilterFieldBase {\n type: \"select\";\n options: FilterFieldOption[];\n}\n\n/** A declared filter field. Add a variant here (and a branch below) for a new value picker. */\nexport type FilterField = FilterFieldText | FilterFieldSelect;\n\nexport interface FilterBarProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"onChange\"> {\n /** Every filter a consumer can add. Order here is the order in the \"add filter\" list. */\n fields: FilterField[];\n /** Straight off useServerTable — a value of undefined/\"\"/false reads as \"not set\",\n * same convention that hook already uses for activeFilterCount. */\n filters: Record<string, unknown>;\n /** Fires on every value edit. Maps 1:1 onto useServerTable's setFilter(id, value). */\n onFilterChange: (key: string, value: unknown) => void;\n /** Fires when a chip's × is clicked. Maps 1:1 onto useServerTable's clearFilter(id). */\n onFilterRemove: (key: string) => void;\n /** Which edge the \"add filter\" popover aligns to. Default \"left\" — the trigger sits\n * at the end of a left-to-right chip row, so its menu opens under its left edge. */\n align?: \"left\" | \"right\";\n className?: string;\n}\n\ntype Panel = { kind: \"add\" } | { kind: \"edit\"; key: string } | null;\n\n/** Same \"is this filter set\" rule as useServerTable's activeFilterCount, so a value this\n * component didn't just write (e.g. restored from a URL) still renders as a chip. */\nconst isSet = (v: unknown): boolean => !(v == null || v === \"\" || v === false);\n\n/**\n * FilterBar — the declarative filter system for a server-driven list.\n *\n * A consumer declares fields once (`{ key, label, type: \"text\" | \"select\", ... }`) and\n * hands this a live `filters` record plus onFilterChange/onFilterRemove — the same three\n * things useServerTable already exposes, so wiring one up is copy-paste, not glue code.\n * Every active filter renders as a Tag chip; this component holds no shadow copy of\n * filter values, only the transient \"which field's popover/input is open right now\" UI\n * state (`panel`), the same way SortMenu holds `open` but never sort state itself.\n *\n * Visual/interaction language is deliberately identical to SortMenu: a secondary Button\n * trigger, a `fd-view-enter` panel positioned with `top: calc(100% + 6px)`, the same\n * click-outside/Escape wiring, and the same `fd-stack`/`fd-row`/`fd-overline`/`fd-muted`/\n * `fd-body-sm` utility classes — so this reads as built by the same hand, not a new\n * import from elsewhere.\n */\nexport function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = \"left\", className = \"\", ...rest }: FilterBarProps) {\n const [panel, setPanel] = React.useState<Panel>(null);\n const rootRef = React.useRef<HTMLSpanElement>(null);\n const textInputRef = React.useRef<HTMLInputElement>(null);\n const optionsRef = React.useRef<HTMLSpanElement>(null);\n\n const editingField = panel && panel.kind === \"edit\" ? fields.find((f) => f.key === panel.key) : undefined;\n // The \"add\" list and a select field's option list are floating overlays that can be\n // dismissed by clicking anywhere else or pressing Escape — a text field's inline input\n // is dismissed by its own onBlur/onKeyDown instead, so it doesn't need this listener.\n const dismissible = !!panel && (panel.kind === \"add\" || (panel.kind === \"edit\" && editingField?.type === \"select\"));\n\n React.useEffect(() => {\n if (!dismissible) return;\n const away = (e: PointerEvent) => { if (rootRef.current && !rootRef.current.contains(e.target as Node)) setPanel(null); };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setPanel(null); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [dismissible]);\n\n // Focus lands in the field's new value input the moment it's added — a text field's\n // own <input>, or the currently-selected (else first) option in a select field's list.\n React.useEffect(() => {\n if (!panel || panel.kind !== \"edit\") return;\n if (editingField?.type === \"text\") {\n textInputRef.current?.focus();\n } else if (editingField?.type === \"select\" && optionsRef.current) {\n const target =\n optionsRef.current.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]') ||\n optionsRef.current.querySelector<HTMLButtonElement>(\"button\");\n target?.focus();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [panel]);\n\n const addableFields = fields.filter((f) => !isSet(filters[f.key]));\n\n const startEditing = (key: string) => setPanel({ kind: \"edit\", key });\n\n return (\n <span className={className} style={{ position: \"relative\", display: \"inline-flex\", flexWrap: \"wrap\", alignItems: \"center\", gap: 8 }} ref={rootRef} {...rest}>\n {fields.map((field) => {\n const value = filters[field.key];\n const editing = panel?.kind === \"edit\" && panel.key === field.key;\n\n if (editing && field.type === \"text\") {\n return (\n <span\n key={field.key}\n className=\"fd-tag\"\n style={{ background: \"var(--surface-brand)\", borderColor: \"var(--border-brand)\", cursor: \"text\" }}\n >\n <input\n ref={textInputRef}\n value={(value as string | undefined) ?? \"\"}\n placeholder={field.placeholder || field.label}\n aria-label={field.label}\n onChange={(e) => onFilterChange(field.key, e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") setPanel(null);\n else if (e.key === \"Escape\") { e.stopPropagation(); setPanel(null); }\n }}\n onBlur={() => setPanel(null)}\n style={{ all: \"unset\", minWidth: 90, color: \"var(--text-on-surface-brand)\" }}\n />\n {isSet(value) ? (\n <span\n className=\"fd-tag-remove\"\n role=\"button\"\n aria-label={\"Remove \" + field.label}\n onClick={(e) => { e.stopPropagation(); onFilterRemove(field.key); setPanel(null); }}\n >\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </span>\n ) : null}\n </span>\n );\n }\n\n if (editing && field.type === \"select\") {\n const chosen = field.options.find((o) => o.value === value);\n return (\n <span key={field.key} style={{ position: \"relative\", display: \"inline-flex\" }}>\n <Tag selected onClick={() => setPanel(null)} onRemove={() => { if (isSet(value)) onFilterRemove(field.key); setPanel(null); }}>\n {field.label}{chosen ? \": \" + chosen.label : \"\"}\n </Tag>\n <span\n className=\"fd-view-enter\"\n style={{ position: \"absolute\", top: \"calc(100% + 6px)\", left: 0, zIndex: 120, minWidth: 200, maxWidth: \"calc(100vw - 32px)\", display: \"block\", background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 10, boxShadow: \"0 16px 44px rgba(11,13,17,.18)\", padding: 8 }}\n >\n <span className=\"fd-stack\" role=\"listbox\" aria-label={field.label} ref={optionsRef} style={{ gap: 2 }}>\n {field.options.map((o) => {\n const on = o.value === value;\n return (\n <button\n type=\"button\" key={o.value} role=\"option\" aria-selected={on}\n className=\"fd-row\"\n onClick={() => { onFilterChange(field.key, o.value); setPanel(null); }}\n style={{ gap: 8, padding: \"4px 8px\", borderRadius: 7, border: 0, width: \"100%\", textAlign: \"left\", cursor: \"pointer\", background: on ? \"var(--surface-brand)\" : \"transparent\" }}\n >\n <span className=\"fd-body-sm\" style={{ flex: 1, fontWeight: on ? 700 : 500, color: on ? \"var(--text-on-surface-brand)\" : \"var(--text)\" }}>{o.label}</span>\n </button>\n );\n })}\n </span>\n </span>\n </span>\n );\n }\n\n if (isSet(value)) {\n const chosen = field.type === \"select\" ? field.options.find((o) => o.value === value) : undefined;\n const display = chosen ? chosen.label : String(value);\n return (\n <Tag key={field.key} selected onClick={() => startEditing(field.key)} onRemove={() => onFilterRemove(field.key)}>\n {field.label}: {display}\n </Tag>\n );\n }\n\n return null;\n })}\n\n {addableFields.length > 0 ? (\n <span style={{ position: \"relative\", display: \"inline-flex\" }}>\n <Button\n size=\"sm\" variant=\"secondary\" icon=\"funnel\"\n aria-haspopup=\"menu\" aria-expanded={panel?.kind === \"add\"}\n onClick={() => setPanel(panel?.kind === \"add\" ? null : { kind: \"add\" })}\n >\n Filter\n </Button>\n {panel?.kind === \"add\" ? (\n <span\n className=\"fd-view-enter\"\n style={{ position: \"absolute\", top: \"calc(100% + 6px)\", [align]: 0, zIndex: 120, width: 220, maxWidth: \"calc(100vw - 32px)\", display: \"block\", background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 10, boxShadow: \"0 16px 44px rgba(11,13,17,.18)\", padding: 8 } as React.CSSProperties}\n >\n <span className=\"fd-stack\" role=\"menu\" aria-label=\"Add filter\" style={{ gap: 2 }}>\n <span className=\"fd-overline fd-muted\" style={{ padding: \"4px 8px 6px\" }}>Add filter</span>\n {addableFields.map((f) => (\n <button\n type=\"button\" key={f.key} role=\"menuitem\"\n className=\"fd-row\"\n onClick={() => startEditing(f.key)}\n style={{ gap: 8, padding: \"4px 8px\", borderRadius: 7, border: 0, width: \"100%\", textAlign: \"left\", cursor: \"pointer\", background: \"transparent\" }}\n >\n <span className=\"fd-body-sm\" style={{ flex: 1, color: \"var(--text)\" }}>{f.label}</span>\n </button>\n ))}\n </span>\n </span>\n ) : null}\n </span>\n ) : null}\n </span>\n );\n}\n","import * as React from \"react\";\n\n/**\n * A flat figure tile — no shadow, no background color, never more than four in a row.\n */\nexport interface StatTileProps extends React.HTMLAttributes<HTMLDivElement> {\n label: string;\n value?: React.ReactNode;\n sub?: React.ReactNode;\n /** \"+12.4%\" or \"-3.1%\" — colour and arrow follow the sign. */\n delta?: string;\n loading?: boolean;\n /** Thin one-line variant for stat rows above tables. */\n compact?: boolean;\n className?: string;\n}\n\nexport function StatTile({ label, value, sub, delta, loading = false, compact = false, className = \"\", ...rest }: StatTileProps) {\n return (\n <div className={[\"fd-stat\", compact ? \"fd-stat-compact\" : \"\", className].filter(Boolean).join(\" \")} {...rest}>\n {loading\n ? <span className=\"fd-skel fd-skel-text\" style={{ display: \"block\", height: compact ? 20 : 28, width: \"62%\" }} />\n : (\n <span className=\"fd-stat-top\">\n <span className=\"fd-stat-figure\">{value}</span>\n {delta ? (\n <span className={delta.startsWith(\"-\") ? \"fd-stat-delta-down\" : \"fd-stat-delta-up\"} style={{ fontWeight: 600, fontSize: \"var(--body-sm-size)\", flex: \"none\" }}>\n <i className={\"ph ph-arrow-\" + (delta.startsWith(\"-\") ? \"down\" : \"up\") + \"-right\"} aria-hidden=\"true\" /> {delta}\n </span>\n ) : null}\n </span>\n )}\n {!loading && sub ? <span className=\"fd-stat-sub\">{sub}</span> : null}\n {loading\n ? <span className=\"fd-skel fd-skel-text\" style={{ display: \"block\", height: 10, width: \"40%\", marginTop: 8 }} />\n : <span className=\"fd-stat-label\" style={{ display: \"block\" }}>{label}</span>}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/* ── highlighting ──────────────────────────────────────────────────────────\n A small, dependency-free tokenizer. It emits classed spans (real nodes, no\n HTML strings), so themes live in CSS and there is no injection surface. */\n\nconst JS_KW = /^(?:const|let|var|function|return|if|else|for|while|do|new|class|extends|import|from|export|default|await|async|try|catch|finally|throw|typeof|instanceof|of|in|switch|case|break|continue|delete|void|yield|static|get|set|this|super|interface|type|enum|implements|public|private|protected|readonly|abstract|as|satisfies|declare|namespace)$/;\n\ntype RuleClass = string | null;\ntype Rule = [RegExp, RuleClass | ((t: string) => RuleClass)];\n\nconst RULES: Record<string, Rule[]> = {\n js: [\n [/\\/\\/[^\\n]*/y, \"com\"], [/\\/\\*[\\s\\S]*?\\*\\//y, \"com\"],\n [/`(?:\\\\[\\s\\S]|\\$\\{[^}]*\\}|[^`\\\\])*`?/y, \"str\"],\n [/'(?:\\\\[\\s\\S]|[^'\\\\\\n])*'?/y, \"str\"], [/\"(?:\\\\[\\s\\S]|[^\"\\\\\\n])*\"?/y, \"str\"],\n [/\\b(?:true|false|null|undefined|NaN|Infinity)\\b/y, \"lit\"],\n [/\\b0[xb][0-9a-f_]+\\b|\\b\\d[\\d_]*(?:\\.\\d+)?(?:e[+-]?\\d+)?\\b/iy, \"num\"],\n [/[A-Za-z_$][\\w$]*/y, (t) => (JS_KW.test(t) ? \"kw\" : /^[A-Z]/.test(t) ? \"type\" : null)],\n [/[{}()[\\];,.]/y, \"pun\"], [/[+\\-*/%=<>!&|?:^~]+/y, \"op\"],\n ],\n py: [\n [/#[^\\n]*/y, \"com\"],\n [/\"\"\"[\\s\\S]*?\"\"\"|'''[\\s\\S]*?'''/y, \"str\"],\n [/f?'(?:\\\\[\\s\\S]|[^'\\\\\\n])*'?|f?\"(?:\\\\[\\s\\S]|[^\"\\\\\\n])*\"?/y, \"str\"],\n [/\\b(?:True|False|None)\\b/y, \"lit\"],\n [/\\b\\d[\\d_]*(?:\\.\\d+)?\\b/y, \"num\"],\n [/@[A-Za-z_][\\w.]*/y, \"fn\"],\n [/[A-Za-z_][\\w]*/y, (t) => (/^(?:def|class|return|if|elif|else|for|while|import|from|as|with|try|except|finally|raise|lambda|yield|global|nonlocal|assert|pass|break|continue|del|in|is|not|and|or|async|await|self)$/.test(t) ? \"kw\" : /^[A-Z]/.test(t) ? \"type\" : null)],\n [/[{}()[\\];,.:]/y, \"pun\"], [/[+\\-*/%=<>!&|^~]+/y, \"op\"],\n ],\n css: [\n [/\\/\\*[\\s\\S]*?\\*\\//y, \"com\"],\n [/'(?:[^'\\\\\\n]|\\\\.)*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/--[\\w-]+/y, \"type\"],\n [/@[\\w-]+/y, \"kw\"],\n [/#[0-9a-f]{3,8}\\b/iy, \"num\"],\n [/\\b\\d*\\.?\\d+(?:px|rem|em|%|vh|vw|s|ms|deg|fr|ch)?\\b/y, \"num\"],\n [/[.#]?[\\w-]+(?=\\s*\\{)/y, \"fn\"],\n [/[\\w-]+(?=\\s*:)/y, \"prop\"],\n [/[{}();:,]/y, \"pun\"], [/[>+~*]/y, \"op\"],\n ],\n html: [\n [/<!--[\\s\\S]*?-->/y, \"com\"],\n [/<\\/?[A-Za-z][\\w-]*/y, \"kw\"],\n [/'(?:[^'\\\\\\n]|\\\\.)*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/[A-Za-z-]+(?==)/y, \"prop\"],\n [/[<>/=]/y, \"pun\"],\n ],\n json: [\n [/\"(?:\\\\[\\s\\S]|[^\"\\\\])*\"(?=\\s*:)/y, \"prop\"],\n [/\"(?:\\\\[\\s\\S]|[^\"\\\\])*\"/y, \"str\"],\n [/\\b(?:true|false|null)\\b/y, \"lit\"],\n [/-?\\b\\d[\\d.]*(?:e[+-]?\\d+)?\\b/iy, \"num\"],\n [/[{}[\\],:]/y, \"pun\"],\n ],\n sql: [\n [/--[^\\n]*/y, \"com\"], [/\\/\\*[\\s\\S]*?\\*\\//y, \"com\"],\n [/'(?:[^'\\\\]|\\\\.|'')*'/y, \"str\"],\n [/\\b\\d+(?:\\.\\d+)?\\b/y, \"num\"],\n [/[A-Za-z_][\\w]*/y, (t) => (/^(?:select|from|where|join|left|right|inner|outer|on|group|order|by|having|limit|offset|insert|into|values|update|set|delete|create|table|alter|drop|index|view|with|as|and|or|not|null|is|in|between|like|case|when|then|else|end|distinct|count|sum|avg|min|max|coalesce|cast|union|all|asc|desc)$/i.test(t) ? \"kw\" : null)],\n [/[(),.;*]/y, \"pun\"], [/[=<>!+\\-/%|]+/y, \"op\"],\n ],\n bash: [\n [/#[^\\n]*/y, \"com\"],\n [/'[^'\\n]*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/\\$\\{?[A-Za-z_][\\w]*\\}?|\\$\\d/y, \"type\"],\n [/(?:^|\\n)\\s*[a-z_][\\w-]*/y, \"fn\"],\n [/\\b(?:if|then|fi|else|elif|for|in|do|done|while|case|esac|function|return|export|local|source|echo|cd|set)\\b/y, \"kw\"],\n [/--?[\\w-]+/y, \"prop\"],\n [/[|&;()<>]/y, \"pun\"],\n ],\n yaml: [\n [/#[^\\n]*/y, \"com\"],\n [/^[ \\t]*-?[ \\t]*[\\w.-]+(?=:)/my, \"prop\"],\n [/'[^'\\n]*'|\"[^\"\\n]*\"/y, \"str\"],\n [/\\b(?:true|false|null|yes|no)\\b/iy, \"lit\"],\n [/\\b\\d[\\d.]*\\b/y, \"num\"],\n [/[:,\\-[\\]{}]/y, \"pun\"],\n ],\n generic: [\n [/\\/\\/[^\\n]*|#[^\\n]*/y, \"com\"],\n [/'(?:[^'\\\\\\n]|\\\\.)*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/\\b\\d[\\d._]*\\b/y, \"num\"],\n [/[{}()[\\];,.:]/y, \"pun\"],\n ],\n};\n\nconst ALIAS: Record<string, string> = {\n javascript: \"js\", jsx: \"js\", ts: \"js\", typescript: \"js\", tsx: \"js\", mjs: \"js\", node: \"js\", vue: \"html\", svelte: \"html\",\n python: \"py\", scss: \"css\", less: \"css\", sass: \"css\", xml: \"html\", svg: \"html\", htm: \"html\",\n json5: \"json\", jsonc: \"json\", postgres: \"sql\", psql: \"sql\", mysql: \"sql\",\n sh: \"bash\", shell: \"bash\", zsh: \"bash\", console: \"bash\", yml: \"yaml\",\n};\n\nexport function languageLabel(lang?: string): string {\n if (!lang) return \"\";\n const map: Record<string, string> = { js: \"JavaScript\", jsx: \"JSX\", ts: \"TypeScript\", tsx: \"TSX\", py: \"Python\", python: \"Python\", sh: \"Shell\", bash: \"Shell\", html: \"HTML\", css: \"CSS\", json: \"JSON\", sql: \"SQL\", yaml: \"YAML\", yml: \"YAML\", md: \"Markdown\", diff: \"Diff\", vue: \"Vue\", go: \"Go\", rb: \"Ruby\", php: \"PHP\", java: \"Java\", rust: \"Rust\", swift: \"Swift\", kt: \"Kotlin\", c: \"C\", cpp: \"C++\", cs: \"C#\" };\n return map[lang.toLowerCase()] || lang.toUpperCase();\n}\n\n/** Tokenise source into [{t, c}] where c is a token class or null for plain text. */\nexport function tokenize(src: string, lang?: string): Array<{ t: string; c: string | null }> {\n const key = ALIAS[(lang || \"\").toLowerCase()] || (RULES[(lang || \"\").toLowerCase()] ? (lang || \"\").toLowerCase() : \"generic\");\n const rules = RULES[key] || RULES.generic;\n const out: Array<{ t: string; c: string | null }> = [];\n const text = src.length > 24000 ? src.slice(0, 24000) : src;\n let i = 0, plain = \"\";\n const flush = () => { if (plain) { out.push({ t: plain, c: null }); plain = \"\"; } };\n while (i < text.length) {\n let hit: { t: string; c: string | null } | null = null;\n for (const [re, cls] of rules) {\n re.lastIndex = i;\n const m = re.exec(text);\n if (m && m.index === i && m[0].length) {\n const c = typeof cls === \"function\" ? cls(m[0]) : cls;\n hit = { t: m[0], c };\n break;\n }\n }\n if (hit) { flush(); out.push(hit); i += hit.t.length; }\n else { plain += text[i]; i++; }\n }\n flush();\n if (src.length > text.length) out.push({ t: \"\\n… truncated\", c: \"com\" });\n return out;\n}\n\nfunction Highlighted({ code, lang }: { code: string; lang?: string }) {\n const toks = React.useMemo(() => tokenize(code, lang), [code, lang]);\n return <>{toks.map((tk, i) => (tk.c ? <span key={i} className={\"tok-\" + tk.c}>{tk.t}</span> : tk.t))}</>;\n}\n\nfunction useCopy(): [boolean, (text: string) => void] {\n const [done, setDone] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n // Restart the window on a repeat copy, and clear it on unmount, or a second\n // copy inherits the first's remaining time and blinks out early.\n React.useEffect(() => () => { if (timer.current) clearTimeout(timer.current); }, []);\n const copy = (text: string) => {\n const write = navigator.clipboard && navigator.clipboard.writeText\n ? navigator.clipboard.writeText(text)\n : Promise.reject();\n write.catch(() => {\n try {\n const ta = document.createElement(\"textarea\");\n ta.value = text; ta.style.position = \"fixed\"; ta.style.opacity = \"0\";\n document.body.appendChild(ta); ta.select(); document.execCommand(\"copy\"); ta.remove();\n } catch { /* noop */ }\n }).finally(() => {\n setDone(true);\n if (timer.current) clearTimeout(timer.current);\n timer.current = setTimeout(() => setDone(false), 1600);\n });\n };\n return [done, copy];\n}\n\nexport interface CodeBlockProps {\n code: string;\n language?: string;\n filename?: string;\n lineNumbers?: boolean;\n wrap?: boolean;\n /** Fold past this many lines. 0 disables. Default 26. */\n collapseAfter?: number;\n copyable?: boolean;\n actions?: React.ReactNode;\n className?: string;\n}\n\n/**\n * A fenced code block: language label, copy, soft-wrap toggle, optional line\n * numbers, and a fold for long listings.\n */\nexport function CodeBlock({\n code = \"\", language, filename, lineNumbers = false, wrap: wrapDefault = false,\n collapseAfter = 26, copyable = true, actions, className = \"\",\n}: CodeBlockProps) {\n const [wrap, setWrap] = React.useState(!!wrapDefault);\n const [open, setOpen] = React.useState(false);\n const [copied, copy] = useCopy();\n const body = String(code).replace(/\\n$/, \"\");\n const lines = body.split(\"\\n\");\n const foldable = collapseAfter > 0 && lines.length > collapseAfter + 6;\n const shown = foldable && !open ? lines.slice(0, collapseAfter).join(\"\\n\") : body;\n\n return (\n <div className={[\"fd-code\", wrap ? \"is-wrap\" : \"\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-code-head\">\n {filename ? <span className=\"fd-code-file\">{filename}</span> : null}\n <span className=\"fd-code-lang\">{languageLabel(language)}</span>\n <span className=\"fd-code-spacer\" />\n {actions}\n <button type=\"button\" className=\"fd-code-act\" onClick={() => setWrap((v) => !v)} aria-pressed={wrap} title={wrap ? \"No wrap\" : \"Soft wrap\"}>\n <i className={\"ph ph-text-\" + (wrap ? \"columns\" : \"align-left\")} aria-hidden=\"true\" />\n </button>\n {copyable ? (\n <button type=\"button\" className={\"fd-code-act\" + (copied ? \" is-done\" : \"\")} onClick={() => copy(body)}>\n <i className={\"ph ph-\" + (copied ? \"check\" : \"copy\")} aria-hidden=\"true\" />\n <span>{copied ? \"Copied\" : \"Copy\"}</span>\n </button>\n ) : null}\n </div>\n <div className=\"fd-code-body\">\n {lineNumbers ? (\n <pre className=\"fd-code-gutter\" aria-hidden=\"true\">{shown.split(\"\\n\").map((_, i) => (i + 1) + \"\\n\").join(\"\")}</pre>\n ) : null}\n <pre className=\"fd-code-pre\" tabIndex={0}><code><Highlighted code={shown} lang={language} /></code></pre>\n </div>\n {foldable ? (\n <button type=\"button\" className=\"fd-code-fold\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n {open ? \"Collapse\" : \"Show all \" + lines.length + \" lines\"}\n </button>\n ) : null}\n </div>\n );\n}\n\nexport interface DiffBlockProps { diff: string; filename?: string; language?: string; collapseAfter?: number; className?: string }\n\n/**\n * A unified diff. Renders +/- lines with their own gutters and a stat line —\n * the shape a code change should always take in a transcript.\n */\nexport function DiffBlock({ diff = \"\", filename, collapseAfter = 34, className = \"\" }: DiffBlockProps) {\n const [open, setOpen] = React.useState(false);\n const [copied, copy] = useCopy();\n const raw = String(diff).replace(/\\n$/, \"\");\n const all = raw.split(\"\\n\").map((line) => {\n if (/^(?:diff |index |---|\\+\\+\\+)/.test(line)) return { k: \"meta\", line };\n if (/^@@/.test(line)) return { k: \"hunk\", line };\n if (line.startsWith(\"+\")) return { k: \"add\", line };\n if (line.startsWith(\"-\")) return { k: \"del\", line };\n return { k: \"ctx\", line };\n });\n const adds = all.filter((l) => l.k === \"add\").length;\n const dels = all.filter((l) => l.k === \"del\").length;\n const foldable = collapseAfter > 0 && all.length > collapseAfter + 6;\n const rows = foldable && !open ? all.slice(0, collapseAfter) : all;\n\n return (\n <div className={[\"fd-code\", \"fd-diff\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-code-head\">\n <i className=\"ph ph-git-diff fd-code-icon\" aria-hidden=\"true\" />\n {filename ? <span className=\"fd-code-file\">{filename}</span> : <span className=\"fd-code-lang\">Diff</span>}\n <span className=\"fd-diff-stat fd-tabular\"><span className=\"is-add\">+{adds}</span><span className=\"is-del\">−{dels}</span></span>\n <span className=\"fd-code-spacer\" />\n <button type=\"button\" className={\"fd-code-act\" + (copied ? \" is-done\" : \"\")} onClick={() => copy(raw)}>\n <i className={\"ph ph-\" + (copied ? \"check\" : \"copy\")} aria-hidden=\"true\" />\n <span>{copied ? \"Copied\" : \"Copy\"}</span>\n </button>\n </div>\n <div className=\"fd-diff-body\">\n {rows.map((r, i) => (\n <div key={i} className={\"fd-diff-line is-\" + r.k}>\n <span className=\"fd-diff-mark\" aria-hidden=\"true\">{r.k === \"add\" ? \"+\" : r.k === \"del\" ? \"−\" : \"\"}</span>\n <code>{r.k === \"add\" || r.k === \"del\" ? r.line.slice(1) : r.line}</code>\n </div>\n ))}\n </div>\n {foldable ? (\n <button type=\"button\" className=\"fd-code-fold\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n {open ? \"Collapse\" : \"Show all \" + all.length + \" lines\"}\n </button>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { CodeBlock, DiffBlock } from \"./CodeBlock\";\nimport type { CodeBlockProps } from \"./CodeBlock\";\n\n/* ── inline ────────────────────────────────────────────────────────────────\n Everything renders to real React nodes. There is no HTML-string path, so the\n injection surface is closed by construction rather than by escaping. */\n\nconst SAFE = /^(?:https?:|mailto:|tel:|#|\\/|\\.{1,2}\\/)/i;\nconst safeHref = (h: unknown): string | null => (SAFE.test(String(h || \"\").trim()) ? String(h).trim() : null);\n\nconst INLINE: Array<[string, RegExp]> = [\n [\"code\", /`([^`\\n]+)`/],\n [\"image\", /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/],\n [\"link\", /\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/],\n [\"cite\", /\\[\\^([\\w.-]+)\\]/],\n [\"strongem\", /\\*\\*\\*([^*]+)\\*\\*\\*/],\n [\"strong\", /\\*\\*([^*]+?)\\*\\*|__([^_]+?)__/],\n [\"em\", /(?<![A-Za-z0-9])\\*([^*\\n]+?)\\*(?![A-Za-z0-9])|(?<![A-Za-z0-9_])_([^_\\n]+?)_(?![A-Za-z0-9_])/],\n [\"del\", /~~([^~]+)~~/],\n [\"autolink\", /<((?:https?:\\/\\/|mailto:)[^>\\s]+)>/],\n [\"bare\", /(?<![\\w@/])(https?:\\/\\/[^\\s<>()]+[^\\s<>().,;:!?])/],\n];\n\ninterface MdCtx {\n allowImages?: boolean;\n headingOffset?: number;\n renderCitation?: (marker: string) => React.ReactNode;\n onLinkClick?: (e: React.MouseEvent) => void;\n codeProps?: Partial<CodeBlockProps>;\n}\n\nfunction inlineNodes(src: string | null | undefined, ctx: MdCtx, keyBase: string): React.ReactNode[] {\n const out: React.ReactNode[] = [];\n let rest = String(src == null ? \"\" : src), guard = 0;\n const key = () => keyBase + \"-\" + out.length;\n while (rest && guard++ < 800) {\n let best: { kind: string; m: RegExpExecArray } | null = null;\n for (const [kind, re] of INLINE) {\n const m = re.exec(rest);\n if (m && (!best || m.index < best.m.index)) best = { kind, m };\n if (best && best.m.index === 0) break;\n }\n if (!best) break;\n const { kind, m } = best;\n if (m.index > 0) out.push(rest.slice(0, m.index));\n const g = (i: number) => m[i];\n if (kind === \"code\") out.push(<code key={key()} className=\"fd-md-code\">{g(1)}</code>);\n else if (kind === \"image\") {\n const src2 = safeHref(g(2));\n out.push(ctx.allowImages && src2\n ? <img key={key()} className=\"fd-md-img\" src={src2} alt={g(1) || \"\"} title={g(3) || undefined} loading=\"lazy\" />\n : <span key={key()} className=\"fd-md-imgalt\">{g(1) || \"image\"}</span>);\n } else if (kind === \"link\") {\n const href = safeHref(g(2));\n out.push(href\n ? <a key={key()} href={href} title={g(3) || undefined} target={/^https?:/i.test(href) ? \"_blank\" : undefined} rel=\"noopener noreferrer\" onClick={ctx.onLinkClick}>{inlineNodes(g(1), ctx, key())}</a>\n : <span key={key()}>{g(1)}</span>);\n } else if (kind === \"cite\") {\n out.push(ctx.renderCitation ? <React.Fragment key={key()}>{ctx.renderCitation(g(1))}</React.Fragment> : <sup key={key()} className=\"fd-md-cite\">{g(1)}</sup>);\n } else if (kind === \"strongem\") out.push(<strong key={key()}><em>{inlineNodes(g(1), ctx, key())}</em></strong>);\n else if (kind === \"strong\") out.push(<strong key={key()}>{inlineNodes(g(1) || g(2), ctx, key())}</strong>);\n else if (kind === \"em\") out.push(<em key={key()}>{inlineNodes(g(1) || g(2), ctx, key())}</em>);\n else if (kind === \"del\") out.push(<del key={key()}>{inlineNodes(g(1), ctx, key())}</del>);\n else if (kind === \"autolink\" || kind === \"bare\") {\n const href = safeHref(g(1));\n out.push(href ? <a key={key()} href={href} target=\"_blank\" rel=\"noopener noreferrer\" onClick={ctx.onLinkClick}>{g(1).replace(/^mailto:/, \"\")}</a> : g(1));\n }\n rest = rest.slice(m.index + m[0].length);\n }\n if (rest) out.push(rest);\n return out;\n}\n\n/* ── blocks ────────────────────────────────────────────────────────────── */\n\nconst RE = {\n fence: /^(\\s*)(`{3,}|~{3,})\\s*([\\w+#-]*)\\s*(?::\\s*(\\S+))?\\s*$/,\n heading: /^(#{1,6})\\s+(.*)$/,\n hr: /^\\s*(?:[-*_]\\s*){3,}$/,\n quote: /^\\s*>\\s?(.*)$/,\n li: /^(\\s*)([-*+]|\\d{1,3}[.)])\\s+(.*)$/,\n task: /^\\[([ xX])\\]\\s+(.*)$/,\n tableSep: /^\\s*\\|?[\\s:|-]*-[\\s:|-]*\\|?\\s*$/,\n};\n\nconst splitRow = (line: string): string[] => line.replace(/^\\s*\\|/, \"\").replace(/\\|\\s*$/, \"\").split(\"|\").map((c) => c.trim());\n\ntype ListItem = { checked?: boolean; children: Block[] };\n\ntype Block =\n | { t: \"code\"; lang: string; file: string; code: string }\n | { t: \"h\"; level: number; text: string }\n | { t: \"hr\" }\n | { t: \"quote\"; children: Block[] }\n | { t: \"list\"; ordered: boolean; start: number; items: ListItem[] }\n | { t: \"table\"; head: string[]; align: string[]; rows: string[][] }\n | { t: \"p\"; text: string };\n\nfunction parseBlocks(src: string): Block[] {\n const lines = String(src == null ? \"\" : src).replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const blocks: Block[] = [];\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n if (!line.trim()) { i++; continue; }\n\n const f = RE.fence.exec(line);\n if (f) {\n const close = new RegExp(\"^\\\\s*\" + f[2][0] + \"{\" + f[2].length + \",}\\\\s*$\");\n const buf: string[] = [];\n i++;\n while (i < lines.length && !close.test(lines[i])) buf.push(lines[i++]);\n i++;\n blocks.push({ t: \"code\", lang: f[3] || \"\", file: f[4] || \"\", code: buf.join(\"\\n\") });\n continue;\n }\n const h = RE.heading.exec(line);\n if (h) { blocks.push({ t: \"h\", level: h[1].length, text: h[2] }); i++; continue; }\n if (RE.hr.test(line)) { blocks.push({ t: \"hr\" }); i++; continue; }\n if (RE.quote.test(line)) {\n const buf: string[] = [];\n while (i < lines.length && (RE.quote.test(lines[i]) || (lines[i].trim() && buf.length && !RE.li.test(lines[i]) && !RE.fence.test(lines[i])))) {\n const q = RE.quote.exec(lines[i]);\n buf.push(q ? q[1] : lines[i].trim());\n i++;\n }\n blocks.push({ t: \"quote\", children: parseBlocks(buf.join(\"\\n\")) });\n continue;\n }\n if (line.includes(\"|\") && lines[i + 1] != null && RE.tableSep.test(lines[i + 1]) && lines[i + 1].includes(\"-\")) {\n const head = splitRow(line);\n const align = splitRow(lines[i + 1]).map((c) => (/^:-+:$/.test(c) ? \"center\" : /-+:$/.test(c) ? \"right\" : \"left\"));\n i += 2;\n const rows: string[][] = [];\n while (i < lines.length && lines[i].includes(\"|\") && lines[i].trim()) rows.push(splitRow(lines[i++]));\n blocks.push({ t: \"table\", head, align, rows });\n continue;\n }\n if (RE.li.test(line)) {\n const items: { raw: string[] }[] = [];\n const baseIndent = RE.li.exec(line)![1].length;\n const ordered = /\\d/.test(RE.li.exec(line)![2]);\n const start = ordered ? parseInt(RE.li.exec(line)![2], 10) : 1;\n while (i < lines.length) {\n const m = RE.li.exec(lines[i]);\n if (!m || m[1].length < baseIndent) {\n if (items.length && lines[i] && lines[i].trim() && lines[i].search(/\\S/) > baseIndent) { items[items.length - 1].raw.push(lines[i].trim()); i++; continue; }\n break;\n }\n if (m[1].length > baseIndent) { items[items.length - 1].raw.push(lines[i].slice(baseIndent + 2)); i++; continue; }\n if (ordered !== /\\d/.test(m[2])) break;\n items.push({ raw: [m[3]] });\n i++;\n while (i < lines.length && lines[i].trim() && !RE.li.test(lines[i]) && lines[i].search(/\\S/) > baseIndent) { items[items.length - 1].raw.push(lines[i].trim()); i++; }\n }\n blocks.push({\n t: \"list\", ordered, start,\n items: items.map((it) => {\n const joined = it.raw.join(\"\\n\");\n const task = RE.task.exec(joined);\n return task\n ? { checked: task[1].toLowerCase() === \"x\", children: parseBlocks(task[2]) }\n : { children: parseBlocks(joined) };\n }),\n });\n continue;\n }\n const buf: string[] = [];\n while (i < lines.length && lines[i].trim() && !RE.fence.test(lines[i]) && !RE.heading.test(lines[i]) && !RE.hr.test(lines[i]) && !RE.quote.test(lines[i]) && !RE.li.test(lines[i])) buf.push(lines[i++]);\n blocks.push({ t: \"p\", text: buf.join(\"\\n\") });\n }\n return blocks;\n}\n\nfunction renderBlocks(blocks: Block[], ctx: MdCtx, path: string): React.ReactNode[] {\n return blocks.map((b, i) => {\n const k = path + \"-\" + i;\n switch (b.t) {\n case \"code\": {\n if ((b.lang || \"\").toLowerCase() === \"diff\") return <DiffBlock key={k} diff={b.code} filename={b.file || undefined} />;\n return <CodeBlock key={k} code={b.code} language={b.lang} filename={b.file || undefined} {...(ctx.codeProps || {})} />;\n }\n case \"h\": {\n const lvl = Math.min(6, Math.max(1, b.level + (ctx.headingOffset || 0)));\n const Tag = (\"h\" + lvl) as React.ElementType;\n return <Tag key={k} className={\"fd-md-h fd-md-h\" + lvl}>{inlineNodes(b.text, ctx, k)}</Tag>;\n }\n case \"hr\": return <hr key={k} className=\"fd-md-hr\" />;\n case \"quote\": return <blockquote key={k} className=\"fd-md-quote\">{renderBlocks(b.children, ctx, k)}</blockquote>;\n case \"list\": {\n const Tag = (b.ordered ? \"ol\" : \"ul\") as React.ElementType;\n const isTask = b.items.some((it) => it.checked != null);\n return (\n <Tag key={k} className={\"fd-md-list\" + (isTask ? \" is-task\" : \"\")} start={b.ordered && b.start !== 1 ? b.start : undefined}>\n {b.items.map((it, j) => (\n <li key={k + \"-\" + j} className={it.checked != null ? (it.checked ? \"is-done\" : \"is-todo\") : undefined}>\n {it.checked != null ? (\n <span className=\"fd-md-task\" aria-hidden=\"true\"><i className={\"ph ph-\" + (it.checked ? \"check-square\" : \"square\")} /></span>\n ) : null}\n <span className=\"fd-md-li\">{renderBlocks(it.children, ctx, k + \"-\" + j)}</span>\n </li>\n ))}\n </Tag>\n );\n }\n case \"table\":\n return (\n <div key={k} className=\"fd-md-tablewrap\">\n <table className=\"fd-md-table\">\n <thead><tr>{b.head.map((c, j) => <th key={j} style={{ textAlign: (b.align[j] || \"left\") as React.CSSProperties[\"textAlign\"] }}>{inlineNodes(c, ctx, k + \"h\" + j)}</th>)}</tr></thead>\n <tbody>\n {b.rows.map((r, ri) => (\n <tr key={ri}>{b.head.map((_, ci) => <td key={ci} style={{ textAlign: (b.align[ci] || \"left\") as React.CSSProperties[\"textAlign\"] }}>{inlineNodes(r[ci] || \"\", ctx, k + ri + \"c\" + ci)}</td>)}</tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n default:\n return <p key={k} className=\"fd-md-p\">{inlineNodes(b.text, ctx, k)}</p>;\n }\n });\n}\n\nexport interface MarkdownProps {\n source: string;\n className?: string;\n codeProps?: Partial<CodeBlockProps>;\n allowImages?: boolean;\n headingOffset?: number;\n /** Renderer for `[^n]` markers. */\n renderCitation?: (marker: string) => React.ReactNode;\n onLinkClick?: (e: React.MouseEvent) => void;\n}\n\n/**\n * Read-only markdown → React nodes. Headings, emphasis, links, lists (incl. task\n * lists), quotes, tables, images, fenced code (handed to CodeBlock, `diff` to\n * DiffBlock) and `[^n]` citation markers.\n *\n * Deliberately read-only: an editor in readonly mode carries a contenteditable,\n * a context menu and popovers it will never use — per message.\n */\nexport function Markdown({\n source = \"\", className = \"\", codeProps, allowImages = true,\n headingOffset = 0, renderCitation, onLinkClick,\n}: MarkdownProps) {\n const ctx: MdCtx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };\n const blocks = React.useMemo(() => parseBlocks(source), [source]);\n return <div className={[\"fd-md\", className].filter(Boolean).join(\" \")}>{renderBlocks(blocks, ctx, \"b\")}</div>;\n}\n\n/** Inline-only markdown, for labels and single-line contexts. */\nexport function MarkdownInline({ source = \"\", className = \"\", onLinkClick }: { source: string; className?: string; onLinkClick?: (e: React.MouseEvent) => void }) {\n return <span className={[\"fd-md-inline\", className].filter(Boolean).join(\" \")}>{inlineNodes(source, { allowImages: false, onLinkClick }, \"i\")}</span>;\n}\n\n/** Strip markdown to plain text — for copy actions, titles and previews. */\nexport function markdownToText(src: string): string {\n return String(src == null ? \"\" : src)\n .replace(/```[\\w+#-]*\\n?([\\s\\S]*?)```/g, \"$1\")\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/^\\s{0,3}#{1,6}\\s+/gm, \"\")\n .replace(/\\*\\*\\*([^*]+)\\*\\*\\*|\\*\\*([^*]+)\\*\\*|__([^_]+)__/g, \"$1$2$3\")\n .replace(/(^|\\W)[*_]([^*_\\n]+)[*_](\\W|$)/g, \"$1$2$3\")\n .replace(/~~([^~]+)~~/g, \"$1\")\n .replace(/^\\s*>\\s?/gm, \"\")\n .trim();\n}\n","\n/**\n * A segmented bar — budget split by channel, delivery against a flight.\n * Unallocated space is hatched, so it looks unfinished rather than empty.\n */\nexport interface MeterSegment {\n label: string;\n value: number;\n /** Defaults to the categorical chart ramp in order. */\n color?: string;\n}\nexport interface MeterProps {\n segments: MeterSegment[];\n unallocated?: number;\n height?: number;\n label?: string;\n legend?: boolean;\n className?: string;\n}\n\nexport function Meter({ segments = [], unallocated = 0, height = 8, label, legend = false, className = \"\" }: MeterProps) {\n const total = segments.reduce((s, x) => s + x.value, 0) + unallocated;\n const pct = (v: number) => (total ? (v / total) * 100 : 0);\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 8 }}>\n {label ? <span className=\"fd-label-lg fd-secondary\">{label}</span> : null}\n <div className=\"fd-meterbar\" style={{ height }}>\n {segments.map((s, i) => (\n <span key={i} className=\"fd-meterbar-seg\" title={s.label}\n style={{ width: pct(s.value) + \"%\", background: s.color || \"var(--chart-\" + ((i % 8) + 1) + \")\", transition: \"width var(--dur-slow) var(--ease)\" }} />\n ))}\n {unallocated > 0 ? <span className=\"fd-meterbar-seg fd-meterbar-unallocated\" title=\"Unallocated\" style={{ width: pct(unallocated) + \"%\" }} /> : null}\n </div>\n {legend ? (\n <div className=\"fd-row\" style={{ gap: 16, flexWrap: \"wrap\" }}>\n {segments.map((s, i) => (\n <span key={i} className=\"fd-row fd-body-sm fd-secondary\" style={{ gap: 7 }}>\n <span style={{ width: 9, height: 9, borderRadius: 2, background: s.color || \"var(--chart-\" + ((i % 8) + 1) + \")\" }} />\n {s.label}\n </span>\n ))}\n {unallocated > 0 ? (\n <span className=\"fd-row fd-body-sm fd-secondary\" style={{ gap: 7 }}>\n <span className=\"fd-meterbar-unallocated\" style={{ width: 9, height: 9, borderRadius: 2 }} />Unallocated\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The standard footer for a server-driven table: range readout, rows-per-page,\n * and windowed page navigation. Presentational only — it holds no state.\n */\nexport interface PaginationProps extends React.HTMLAttributes<HTMLDivElement> {\n /** 1-indexed current page. */\n page?: number;\n pageSize?: number;\n /** Total matching rows on the server, not the length of the current page. */\n total?: number;\n pageSizes?: number[];\n onPageChange?: (page: number) => void;\n /** Omit to hide the rows-per-page control. */\n onPageSizeChange?: (pageSize: number) => void;\n loading?: boolean;\n /** Noun for the readout — \"rows\", \"campuses\", \"placements\". */\n unit?: string;\n className?: string;\n}\n\n/**\n * Pagination — the standard footer for every server-driven table.\n * Purely presentational: it reports intent through onPageChange / onPageSizeChange\n * and never derives its own state, so it stays honest against a real endpoint.\n */\nexport function Pagination({\n page = 1, pageSize = 25, total = 0, pageSizes = [10, 25, 50, 100],\n onPageChange, onPageSizeChange, loading = false, unit = \"rows\", className = \"\", ...rest\n}: PaginationProps) {\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const from = total === 0 ? 0 : (page - 1) * pageSize + 1;\n const to = Math.min(total, page * pageSize);\n const go = (p: number) => { if (onPageChange && p >= 1 && p <= totalPages && p !== page) onPageChange(p); };\n\n const nums: (number | string)[] = [];\n const span = 1;\n for (let i = 1; i <= totalPages; i++) {\n if (i === 1 || i === totalPages || Math.abs(i - page) <= span) nums.push(i);\n else if (nums[nums.length - 1] !== \"…\") nums.push(\"…\");\n }\n\n return (\n <div className={[\"fd-pag\", className].filter(Boolean).join(\" \")} {...rest}>\n <span className=\"fd-pag-count\">\n {loading ? <span className=\"fd-skel fd-skel-text\" style={{ display: \"inline-block\", height: 12, width: 108 }} />\n : total === 0 ? <>No {unit}</> : <><strong>{from.toLocaleString()}–{to.toLocaleString()}</strong> of {total.toLocaleString()} {unit}</>}\n </span>\n {onPageSizeChange ? (\n <label className=\"fd-pag-size\">\n <span>Rows</span>\n <select value={pageSize} onChange={(e) => onPageSizeChange(Number(e.target.value))} aria-label=\"Rows per page\">\n {pageSizes.map((n) => <option key={n} value={n}>{n}</option>)}\n </select>\n </label>\n ) : null}\n <span className=\"fd-pag-nav\">\n <button type=\"button\" onClick={() => go(1)} disabled={page <= 1} aria-label=\"First page\"><i className=\"ph ph-caret-double-left\" /></button>\n <button type=\"button\" onClick={() => go(page - 1)} disabled={page <= 1} aria-label=\"Previous page\"><i className=\"ph ph-caret-left\" /></button>\n {nums.map((n, i) => n === \"…\"\n ? <span key={\"e\" + i} className=\"fd-pag-gap\" aria-hidden=\"true\">…</span>\n : <button key={n} type=\"button\" onClick={() => go(n as number)} aria-current={n === page ? \"page\" : undefined}\n className={n === page ? \"is-current\" : \"\"}>{n}</button>)}\n <button type=\"button\" onClick={() => go(page + 1)} disabled={page >= totalPages} aria-label=\"Next page\"><i className=\"ph ph-caret-right\" /></button>\n <button type=\"button\" onClick={() => go(totalPages)} disabled={page >= totalPages} aria-label=\"Last page\"><i className=\"ph ph-caret-double-right\" /></button>\n </span>\n </div>\n );\n}\n","import * as React from \"react\";\n\nconst MIN = 60e3, HOUR = 36e5, DAY = 864e5;\n\n/** \"just now\" · \"4 min ago\" · \"in 4 min\" · \"Wed 5:00 PM\" · \"12 Mar\" */\nexport function formatRelative(value: string | Date, now?: number): string {\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n if (!t || isNaN(t)) return \"\";\n const ref = now || Date.now();\n const diff = t - ref;\n const abs = Math.abs(diff);\n const future = diff > 0;\n if (abs < 45e3) return future ? \"in a moment\" : \"just now\";\n if (abs < HOUR) { const m = Math.round(abs / MIN); return future ? \"in \" + m + \" min\" : m + \" min ago\"; }\n if (abs < 6 * HOUR) {\n const h = Math.floor(abs / HOUR), m = Math.round((abs % HOUR) / MIN);\n const s = h + \"h\" + (m ? \" \" + m + \"m\" : \"\");\n return future ? \"in \" + s : s + \" ago\";\n }\n const d = new Date(t);\n const sameDay = new Date(ref).toDateString() === d.toDateString();\n const time = d.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n if (sameDay) return time;\n if (abs < 6 * DAY) return d.toLocaleDateString([], { weekday: \"short\" }) + \" \" + time;\n return d.toLocaleDateString([], { day: \"numeric\", month: \"short\" });\n}\n\n/** Absolute, for the title attribute. */\nexport function formatAbsolute(value: string | Date): string {\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n if (!t || isNaN(t)) return \"\";\n return new Date(t).toLocaleString([], { dateStyle: \"medium\", timeStyle: \"short\" });\n}\n\n/** Clock time only — \"3:42 PM\". */\nexport function formatClock(value: string | Date): string {\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n if (!t || isNaN(t)) return \"\";\n return new Date(t).toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n}\n\n/** ms → \"1m 34s\" · \"12.4s\" · \"840ms\" */\nexport function formatDuration(ms: number): string {\n if (ms == null || isNaN(ms)) return \"\";\n if (ms < 1000) return Math.round(ms) + \"ms\";\n if (ms < 60e3) { const s = ms / 1000; return (s < 10 ? s.toFixed(1) : Math.round(s)) + \"s\"; }\n const m = Math.floor(ms / 60e3), s = Math.round((ms % 60e3) / 1000);\n if (m < 60) return m + \"m\" + (s ? \" \" + s + \"s\" : \"\");\n const h = Math.floor(m / 60);\n return h + \"h\" + (m % 60 ? \" \" + (m % 60) + \"m\" : \"\");\n}\n\nexport interface RelativeTimeProps { value: string | Date; prefix?: string; refresh?: boolean; className?: string }\n\n/**\n * A self-refreshing relative timestamp. Ticks no faster than the unit it shows,\n * and stops entirely once the value is days old.\n */\nexport function RelativeTime({ value, prefix, className = \"\", refresh = true, ...rest }: RelativeTimeProps) {\n const [, force] = React.useState(0);\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n React.useEffect(() => {\n if (!refresh || !t || isNaN(t)) return;\n const abs = Math.abs(t - Date.now());\n if (abs > DAY) return;\n const every = abs < HOUR ? 15e3 : 60e3;\n const id = setInterval(() => force((n) => n + 1), every);\n return () => clearInterval(id);\n }, [t, refresh]);\n if (!t || isNaN(t)) return null;\n return (\n <time className={className} dateTime={new Date(t).toISOString()} title={formatAbsolute(new Date(t))} {...rest}>\n {prefix ? prefix + \" \" : \"\"}{formatRelative(new Date(t))}\n </time>\n );\n}\n","import * as React from \"react\";\nimport { formatBytes } from \"../../kits/files.js\";\n\nconst VARIANT_FILL: Record<string, string> = {\n brand: \"var(--brand)\",\n neutral: \"var(--n-400)\",\n quiet: \"var(--n-300)\",\n ok: \"var(--ok-solid)\",\n warn: \"var(--warn-solid)\",\n danger: \"var(--danger-solid)\",\n info: \"var(--info-solid)\",\n};\nconst CHART = [\"var(--chart-1)\", \"var(--chart-2)\", \"var(--chart-3)\", \"var(--chart-4)\", \"var(--chart-5)\", \"var(--chart-6)\", \"var(--chart-7)\", \"var(--chart-8)\"];\n\nconst compact = (n: number): string => {\n if (n == null || isNaN(n)) return \"\";\n const a = Math.abs(n);\n if (a >= 1e9) return (n / 1e9).toFixed(a >= 1e10 ? 0 : 1).replace(/\\.0$/, \"\") + \"B\";\n if (a >= 1e6) return (n / 1e6).toFixed(a >= 1e7 ? 0 : 1).replace(/\\.0$/, \"\") + \"M\";\n if (a >= 1e3) return (n / 1e3).toFixed(a >= 1e4 ? 0 : 1).replace(/\\.0$/, \"\") + \"k\";\n return String(Math.round(n));\n};\n\nexport const meterFormats = {\n count: (n: number) => n.toLocaleString(),\n compact,\n bytes: formatBytes,\n percentOf: (total: number) => (n: number) => (total ? Math.round((n / total) * 100) : 0) + \"%\",\n};\n\nexport interface MeterSegmentInput {\n id?: string;\n label: string;\n value: number;\n variant?: \"brand\" | \"neutral\" | \"quiet\" | \"ok\" | \"warn\" | \"danger\" | \"info\";\n /** Any CSS colour; overrides variant. Defaults to the chart ramp in order. */\n color?: string;\n}\n\nexport interface SegmentedMeterProps {\n total: number;\n segments: MeterSegmentInput[];\n label?: string;\n /** Value formatter. meterFormats.compact | .count | .bytes */\n format?: (n: number) => string;\n height?: number;\n legend?: boolean;\n showTotal?: boolean;\n showPercent?: boolean;\n remainderLabel?: string;\n onClick?: () => void;\n className?: string;\n /** Base id for the meter's aria-labelledby target; falls back to React.useId(). */\n id?: string;\n}\n\n/**\n * A capacity bar split into categories — a context window, a disk quota, a budget\n * burn-down, a rate limit. Deliberately free of any AI vocabulary: it takes a total\n * and labelled segments, and reports the remainder as free space.\n *\n * A zero or missing total reports 0%, never NaN%.\n */\nexport function SegmentedMeter({\n total = 0,\n segments = [],\n label,\n format = compact,\n height = 6,\n legend = false,\n showTotal = true,\n showPercent = true,\n remainderLabel = \"Free\",\n onClick,\n className = \"\",\n id,\n}: SegmentedMeterProps) {\n const safeTotal = Number(total) > 0 ? Number(total) : 0;\n const items = segments.filter((s) => s && Number(s.value) > 0);\n const used = items.reduce((n, s) => n + Number(s.value), 0);\n const pct = safeTotal ? Math.min(100, Math.round((used / safeTotal) * 100)) : 0;\n const w = (v: number) => (safeTotal ? Math.max(0, Math.min(100, (Number(v) / safeTotal) * 100)) : 0);\n const fill = (s: MeterSegmentInput, i: number) => s.color || (s.variant ? VARIANT_FILL[s.variant] : undefined) || CHART[i % CHART.length];\n const generatedId = React.useId();\n const uid = id || generatedId;\n\n return (\n <div className={[\"fd-segmeter\", className].filter(Boolean).join(\" \")} onClick={onClick}>\n {(label || showTotal) ? (\n <div className=\"fd-segmeter-head\">\n {label ? <span className=\"fd-segmeter-label\" id={uid + \"-l\"}>{label}</span> : <span />}\n {showTotal ? (\n <span className=\"fd-segmeter-total fd-tabular\">\n {format(used)}<span className=\"fd-segmeter-sep\"> / </span>{safeTotal ? format(safeTotal) : \"—\"}\n {showPercent ? <span className=\"fd-segmeter-pct\"> ({pct}%)</span> : null}\n </span>\n ) : null}\n </div>\n ) : null}\n <div\n className=\"fd-segmeter-rail\"\n style={{ height }}\n role=\"meter\"\n aria-labelledby={label ? uid + \"-l\" : undefined}\n aria-label={label ? undefined : \"Usage\"}\n aria-valuenow={used}\n aria-valuemin={0}\n aria-valuemax={safeTotal || 100}\n aria-valuetext={format(used) + \" of \" + (safeTotal ? format(safeTotal) : \"unknown\") + \" — \" + pct + \"%\"}\n >\n {items.map((s, i) => (\n <span\n key={s.id || s.label || i}\n className=\"fd-segmeter-seg\"\n style={{ width: w(s.value) + \"%\", background: fill(s, i), transitionDelay: (i * 40) + \"ms\" }}\n title={s.label + \" · \" + format(s.value)}\n />\n ))}\n </div>\n {legend ? (\n <ul className=\"fd-segmeter-legend\">\n {items.map((s, i) => (\n <li key={s.id || s.label || i}>\n <span className=\"fd-segmeter-dot\" style={{ background: fill(s, i) }} aria-hidden=\"true\" />\n <span className=\"fd-segmeter-key\">{s.label}</span>\n <span className=\"fd-segmeter-val fd-tabular\">{format(s.value)}</span>\n </li>\n ))}\n {safeTotal && used < safeTotal ? (\n <li className=\"is-remainder\">\n <span className=\"fd-segmeter-dot is-empty\" aria-hidden=\"true\" />\n <span className=\"fd-segmeter-key\">{remainderLabel}</span>\n <span className=\"fd-segmeter-val fd-tabular\">{format(safeTotal - used)}</span>\n </li>\n ) : null}\n </ul>\n ) : null}\n </div>\n );\n}\n\nexport interface QuotaRowProps { label: React.ReactNode; percent: number; note?: React.ReactNode; tone?: \"brand\" | \"ok\" | \"warn\" | \"danger\"; className?: string }\n\n/**\n * One quota line: name, an optional reset note, a percentage and a bar.\n * Rate limits, plan allowances, storage tiers.\n */\nexport function QuotaRow({ label, percent = 0, note, tone, className = \"\" }: QuotaRowProps) {\n const p = Math.max(0, Math.min(100, Math.round(Number(percent) || 0)));\n const auto = p >= 90 ? \"danger\" : p >= 70 ? \"warn\" : \"brand\";\n return (\n <div className={[\"fd-quota\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-quota-head\">\n <span className=\"fd-quota-label\">{label}</span>\n {note ? <span className=\"fd-quota-note\">{note}</span> : null}\n <span className=\"fd-quota-pct fd-tabular\">{p}%</span>\n </div>\n <div className=\"fd-quota-rail\" role=\"meter\" aria-label={typeof label === \"string\" ? label : undefined} aria-valuenow={p} aria-valuemin={0} aria-valuemax={100}>\n <span className=\"fd-quota-fill\" style={{ width: p + \"%\", background: VARIANT_FILL[tone || auto] }} />\n </div>\n </div>\n );\n}\n","/**\n * File intake helpers — generic, no chat vocabulary.\n * Nothing here touches the DOM event lifecycle: extractors REPORT what they found,\n * the host decides whether to consume the event.\n *\n * Shared by the forms group and the chat kit — promoted to a top-level shared kit\n * since multiple component groups depend on it.\n */\n\n/* Shared file helpers for the forms group and the chat kit. Every component that\n handles a file speaks this Attachment shape — one type, not three. */\n/** The host library's file shape. Use it for every file everywhere. */\nexport interface Attachment {\n id: string;\n name: string;\n size: number;\n mime: string;\n url: string;\n /** Local preview while uploading. */\n blobUrl?: string;\n /** Non-null and < 100 means uploading. */\n progress?: number | null;\n thumb?: { url: string };\n /** Failed upload. Takes priority over progress. */\n error?: string;\n /** Free-text replacement for the size line, e.g. \"6 lines · pasted\". */\n meta?: string;\n /** Present only before upload; strip it before sending. */\n file?: File;\n}\n\nexport interface FileRejection { file: File; reason: \"type\" | \"size\"; message: string }\n\nexport function formatBytes(n: number): string {\n if (n == null || isNaN(n)) return \"\";\n if (n < 1024) return n + \" B\";\n const u = [\"KB\", \"MB\", \"GB\", \"TB\"];\n let v = n / 1024, i = 0;\n while (v >= 1024 && i < u.length - 1) { v /= 1024; i++; }\n return (v < 10 ? v.toFixed(1) : Math.round(v)) + \" \" + u[i];\n}\n\nexport function extensionOf(name: string): string {\n const m = /\\.([A-Za-z0-9]+)$/.exec(name || \"\");\n return m ? m[1].toLowerCase() : \"\";\n}\n\nconst ICON_BY_EXT: Record<string, string> = {\n pdf: \"file-pdf\", doc: \"file-doc\", docx: \"file-doc\", rtf: \"file-doc\",\n xls: \"file-xls\", xlsx: \"file-xls\", csv: \"file-csv\", tsv: \"file-csv\",\n ppt: \"file-ppt\", pptx: \"file-ppt\",\n zip: \"file-zip\", gz: \"file-zip\", tar: \"file-zip\", rar: \"file-zip\",\n js: \"file-js\", jsx: \"file-js\", ts: \"file-ts\", tsx: \"file-ts\",\n json: \"brackets-curly\", html: \"file-html\", css: \"file-css\", md: \"file-md\",\n py: \"file-py\", sql: \"database\", sh: \"terminal\", txt: \"file-text\", log: \"file-text\",\n};\n\n/** Phosphor icon name for a file: type first, extension second. */\nexport function iconForMime(mime?: string, name?: string): string {\n const m = (mime || \"\").toLowerCase();\n if (m.startsWith(\"image/\")) return \"image\";\n if (m.startsWith(\"video/\")) return \"video\";\n if (m.startsWith(\"audio/\")) return \"music-notes\";\n const byExt = ICON_BY_EXT[extensionOf(name || \"\")];\n if (byExt) return byExt;\n if (m === \"application/pdf\") return \"file-pdf\";\n if (m.startsWith(\"text/\")) return \"file-text\";\n return \"file\";\n}\n\nexport function isImage(mime?: string, name?: string): boolean {\n if ((mime || \"\").toLowerCase().startsWith(\"image/\")) return true;\n return [\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"avif\", \"svg\", \"bmp\"].includes(extensionOf(name || \"\"));\n}\n\n/** accept-attribute semantics: \".png,image/*,text/plain\" */\nexport function acceptMatches(file: File, accept?: string): boolean {\n if (!accept) return true;\n const mime = (file.type || \"\").toLowerCase();\n const name = (file.name || \"\").toLowerCase();\n return accept.split(\",\").map((s) => s.trim().toLowerCase()).filter(Boolean).some((rule) => {\n if (rule.startsWith(\".\")) return name.endsWith(rule);\n if (rule.endsWith(\"/*\")) return mime.startsWith(rule.slice(0, -1));\n return mime === rule;\n });\n}\n\n/** Split a FileList against accept + size. Rejections carry a reason string, never a silent drop. */\nexport function filterFiles(\n files: FileList | File[],\n opts?: { accept?: string; maxFileSize?: number },\n): { accepted: File[]; rejected: FileRejection[] } {\n const o = opts || {};\n const accepted: File[] = [], rejected: FileRejection[] = [];\n Array.from(files || []).forEach((file) => {\n if (!acceptMatches(file, o.accept)) { rejected.push({ file, reason: \"type\", message: (file.name || \"This file\") + \" isn't an accepted type.\" }); return; }\n if (o.maxFileSize && file.size > o.maxFileSize) { rejected.push({ file, reason: \"size\", message: (file.name || \"This file\") + \" is \" + formatBytes(file.size) + \" — the limit is \" + formatBytes(o.maxFileSize) + \".\" }); return; }\n accepted.push(file);\n });\n return { accepted, rejected };\n}\n\n/** Human name for a synthesised paste file: \"Pasted text (380 lines).txt\" */\nexport function pastedTextName(text: string): string {\n const lines = text.split(\"\\n\").length;\n if (lines === 1) return \"Pasted text (\" + text.length.toLocaleString() + \" characters).txt\";\n return \"Pasted text (\" + lines.toLocaleString() + \" lines).txt\";\n}\n\nfunction makeTextFile(text: string, name: string): File {\n const type = \"text/plain\";\n try {\n return new File([text], name, { type });\n } catch {\n const blob = new Blob([text], { type }) as File;\n Object.assign(blob, { name, lastModified: Date.now() });\n return blob;\n }\n}\n\n/** Legacy jQuery-style event shape — some hosts still normalise paste events this way. */\ntype ClipboardEventLike = ClipboardEvent & { originalEvent?: ClipboardEvent };\n\n/**\n * What a paste is carrying, in one pass. NEVER calls preventDefault — it returns\n * `source: null` when nothing was produced, so the host can let the event fall\n * through. That is what makes it reusable in any input.\n */\nexport function extractClipboardFiles(\n event: ClipboardEvent,\n opts?: { largePasteThreshold?: number; accept?: string; maxFileSize?: number; name?: string },\n): { files: File[]; source: \"files\" | \"text\" | null; rejected: FileRejection[]; text?: string } {\n const o = opts || {};\n const threshold = o.largePasteThreshold == null ? 4000 : o.largePasteThreshold;\n const evt = event as ClipboardEventLike;\n const dt = event && (evt.clipboardData || (evt.originalEvent && evt.originalEvent.clipboardData));\n if (!dt) return { files: [], source: null, rejected: [] };\n\n const raw = Array.from(dt.files || []);\n const fromItems: File[] = raw.length\n ? raw\n : Array.from(dt.items || [])\n .filter((i) => i.kind === \"file\")\n .map((i) => i.getAsFile())\n .filter((f): f is File => f !== null);\n\n if (fromItems.length) {\n const { accepted, rejected } = filterFiles(fromItems, o);\n return { files: accepted, source: accepted.length ? \"files\" : null, rejected };\n }\n\n const text = dt.getData ? dt.getData(\"text/plain\") : \"\";\n if (threshold > 0 && text && text.length > threshold) {\n const file = makeTextFile(text, o.name || pastedTextName(text));\n const { accepted, rejected } = filterFiles([file], { accept: o.accept, maxFileSize: o.maxFileSize });\n return { files: accepted, source: accepted.length ? \"text\" : null, rejected, text };\n }\n return { files: [], source: null, rejected: [] };\n}\n\nlet attachmentSeq = 0;\n/**\n * Local, immediately-renderable stand-in for a file being uploaded.\n * Shape is the host library's file type — id/name/size/mime/url/progress/thumb/error.\n */\nexport function toAttachment(file: File, extra?: Partial<Attachment>): Attachment {\n const url = typeof URL !== \"undefined\" && URL.createObjectURL ? URL.createObjectURL(file) : \"\";\n const image = isImage(file.type, file.name);\n const base: Attachment = {\n id: \"att_\" + (++attachmentSeq) + \"_\" + Date.now().toString(36),\n name: file.name || \"file\",\n size: file.size || 0,\n mime: file.type || \"application/octet-stream\",\n url,\n blobUrl: url,\n progress: null,\n thumb: image && url ? { url } : undefined,\n file,\n };\n return Object.assign(base, extra || {});\n}\n\nexport function revokeAttachment(att: Attachment): void {\n try { if (att && att.blobUrl) URL.revokeObjectURL(att.blobUrl); } catch { /* noop */ }\n}\n\n/**\n * Namespace export — `const { formatBytes } = window.<Namespace>.FileKit;`\n */\nexport const FileKit = {\n formatBytes,\n extensionOf,\n iconForMime,\n isImage,\n acceptMatches,\n filterFiles,\n pastedTextName,\n extractClipboardFiles,\n toAttachment,\n revokeAttachment,\n};\n","import * as React from \"react\";\nimport { Button } from \"../actions/Button\";\n\nexport interface SortMenuField {\n /** Sort key sent to the endpoint. */\n key: string;\n /** Human label shown in the menu and on the collapsed trigger. */\n label: string;\n /** Numeric fields read \"lowest/highest first\" instead of \"A to Z\". */\n numeric?: boolean;\n}\n\nexport interface SortMenuProps extends React.HTMLAttributes<HTMLSpanElement> {\n fields: SortMenuField[];\n /** Current sort, straight from the endpoint's response envelope. */\n sort?: { key: string; dir: \"asc\" | \"desc\" } | null;\n onSort?: (key: string, dir: \"asc\" | \"desc\") => void;\n /** Which edge the popover aligns to. Default \"right\". */\n align?: \"left\" | \"right\";\n /** Trigger button height, same scale as every other control in the kit (Button,\n * Input). Default \"md\" — matches Input/SearchField's own default height, since\n * this is most often placed directly alongside a SearchField in one header row\n * (see TransferList) and the two need to line up. Pass \"sm\" for a denser,\n * standalone placement. */\n size?: \"sm\" | \"md\";\n className?: string;\n}\n\n/**\n * SortMenu — the sort control for every server-driven table.\n *\n * A raw \"sort=crp&dir=desc\" readout tells a user what the machine is doing, not what\n * they asked for. This states the field in words and offers both directions as explicit\n * targets, so choosing \"highest first\" is one click rather than a toggle you have to\n * click twice and then verify.\n *\n * Direction wording follows the field type — numeric fields read \"lowest/highest first\",\n * text fields \"A to Z\" — while both use the same arrow pair, because varying the icon by\n * type encodes a distinction nobody asked for and reads as inconsistency.\n *\n * Purely presentational: reports intent through onSort(key, dir) and never holds sort\n * state, so it stays honest against a real endpoint.\n */\nexport function SortMenu({ fields = [], sort, onSort, align = \"right\", size = \"md\", className = \"\", ...rest }: SortMenuProps) {\n const [open, setOpen] = React.useState(false);\n const ref = React.useRef<HTMLSpanElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n\n const cur = fields.find((f) => f.key === (sort && sort.key));\n const dir = sort && sort.dir;\n\n const arrow = (f: SortMenuField, d: \"asc\" | \"desc\") => {\n const on = cur && cur.key === f.key && dir === d;\n const label = d === \"asc\" ? (f.numeric ? \"lowest first\" : \"A to Z\") : (f.numeric ? \"highest first\" : \"Z to A\");\n return (\n <button type=\"button\" aria-label={f.label + \", \" + label} aria-pressed={on} onClick={() => onSort && onSort(f.key, d)}\n style={{ display: \"grid\", placeItems: \"center\", width: 26, height: 26, borderRadius: 6, cursor: \"pointer\",\n border: \"1px solid \" + (on ? \"var(--brand)\" : \"var(--border)\"),\n background: on ? \"var(--brand)\" : \"var(--surface)\", color: on ? \"#fff\" : \"var(--text-muted)\" }}>\n <i className={\"ph ph-arrow-\" + (d === \"asc\" ? \"up\" : \"down\")} style={{ fontSize: 13 }} />\n </button>\n );\n };\n\n return (\n <span className={className} style={{ position: \"relative\", display: \"inline-flex\" }} ref={ref} {...rest}>\n <Button size={size} variant=\"secondary\" icon={dir === \"asc\" ? \"sort-ascending\" : \"sort-descending\"} onClick={() => setOpen(!open)}>\n {cur ? cur.label : \"Unsorted\"}\n <i className={\"ph ph-\" + (dir === \"asc\" ? \"arrow-up\" : \"arrow-down\")} style={{ fontSize: 12, marginLeft: 6, opacity: 0.75 }} />\n </Button>\n {open ? (\n <span className=\"fd-view-enter\" style={{ position: \"absolute\", top: \"calc(100% + 6px)\", [align]: 0, zIndex: 120, width: 280, maxWidth: \"calc(100vw - 32px)\", display: \"block\", background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 10, boxShadow: \"0 16px 44px rgba(11,13,17,.18)\", padding: 8 } as React.CSSProperties}>\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span className=\"fd-overline fd-muted\" style={{ padding: \"4px 8px 6px\" }}>Sort by</span>\n {fields.map((f) => {\n const active = cur && cur.key === f.key;\n return (\n <span key={f.key} className=\"fd-row\" style={{ gap: 8, padding: \"4px 8px\", borderRadius: 7, background: active ? \"var(--surface-brand)\" : \"transparent\" }}>\n <span className=\"fd-body-sm\" style={{ flex: 1, fontWeight: active ? 700 : 500, color: active ? \"var(--text-on-surface-brand)\" : \"var(--text)\" }}>{f.label}</span>\n {arrow(f, \"asc\")}\n {arrow(f, \"desc\")}\n </span>\n );\n })}\n </span>\n </span>) : null}\n </span>\n );\n}\n","import * as React from \"react\";\nimport { formatDuration } from \"./RelativeTime\";\n\nconst KIND_ICON: Record<string, string> = { tool: \"wrench\", search: \"magnifying-glass\", read: \"file-text\", write: \"pencil-simple\", reasoning: \"brain\", run: \"terminal\", fetch: \"cloud-arrow-down\" };\n\nexport interface Step {\n id: string;\n /** Short verb + target: \"Queried calls table\". */\n label: string;\n kind?: \"tool\" | \"search\" | \"read\" | \"write\" | \"reasoning\" | \"run\" | \"fetch\";\n /** Raw input/output or reasoning text, behind a disclosure. */\n detail?: string;\n durationMs?: number;\n status?: \"running\" | \"ok\" | \"error\";\n}\n\n/** Flat collapsible rows — never one card per tool call. */\nexport interface StepListProps { steps: Step[]; label?: string; defaultOpen?: boolean; open?: boolean; onToggle?: (open: boolean) => void; showDurations?: boolean; dense?: boolean; className?: string }\n\n/**\n * A flat, collapsible list of work steps — one row per step, never one card per\n * call. A long run stays readable: it is a list, not a stack.\n */\nexport function StepList({\n steps = [], label, defaultOpen = false, open: openProp, onToggle,\n showDurations = true, dense = false, className = \"\",\n}: StepListProps) {\n const [openState, setOpenState] = React.useState(defaultOpen);\n const open = openProp == null ? openState : openProp;\n const [expanded, setExpanded] = React.useState<Record<string, boolean>>({});\n if (!steps.length) return null;\n\n const running = steps.some((s) => s.status === \"running\");\n const failed = steps.filter((s) => s.status === \"error\").length;\n const total = steps.reduce((n, s) => n + (s.durationMs || 0), 0);\n const current = steps.filter((s) => s.status === \"running\").slice(-1)[0];\n\n const summary = label || (running\n ? (current ? current.label : \"Working\")\n : (total ? \"Worked for \" + formatDuration(total) : \"Steps\"));\n\n const toggle = () => {\n const next = !open;\n if (openProp == null) setOpenState(next);\n onToggle && onToggle(next);\n };\n\n return (\n <div className={[\"fd-steps\", dense ? \"is-dense\" : \"\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")}>\n <button type=\"button\" className=\"fd-steps-head\" onClick={toggle} aria-expanded={open}>\n {running ? <span className=\"fd-steps-spin\" aria-hidden=\"true\" /> : <i className={\"ph ph-\" + (failed ? \"warning-circle\" : \"check-circle\")} aria-hidden=\"true\" />}\n <span className=\"fd-steps-title\">{summary}</span>\n <span className=\"fd-steps-count fd-tabular\">\n {steps.length} step{steps.length === 1 ? \"\" : \"s\"}\n {failed ? <span className=\"fd-steps-failed\"> · {failed} failed</span> : null}\n </span>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\") + \" fd-steps-caret\"} aria-hidden=\"true\" />\n </button>\n {open ? (\n <ol className=\"fd-steps-list\">\n {steps.map((s, i) => {\n const id = s.id || i;\n const isOpen = !!expanded[id];\n const icon = KIND_ICON[s.kind || \"\"] || \"dot-outline\";\n return (\n <li key={id} className={\"fd-step is-\" + (s.status || \"ok\")}>\n <div className=\"fd-step-row\">\n <span className=\"fd-step-icon\" aria-hidden=\"true\">\n {s.status === \"running\" ? <span className=\"fd-steps-spin\" /> : <i className={\"ph ph-\" + icon} />}\n </span>\n {s.detail ? (\n <button type=\"button\" className=\"fd-step-label\" aria-expanded={isOpen}\n onClick={() => setExpanded((m) => Object.assign({}, m, { [id]: !isOpen }))}>\n <span>{s.label}</span>\n <i className={\"ph ph-caret-\" + (isOpen ? \"up\" : \"down\")} aria-hidden=\"true\" />\n </button>\n ) : <span className=\"fd-step-label is-static\">{s.label}</span>}\n {s.status === \"error\" ? <span className=\"fd-step-badge is-error\">failed</span> : null}\n {showDurations && s.durationMs ? <span className=\"fd-step-dur fd-tabular\">{formatDuration(s.durationMs)}</span> : null}\n </div>\n {s.detail && isOpen ? <pre className=\"fd-step-detail\">{s.detail}</pre> : null}\n </li>\n );\n })}\n </ol>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** Number of rows kept mounted above and below the visible band. Two buffers this size\n * (one per edge) plus the visible band itself is what keeps the mounted node count\n * bounded — see the file doc comment below for why 20 is the right number here. */\nexport const VIRTUAL_LIST_BUFFER_ROWS = 20;\n\nexport interface VirtualWindow {\n /** Index of the first row a viewport of this height would actually show. */\n visibleStart: number;\n /** Index of the last row a viewport of this height would actually show (inclusive). */\n visibleEnd: number;\n /** Index of the first row that should be mounted in the DOM (visibleStart minus the buffer, clamped to 0). */\n startIndex: number;\n /** Index of the last row that should be mounted in the DOM (inclusive; visibleEnd plus the buffer, clamped to itemCount - 1). */\n endIndex: number;\n /** Full scrollable height in px — this is what makes the scrollbar/scroll range honest\n * about itemCount even though only a slice of it is ever mounted. */\n totalHeight: number;\n /** px the mounted block must be pushed down so its rows land at their real scroll position. */\n offsetY: number;\n}\n\n/**\n * Pure windowing math: given a scroll position and the shape of the data, decide which\n * row indices are visible and which should actually be mounted. Kept free of React and\n * the DOM on purpose — see VirtualList's doc comment for why this is exported and tested\n * on its own rather than only indirectly through a mounted component.\n *\n * Every fixed-height virtualizer boils down to integer division: row i sits at\n * `i * itemHeight` px, so scrollTop/itemHeight lands on the first partially-visible row\n * and (scrollTop + viewportHeight)/itemHeight lands on the last one. Everything else here\n * is clamping that to the buffer and to the real item count.\n */\nexport function computeVirtualWindow(opts: {\n scrollTop: number;\n viewportHeight: number;\n itemHeight: number;\n itemCount: number;\n bufferRows?: number;\n}): VirtualWindow {\n const { scrollTop, viewportHeight, itemHeight, itemCount, bufferRows = VIRTUAL_LIST_BUFFER_ROWS } = opts;\n\n if (itemCount <= 0 || itemHeight <= 0) {\n return { visibleStart: 0, visibleEnd: -1, startIndex: 0, endIndex: -1, totalHeight: 0, offsetY: 0 };\n }\n\n const lastPossible = itemCount - 1;\n const visibleStart = Math.min(lastPossible, Math.max(0, Math.floor(scrollTop / itemHeight)));\n const visibleRows = Math.max(1, Math.ceil(viewportHeight / itemHeight));\n const visibleEnd = Math.min(lastPossible, visibleStart + visibleRows - 1);\n\n const startIndex = Math.max(0, visibleStart - bufferRows);\n const endIndex = Math.min(lastPossible, visibleEnd + bufferRows);\n\n return {\n visibleStart,\n visibleEnd,\n startIndex,\n endIndex,\n totalHeight: itemCount * itemHeight,\n offsetY: startIndex * itemHeight,\n };\n}\n\n/**\n * Given the current window and the real item count, says whether the visible band has\n * come within one buffer's width of either edge of what's currently loaded — the signal\n * VirtualList uses to ask its caller for more. Threading it through the *visible* band\n * (not the mounted one) means the caller gets asked while the buffer still has rows left\n * to show, not only once the user has scrolled past all of them.\n */\nexport function computeNeedMore(\n win: Pick<VirtualWindow, \"visibleStart\" | \"visibleEnd\">,\n itemCount: number,\n bufferRows: number = VIRTUAL_LIST_BUFFER_ROWS\n): { start: boolean; end: boolean } {\n if (itemCount <= 0) return { start: true, end: true };\n return {\n start: win.visibleStart <= bufferRows,\n end: itemCount - 1 - win.visibleEnd <= bufferRows,\n };\n}\n\nexport interface VirtualListProps<T> {\n /** Whatever the caller currently has loaded — not the full remote collection. */\n items: T[];\n /** Fixed row height in px. Every row is assumed to be exactly this tall. */\n itemHeight: number;\n renderItem: (item: T, index: number) => React.ReactNode;\n /** Fired when the visible band comes within one buffer's width of an edge of `items`\n * and that edge isn't known to be exhausted. The caller owns fetching — this only asks. */\n onNeedMore: (direction: \"start\" | \"end\") => void;\n /** Which edges of `items` still have more behind them. Omitted/undefined reads as \"yes,\n * there might be more\" for that edge, since an unknown edge is the common starting state. */\n hasMore?: { start?: boolean; end?: boolean };\n /** Suppresses onNeedMore while a fetch the caller already started is in flight. Drives the\n * small pinned spinner at the bottom of the list — rows already mounted stay exactly as\n * they are, since this only ever means \"more is being appended,\" never \"what's on screen\n * might be stale.\" For the append-vs-replace distinction, see `refreshing` below. */\n loading?: boolean;\n /** True while the caller is replacing the WHOLE result set (a search or sort change), as\n * opposed to `loading` appending more onto the end. `items` is expected to still be the\n * PREVIOUS result set while this is true — this renders it underneath a full-panel scrim\n * instead of clearing to empty, so a search/sort edit never blanks the list while the new\n * page is in flight. Swap `items` to the new rows once they land and this back to false. */\n refreshing?: boolean;\n /** Copy shown in the `refreshing` overlay's centered card, next to its spinner. */\n refreshingLabel?: string;\n keyOf: (item: T) => string | number;\n /** Viewport height in px. Default (400) is ten rows at the kit's --control-h-md (44px). */\n height?: number;\n emptyState?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * VirtualList — a fixed-height windowed viewport for a list the caller may be streaming\n * in from a few thousand rows at a time.\n *\n * Why fixed row height only: variable-height virtualization needs a measurement pass\n * (render off-screen, read the real height, then correct the scroll math) which is a\n * meaningfully bigger and more fragile piece of engineering than this kit needs for any\n * consumer it has today. Every current use case is a single-line-or-two row of known,\n * consistent height, so the simplest correct approach is the right one: the caller states\n * itemHeight, and the math is plain arithmetic (see computeVirtualWindow).\n *\n * Why plain onScroll + scrollTop math instead of IntersectionObserver: an observer would\n * still need one sentinel per boundary and a ResizeObserver alongside it to keep the\n * scroll track honest as itemCount changes — no less code, and it trades arithmetic you\n * can unit test for browser timing you can't. scrollTop/clientHeight are synchronous and\n * exact, so the windowing math stays a pure function (computeVirtualWindow, exported and\n * tested on its own below) with the component itself doing nothing but reading scrollTop\n * and rendering the slice that function names.\n *\n * The window keeps ~10 rows actually visible plus a VIRTUAL_LIST_BUFFER_ROWS-row buffer\n * mounted above and below (~50 rows mounted at once at the default height), which is\n * enough that fast wheel/trackpad scrolling never outruns the mounted band before the\n * next onScroll fires, without ever mounting more than a small bounded slice regardless\n * of how many thousand rows `items` holds.\n *\n * Fully controlled: this holds no item data and no page state, only the scroll position\n * needed to compute the window. The caller owns fetching more rows (onNeedMore) and\n * knowing when an edge is exhausted (hasMore).\n */\nexport function VirtualList<T>({\n items,\n itemHeight,\n renderItem,\n onNeedMore,\n hasMore,\n loading = false,\n refreshing = false,\n refreshingLabel = \"Searching…\",\n keyOf,\n height = 400,\n emptyState,\n className = \"\",\n style,\n}: VirtualListProps<T>) {\n const [scrollTop, setScrollTop] = React.useState(0);\n // Tracks the item count at which each edge was last requested, so a given edge is\n // asked for exactly once per batch rather than on every scroll tick while it sits\n // within the buffer zone waiting for the caller's fetch to land.\n const requested = React.useRef<{ start: number | null; end: number | null }>({ start: null, end: null });\n\n const win = React.useMemo(\n () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: items.length }),\n [scrollTop, height, itemHeight, items.length]\n );\n const need = React.useMemo(() => computeNeedMore(win, items.length), [win, items.length]);\n\n const wantStart = need.start && hasMore?.start !== false;\n const wantEnd = need.end && hasMore?.end !== false;\n\n React.useEffect(() => {\n if (loading || !wantStart || requested.current.start === items.length) return;\n requested.current.start = items.length;\n onNeedMore(\"start\");\n }, [wantStart, loading, items.length, onNeedMore]);\n\n React.useEffect(() => {\n if (loading || !wantEnd || requested.current.end === items.length) return;\n requested.current.end = items.length;\n onNeedMore(\"end\");\n }, [wantEnd, loading, items.length, onNeedMore]);\n\n // Which of `items`' keys are new since the last commit — drives each fresh row's\n // brief fade/scale-in. Compared against the FULL `items` array (not the mounted\n // window), so scrolling a already-loaded row into view is never mistaken for a\n // newly-added one; only a row genuinely absent from the previous commit's `items`\n // gets the enter treatment. Read during render off last commit's snapshot, then\n // that snapshot is advanced in an effect after paint — never mutated inline during\n // render itself.\n const lastKeysRef = React.useRef<Set<string | number> | null>(null);\n const newKeys = React.useMemo(() => {\n const prev = lastKeysRef.current;\n if (!prev) return new Set<string | number>(); // first mount — nothing \"new\" to animate in\n const fresh = new Set<string | number>();\n for (const item of items) {\n const k = keyOf(item);\n if (!prev.has(k)) fresh.add(k);\n }\n return fresh;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items]);\n React.useEffect(() => {\n lastKeysRef.current = new Set(items.map(keyOf));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items]);\n\n if (!items.length && !loading && !refreshing && emptyState) {\n return (\n <div className={[\"fd-vlist-wrap\", className].filter(Boolean).join(\" \")} style={{ height, position: \"relative\", ...style }}>\n <div className=\"fd-vlist fd-scrollbar\" style={{ height: \"100%\", overflow: \"auto\" }}>\n {emptyState}\n </div>\n </div>\n );\n }\n\n const rows: React.ReactNode[] = [];\n for (let i = win.startIndex; i <= win.endIndex; i++) {\n const item = items[i];\n if (item === undefined) continue;\n const key = keyOf(item);\n rows.push(\n <div\n key={key}\n className=\"fd-vlist-row\"\n style={{ height: itemHeight, boxSizing: \"border-box\", transform: \"translateY(\" + i * itemHeight + \"px)\" }}\n >\n <div className={newKeys.has(key) ? \"fd-vlist-row-content fd-vlist-row-enter\" : \"fd-vlist-row-content\"}>\n {renderItem(item, i)}\n </div>\n </div>\n );\n }\n\n return (\n <div className={[\"fd-vlist-wrap\", className].filter(Boolean).join(\" \")} style={{ height, position: \"relative\", ...style }}>\n <div\n className=\"fd-vlist fd-scrollbar\"\n style={{ height: \"100%\", overflowY: \"auto\", overflowX: \"hidden\", position: \"relative\" }}\n onScroll={(e) => setScrollTop(e.currentTarget.scrollTop)}\n >\n <div style={{ height: win.totalHeight, position: \"relative\" }}>{rows}</div>\n {loading ? (\n <div style={{ position: \"sticky\", bottom: 0, left: 0, right: 0, display: \"grid\", placeItems: \"center\", padding: \"8px 0\", background: \"var(--surface)\" }}>\n <span className=\"fd-spinner\" aria-hidden=\"true\" />\n </div>\n ) : null}\n </div>\n {refreshing ? (\n <div className=\"fd-vlist-refresh-scrim\">\n <div className=\"fd-vlist-refresh-card\">\n <span className=\"fd-spinner\" aria-hidden=\"true\" />\n <span className=\"fd-body-sm\">{refreshingLabel}</span>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { IconButton } from \"../actions/IconButton\";\n\nexport interface EntityRowAction {\n /** Phosphor icon name, e.g. \"plus\" */\n icon: string;\n /** Accessible name for the action button. */\n label: string;\n onClick: () => void;\n /** Tints the icon — \"add\" reads as constructive (ok-text), \"remove\" as destructive\n * (danger-text). No effect on layout, only color, so a caller can still pass any icon. */\n tone?: \"add\" | \"remove\";\n}\n\nexport interface EntityRowProps {\n title: string;\n /** A secondary line — a count, a subtitle, whatever the caller's data has that a raw\n * title doesn't. Optional because plenty of rows are fine with just a name. */\n meta?: React.ReactNode;\n action?: EntityRowAction;\n /** Marks the row a drag source: shows the grip icon and a grab cursor, and reports\n * `onPointerDown` so the caller's own pointer-based drag (see TransferList) can pick\n * the gesture up from there. Deliberately NOT the native HTML `draggable` attribute\n * (see the file doc comment for why) — this row never starts a native browser drag. */\n draggable?: boolean;\n onPointerDown?: (e: React.PointerEvent<HTMLDivElement>) => void;\n style?: React.CSSProperties;\n className?: string;\n}\n\n/**\n * EntityRow — a single row for a name plus an optional secondary line and an optional\n * action, meant to be stamped out by the hundreds inside a VirtualList.\n *\n * A real card per row, not flat text: its own surface distinct from the list's\n * background (`--surface-2` against the list's `--surface`), a hairline border, a soft\n * rest-state shadow that lifts on hover — the same `--r-md`/`--e-1`/`--e-2` elevation\n * vocabulary Card itself uses (see styles/components.css's \".fd-erow\" rules), just at\n * the tighter radius a compact row reads better at than Card's own `--r-lg`. Height is\n * still left to the caller (it fills 100% of its parent) because VirtualList is what\n * actually fixes row height, and duplicating that number here would be one more place a\n * future change has to remember to update — the card treatment lives entirely in\n * padding/border/shadow, not height.\n *\n * The drag/drop split is deliberate: a row only ever needs to say \"I am the thing being\n * dragged\" (draggable + onPointerDown), never \"something was dropped on me\" — nothing in\n * this kit drops one row onto another to reorder it, only a row onto a list to move it\n * there. Putting the drop handling on every row would mean wiring the same drop logic N\n * times over instead of once on the list container that actually owns it (see\n * TransferList's own doc comment for why it drives a pointer-based custom drag rather than\n * native HTML5 DnD — in short, a native drag image is a static snapshot, not a live\n * element, so it can't sustain a persistent tilt that follows the cursor), so this only\n * exposes the source half of the contract: `onPointerDown` hands the gesture off to\n * whatever the caller wants to do with it (TransferList starts tracking a drag once the\n * pointer has moved past a small threshold, so a plain click still reads as a click).\n * The action button exists precisely so drag-and-drop is never the only way to do the\n * same move — pointer-only and keyboard users get an equally real affordance, not a\n * degraded fallback.\n */\nexport function EntityRow({ title, meta, action, draggable = false, onPointerDown, style, className = \"\" }: EntityRowProps) {\n return (\n <div\n onPointerDown={onPointerDown}\n className={[\"fd-erow\", className].filter(Boolean).join(\" \")}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n height: \"100%\",\n padding: \"0 14px\",\n cursor: draggable ? \"grab\" : undefined,\n // Own the gesture on touch too — without this, a touch-drag on a draggable row\n // starts the page scrolling instead of (or as well as) the pointer drag.\n touchAction: draggable ? \"none\" : undefined,\n ...style,\n }}\n >\n {draggable ? (\n <i className=\"ph ph-dots-six-vertical\" aria-hidden=\"true\" style={{ fontSize: 14, flex: \"none\", color: \"var(--text-muted)\" }} />\n ) : null}\n <span style={{ flex: 1, minWidth: 0, display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 600, color: \"var(--text)\", whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\" }}>\n {title}\n </span>\n {meta ? (\n <span style={{ fontSize: \"var(--overline-size)\", color: \"var(--text-muted)\", whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\" }}>\n {meta}\n </span>\n ) : null}\n </span>\n {action ? (\n <IconButton\n icon={action.icon}\n label={action.label}\n size=\"sm\"\n onClick={action.onClick}\n style={{ color: action.tone === \"add\" ? \"var(--ok-text)\" : action.tone === \"remove\" ? \"var(--danger-text)\" : undefined }}\n />\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { SearchField } from \"../forms/SearchField\";\nimport { SortMenu, type SortMenuField } from \"./SortMenu\";\nimport { VirtualList } from \"./VirtualList\";\nimport { EntityRow } from \"./EntityRow\";\nimport { EmptyState } from \"../feedback/EmptyState\";\n\nexport type TransferListSide = \"left\" | \"right\";\n\nexport interface TransferListSideProps<T> {\n /** Whatever this side currently has loaded — not its full remote collection. */\n items: T[];\n /** Total matching count on the server, if known — shown next to the label. */\n total?: number;\n loading?: boolean;\n /** True while this side's WHOLE result set is being replaced (a search or sort\n * change), not merely appended to. `items` should still be the previous result set\n * while this is true — see VirtualList's own `refreshing` prop, which this threads\n * straight through. */\n refreshing?: boolean;\n search: string;\n onSearchChange: (value: string) => void;\n sort?: { key: string; dir: \"asc\" | \"desc\" } | null;\n sortFields: SortMenuField[];\n onSort: (key: string, dir: \"asc\" | \"desc\") => void;\n onNeedMore: (direction: \"start\" | \"end\") => void;\n hasMore?: { start?: boolean; end?: boolean };\n /** Heading text for this side. Fully caller-supplied — this component has no opinion\n * about what the two sides represent. */\n label?: string;\n /** Copy shown in the full-panel drop overlay while a drag is over this side. Falls\n * back to a generic \"Drop here\" (plus `label`, if set) when omitted — set this for\n * exact per-side wording (e.g. \"Drop to add to audience\" / \"Drop to remove from\n * audience\"), since that phrasing is about what a drop here DOES, which only the\n * caller's domain actually knows. */\n dropLabel?: string;\n}\n\nexport interface TransferListProps<T> {\n left: TransferListSideProps<T>;\n right: TransferListSideProps<T>;\n keyOf: (item: T) => string | number;\n renderLabel: (item: T) => string;\n renderMeta?: (item: T) => React.ReactNode;\n /** Fired by both a drag-drop and the equivalent +/- click. The caller owns actually\n * moving the item between whatever backing lists it maintains — this component never\n * mutates `left.items`/`right.items` itself. */\n onMove: (item: T, from: TransferListSide, to: TransferListSide) => void;\n /** Row height fed straight through to each side's VirtualList. Default (44) matches\n * the kit's --control-h-md, since that's the height EntityRow is tuned to look right at. */\n itemHeight?: number;\n /** Viewport height fed straight through to each side's VirtualList. */\n listHeight?: number;\n className?: string;\n}\n\nconst emptyHasMore: { start?: boolean; end?: boolean } = {};\n\n/** Pointer clientX/clientY has to move at least this many px past pointerdown before a\n * press-and-hold on a row reads as a drag rather than a click — without a threshold,\n * the action button's own click (which also fires pointerdown first) would be swallowed\n * the instant it started, and a plain unsteady tap would spuriously start a drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\ninterface DragState<T> {\n item: T;\n from: TransferListSide;\n key: string | number;\n pointerId: number;\n /** Pointer position, in row-local coordinates, at pickup — keeps the ghost glued to\n * wherever on the card the user actually grabbed it, instead of snapping to a corner. */\n offsetX: number;\n offsetY: number;\n width: number;\n height: number;\n /** Latest pointer position in viewport coordinates. */\n x: number;\n y: number;\n}\n\n/**\n * TransferList — a dual-list picker for moving items between two collections, by drag or\n * by a click, over a search box and a sort control each side owns independently.\n *\n * Deliberately named \"left\"/\"right\" rather than e.g. \"available\"/\"selected\": the product\n * this ships for is one particular use of it, but nothing about moving rows between two\n * lists is specific to that use, and baking in \"available\"/\"selected\" (or worse, this\n * kit's actual first consumer's own vocabulary) would make every *other* two-list picker\n * this kit will ever be asked for a second component instead of a second set of props. A\n * caller wanting domain words passes them through `label`/`dropLabel`.\n *\n * A pointer-based custom drag, not native HTML5 DnD, and not a library: this kit ships\n * zero runtime dependencies on purpose, and a pointer-events implementation (pointerdown/\n * pointermove/pointerup driving a portaled ghost element) is still zero-dependency — just\n * more code than `draggable`. It replaced an earlier native-HTML5-DnD version once the\n * spec called for a real \"card lifts out of the list and tilts, following the cursor\"\n * feel: a native drag image (`dataTransfer.setDragImage`) is a static snapshot taken once\n * at dragstart, not a live element, so it can't sustain a persistent rotation that tracks\n * the pointer for the duration of the drag — only owning the pointer events ourselves can.\n * Each row's pointerdown (via EntityRow's `onPointerDown`) arms a potential drag; nothing\n * visually happens until the pointer actually moves past `DRAG_THRESHOLD_PX`, so a plain\n * click (on the row, or on its +/- action button) is never mistaken for one. Once armed,\n * window-level pointermove/pointerup/pointercancel listeners (not per-row ones, since the\n * row being dragged gets replaced by a placeholder mid-drag) track the gesture to\n * completion; which side the pointer is currently over is decided by hit-testing each\n * side's own bounding rect against the pointer position, not by any per-row target.\n *\n * The +/- action on every row is not a fallback bolted on for accessibility box-ticking:\n * it is the same onMove call a drop makes, exposed as a first-class equivalent, because\n * drag-and-drop alone would silently exclude anyone not using a mouse.\n *\n * Fully controlled and stateless about the actual item sets: `left`/`right` are handed in\n * whole, this never copies or reorders them, and the only state kept locally is which row\n * is mid-drag and which side a drag is currently over — pure interaction feedback, thrown\n * away the moment the drag ends.\n */\nexport function TransferList<T>({\n left,\n right,\n keyOf,\n renderLabel,\n renderMeta,\n onMove,\n itemHeight = 44,\n listHeight = 440,\n className = \"\",\n}: TransferListProps<T>) {\n const [drag, setDrag] = React.useState<DragState<T> | null>(null);\n const [dragOverSide, setDragOverSide] = React.useState<TransferListSide | null>(null);\n const dragRef = React.useRef<DragState<T> | null>(null);\n const armedRef = React.useRef<{\n item: T;\n from: TransferListSide;\n key: string | number;\n pointerId: number;\n startX: number;\n startY: number;\n offsetX: number;\n offsetY: number;\n width: number;\n height: number;\n } | null>(null);\n const sideRefs = React.useRef<Record<TransferListSide, HTMLDivElement | null>>({ left: null, right: null });\n\n const hitTestSide = React.useCallback((x: number, y: number): TransferListSide | null => {\n for (const side of [\"left\", \"right\"] as TransferListSide[]) {\n const el = sideRefs.current[side];\n if (!el) continue;\n const r = el.getBoundingClientRect();\n if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) return side;\n }\n return null;\n }, []);\n\n const findItem = React.useCallback(\n (side: TransferListSide, key: string | number): T | undefined =>\n (side === \"left\" ? left.items : right.items).find((it) => keyOf(it) === key),\n [left.items, right.items, keyOf]\n );\n\n const beginDrag = (e: React.PointerEvent<HTMLDivElement>, item: T, from: TransferListSide) => {\n if (e.button !== 0) return;\n // Never arm a drag from the row's own +/- action button — that's a plain click\n // target in its own right (see EntityRowAction), not a drag handle.\n if ((e.target as HTMLElement).closest && (e.target as HTMLElement).closest(\"button\")) return;\n // Stop the browser's own native text-selection/drag gesture from starting at the\n // same time as ours — without this, a real mouse drag leaves a stray text\n // selection highlight across whatever the pointer passes over mid-drag.\n e.preventDefault();\n const rect = e.currentTarget.getBoundingClientRect();\n armedRef.current = {\n item,\n from,\n key: keyOf(item),\n pointerId: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n offsetX: e.clientX - rect.left,\n offsetY: e.clientY - rect.top,\n width: rect.width,\n height: rect.height,\n };\n };\n\n React.useEffect(() => {\n const onMovePointer = (e: PointerEvent) => {\n const armed = armedRef.current;\n if (!armed || e.pointerId !== armed.pointerId) return;\n if (!dragRef.current) {\n const dx = e.clientX - armed.startX;\n const dy = e.clientY - armed.startY;\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD_PX) return;\n const started: DragState<T> = {\n item: armed.item,\n from: armed.from,\n key: armed.key,\n pointerId: armed.pointerId,\n offsetX: armed.offsetX,\n offsetY: armed.offsetY,\n width: armed.width,\n height: armed.height,\n x: e.clientX,\n y: e.clientY,\n };\n dragRef.current = started;\n setDrag(started);\n } else {\n dragRef.current = { ...dragRef.current, x: e.clientX, y: e.clientY };\n setDrag(dragRef.current);\n }\n const hit = hitTestSide(e.clientX, e.clientY);\n setDragOverSide(hit && hit !== armed.from ? hit : null);\n };\n\n const endDrag = (e: PointerEvent) => {\n const armed = armedRef.current;\n if (!armed || e.pointerId !== armed.pointerId) return;\n const wasDragging = dragRef.current;\n armedRef.current = null;\n dragRef.current = null;\n setDrag(null);\n setDragOverSide(null);\n if (!wasDragging) return; // never crossed the threshold — this was a click, not a drag\n const hit = hitTestSide(e.clientX, e.clientY);\n if (hit && hit !== armed.from) {\n const item = findItem(armed.from, armed.key);\n if (item !== undefined) onMove(item, armed.from, hit);\n }\n };\n\n window.addEventListener(\"pointermove\", onMovePointer);\n window.addEventListener(\"pointerup\", endDrag);\n window.addEventListener(\"pointercancel\", endDrag);\n return () => {\n window.removeEventListener(\"pointermove\", onMovePointer);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n };\n }, [hitTestSide, findItem, onMove]);\n\n // Suppress text selection for the duration of an actual drag — with the ghost\n // portaled to document.body and tracking the pointer across the whole page, an\n // ordinary mouse-drag gesture would otherwise select surrounding page text as it goes.\n React.useEffect(() => {\n if (!drag || typeof document === \"undefined\") return;\n const prev = document.body.style.userSelect;\n document.body.style.userSelect = \"none\";\n return () => {\n document.body.style.userSelect = prev;\n };\n }, [drag]);\n\n const renderSide = (side: TransferListSide, cfg: TransferListSideProps<T>, opposite: TransferListSide) => {\n const showOverlay = drag != null && dragOverSide === side;\n return (\n <div\n ref={(el) => {\n sideRefs.current[side] = el;\n }}\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n padding: 10,\n borderRadius: 10,\n border: \"1px solid \" + (dragOverSide === side ? \"var(--brand)\" : \"var(--border)\"),\n background: \"var(--surface)\",\n position: \"relative\",\n }}\n >\n {cfg.label ? (\n <span className=\"fd-overline fd-muted\">\n {cfg.label}\n {cfg.total != null ? \" (\" + cfg.total.toLocaleString() + \")\" : \"\"}\n </span>\n ) : null}\n <span className=\"fd-row\" style={{ gap: 8 }}>\n <SearchField value={cfg.search} onChange={cfg.onSearchChange} placeholder=\"Search\" aria-label={(cfg.label || side) + \" search\"} style={{ flex: 1 }} />\n <SortMenu fields={cfg.sortFields} sort={cfg.sort} onSort={cfg.onSort} align={side === \"left\" ? \"left\" : \"right\"} />\n </span>\n <VirtualList\n items={cfg.items}\n itemHeight={itemHeight}\n height={listHeight}\n keyOf={keyOf}\n loading={cfg.loading}\n refreshing={cfg.refreshing}\n hasMore={cfg.hasMore || emptyHasMore}\n onNeedMore={cfg.onNeedMore}\n emptyState={<EmptyState icon=\"tray\" title=\"Nothing here\" />}\n renderItem={(item) => {\n const isBeingDragged = drag != null && drag.from === side && drag.key === keyOf(item);\n if (isBeingDragged) {\n // The vacated slot reads as an obviously-empty placeholder, not a\n // still-there-but-faded real row — the real card is off with the pointer\n // (see the portaled ghost below), tilted, not sitting here at all.\n return <div className=\"fd-erow-placeholder\" aria-hidden=\"true\" />;\n }\n return (\n <EntityRow\n title={renderLabel(item)}\n meta={renderMeta ? renderMeta(item) : undefined}\n draggable\n onPointerDown={(e) => beginDrag(e, item, side)}\n action={{\n icon: side === \"left\" ? \"plus\" : \"minus\",\n label: (side === \"left\" ? \"Move to \" : \"Move from \") + (side === \"left\" ? right.label || \"the other list\" : left.label || \"the other list\"),\n tone: side === \"left\" ? \"add\" : \"remove\",\n onClick: () => onMove(item, side, opposite),\n }}\n />\n );\n }}\n />\n {showOverlay ? (\n <div className=\"fd-tlist-drop-overlay\" aria-hidden=\"true\">\n <span className=\"fd-tlist-drop-card\">\n <i className=\"ph ph-tray-arrow-down\" style={{ fontSize: 18 }} aria-hidden=\"true\" />\n <span className=\"fd-body-sm\" style={{ fontWeight: 600 }}>\n {cfg.dropLabel || \"Drop here\" + (cfg.label ? \" — \" + cfg.label : \"\")}\n </span>\n </span>\n </div>\n ) : null}\n </div>\n );\n };\n\n return (\n <div className={[\"fd-tlist\", className].filter(Boolean).join(\" \")} style={{ display: \"flex\", gap: 16, alignItems: \"flex-start\" }}>\n {renderSide(\"left\", left, \"right\")}\n {renderSide(\"right\", right, \"left\")}\n {drag\n ? createPortal(\n <div\n aria-hidden=\"true\"\n className=\"fd-erow-ghost\"\n style={{\n position: \"fixed\",\n left: 0,\n top: 0,\n width: drag.width,\n height: drag.height,\n transform: `translate(${drag.x - drag.offsetX}px, ${drag.y - drag.offsetY}px) rotate(-3deg)`,\n pointerEvents: \"none\",\n zIndex: 1000,\n }}\n >\n <EntityRow title={renderLabel(drag.item)} meta={renderMeta ? renderMeta(drag.item) : undefined} draggable className=\"fd-erow-dragging\" />\n </div>,\n document.body\n )\n : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * Labelled text field. 44px tall, 8px radius, hairline border, blue focus ring.\n */\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n label?: string;\n help?: string;\n /** Present = error state. Replaces help text. */\n error?: string;\n /** Static text inside the field, left — e.g. \"$\" */\n prefix?: React.ReactNode;\n /** Static text inside the field, right — e.g. \"CPM\" */\n suffix?: React.ReactNode;\n /** Phosphor icon name shown left of the input */\n icon?: string;\n /** Right-aligned tabular figures. Use for every money or count field. */\n numeric?: boolean;\n required?: boolean;\n size?: \"md\" | \"lg\";\n /** Inline spinner on the right — for async validation or a value still arriving. */\n loading?: boolean;\n /** Applied to the outer .fd-field element — this is where width belongs. */\n style?: React.CSSProperties;\n /** Applied to the inner input element. Rarely needed. */\n inputStyle?: React.CSSProperties;\n}\n\nexport function Input({\n label, help, error, prefix, suffix, icon, numeric = false, required = false,\n size = \"md\", loading = false, disabled = false, id, className = \"\", style, inputStyle, ...rest\n}: InputProps) {\n const fieldId = id || (rest.name ? \"fd-\" + rest.name : undefined);\n const box = [\n \"fd-input\",\n numeric ? \"fd-input-num\" : \"\",\n error ? \"fd-input-error\" : \"\",\n disabled ? \"fd-input-disabled\" : \"\",\n size === \"lg\" ? \"fd-input-lg\" : \"\",\n className\n ].filter(Boolean).join(\" \");\n\n return (\n <div className=\"fd-field\" style={style}>\n {label ? (\n <label className=\"fd-field-label\" htmlFor={fieldId}>\n {label}{required ? <span className=\"fd-field-req\" aria-hidden=\"true\">*</span> : null}\n </label>\n ) : null}\n <div className={box}>\n {icon ? <span className=\"fd-input-icon\"><i className={\"ph ph-\" + icon} aria-hidden=\"true\" /></span> : null}\n {prefix ? <span className=\"fd-input-affix\">{prefix}</span> : null}\n <input id={fieldId} disabled={disabled} style={inputStyle} aria-invalid={error ? \"true\" : undefined} {...rest} />\n {loading ? <span className=\"fd-spinner\" style={{ color: \"var(--text-muted)\" }} aria-label=\"Loading\" /> : null}\n {suffix && !loading ? <span className=\"fd-input-affix\">{suffix}</span> : null}\n </div>\n {error ? (\n <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n ) : help ? (\n <span className=\"fd-field-help\">{help}</span>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Input } from \"./Input\";\n\nexport interface SearchFieldProps {\n /** Current search text. */\n value: string;\n /** Fires with the new text on every keystroke — a plain string, not a raw\n * DOM event, so this drops in above a filterable list with zero boilerplate. */\n onChange: (value: string) => void;\n placeholder?: string;\n /** Fires when the clear (\"x\") button is pressed. Defaults to onChange(\"\"). */\n onClear?: () => void;\n /** Applied to the outer .fd-field element — this is where width belongs. */\n style?: React.CSSProperties;\n className?: string;\n /** Visible field label, same as Input. Most search fields skip this and rely on placeholder. */\n label?: string;\n disabled?: boolean;\n id?: string;\n name?: string;\n \"aria-label\"?: string;\n}\n\n/**\n * SearchField — the one keyword field that belongs above a filterable list.\n *\n * A thin wrapper around Input: a magnifying-glass icon on the left (Input's\n * own `icon` prop) and a clear (\"x\") button on the right that appears only\n * once there's something to clear. The clear button rides in Input's\n * existing `suffix` slot rather than inventing new inset layout, and its\n * styling matches Select's clearable \"x\" (`ph-x-circle`, `all: unset`,\n * `text-muted`) so every clear affordance in the kit looks the same.\n *\n * Controlled, string-in/string-out. Debouncing is the consumer's job (or a\n * future concern) — building it in here would be hidden behavior a caller\n * can't see or override.\n */\nexport function SearchField({\n value, onChange, placeholder, onClear, style, className, label, disabled, id, name, ...rest\n}: SearchFieldProps) {\n const clear = onClear || (() => onChange(\"\"));\n return (\n <Input\n id={id}\n name={name}\n label={label}\n icon=\"magnifying-glass\"\n value={value}\n disabled={disabled}\n placeholder={placeholder}\n style={style}\n className={className}\n onChange={(e) => onChange(e.target.value)}\n suffix={\n value ? (\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={clear}\n style={{ all: \"unset\", cursor: \"pointer\", color: \"var(--text-muted)\", display: \"grid\", placeItems: \"center\", padding: 2 }}\n >\n <i className=\"ph ph-x-circle\" style={{ fontSize: 15 }} aria-hidden=\"true\" />\n </button>\n ) : undefined\n }\n {...rest}\n />\n );\n}\n","import * as React from \"react\";\n\n/**\n * Multi-select control with a 44px comfortable hit area.\n */\nexport interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label: React.ReactNode;\n description?: React.ReactNode;\n /** Renders as a bordered selectable card — for the big, calm choices. */\n card?: boolean;\n indeterminate?: boolean;\n}\n\nexport function Checkbox({ label, description, card = false, indeterminate = false, className = \"\", ...rest }: CheckboxProps) {\n const ref = React.useRef<HTMLInputElement>(null);\n React.useEffect(() => { if (ref.current) ref.current.indeterminate = indeterminate; }, [indeterminate]);\n return (\n <label className={[\"fd-choice\", card ? \"fd-choice-card\" : \"\", className].filter(Boolean).join(\" \")}>\n <span className=\"fd-choice-input\">\n <input ref={ref} type=\"checkbox\" {...rest} />\n <span className=\"fd-choice-box\" aria-hidden=\"true\">\n <i className={indeterminate ? \"ph ph-minus\" : \"ph ph-check\"} />\n </span>\n </span>\n <span className=\"fd-choice-text\">\n <span className=\"fd-choice-title\">{label}</span>\n {description ? <span className=\"fd-choice-desc\">{description}</span> : null}\n </span>\n </label>\n );\n}\n","import * as React from \"react\";\n\n/** One-of-many control. Share a name across the group. */\nexport interface RadioProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label: React.ReactNode;\n description?: React.ReactNode;\n card?: boolean;\n}\n\nexport function Radio({ label, description, card = false, className = \"\", ...rest }: RadioProps) {\n return (\n <label className={[\"fd-choice\", card ? \"fd-choice-card\" : \"\", className].filter(Boolean).join(\" \")}>\n <span className=\"fd-choice-input\">\n <input type=\"radio\" {...rest} />\n <span className=\"fd-choice-box fd-choice-box-round\" aria-hidden=\"true\"><span className=\"fd-choice-dot\" /></span>\n </span>\n <span className=\"fd-choice-text\">\n <span className=\"fd-choice-title\">{label}</span>\n {description ? <span className=\"fd-choice-desc\">{description}</span> : null}\n </span>\n </label>\n );\n}\n","import * as React from \"react\";\n\n/** An immediate on/off setting — no Save button. Use Checkbox inside forms instead. */\nexport interface SwitchProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: React.ReactNode;\n description?: React.ReactNode;\n}\n\nexport function Switch({ label, description, className = \"\", ...rest }: SwitchProps) {\n return (\n <label className={[\"fd-switch\", className].filter(Boolean).join(\" \")}>\n <input type=\"checkbox\" role=\"switch\" {...rest} />\n <span className=\"fd-switch-track\"><span className=\"fd-switch-thumb\" /></span>\n {label ? (\n <span className=\"fd-choice-text\">\n <span className=\"fd-switch-label\">{label}</span>\n {description ? <span className=\"fd-choice-desc\">{description}</span> : null}\n </span>\n ) : null}\n </label>\n );\n}\n","import * as React from \"react\";\n\n/** Multi-line field. Same chrome as Input; vertical resize only. */\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n label?: string;\n help?: string;\n error?: string;\n required?: boolean;\n rows?: number;\n /** Applied to the field wrapper. */\n style?: React.CSSProperties;\n}\n\nexport function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = \"\", style, ...rest }: TextareaProps) {\n const fieldId = id || (rest.name ? \"fd-\" + rest.name : undefined);\n const box = [\"fd-input\", \"fd-input-textarea\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\", className].filter(Boolean).join(\" \");\n return (\n <div className=\"fd-field\" style={style}>\n {label ? <label className=\"fd-field-label\" htmlFor={fieldId}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={box}>\n <textarea id={fieldId} rows={rows} disabled={disabled} aria-invalid={error ? \"true\" : undefined} {...rest} />\n </div>\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** Numeric field with thousands formatting on blur, +/- steppers with hold-to-repeat acceleration, arrow keys (shift = bigStep), and min/max clamping. */\nexport interface NumberInputProps {\n label?: string; help?: string; error?: string;\n prefix?: string; suffix?: string;\n required?: boolean; disabled?: boolean;\n min?: number; max?: number; step?: number;\n /** Larger step used while holding the steppers or shift+arrows. */\n bigStep?: number;\n /** Thousands-format the display when not editing. Default true. */\n format?: boolean;\n value?: number | string;\n /** Called with {target:{value}} where value is a number. */\n onChange?: (e: any) => void;\n placeholder?: string;\n style?: any; className?: string;\n}\n\nexport function NumberInput({\n label, help, error, prefix, suffix, required = false, disabled = false,\n min = -Infinity, max = Infinity, step = 1, bigStep, value, onChange,\n format = true, className = \"\", style, placeholder\n}: NumberInputProps) {\n const num = (v: any): number | null => { const n = Number(String(v == null ? \"\" : v).replace(/[^0-9.-]/g, \"\")); return isNaN(n) ? null : n; };\n const [text, setText] = React.useState(value == null || value === \"\" ? \"\" : String(value));\n const [editing, setEditing] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => { if (!editing) setText(value == null || value === \"\" ? \"\" : String(value)); }, [value, editing]);\n const clamp = (n: number) => Math.min(max, Math.max(min, n));\n const fire = (n: number) => onChange && onChange({ target: { value: n } });\n const bump = (dir: number, mult = 1) => {\n const cur = num(text) ?? num(value) ?? (min === -Infinity ? 0 : min);\n const next = clamp(cur + dir * (bigStep && mult > 1 ? bigStep : step) * (bigStep ? 1 : mult));\n setText(String(next)); fire(next);\n };\n const hold = (dir: number) => {\n bump(dir);\n let n = 0;\n const tick = () => { n++; bump(dir, n > 6 ? 4 : 1); timer.current = setTimeout(tick, n > 12 ? 40 : n > 6 ? 70 : 120); };\n timer.current = setTimeout(tick, 420);\n };\n const release = () => { if (timer.current) clearTimeout(timer.current); };\n React.useEffect(() => () => { if (timer.current) clearTimeout(timer.current); }, []);\n const shown = editing ? text : (() => { const n = num(text); return n == null ? \"\" : (format ? n.toLocaleString() : String(n)); })();\n const box = [\"fd-input\", \"fd-input-num\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \");\n return (\n <div className={[\"fd-field\", className].filter(Boolean).join(\" \")} style={style}>\n {label ? <label className=\"fd-field-label\">{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={box} style={{ gap: 8 }}>\n {prefix ? <span className=\"fd-input-affix\">{prefix}</span> : null}\n <input inputMode=\"numeric\" disabled={disabled} placeholder={placeholder} value={shown}\n onFocus={() => setEditing(true)}\n onBlur={() => { setEditing(false); const n = num(text); if (n != null) { const c = clamp(n); setText(String(c)); fire(c); } }}\n onChange={(e) => { setText(e.target.value); const n = num(e.target.value); if (n != null) fire(n); }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowUp\") { e.preventDefault(); bump(1, e.shiftKey ? 2 : 1); }\n else if (e.key === \"ArrowDown\") { e.preventDefault(); bump(-1, e.shiftKey ? 2 : 1); }\n }} />\n {suffix ? <span className=\"fd-input-affix\">{suffix}</span> : null}\n <span className=\"fd-row\" style={{ gap: 4, flex: \"none\" }}>\n <button type=\"button\" className=\"fd-stepbtn\" aria-label=\"Decrease\" disabled={disabled || (num(text) ?? 0) <= min}\n onPointerDown={() => hold(-1)} onPointerUp={release} onPointerLeave={release}><i className=\"ph ph-minus\" /></button>\n <button type=\"button\" className=\"fd-stepbtn\" aria-label=\"Increase\" disabled={disabled || (num(text) ?? 0) >= max}\n onPointerDown={() => hold(1)} onPointerUp={release} onPointerLeave={release}><i className=\"ph ph-plus\" /></button>\n </span>\n </div>\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/** Rich popover select: animated listbox, keyboard nav + type-ahead, search over 8 options, option icons, descriptions, meta and groups. API-compatible with the old native select. */\nexport interface SelectOption { value: string; label: string; description?: string; icon?: string; meta?: any; group?: string; disabled?: boolean }\nexport interface SelectProps {\n label?: string; help?: string; error?: string;\n options: Array<string | SelectOption>;\n placeholder?: string; required?: boolean; disabled?: boolean;\n /** Options still arriving — the control locks and shows a spinner. */\n loading?: boolean;\n /** Force the search box on/off; default: on when over 8 options. */\n searchable?: boolean;\n /** Show an x that clears back to placeholder. */\n clearable?: boolean;\n /** Pick several: `value` is an array, the popover stays open, options get\n * checkboxes, and a footer offers Select all / Clear. */\n multiple?: boolean;\n /** With `multiple`, override the collapsed box text for 2+ selections. */\n summary?: (values: string[]) => string;\n value?: string | string[];\n /** Called with {target:{value}} like a native select — an array when `multiple`. */\n onChange?: (e: any) => void;\n name?: string;\n /** Applied to the outer .fd-field element — this is where width belongs. */\n style?: any; className?: string;\n /** Element id — forwarded to the trigger button and the label's htmlFor. Not present on the original .d.ts but required by the source markup. */\n id?: string;\n}\n\nconst norm = (o: string | SelectOption): SelectOption => (typeof o === \"string\" ? { value: o, label: o } : o);\n\ninterface PopPos {\n left: number;\n width: number;\n top: number | null;\n bottom: number | null;\n up: boolean;\n maxH: number;\n}\n\nfunction usePopPos(open: boolean, ref: React.RefObject<HTMLElement>, estH: number, estW?: number): PopPos | null {\n const [pos, setPos] = React.useState<PopPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !ref.current) { setPos(null); return; }\n const calc = () => {\n const r = ref.current!.getBoundingClientRect();\n const below = window.innerHeight - r.bottom;\n const up = below < estH && r.top > below;\n const w = Math.max(r.width, estW || 0);\n const maxH = Math.min(window.innerHeight - 16, Math.max(160, (up ? r.top : below) - 14));\n setPos({\n left: Math.max(8, Math.min(r.left, window.innerWidth - w - 8)), width: r.width,\n top: up ? null : r.bottom + 6, bottom: up ? window.innerHeight - r.top + 6 : null, up, maxH,\n });\n };\n calc();\n window.addEventListener(\"scroll\", calc, true);\n window.addEventListener(\"resize\", calc);\n return () => { window.removeEventListener(\"scroll\", calc, true); window.removeEventListener(\"resize\", calc); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n return pos;\n}\n\nconst popStyle = (pos: PopPos, extra: React.CSSProperties): React.CSSProperties => ({\n position: \"fixed\", left: pos.left, top: pos.top == null ? \"auto\" : pos.top, bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n transformOrigin: pos.up ? \"bottom center\" : \"top center\", maxHeight: pos.maxH, overflowY: \"auto\", ...extra,\n});\n\nexport function Select({\n label, help, error, options = [], placeholder = \"Select…\", required = false,\n disabled = false, loading = false, value, onChange, searchable, clearable = false,\n multiple = false, summary,\n id, className = \"\", style, ...rest\n}: SelectProps) {\n const opts = options.map(norm);\n const vals = multiple ? (Array.isArray(value) ? value : value ? [value] : []) : [];\n const isOn = (v: string) => (multiple ? vals.includes(v) : v === value);\n const hasSearch = searchable === undefined ? opts.length > 8 : searchable;\n const [open, setOpen] = React.useState(false);\n const [q, setQ] = React.useState(\"\");\n const [active, setActive] = React.useState(-1);\n const rootRef = React.useRef<HTMLDivElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const popRef = React.useRef<HTMLDivElement>(null);\n const listRef = React.useRef<HTMLDivElement>(null);\n const typeBuf = React.useRef({ s: \"\", t: 0 });\n const selected = multiple ? null : opts.find((o) => o.value === value);\n const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];\n const pos = usePopPos(open, boxRef, hasSearch ? 390 : 340, 260);\n const boxText = multiple\n ? (chosen.length === 0 ? placeholder\n : chosen.length === 1 ? chosen[0].label\n : summary ? summary(chosen.map((o) => o.value)) : chosen.length + \" selected\")\n : (selected ? selected.label : placeholder);\n\n const visible = q ? opts.filter((o) => (o.label + \" \" + (o.description || \"\") + \" \" + (o.group || \"\")).toLowerCase().includes(q.toLowerCase())) : opts;\n\n const fire = (v: string | string[]) => { onChange && onChange({ target: { value: v } }); };\n const pick = (o: SelectOption) => {\n if (o.disabled) return;\n if (multiple) { fire(vals.includes(o.value) ? vals.filter((v) => v !== o.value) : [...vals, o.value]); return; }\n fire(o.value); setOpen(false);\n };\n const toggle = () => {\n if (disabled || loading) return;\n if (!open) { setQ(\"\"); setActive(Math.max(0, opts.findIndex((o) => isOn(o.value)))); }\n setOpen(!open);\n };\n\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (rootRef.current && rootRef.current.contains(e.target as Node)) return;\n if (popRef.current && popRef.current.contains(e.target as Node)) return;\n setOpen(false);\n };\n document.addEventListener(\"pointerdown\", away);\n return () => document.removeEventListener(\"pointerdown\", away);\n }, [open]);\n\n React.useEffect(() => {\n if (!open || active < 0 || !listRef.current) return;\n const el = listRef.current.querySelector('[data-i=\"' + active + '\"]') as HTMLElement | null;\n if (el) {\n const L = listRef.current, top = el.offsetTop - L.offsetTop;\n if (top < L.scrollTop) L.scrollTop = top - 4;\n else if (top + el.offsetHeight > L.scrollTop + L.clientHeight) L.scrollTop = top + el.offsetHeight - L.clientHeight + 4;\n }\n }, [active, open]);\n\n const onKey = (e: React.KeyboardEvent<HTMLElement>) => {\n if (disabled) return;\n if (!open && (e.key === \"Enter\" || e.key === \" \" || e.key === \"ArrowDown\" || e.key === \"ArrowUp\")) { e.preventDefault(); toggle(); return; }\n if (!open) {\n if (e.key.length === 1 && /\\S/.test(e.key)) {\n const now = Date.now();\n typeBuf.current = { s: (now - typeBuf.current.t < 700 ? typeBuf.current.s : \"\") + e.key.toLowerCase(), t: now };\n const hit = opts.find((o) => o.label.toLowerCase().startsWith(typeBuf.current.s));\n if (hit && !multiple) fire(hit.value);\n }\n return;\n }\n if (e.key === \"Escape\") { e.preventDefault(); setOpen(false); }\n else if (e.key === \"ArrowDown\") { e.preventDefault(); setActive((a) => Math.min(visible.length - 1, a + 1)); }\n else if (e.key === \"ArrowUp\") { e.preventDefault(); setActive((a) => Math.max(0, a - 1)); }\n else if (e.key === \"Home\") { e.preventDefault(); setActive(0); }\n else if (e.key === \"End\") { e.preventDefault(); setActive(visible.length - 1); }\n else if (e.key === \"Enter\") { e.preventDefault(); if (visible[active]) pick(visible[active]); }\n else if (e.key === \"Tab\") setOpen(false);\n };\n\n const groups: { g: string; items: { o: SelectOption; i: number }[] }[] = [];\n visible.forEach((o, i) => {\n const g = o.group || \"\";\n const last = groups[groups.length - 1];\n if (!last || last.g !== g) groups.push({ g, items: [{ o, i }] });\n else last.items.push({ o, i });\n });\n\n const fieldId = id || (rest.name ? \"fd-\" + rest.name : undefined);\n const box = [\"fd-input\", \"fd-select\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \");\n return (\n <div className={[\"fd-field\", \"fd-popfield\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")} style={style} ref={rootRef}>\n {label ? <label className=\"fd-field-label\" htmlFor={fieldId} onClick={toggle}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={box} style={{ cursor: disabled ? \"not-allowed\" : \"pointer\" }} ref={boxRef}>\n <button type=\"button\" id={fieldId} disabled={disabled || loading} onClick={toggle} onKeyDown={onKey}\n role=\"combobox\" aria-expanded={open} aria-haspopup=\"listbox\"\n style={{ all: \"unset\", flex: 1, minWidth: 0, display: \"flex\", alignItems: \"center\", gap: 8, cursor: \"inherit\", overflow: \"hidden\" }}>\n {selected && selected.icon ? <i className={\"ph ph-\" + selected.icon} style={{ flex: \"none\", color: \"var(--text-2)\" }} /> : null}\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", color: (multiple ? chosen.length : selected) ? \"var(--text)\" : \"var(--text-muted)\" }}>\n {boxText}\n </span>\n {multiple && chosen.length > 1 ? <span className=\"fd-mono\" style={{ flex: \"none\", fontSize: 11, fontWeight: 700, padding: \"1px 6px\", borderRadius: 99, background: \"var(--brand)\", color: \"#fff\" }}>{chosen.length}</span> : null}\n </button>\n {clearable && (multiple ? chosen.length > 0 : selected) && !loading ? (\n <button type=\"button\" aria-label=\"Clear\" onClick={(e) => { e.stopPropagation(); fire(multiple ? [] : \"\"); }}\n style={{ all: \"unset\", cursor: \"pointer\", color: \"var(--text-muted)\", display: \"grid\", placeItems: \"center\", padding: 2 }}>\n <i className=\"ph ph-x-circle\" style={{ fontSize: 15 }} />\n </button>) : null}\n {loading\n ? <span className=\"fd-spinner\" style={{ color: \"var(--text-muted)\" }} aria-label=\"Loading options\" />\n : <span className=\"fd-select-caret\" onClick={toggle}><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>}\n </div>\n {open && pos ? createPortal(\n <div className={\"fd-pop\" + (pos.up ? \" is-up\" : \"\")} ref={popRef}\n style={popStyle(pos, { minWidth: Math.max(pos.width, 260), maxWidth: 380, zIndex: 130, overflowY: \"hidden\" })}>\n {hasSearch ? (\n <div className=\"fd-pop-search\">\n <i className=\"ph ph-magnifying-glass\" style={{ color: \"var(--text-muted)\", fontSize: 14 }} />\n <input autoFocus placeholder=\"Search…\" value={q} onKeyDown={onKey}\n onChange={(e) => { setQ(e.target.value); setActive(0); }} />\n {q ? <span className=\"fd-body-sm fd-muted\">{visible.length}</span> : null}\n </div>) : null}\n <div className=\"fd-pop-list\" role=\"listbox\" aria-multiselectable={multiple || undefined} ref={listRef} style={{ maxHeight: Math.max(120, pos.maxH - (hasSearch ? 64 : 12) - (multiple ? 42 : 0)) }}>\n {visible.length === 0 ? <div className=\"fd-pop-empty\">Nothing matches \"{q}\".</div> : groups.map((grp) => (\n <React.Fragment key={grp.g || \"_\"}>\n {grp.g ? <div className=\"fd-pop-group\">{grp.g}</div> : null}\n {grp.items.map(({ o, i }) => (\n <button type=\"button\" key={String(o.value)} data-i={i} role=\"option\" aria-selected={isOn(o.value)}\n aria-disabled={o.disabled || undefined}\n className={[\"fd-opt\", i === active ? \"is-active\" : \"\", isOn(o.value) ? \"is-selected\" : \"\"].filter(Boolean).join(\" \")}\n onMouseEnter={() => setActive(i)} onClick={() => pick(o)}>\n {multiple ? (\n <span aria-hidden=\"true\" style={{ flex: \"none\", display: \"grid\", placeItems: \"center\", width: 16, height: 16, borderRadius: 4, border: \"1.5px solid \" + (isOn(o.value) ? \"var(--brand)\" : \"var(--border-strong, var(--border))\"), background: isOn(o.value) ? \"var(--brand)\" : \"var(--surface)\", color: \"#fff\" }}>\n {isOn(o.value) ? <i className=\"ph ph-check\" style={{ fontSize: 11 }} /> : null}\n </span>) : null}\n {o.icon ? <span className=\"fd-opt-icon\"><i className={\"ph ph-\" + o.icon} /></span> : null}\n <span style={{ flex: 1, minWidth: 0 }}>\n <span className=\"fd-opt-label\">{o.label}</span>\n {o.description ? <span className=\"fd-opt-desc\">{o.description}</span> : null}\n </span>\n {o.meta ? <span className=\"fd-opt-meta\">{o.meta}</span> : null}\n {multiple ? null : <span className=\"fd-opt-check\">{o.value === value ? <i className=\"ph ph-check\" /> : null}</span>}\n </button>\n ))}\n </React.Fragment>\n ))}\n </div>\n {multiple ? (\n <div className=\"fd-row\" style={{ gap: 10, padding: \"8px 12px\", borderTop: \"1px solid var(--border)\" }}>\n <button type=\"button\" onClick={() => fire(visible.filter((o) => !o.disabled).map((o) => o.value))}\n style={{ all: \"unset\", cursor: \"pointer\", fontSize: \"var(--body-sm-size)\", fontWeight: 600, color: \"var(--brand)\" }}>Select all</button>\n <span style={{ flex: 1 }} />\n <span className=\"fd-body-sm fd-muted\">{vals.length} of {opts.length}</span>\n <button type=\"button\" disabled={!vals.length} onClick={() => fire([])}\n style={{ all: \"unset\", cursor: vals.length ? \"pointer\" : \"default\", fontSize: \"var(--body-sm-size)\", fontWeight: 600, color: vals.length ? \"var(--text-2)\" : \"var(--text-muted)\" }}>Clear</button>\n </div>) : null}\n </div>, document.body) : null}\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\nconst MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nconst DOW = [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"];\nconst iso = (d: Date) => d.getFullYear() + \"-\" + String(d.getMonth() + 1).padStart(2, \"0\") + \"-\" + String(d.getDate()).padStart(2, \"0\");\nconst parse = (s?: string | null): Date | null => { if (!s) return null; const [y, m, d] = s.split(\"-\").map(Number); return new Date(y, m - 1, d); };\nconst fmt = (s?: string | null) => { const d = parse(s); return d ? MONTHS[d.getMonth()].slice(0, 3) + \" \" + d.getDate() + \", \" + d.getFullYear() : \"\"; };\n\ninterface PopPos {\n left: number;\n width: number;\n top: number | null;\n bottom: number | null;\n up: boolean;\n maxH: number;\n}\n\nfunction usePopPos(open: boolean, ref: React.RefObject<HTMLElement>, estH: number, estW?: number): PopPos | null {\n const [pos, setPos] = React.useState<PopPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !ref.current) { setPos(null); return; }\n const calc = () => {\n const r = ref.current!.getBoundingClientRect();\n const below = window.innerHeight - r.bottom;\n const up = below < estH && r.top > below;\n const w = Math.max(r.width, estW || 0);\n const maxH = Math.min(window.innerHeight - 16, Math.max(160, (up ? r.top : below) - 14));\n setPos({\n left: Math.max(8, Math.min(r.left, window.innerWidth - w - 8)), width: r.width,\n top: up ? null : r.bottom + 6, bottom: up ? window.innerHeight - r.top + 6 : null, up, maxH,\n });\n };\n calc();\n window.addEventListener(\"scroll\", calc, true);\n window.addEventListener(\"resize\", calc);\n return () => { window.removeEventListener(\"scroll\", calc, true); window.removeEventListener(\"resize\", calc); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n return pos;\n}\nconst popStyle = (pos: PopPos, extra: React.CSSProperties): React.CSSProperties => ({\n position: \"fixed\", left: pos.left, top: pos.top == null ? \"auto\" : pos.top, bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n transformOrigin: pos.up ? \"bottom center\" : \"top center\", maxHeight: pos.maxH, overflowY: \"auto\", ...extra,\n});\n\n/** Calendar popover date field. Click the title to drill month -> year; range mode picks start then end with live hover preview. Values are ISO strings (\"2026-03-01\"). */\nexport interface DatePickerProps {\n label?: string; help?: string; error?: string;\n required?: boolean; disabled?: boolean;\n /** false: value is \"YYYY-MM-DD\". true: value is {start, end}. */\n range?: boolean;\n value?: any;\n /** Called with {target:{value}} — string, or {start,end} in range mode. */\n onChange?: (e: any) => void;\n placeholder?: string;\n style?: any; className?: string;\n}\n\n/** The bare calendar, for embedding in custom surfaces. months=2 renders two side-by-side months (used by range mode). */\nexport interface CalendarProps { value?: any; range?: boolean; onPick: (v: any) => void; initialMonth?: string; months?: number }\n\nexport function Calendar({ value, range = false, onPick, initialMonth, months = 1 }: CalendarProps) {\n const today = new Date();\n const sel = range ? value || {} : { start: value, end: value };\n const anchor = parse(sel.start) || parse(initialMonth) || today;\n const [vy, setVy] = React.useState(anchor.getFullYear());\n const [vm, setVm] = React.useState(anchor.getMonth());\n const [mode, setMode] = React.useState(\"days\"); // days | months | years\n const [hover, setHover] = React.useState<string | null>(null);\n const s = parse(sel.start), e = parse(sel.end);\n const hoverEnd = range && s && !e && hover ? parse(hover) : null;\n const inRange = (d: Date) => {\n const lo = s, hi = e || hoverEnd;\n return lo && hi && d > (lo < hi ? lo : hi) && d < (lo < hi ? hi : lo);\n };\n const isEdge = (d: Date) => (s && iso(d) === iso(s)) || (e && iso(d) === iso(e));\n const clickDay = (d: Date) => {\n const v = iso(d);\n if (!range) { onPick(v); return; }\n if (!sel.start || (sel.start && sel.end)) onPick({ start: v, end: \"\" });\n else {\n const a = parse(sel.start)!;\n onPick(d < a ? { start: v, end: sel.start } : { start: sel.start, end: v });\n }\n };\n const nav = (d: number) => { let m = vm + d, y = vy; if (m < 0) { m = 11; y--; } if (m > 11) { m = 0; y++; } setVm(m); setVy(y); };\n const monthGrid = (y: number, m: number) => {\n const startPad = new Date(y, m, 1).getDay();\n const cells: Date[] = [];\n for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));\n return (\n <div className=\"fd-cal-grid\" style={{ width: months > 1 ? 252 : \"auto\", flex: \"none\" }} onMouseLeave={() => setHover(null)}>\n {DOW.map((d) => <span key={d} className=\"fd-cal-dow\">{d}</span>)}\n {cells.map((d, i) => (\n <button type=\"button\" key={i}\n className={[\"fd-cal-day\", d.getMonth() !== m ? \"is-out\" : \"\", iso(d) === iso(today) ? \"is-today\" : \"\", inRange(d) ? \"in-range\" : \"\", isEdge(d) ? \"is-edge\" : \"\"].filter(Boolean).join(\" \")}\n onClick={() => clickDay(d)} onMouseEnter={() => range && setHover(iso(d))}>\n {d.getDate()}\n </button>\n ))}\n </div>\n );\n };\n const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;\n return (\n <div className=\"fd-cal\" style={{ width: months > 1 && mode === \"days\" ? \"auto\" : undefined }}>\n <div className=\"fd-cal-head\">\n <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Previous\" onClick={() => mode === \"years\" ? setVy(vy - 12) : mode === \"months\" ? setVy(vy - 1) : nav(-1)}><i className=\"ph ph-caret-left\" /></button>\n <button type=\"button\" className=\"fd-cal-title\" onClick={() => setMode(mode === \"days\" ? \"months\" : mode === \"months\" ? \"years\" : \"days\")}>\n {mode === \"days\" ? MONTHS[vm] + \" \" + vy : mode === \"months\" ? vy : (vy - 5) + \" – \" + (vy + 6)}\n <i className=\"ph ph-caret-down\" style={{ fontSize: 10, marginLeft: 6, color: \"var(--text-muted)\" }} />\n </button>\n {months > 1 && mode === \"days\" ? <span className=\"fd-cal-title\" style={{ cursor: \"default\", background: \"none\" }}>{MONTHS[nextM] + \" \" + nextY}</span> : null}\n <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Next\" onClick={() => mode === \"years\" ? setVy(vy + 12) : mode === \"months\" ? setVy(vy + 1) : nav(1)}><i className=\"ph ph-caret-right\" /></button>\n </div>\n {mode === \"days\" ? (\n <div style={{ display: \"flex\", gap: 18 }}>\n {monthGrid(vy, vm)}\n {months > 1 ? monthGrid(nextY, nextM) : null}\n </div>\n ) : mode === \"months\" ? (\n <div className=\"fd-cal-grid-months\">\n {MONTHS.map((m, i) => (\n <button type=\"button\" key={m} className={\"fd-cal-cell\" + (i === vm && s && s.getFullYear() === vy ? \" is-sel\" : \"\")}\n onClick={() => { setVm(i); setMode(\"days\"); }}>{m.slice(0, 3)}</button>\n ))}\n </div>\n ) : (\n <div className=\"fd-cal-grid-months\">\n {Array.from({ length: 12 }, (_, i) => vy - 5 + i).map((y) => (\n <button type=\"button\" key={y} className={\"fd-cal-cell\" + (y === vy ? \" is-sel\" : \"\")}\n onClick={() => { setVy(y); setMode(\"months\"); }}>{y}</button>\n ))}\n </div>\n )}\n <div className=\"fd-cal-foot\">\n <button type=\"button\" className=\"fd-btn fd-btn-link\" style={{ fontSize: 12.5 }}\n onClick={() => { setVy(today.getFullYear()); setVm(today.getMonth()); setMode(\"days\"); }}>Today</button>\n <span style={{ flex: 1 }} />\n {range && sel.start ? <span className=\"fd-body-sm fd-muted\">{fmt(sel.start)}{sel.end ? \" → \" + fmt(sel.end) : \" → pick an end\"}</span> : null}\n </div>\n </div>\n );\n}\n\nexport function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, className = \"\", style, ...rest }: DatePickerProps) {\n const [open, setOpen] = React.useState(false);\n const rootRef = React.useRef<HTMLDivElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const popRef = React.useRef<HTMLDivElement>(null);\n const pos = usePopPos(open, boxRef, 430, range ? 600 : 316);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (rootRef.current && rootRef.current.contains(e.target as Node)) return;\n if (popRef.current && popRef.current.contains(e.target as Node)) return;\n setOpen(false);\n };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n const display = range\n ? (value && value.start ? fmt(value.start) + (value.end ? \" → \" + fmt(value.end) : \" → …\") : \"\")\n : fmt(value);\n const toggle = () => { if (!disabled) setOpen(!open); };\n return (\n <div className={[\"fd-field\", \"fd-popfield\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")} style={style} ref={rootRef}>\n {label ? <label className=\"fd-field-label\" onClick={toggle}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={[\"fd-input\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \")} style={{ cursor: disabled ? \"not-allowed\" : \"pointer\" }} onClick={toggle} ref={boxRef}>\n <span className=\"fd-input-icon\"><i className=\"ph ph-calendar-blank\" aria-hidden=\"true\" /></span>\n <button type=\"button\" disabled={disabled} onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); toggle(); } }}\n style={{ all: \"unset\", flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", cursor: \"inherit\", color: display ? \"var(--text)\" : \"var(--text-muted)\" }} {...rest}>\n {display || placeholder || (range ? \"Pick a date range\" : \"Pick a date\")}\n </button>\n <span className=\"fd-select-caret\"><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>\n </div>\n {open && pos ? createPortal(\n <div className={\"fd-pop\" + (pos.up ? \" is-up\" : \"\")} ref={popRef} style={popStyle(pos, { width: \"max-content\", minWidth: 0, zIndex: 130 })}>\n <Calendar range={range} months={range ? 2 : 1} value={value}\n onPick={(v: any) => { onChange && onChange({ target: { value: v } }); if (!range || (v.start && v.end)) setOpen(false); }} />\n </div>, document.body) : null}\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\nconst pad = (n: number) => String(n).padStart(2, \"0\");\n\ninterface PopPos {\n left: number;\n width: number;\n top: number | null;\n bottom: number | null;\n up: boolean;\n maxH: number;\n}\n\nfunction usePopPos(open: boolean, ref: React.RefObject<HTMLElement>, estH: number, estW?: number): PopPos | null {\n const [pos, setPos] = React.useState<PopPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !ref.current) { setPos(null); return; }\n const calc = () => {\n const r = ref.current!.getBoundingClientRect();\n const below = window.innerHeight - r.bottom;\n const up = below < estH && r.top > below;\n const w = Math.max(r.width, estW || 0);\n const maxH = Math.min(window.innerHeight - 16, Math.max(160, (up ? r.top : below) - 14));\n setPos({\n left: Math.max(8, Math.min(r.left, window.innerWidth - w - 8)), width: r.width,\n top: up ? null : r.bottom + 6, bottom: up ? window.innerHeight - r.top + 6 : null, up, maxH,\n });\n };\n calc();\n window.addEventListener(\"scroll\", calc, true);\n window.addEventListener(\"resize\", calc);\n return () => { window.removeEventListener(\"scroll\", calc, true); window.removeEventListener(\"resize\", calc); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n return pos;\n}\nconst popStyle = (pos: PopPos, extra: React.CSSProperties): React.CSSProperties => ({\n position: \"fixed\", left: pos.left, top: pos.top == null ? \"auto\" : pos.top, bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n transformOrigin: pos.up ? \"bottom center\" : \"top center\", maxHeight: pos.maxH, overflowY: \"auto\", ...extra,\n});\n\n/** Analog clock-face time field: tap or drag the hand to set the hour, auto-advances to minutes; AM/PM chips; \"Now\" shortcut. Value is 24h \"HH:MM\". */\nexport interface TimePickerProps {\n label?: string; help?: string; error?: string;\n required?: boolean; disabled?: boolean;\n /** 24h \"HH:MM\", e.g. \"14:30\". */\n value?: string;\n /** Called with {target:{value}}. */\n onChange?: (e: any) => void;\n placeholder?: string;\n style?: any; className?: string;\n}\n\n/** The bare clock face, for embedding (e.g. below a Calendar). */\nexport interface ClockFaceProps { value?: string; onChange: (v: string) => void }\n\nexport function ClockFace({ value = \"09:00\", onChange }: ClockFaceProps) {\n let [h24, m] = value.split(\":\").map(Number);\n if (isNaN(h24)) h24 = 9;\n if (isNaN(m)) m = 0;\n const pm = h24 >= 12;\n const h12 = h24 % 12 === 0 ? 12 : h24 % 12;\n const [mode, setMode] = React.useState(\"h\"); // h | m\n const faceRef = React.useRef<HTMLDivElement>(null);\n const dragging = React.useRef(false);\n const set = (h: number, mm: number, isPm: boolean) => onChange((isPm ? (h % 12) + 12 : h % 12) + \":\" + pad(mm));\n const R = 108, NR = 80;\n const nums = mode === \"h\" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);\n const selNum = mode === \"h\" ? h12 : m;\n const angleOf = (n: number) => (mode === \"h\" ? (n % 12) * 30 : (n / 5) * 30) - 90;\n const fromPointer = (e: React.PointerEvent) => {\n const r = faceRef.current!.getBoundingClientRect();\n const x = e.clientX - r.left - R, y = e.clientY - r.top - R;\n let deg = Math.atan2(y, x) * 180 / Math.PI + 90;\n if (deg < 0) deg += 360;\n if (mode === \"h\") {\n const h = Math.round(deg / 30) % 12 || 12;\n set(h === 12 ? 12 : h, m, pm);\n } else {\n const mm = Math.round(deg / 6) % 60;\n set(h12, mm, pm);\n }\n };\n const down = (e: React.PointerEvent) => { dragging.current = true; faceRef.current && faceRef.current.setPointerCapture && faceRef.current.setPointerCapture(e.pointerId); fromPointer(e); };\n const move = (e: React.PointerEvent) => { if (dragging.current) fromPointer(e); };\n const upH = () => { if (dragging.current) { dragging.current = false; if (mode === \"h\") setMode(\"m\"); } };\n const handAngle = mode === \"h\" ? (h12 % 12) * 30 : m * 6;\n const minuteOff = mode === \"m\" && m % 5 !== 0;\n return (\n <div style={{ padding: \"4px 14px 14px\" }}>\n <div className=\"fd-clock-digits\">\n <button type=\"button\" className={\"fd-clock-digit\" + (mode === \"h\" ? \" is-active\" : \"\")} onClick={() => setMode(\"h\")}>{pad(h12)}</button>\n <span style={{ fontSize: 24, fontWeight: 700, color: \"var(--text-muted)\" }}>:</span>\n <button type=\"button\" className={\"fd-clock-digit\" + (mode === \"m\" ? \" is-active\" : \"\")} onClick={() => setMode(\"m\")}>{pad(m)}</button>\n <span className=\"fd-stack\" style={{ gap: 3, marginLeft: 8 }}>\n {[\"AM\", \"PM\"].map((ap) => (\n <button type=\"button\" key={ap} onClick={() => set(h12, m, ap === \"PM\")}\n style={{ border: \"1px solid \" + ((ap === \"PM\") === pm ? \"var(--brand)\" : \"var(--border)\"), background: (ap === \"PM\") === pm ? \"var(--surface-brand)\" : \"var(--surface)\", color: (ap === \"PM\") === pm ? \"var(--brand)\" : \"var(--text-muted)\", borderRadius: 6, font: \"inherit\", fontSize: 11, fontWeight: 700, padding: \"3px 8px\", cursor: \"pointer\" }}>{ap}</button>\n ))}\n </span>\n </div>\n <div className=\"fd-clock\" ref={faceRef} onPointerDown={down} onPointerMove={move} onPointerUp={upH}>\n <span className=\"fd-clock-hand\" style={{ height: NR - (minuteOff ? 14 : 16), transform: \"translateX(-50%) rotate(\" + handAngle + \"deg)\", bottom: \"50%\" }} />\n <span className=\"fd-clock-pivot\" />\n {minuteOff ? <span style={{ position: \"absolute\", left: \"50%\", top: \"50%\", width: 10, height: 10, margin: -5, borderRadius: \"50%\", border: \"2px solid var(--brand)\", background: \"var(--surface)\", transform: \"rotate(\" + handAngle + \"deg) translateY(-\" + (NR - 6) + \"px)\", transformOrigin: \"center\", pointerEvents: \"none\" }} /> : null}\n {nums.map((n) => {\n const a = angleOf(n) * Math.PI / 180;\n return (\n <span key={n} className={\"fd-clock-num\" + (n === selNum || (mode === \"m\" && n === Math.round(m / 5) * 5 % 60 && m % 5 === 0) ? \" is-sel\" : \"\")}\n style={{ left: R + Math.cos(a) * NR, top: R + Math.sin(a) * NR }}>\n {mode === \"m\" ? pad(n) : n}\n </span>\n );\n })}\n </div>\n <div className=\"fd-row\" style={{ justifyContent: \"center\", gap: 6 }}>\n <span className=\"fd-body-sm fd-muted\">{mode === \"h\" ? \"Pick the hour — drag or tap\" : \"Now the minutes\"}</span>\n </div>\n </div>\n );\n}\n\nexport function TimePicker({ label, help, error, required = false, disabled = false, value = \"\", onChange, placeholder = \"Pick a time\", className = \"\", style }: TimePickerProps) {\n const [open, setOpen] = React.useState(false);\n const rootRef = React.useRef<HTMLDivElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const popRef = React.useRef<HTMLDivElement>(null);\n const pos = usePopPos(open, boxRef, 420, 262);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (rootRef.current && rootRef.current.contains(e.target as Node)) return;\n if (popRef.current && popRef.current.contains(e.target as Node)) return;\n setOpen(false);\n };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n const disp = () => {\n if (!value) return \"\";\n const [h, m] = value.split(\":\").map(Number);\n return (h % 12 === 0 ? 12 : h % 12) + \":\" + pad(m) + \" \" + (h >= 12 ? \"PM\" : \"AM\");\n };\n const toggle = () => { if (!disabled) setOpen(!open); };\n return (\n <div className={[\"fd-field\", \"fd-popfield\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")} style={style} ref={rootRef}>\n {label ? <label className=\"fd-field-label\" onClick={toggle}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={[\"fd-input\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \")} style={{ cursor: disabled ? \"not-allowed\" : \"pointer\" }} onClick={toggle} ref={boxRef}>\n <span className=\"fd-input-icon\"><i className=\"ph ph-clock\" aria-hidden=\"true\" /></span>\n <button type=\"button\" disabled={disabled} onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); toggle(); } }}\n style={{ all: \"unset\", flex: 1, cursor: \"inherit\", color: value ? \"var(--text)\" : \"var(--text-muted)\" }}>\n {disp() || placeholder}\n </button>\n <span className=\"fd-select-caret\"><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>\n </div>\n {open && pos ? createPortal(\n <div className={\"fd-pop\" + (pos.up ? \" is-up\" : \"\")} ref={popRef} style={popStyle(pos, { width: 262, minWidth: 0, zIndex: 130 })}>\n <ClockFace value={value || \"09:00\"} onChange={(v) => onChange && onChange({ target: { value: v } })} />\n <div className=\"fd-cal-foot\" style={{ margin: \"0 14px 12px\", paddingTop: 10 }}>\n <button type=\"button\" className=\"fd-btn fd-btn-link\" style={{ fontSize: 12.5 }}\n onClick={() => { const d = new Date(); onChange && onChange({ target: { value: d.getHours() + \":\" + pad(d.getMinutes()) } }); }}>Now</button>\n <span style={{ flex: 1 }} />\n <button type=\"button\" className=\"fd-btn fd-btn-primary fd-btn-sm\" onClick={() => setOpen(false)}>Done</button>\n </div>\n </div>, document.body) : null}\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * Continuous value control. In the media planner this is the reallocation slider:\n * a live chip follows the handle while dragging and the commit is explicit.\n */\nexport interface SliderProps {\n label?: string;\n min?: number;\n max?: number;\n step?: number;\n value?: number;\n onChange?: (value: number) => void;\n /** Renders the value in the chip and header, e.g. v => \"$\" + v.toLocaleString() */\n format?: (value: number) => string;\n showChip?: boolean;\n help?: string;\n className?: string;\n}\n\nexport function Slider({\n label, min = 0, max = 100, step = 1, value, onChange,\n format = (v: number) => String(v), showChip = true, help, className = \"\", ...rest\n}: SliderProps) {\n const [dragging, setDragging] = React.useState(false);\n const v = value === undefined ? min : Number(value);\n const pct = max === min ? 0 : ((v - min) / (max - min)) * 100;\n return (\n <div className={[\"fd-field\", className].filter(Boolean).join(\" \")}>\n {label ? (\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n <span className=\"fd-field-label\">{label}</span>\n <span className=\"fd-num\" style={{ color: \"var(--text-2)\" }}>{format(v)}</span>\n </div>\n ) : null}\n <div className=\"fd-slider\">\n <span className=\"fd-slider-fill\" style={{ width: pct + \"%\" }} />\n {showChip && dragging ? (\n <span className=\"fd-slider-chip\" style={{ left: pct + \"%\" }}>{format(v)}</span>\n ) : null}\n <input type=\"range\" min={min} max={max} step={step} value={v}\n onChange={onChange ? (e) => onChange!(Number(e.target.value)) : undefined}\n onPointerDown={() => setDragging(true)}\n onPointerUp={() => setDragging(false)}\n onBlur={() => setDragging(false)}\n aria-label={label} {...rest} />\n </div>\n {help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** Dual-thumb range slider: drag either thumb or the rail, value bubbles while dragging or focused, tick marks with labels, optional magnetic snap, keyboard (arrows, shift for 10%, Home/End). */\nexport interface RangeSliderProps {\n label?: string; help?: string;\n min?: number; max?: number; step?: number;\n /** [low, high] */\n value: [number, number];\n onChange: (v: [number, number]) => void;\n /** Minimum distance the thumbs keep between them. */\n minGap?: number;\n /** Tick stops; label is optional. */\n marks?: Array<{ value: number; label?: string }>;\n /** Ordinal mode: unevenly spaced legal values (numbers, or {value,label}); the\n * slider then travels in even steps between them and reports real values.\n * Infinity is allowed for an open upper bound — give it a label like \"No limit\". */\n stops?: Array<number | { value: number; label?: string }>;\n /** Magnetically snap to nearby marks while dragging. */\n snap?: boolean;\n format?: (v: number) => string;\n className?: string;\n}\n\nexport function RangeSlider({\n label, min = 0, max = 100, step = 1, value, onChange, minGap = 0,\n marks = [], snap = false, stops, format, help, className = \"\", ...rest\n}: RangeSliderProps & Record<string, any>): JSX.Element {\n // Hooks must run unconditionally on every render (Rules of Hooks) — declared\n // here even though ordinal mode below doesn't use them, since it delegates\n // to a nested <RangeSlider> instance rather than using this one's state.\n const fmt = format || ((v: number) => String(v));\n const [a, b] = value || [min, max];\n const [drag, setDrag] = React.useState<number | null>(null); // 0 | 1 | null\n const [focus, setFocus] = React.useState<number | null>(null);\n const railRef = React.useRef<HTMLSpanElement>(null);\n const pct = (v: number) => max === min ? 0 : ((v - min) / (max - min)) * 100;\n const clampPair = (i: number, v: number): [number, number] => {\n v = Math.min(max, Math.max(min, Math.round(v / step) * step));\n if (snap && marks.length) {\n const near = marks.reduce((best, m) => Math.abs(m.value - v) < Math.abs(best - v) ? m.value : best, Infinity);\n if (Math.abs(near - v) <= (max - min) * 0.015) v = near;\n }\n const pair: [number, number] = i === 0 ? [Math.min(v, b - minGap), b] : [a, Math.max(v, a + minGap)];\n return pair;\n };\n const fromEvent = (e: { clientX: number }) => {\n const r = railRef.current!.getBoundingClientRect();\n return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);\n };\n React.useEffect(() => {\n if (drag === null) return;\n const mv = (e: PointerEvent) => onChange && onChange(clampPair(drag, fromEvent(e)));\n const upH = () => setDrag(null);\n window.addEventListener(\"pointermove\", mv);\n window.addEventListener(\"pointerup\", upH);\n return () => { window.removeEventListener(\"pointermove\", mv); window.removeEventListener(\"pointerup\", upH); };\n }, [drag, a, b]);\n\n /* Ordinal mode: with `stops` the slider works in index space, so unevenly\n spaced breakpoints (0, 5k, 10k … 100k, No limit) get even handle travel and\n only ever land on a legal value. Delegates to the linear implementation. */\n if (stops && stops.length > 1) {\n const S: Array<{ value: number; label?: string }> = stops.map((s) => (typeof s === \"object\" ? s : { value: s }));\n const num = (v: any) => (v === Infinity || v == null ? Number.MAX_SAFE_INTEGER : v);\n const idxOf = (v: any) => S.reduce((best, s, i) => (Math.abs(num(s.value) - num(v)) < Math.abs(num(S[best].value) - num(v)) ? i : best), 0);\n const labelOf = (i: number) => { const s = S[Math.round(i)] || S[0]; return s.label != null ? s.label : String(s.value); };\n const thin = S.length > 7 ? Math.ceil(S.length / 5) : 1;\n const pair = value || [S[0].value, S[S.length - 1].value];\n return (\n <RangeSlider {...rest} label={label} help={help} className={className}\n min={0} max={S.length - 1} step={1} minGap={minGap}\n value={[idxOf(pair[0]), idxOf(pair[1])]}\n onChange={(p) => onChange && onChange([S[p[0]].value, S[p[1]].value])}\n marks={marks.length ? marks : S.map((_s, i) => ({ value: i, label: (i === 0 || i === S.length - 1 || i % thin === 0) ? labelOf(i) : undefined }))}\n format={format ? (i: number) => format!(S[Math.round(i)].value) : labelOf} />\n );\n }\n const startDrag = (i: number) => (e: React.PointerEvent) => {\n e.preventDefault();\n (e.target as Element).setPointerCapture && (e.target as Element).setPointerCapture(e.pointerId);\n setDrag(i);\n };\n const onRailDown = (e: React.PointerEvent) => {\n const v = fromEvent(e);\n const i = Math.abs(v - a) <= Math.abs(v - b) ? 0 : 1;\n onChange && onChange(clampPair(i, v));\n setDrag(i);\n };\n const key = (i: number) => (e: React.KeyboardEvent) => {\n const big = (max - min) / 10;\n let d = 0;\n if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") d = -(e.shiftKey ? big : step);\n else if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") d = e.shiftKey ? big : step;\n else if (e.key === \"Home\") { onChange(clampPair(i, min)); e.preventDefault(); return; }\n else if (e.key === \"End\") { onChange(clampPair(i, max)); e.preventDefault(); return; }\n else return;\n e.preventDefault();\n onChange && onChange(clampPair(i, (i === 0 ? a : b) + d));\n };\n const showChip = (i: number) => drag === i || focus === i;\n const hasLabels = marks.some((m) => m.label);\n return (\n <div className={[\"fd-field\", className].filter(Boolean).join(\" \")} {...rest}>\n {label ? (\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n <span className=\"fd-field-label\">{label}</span>\n <span className=\"fd-num\" style={{ color: \"var(--text-2)\" }}>{fmt(a)} – {fmt(b)}</span>\n </div>\n ) : null}\n <div className={\"fd-range\" + (hasLabels ? \" has-labels\" : \"\")} onPointerDown={onRailDown}>\n <span className=\"fd-range-rail\" ref={railRef} />\n <span className=\"fd-range-fill\" style={{ left: pct(a) + \"%\", width: (pct(b) - pct(a)) + \"%\" }} />\n {marks.map((m) => (\n <React.Fragment key={m.value}>\n <span className={\"fd-range-mark\" + (m.value >= a && m.value <= b ? \" is-in\" : \"\")} style={{ left: pct(m.value) + \"%\" }} />\n {m.label ? <span className=\"fd-range-mark-label\" style={{ left: pct(m.value) + \"%\" }}>{m.label}</span> : null}\n </React.Fragment>\n ))}\n {[a, b].map((v, i) => (\n <span key={i} className={\"fd-range-thumb\" + (drag === i ? \" is-drag\" : \"\")} style={{ left: pct(v) + \"%\" }}\n tabIndex={0} role=\"slider\" aria-valuemin={min} aria-valuemax={max} aria-valuenow={v}\n aria-label={(label || \"Range\") + (i === 0 ? \" minimum\" : \" maximum\")}\n onPointerDown={startDrag(i)} onKeyDown={key(i)}\n onFocus={() => setFocus(i)} onBlur={() => setFocus(null)}>\n <span className=\"fd-range-chip\" style={{ opacity: showChip(i) ? 1 : undefined }}>{fmt(v)}</span>\n </span>\n ))}\n </div>\n {help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { filterFiles, toAttachment } from \"../../kits/files\";\nimport type { Attachment, FileRejection } from \"../../kits/files\";\n\nexport interface DropzoneProps {\n onFiles?: (files: File[]) => void;\n onReject?: (rejections: FileRejection[]) => void;\n accept?: string;\n maxFileSize?: number;\n multiple?: boolean;\n disabled?: boolean;\n label?: string;\n hint?: string;\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * A drop target that wraps any content. Reports accepted files and rejections;\n * it never uploads anything itself.\n */\nexport function Dropzone({\n onFiles, onReject, accept, maxFileSize, multiple = true, disabled = false,\n label = \"Drop files to attach\", hint, children, className = \"\", style,\n}: DropzoneProps) {\n const [over, setOver] = React.useState(false);\n const depth = React.useRef(0);\n\n const has = (e: React.DragEvent) => {\n const dt = e.dataTransfer;\n if (!dt) return false;\n return Array.from(dt.types || []).indexOf(\"Files\") !== -1;\n };\n\n const enter = (e: React.DragEvent) => { if (disabled || !has(e)) return; depth.current++; setOver(true); };\n const leave = () => { depth.current = Math.max(0, depth.current - 1); if (!depth.current) setOver(false); };\n const over_ = (e: React.DragEvent) => { if (disabled || !has(e)) return; e.preventDefault(); e.dataTransfer.dropEffect = \"copy\"; };\n const drop = (e: React.DragEvent) => {\n if (disabled || !has(e)) return;\n e.preventDefault();\n depth.current = 0; setOver(false);\n const picked = multiple ? Array.from(e.dataTransfer.files) : Array.from(e.dataTransfer.files).slice(0, 1);\n const { accepted, rejected } = filterFiles(picked, { accept, maxFileSize });\n if (rejected.length && onReject) onReject(rejected);\n if (accepted.length && onFiles) onFiles(accepted);\n };\n\n return (\n <div\n className={[\"fd-dropzone\", over ? \"is-over\" : \"\", className].filter(Boolean).join(\" \")}\n style={style}\n onDragEnter={enter} onDragLeave={leave} onDragOver={over_} onDrop={drop}\n >\n {children}\n {over ? (\n <div className=\"fd-dropzone-veil\" aria-hidden=\"true\">\n <div className=\"fd-dropzone-card\">\n <i className=\"ph ph-tray-arrow-down\" />\n <span className=\"fd-dropzone-label\">{label}</span>\n {hint ? <span className=\"fd-dropzone-hint\">{hint}</span> : null}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface FilePickButtonProps extends Omit<DropzoneProps, \"children\" | \"label\" | \"hint\" | \"style\"> { label?: string; icon?: string; children?: React.ReactNode }\n\n/** A file input behind any trigger. Resets between picks so re-picking the same file fires. */\nexport function FilePickButton({\n onFiles, onReject, accept, maxFileSize, multiple = true, disabled,\n label = \"Attach files\", icon = \"paperclip\", className = \"\", children,\n}: FilePickButtonProps) {\n const ref = React.useRef<HTMLInputElement>(null);\n return (\n <React.Fragment>\n <button\n type=\"button\" className={[\"fd-attachbtn\", className].filter(Boolean).join(\" \")} disabled={disabled}\n aria-label={label} title={label} onClick={() => ref.current && ref.current.click()}\n >\n {children != null ? children : <i className={\"ph ph-\" + icon} aria-hidden=\"true\" />}\n </button>\n <input\n ref={ref} type=\"file\" accept={accept} multiple={multiple} className=\"fd-sr\"\n onChange={(e) => {\n const { accepted, rejected } = filterFiles(e.target.files as FileList, { accept, maxFileSize });\n if (rejected.length && onReject) onReject(rejected);\n if (accepted.length && onFiles) onFiles(accepted);\n e.target.value = \"\";\n }}\n />\n </React.Fragment>\n );\n}\n\nexport type FileUploadHandler = (file: File, onProgress: (pct: number) => void, signal?: AbortSignal) => Promise<{ url: string; thumb?: { url: string } } | void>;\n\n/**\n * Upload orchestration for a staged set of files: progress per file, per-file\n * errors, retry, and cancel — the same behaviour an upload field has.\n *\n * `upload(file, onProgress, signal)` must resolve to `{url, thumb?}` or throw.\n * Nothing here knows what a chat is; it is the app's upload handler that does.\n */\nexport function useStagedFiles(\n upload?: FileUploadHandler,\n opts?: { onUploaded?: (a: Attachment) => void; onError?: (e: unknown, a: Attachment) => void }\n): {\n items: Attachment[];\n add: (files: File[] | FileList) => Attachment[];\n remove: (a: Attachment) => void;\n retry: (a: Attachment) => void;\n clear: () => void;\n busy: boolean;\n setItems: (items: Attachment[]) => void;\n} {\n const o = opts || {};\n const [items, setItems] = React.useState<Attachment[]>([]);\n const controllers = React.useRef<Record<string, AbortController | null>>({});\n\n const patch = (id: string, next: Partial<Attachment>) => setItems((list) => list.map((f) => (f.id === id ? Object.assign({}, f, next) : f)));\n\n const run = React.useCallback((att: Attachment) => {\n if (!upload) return;\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n controllers.current[att.id] = ac;\n patch(att.id, { progress: 0, error: undefined });\n Promise.resolve()\n .then(() => upload!(att.file as File, (p) => patch(att.id, { progress: Math.max(0, Math.min(99, p)) }), ac ? ac.signal : undefined))\n .then((res) => {\n const r = res || {};\n patch(att.id, { progress: 100, url: (r as any).url || att.url, thumb: (r as any).thumb || att.thumb, error: undefined, remote: true } as any);\n o.onUploaded && o.onUploaded(att);\n })\n .catch((err) => {\n if (ac && ac.signal.aborted) return;\n patch(att.id, { progress: null, error: (err && err.message) || \"Upload failed\" } as any);\n o.onError && o.onError(err, att);\n })\n .finally(() => { delete controllers.current[att.id]; });\n }, [upload]);\n\n const add = React.useCallback((files: File[] | FileList) => {\n if (!upload) return []; // nowhere to put it: refuse rather than strand it\n const atts = Array.from(files).map((f) => toAttachment(f));\n setItems((list) => list.concat(atts));\n atts.forEach(run);\n return atts;\n }, [upload, run]);\n\n const remove = React.useCallback((att: Attachment) => {\n const ac = controllers.current[att.id];\n if (ac) { try { ac.abort(); } catch (_e) { /* noop */ } delete controllers.current[att.id]; }\n setItems((list) => list.filter((f) => f.id !== att.id));\n }, []);\n\n const retry = React.useCallback((att: Attachment) => { run(att); }, [run]);\n const clear = React.useCallback(() => {\n Object.values(controllers.current).forEach((ac) => { try { ac && ac.abort(); } catch (_e) { /* noop */ } });\n controllers.current = {};\n setItems([]);\n }, []);\n\n const busy = items.some((f) => f.progress != null && f.progress < 100 && !f.error);\n return { items, add, remove, retry, clear, busy, setItems };\n}\n\n/** Namespace export — useStagedFiles is a hook, so it cannot be capital-initial itself. */\nexport const DropzoneKit = { useStagedFiles };\n","import * as React from \"react\";\nimport { formatBytes, iconForMime, isImage } from \"../../kits/files\";\nimport type { Attachment } from \"../../kits/files\";\n\nconst truncateMiddle = (name: string, max = 34) => {\n if (!name || name.length <= max) return name;\n const ext = /\\.[A-Za-z0-9]+$/.exec(name);\n const tail = ext ? ext[0] : \"\";\n const head = name.slice(0, Math.max(6, max - tail.length - 2));\n return head + \"…\" + tail;\n};\n\nfunction Progress({ value }: { value: number }) {\n return (\n <span className=\"fd-file-prog\" role=\"progressbar\" aria-valuenow={Math.round(value)} aria-valuemin={0} aria-valuemax={100}>\n <span className=\"fd-file-prog-fill\" style={{ width: Math.max(4, Math.min(100, value)) + \"%\" }} />\n </span>\n );\n}\n\nexport interface FileChipProps { file: Attachment; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void; compact?: boolean; className?: string }\n\n/**\n * A compact file row: icon or thumbnail, name, size, live upload progress,\n * error state, and an optional remove control. One file component everywhere —\n * images get real thumbnails, video gets a play badge, uploads get a bar.\n */\nexport function FileChip({ file, onOpen, onRemove, onRetry, compact = false, className = \"\" }: FileChipProps) {\n if (!file) return null;\n const uploading = file.progress != null && file.progress < 100 && !file.error;\n const image = isImage(file.mime, file.name);\n const thumb = (file.thumb && file.thumb.url) || (image ? file.blobUrl || file.url : null);\n const meta = file.meta || (file.size ? formatBytes(file.size) : \"\");\n const clickable = !!onOpen && !uploading;\n\n return (\n <div className={[\"fd-file\", compact ? \"is-compact\" : \"\", file.error ? \"is-error\" : \"\", uploading ? \"is-uploading\" : \"\", className].filter(Boolean).join(\" \")}>\n <button\n type=\"button\" className=\"fd-file-main\" disabled={!clickable}\n onClick={clickable ? () => onOpen!(file) : undefined}\n title={file.name + (meta ? \" · \" + meta : \"\")}\n >\n <span className=\"fd-file-icon\">\n {thumb ? <img src={thumb} alt=\"\" /> : <i className={\"ph ph-\" + iconForMime(file.mime, file.name)} aria-hidden=\"true\" />}\n {(file.mime || \"\").startsWith(\"video/\") ? <i className=\"ph ph-play fd-file-play\" aria-hidden=\"true\" /> : null}\n </span>\n <span className=\"fd-file-text\">\n <span className=\"fd-file-name\">{truncateMiddle(file.name, compact ? 26 : 40)}</span>\n <span className=\"fd-file-meta\">\n {file.error\n ? <span className=\"fd-file-err\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{file.error}</span>\n : uploading ? <span className=\"fd-tabular\">{Math.round(file.progress as number)}% uploaded</span>\n : meta}\n </span>\n </span>\n </button>\n {uploading ? <Progress value={file.progress as number} /> : null}\n {file.error && onRetry ? (\n <button type=\"button\" className=\"fd-file-act\" onClick={() => onRetry!(file)} aria-label={\"Retry upload of \" + file.name}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {onRemove ? (\n <button type=\"button\" className=\"fd-file-act\" onClick={() => onRemove!(file)} aria-label={\"Remove \" + file.name}>\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n );\n}\n\nexport interface FileTileProps { file: Attachment; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; maxHeight?: number; className?: string }\n\n/**\n * An image-forward tile. Pasted screenshots belong here, not in a chip —\n * the picture is the content.\n */\nexport function FileTile({ file, onOpen, onRemove, maxHeight = 200, className = \"\" }: FileTileProps) {\n if (!file) return null;\n const src = (file.thumb && file.thumb.url) || file.blobUrl || file.url;\n const uploading = file.progress != null && file.progress < 100 && !file.error;\n return (\n <figure className={[\"fd-tile\", uploading ? \"is-uploading\" : \"\", file.error ? \"is-error\" : \"\", className].filter(Boolean).join(\" \")}>\n <button type=\"button\" className=\"fd-tile-btn\" onClick={onOpen ? () => onOpen!(file) : undefined} disabled={!onOpen}>\n {src ? <img src={src} alt={file.name || \"\"} style={{ maxHeight }} loading=\"lazy\" />\n : <span className=\"fd-tile-fallback\"><i className={\"ph ph-\" + iconForMime(file.mime, file.name)} aria-hidden=\"true\" /></span>}\n </button>\n {uploading ? <Progress value={file.progress as number} /> : null}\n {file.error ? <figcaption className=\"fd-tile-err\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{file.error}</figcaption> : null}\n {onRemove ? (\n <button type=\"button\" className=\"fd-tile-x\" onClick={() => onRemove!(file)} aria-label={\"Remove \" + file.name}>\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </figure>\n );\n}\n\n/**\n * One row of uniform tiles — the staging tray. Same size whatever the type:\n * images crop to fill, documents show a truncated name and their size.\n * Overflow scrolls sideways instead of growing the tray.\n */\nexport interface FileStripProps { files: Attachment[]; size?: number; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void; className?: string }\n\nexport function FileStrip({ files = [], size = 68, onOpen, onRemove, onRetry, className = \"\" }: FileStripProps) {\n const list = files.filter(Boolean);\n if (!list.length) return null;\n return (\n <div className={[\"fd-filestrip\", \"fd-scrollbar\", className].filter(Boolean).join(\" \")} style={{ \"--fd-cell\": size + \"px\" } as React.CSSProperties}>\n {list.map((f) => <FileCell key={f.id || f.name} file={f} onOpen={onOpen} onRemove={onRemove} onRetry={onRetry} />)}\n </div>\n );\n}\n\nconst shortName = (name: string, keep = 5) => {\n const s = String(name || \"file\");\n const ext = /\\.([A-Za-z0-9]{1,5})$/.exec(s);\n const tail = ext ? \".\" + ext[1] : \"\";\n const stem = tail ? s.slice(0, -tail.length) : s;\n return stem.length > keep ? stem.slice(0, keep) + \"…\" + tail : stem + tail;\n};\n\ninterface FileCellProps { file: Attachment; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void }\n\nfunction FileCell({ file, onOpen, onRemove, onRetry }: FileCellProps) {\n const uploading = file.progress != null && file.progress < 100 && !file.error;\n const image = isImage(file.mime, file.name);\n const thumb = (file.thumb && file.thumb.url) || (image ? file.blobUrl || file.url : null);\n const label = file.name + (file.size ? \" · \" + formatBytes(file.size) : \"\");\n return (\n <div className={[\"fd-cell\", file.error ? \"is-error\" : \"\", uploading ? \"is-uploading\" : \"\"].filter(Boolean).join(\" \")} title={file.error ? file.name + \" — \" + file.error : label}>\n <button type=\"button\" className=\"fd-cell-main\" onClick={onOpen ? () => onOpen!(file) : undefined} disabled={!onOpen || uploading} aria-label={\"Open \" + file.name}>\n {thumb ? <img src={thumb} alt=\"\" /> : (\n <span className=\"fd-cell-doc\">\n <i className={\"ph ph-\" + iconForMime(file.mime, file.name)} aria-hidden=\"true\" />\n <span className=\"fd-cell-name\">{shortName(file.name)}</span>\n <span className=\"fd-cell-size\">{file.meta || formatBytes(file.size)}</span>\n </span>\n )}\n {(file.mime || \"\").startsWith(\"video/\") ? <i className=\"ph ph-play fd-cell-play\" aria-hidden=\"true\" /> : null}\n </button>\n {uploading ? <Progress value={file.progress as number} /> : null}\n {file.error ? (\n <span className=\"fd-cell-err\" aria-hidden=\"true\"><i className=\"ph ph-warning-circle\" /></span>\n ) : null}\n {file.error && onRetry ? (\n <button type=\"button\" className=\"fd-cell-x is-retry\" onClick={() => onRetry!(file)} aria-label={\"Retry upload of \" + file.name}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {onRemove ? (\n <button type=\"button\" className=\"fd-cell-x\" onClick={() => onRemove!(file)} aria-label={\"Remove \" + file.name}>\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n );\n}\n\n/** Images as tiles, everything else as chips. */\nexport interface FileGridProps { files: Attachment[]; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void; tiles?: boolean; maxHeight?: number; compact?: boolean; className?: string }\n\n/**\n * A set of files: images as tiles, everything else as chips.\n * `tiles={false}` forces the compact all-chips form for tight columns.\n */\nexport function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeight = 200, compact = false, className = \"\" }: FileGridProps) {\n const list = files.filter(Boolean);\n if (!list.length) return null;\n const pics = tiles ? list.filter((f) => isImage(f.mime, f.name)) : [];\n const rest = list.filter((f) => pics.indexOf(f) === -1);\n return (\n <div className={[\"fd-filegrid\", className].filter(Boolean).join(\" \")}>\n {pics.length ? (\n <div className=\"fd-filegrid-tiles\">\n {pics.map((f) => <FileTile key={f.id || f.name} file={f} onOpen={onOpen} onRemove={onRemove} maxHeight={maxHeight} />)}\n </div>\n ) : null}\n {rest.length ? (\n <div className=\"fd-filegrid-chips\">\n {rest.map((f) => <FileChip key={f.id || f.name} file={f} onOpen={onOpen} onRemove={onRemove} onRetry={onRetry} compact={compact} />)}\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/* ── rich markdown composer ────────────────────────────────────────────────\n A contenteditable whose text content is EXACTLY the markdown source, one\n element per line. Because the caret lives in the real text, decoration is\n free: headings can be bigger, bold can be bold, quotes can be indented —\n there is no mirror to keep in metric lockstep. Markers stay in the text\n (dimmed), so what you typed is always what gets sent.\n\n All structural input — Enter, paste, line breaks — is intercepted, and the\n DOM is re-synced line by line after every change, so the browser never gets\n to invent nested divs. */\n\nconst isMac = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || \"\");\n\nconst INLINE_RE = /(\\*\\*\\*[^*\\n]+\\*\\*\\*|\\*\\*[^*\\n]+\\*\\*|__[^_\\n]+__|~~[^~\\n]+~~|`[^`\\n]+`|\\*[^*\\s][^*\\n]*\\*|(?<![A-Za-z0-9_])_[^_\\s][^_\\n]*_|\\[[^\\]\\n]*\\]\\([^)\\s\\n]*\\)|https?:\\/\\/\\S+)/g;\n\n/** [text, className] pairs whose concatenation equals the input, exactly. */\nfunction inlineParts(text: string): Array<[string, string]> {\n const out: Array<[string, string]> = [];\n let last = 0, m: RegExpExecArray | null;\n INLINE_RE.lastIndex = 0;\n while ((m = INLINE_RE.exec(text))) {\n if (m.index > last) out.push([text.slice(last, m.index), \"\"]);\n const tk = m[0];\n const wrap = (n: number, cls: string) => { out.push([tk.slice(0, n), \"rme-mk\"], [tk.slice(n, tk.length - n), cls], [tk.slice(tk.length - n), \"rme-mk\"]); };\n if (/^\\*\\*\\*/.test(tk)) wrap(3, \"rme-b rme-i\");\n else if (/^\\*\\*/.test(tk) || /^__/.test(tk)) wrap(2, \"rme-b\");\n else if (/^~~/.test(tk)) wrap(2, \"rme-s\");\n else if (/^`/.test(tk)) wrap(1, \"rme-c\");\n else if (/^\\[/.test(tk)) {\n const cut = tk.indexOf(\"](\");\n out.push([\"[\", \"rme-mk\"], [tk.slice(1, cut), \"rme-lk\"], [tk.slice(cut, tk.length), \"rme-mk\"]);\n } else if (/^https?:/.test(tk)) out.push([tk, \"rme-lk\"]);\n else wrap(1, \"rme-i\");\n last = m.index + tk.length;\n }\n if (last < text.length) out.push([text.slice(last), \"\"]);\n return out.filter((p) => p[0] !== \"\");\n}\n\nconst RE_H = /^(#{1,6})(\\s+)(.*)$/;\nconst RE_LI = /^(\\s*)([-*+]|\\d{1,3}[.)])(\\s+)(\\[[ xX]\\]\\s+)?(.*)$/;\nconst RE_Q = /^(\\s*)(>+)(\\s*)(.*)$/;\nconst RE_FENCE = /^\\s*(```|~~~)(.*)$/;\n\n/** Build one line element. Its textContent is the source line, character for character. */\nfunction buildLine(doc: Document, line: string, inFence: boolean): HTMLElement {\n const el = doc.createElement(\"div\");\n el.className = \"fd-rme-line\";\n el.setAttribute(\"data-src\", line);\n const put = (text: string, cls: string) => {\n if (!text) return;\n if (!cls) { el.appendChild(doc.createTextNode(text)); return; }\n const s = doc.createElement(\"span\");\n s.className = cls;\n s.textContent = text;\n el.appendChild(s);\n };\n\n const fence = RE_FENCE.exec(line);\n if (fence || inFence) {\n el.classList.add(\"is-code\");\n if (fence) { put(fence[1], \"rme-mk\"); put(fence[2], \"rme-lang\"); }\n else put(line, \"\");\n if (!line) el.appendChild(doc.createElement(\"br\"));\n return el;\n }\n\n const h = RE_H.exec(line);\n if (h) {\n el.classList.add(\"is-h\" + h[1].length);\n put(h[1], \"rme-mk\"); put(h[2], \"rme-mk\");\n inlineParts(h[3]).forEach(([t, c]) => put(t, c));\n return el;\n }\n const q = RE_Q.exec(line);\n if (q && q[2]) {\n el.classList.add(\"is-quote\");\n put(q[1], \"\"); put(q[2] + q[3], \"rme-mk\");\n inlineParts(q[4]).forEach(([t, c]) => put(t, c));\n return el;\n }\n const li = RE_LI.exec(line);\n if (li) {\n el.classList.add(\"is-li\");\n if (li[1]) el.style.paddingLeft = (li[1].length * 8) + \"px\";\n put(li[1], \"\"); put(li[2], \"rme-bullet\"); put(li[3], \"rme-mk\");\n if (li[4]) put(li[4], /x/i.test(li[4]) ? \"rme-task is-done\" : \"rme-task\");\n inlineParts(li[5]).forEach(([t, c]) => put(t, c));\n return el;\n }\n if (/^\\s*\\|/.test(line)) {\n el.classList.add(\"is-table\");\n put(line, \"\");\n return el;\n }\n if (/^\\s*(?:[-*_]\\s*){3,}$/.test(line)) {\n el.classList.add(\"is-rule\");\n put(line, \"rme-mk\");\n return el;\n }\n\n const parts = inlineParts(line);\n if (!parts.length) el.appendChild(doc.createElement(\"br\"));\n else parts.forEach(([t, c]) => put(t, c));\n return el;\n}\n\n/* ── caret <-> character offset ─────────────────────────────────────────────\n One walk produces both the source text and the offsets of the selection\n endpoints, so the two can never disagree. It tolerates a flattened DOM\n (select-all-and-type, autocorrect, drag-drop) because the next sync rebuilds\n the structure from the text it read. */\n\nconst IS_BLOCK = (n: Node): boolean => n.nodeType === 1 && /^(DIV|P|LI|H[1-6]|BLOCKQUOTE|PRE|SECTION)$/.test((n as Element).tagName);\n\nconst lineTextOf = (el: Element): string => {\n let s = \"\";\n el.childNodes.forEach((n) => { s += (n.nodeType === 1 && (n as Element).tagName === \"BR\") ? \"\" : (n.textContent || \"\"); });\n return s;\n};\n\ninterface CaretPoint { node: Node; offset: number }\n\nfunction readDom(root: Element, points?: Array<CaretPoint | null | undefined>): { text: string; points: number[] } {\n const pts = points || [];\n const out: Array<number | null> = pts.map(() => null);\n let text = \"\";\n\n const hit = (node: Node, resolve: (offset: number) => number) => {\n pts.forEach((p, i) => { if (out[i] == null && p && p.node === node) out[i] = resolve(p.offset); });\n };\n const childPrefix = (el: Element, upto: number) => {\n let n = 0;\n for (let j = 0; j < upto && j < el.childNodes.length; j++) {\n const c = el.childNodes[j];\n n += (c.nodeType === 1 && (c as Element).tagName === \"BR\") ? 0 : (c.textContent || \"\").length;\n }\n return n;\n };\n\n const walkInline = (el: Element) => {\n el.childNodes.forEach((n) => {\n if (n.nodeType === 3) {\n hit(n, (o) => text.length + Math.min(o, (n as Text).nodeValue!.length));\n text += (n as Text).nodeValue;\n } else if (n.nodeType === 1 && (n as Element).tagName !== \"BR\") {\n hit(n, (o) => text.length + childPrefix(n as Element, o));\n walkInline(n as Element);\n }\n });\n };\n\n const children = Array.from(root.childNodes);\n let first = true;\n children.forEach((n) => {\n if (IS_BLOCK(n)) {\n if (!first) text += \"\\n\";\n first = false;\n hit(n, (o) => text.length + childPrefix(n as Element, o));\n walkInline(n as Element);\n } else if (n.nodeType === 1 && (n as Element).tagName === \"BR\") {\n text += \"\\n\";\n first = false;\n } else {\n first = false;\n hit(n, (o) => text.length + Math.min(o || 0, ((n as Text).nodeValue || \"\").length));\n text += n.textContent || \"\";\n }\n });\n\n // a caret dropped on the root itself addresses a child index\n pts.forEach((p, i) => {\n if (out[i] != null || !p || p.node !== root) return;\n let t = 0;\n for (let j = 0; j < p.offset && j < children.length; j++) {\n const c = children[j];\n t += IS_BLOCK(c) ? (j ? 1 : 0) + lineTextOf(c as Element).length : (c.textContent || \"\").length;\n }\n out[i] = t;\n });\n\n return { text, points: out.map((v) => (v == null ? text.length : v)) };\n}\n\nfunction placeCaret(root: Element, offset: number): void {\n const lines = Array.from(root.children);\n let remaining = Math.max(0, offset);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const len = (line.textContent || \"\").length;\n if (remaining <= len || i === lines.length - 1) {\n const walker = document.createTreeWalker(line, NodeFilter.SHOW_TEXT);\n let t: Node | null, seen = 0, target: Text | null = null, targetOffset = 0;\n while ((t = walker.nextNode())) {\n const L = (t as Text).nodeValue!.length;\n if (seen + L >= remaining) { target = t as Text; targetOffset = Math.min(L, remaining - seen); break; }\n seen += L; target = t as Text; targetOffset = L;\n }\n const sel = window.getSelection();\n const range = document.createRange();\n if (target) range.setStart(target, targetOffset);\n else range.setStart(line, 0);\n range.collapse(true);\n sel!.removeAllRanges();\n sel!.addRange(range);\n return;\n }\n remaining -= len + 1;\n }\n}\n\n/* Structure-tolerant read-back lives in readDom above. */\n\nfunction syncDom(root: Element, value: any): void {\n const lines = String(value == null ? \"\" : value).split(\"\\n\");\n const doc = root.ownerDocument;\n let inFence = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const wasFence = inFence;\n if (RE_FENCE.test(line)) inFence = !inFence;\n const existing = root.children[i];\n const key = (wasFence ? \"1|\" : \"0|\") + line;\n if (existing && existing.getAttribute(\"data-key\") === key) continue;\n const next = buildLine(doc, line, wasFence);\n next.setAttribute(\"data-key\", key);\n if (existing) root.replaceChild(next, existing);\n else root.appendChild(next);\n }\n while (root.children.length > lines.length) root.removeChild(root.lastChild as Node);\n}\n\nconst LIST_CONT = RE_LI;\n\nexport interface MarkdownEditorHandle {\n focus(opts?: FocusOptions): void;\n blur(): void;\n readonly element: HTMLElement | null;\n getSelection(): { start: number; end: number };\n replaceRange(start: number, end: number, text: string, caretAt?: number): void;\n insert(text: string): void;\n wrapSelection(before: string, after?: string, placeholder?: string): void;\n prefixLines(prefix: string): void;\n}\nexport interface EditorTrigger { type: \"slash\" | \"mention\"; query: string; from: number; to: number }\n\n/**\n * Rich markdown composer. A contenteditable whose text content IS the markdown\n * source, one element per line — so headings can be bigger and bold can be bold\n * without a mirror to keep in metric lockstep.\n *\n * Keydown ordering contract: the host sees the event FIRST (onKeyDown), may call\n * preventDefault(), and the editor then checks defaultPrevented and skips its own\n * handling. onPaste follows the same contract.\n */\nexport interface MarkdownEditorProps {\n value: string;\n onChange?: (next: string) => void;\n onSubmit?: (value: string) => void;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onPaste?: (e: React.ClipboardEvent) => void;\n onTrigger?: (t: EditorTrigger | null) => void;\n placeholder?: string;\n disabled?: boolean;\n readOnly?: boolean;\n maxLength?: number;\n minRows?: number;\n maxRows?: number;\n autoFocus?: boolean;\n /** Enter sends, Shift+Enter inserts a newline. Default true. */\n submitOnEnter?: boolean;\n ariaLabel?: string;\n className?: string;\n id?: string;\n}\n\n/**\n * The composer field.\n *\n * Keydown ordering contract — the host sees the event FIRST:\n * editor emits onKeyDown → host may call preventDefault()\n * → editor checks event.defaultPrevented and skips its own handling\n * Emitting after the internal handler would make the host's preventDefault\n * arrive too late. onPaste follows the same contract.\n */\nexport const MarkdownEditor = React.forwardRef<MarkdownEditorHandle, MarkdownEditorProps>(function MarkdownEditor({\n value = \"\", onChange, onSubmit, onKeyDown, onPaste, onTrigger,\n placeholder = \"\", disabled = false, readOnly = false, maxLength,\n minRows = 1, maxRows = 12, autoFocus = false,\n submitOnEnter = true, ariaLabel = \"Message\", className = \"\", id,\n}, ref) {\n const boxRef = React.useRef<HTMLDivElement>(null);\n const composing = React.useRef(false);\n const pendingCaret = React.useRef<number | null>(null);\n\n /* keep the DOM in step with `value`, then restore the caret */\n React.useLayoutEffect(() => {\n const root = boxRef.current;\n if (!root || composing.current) return;\n const active = document.activeElement === root || root.contains(document.activeElement);\n syncDom(root, value);\n const caret = pendingCaret.current;\n pendingCaret.current = null;\n if (active && caret != null) placeCaret(root, caret);\n }, [value]);\n\n React.useEffect(() => { if (autoFocus && boxRef.current) boxRef.current.focus(); }, [autoFocus]);\n\n const caretNow = (): number => {\n const root = boxRef.current;\n const sel = window.getSelection();\n if (!root || !sel || !sel.rangeCount) return 0;\n const r = sel.getRangeAt(0);\n return readDom(root, [{ node: r.startContainer, offset: r.startOffset }]).points[0];\n };\n\n const selectionNow = (): { start: number; end: number } => {\n const root = boxRef.current;\n const sel = window.getSelection();\n if (!root || !sel || !sel.rangeCount) return { start: value.length, end: value.length };\n const r = sel.getRangeAt(0);\n const read = readDom(root, [{ node: r.startContainer, offset: r.startOffset }, { node: r.endContainer, offset: r.endOffset }]);\n const [a, b] = read.points;\n return { start: Math.min(a, b), end: Math.max(a, b) };\n };\n\n const commit = (next: string, caret?: number | null) => {\n if (maxLength && next.length > maxLength) return;\n pendingCaret.current = caret == null ? null : caret;\n onChange && onChange(next);\n if (onTrigger) detect(next, caret == null ? next.length : caret);\n };\n\n const api: MarkdownEditorHandle = {\n focus: (o) => boxRef.current && boxRef.current.focus(o),\n blur: () => { boxRef.current && boxRef.current.blur(); },\n get element() { return boxRef.current; },\n getSelection: selectionNow,\n replaceRange: (start, end, text, caretAt) => {\n const next = value.slice(0, start) + text + value.slice(end);\n commit(next, caretAt == null ? start + text.length : caretAt);\n },\n insert: (text) => { const s = selectionNow(); api.replaceRange(s.start, s.end, text); },\n wrapSelection: (before, after, placeholderText) => {\n const s = selectionNow();\n const sel = value.slice(s.start, s.end);\n const close = after == null ? before : after;\n const already = value.slice(s.start - before.length, s.start) === before && value.slice(s.end, s.end + close.length) === close;\n if (already) {\n const next = value.slice(0, s.start - before.length) + sel + value.slice(s.end + close.length);\n commit(next, s.start - before.length + sel.length);\n return;\n }\n const inner = sel || placeholderText || \"\";\n const next = value.slice(0, s.start) + before + inner + close + value.slice(s.end);\n commit(next, sel ? s.start + before.length + inner.length + close.length : s.start + before.length + inner.length);\n },\n prefixLines: (prefix) => {\n const s = selectionNow();\n const from = value.lastIndexOf(\"\\n\", Math.max(0, s.start - 1)) + 1;\n const toRaw = value.indexOf(\"\\n\", s.end);\n const to = toRaw === -1 ? value.length : toRaw;\n const block = value.slice(from, to);\n const on = block.split(\"\\n\").every((l) => !l.trim() || l.startsWith(prefix));\n const next = block.split(\"\\n\").map((l) => (on ? l.replace(prefix, \"\") : prefix + l)).join(\"\\n\");\n api.replaceRange(from, to, next, from + next.length);\n },\n };\n React.useImperativeHandle(ref, () => api);\n\n /* trigger detection: / at line start, @ anywhere */\n function detect(text: string, caret: number) {\n if (!onTrigger) return;\n const upto = text.slice(0, caret);\n const line = upto.slice(upto.lastIndexOf(\"\\n\") + 1);\n const slash = /^\\/([\\w-]*)$/.exec(line);\n if (slash) { onTrigger({ type: \"slash\", query: slash[1], from: caret - slash[0].length, to: caret }); return; }\n const at = /(?:^|\\s)@([\\w./-]*)$/.exec(upto);\n if (at) { const tok = at[0].replace(/^\\s/, \"\"); onTrigger({ type: \"mention\", query: at[1], from: caret - tok.length, to: caret }); return; }\n onTrigger(null);\n }\n\n const newlineAtCaret = () => {\n const s = selectionNow();\n const lineStart = value.lastIndexOf(\"\\n\", Math.max(0, s.start - 1)) + 1;\n const line = value.slice(lineStart, s.start);\n const li = LIST_CONT.exec(line);\n const q = RE_Q.exec(line);\n if (li && li[5].trim()) {\n const bullet = /\\d/.test(li[2]) ? (parseInt(li[2], 10) + 1) + li[2].replace(/\\d+/, \"\") : li[2];\n const ins = \"\\n\" + li[1] + bullet + li[3] + (li[4] ? \"[ ] \" : \"\");\n api.replaceRange(s.start, s.end, ins);\n return;\n }\n if (li && !li[5].trim()) { api.replaceRange(lineStart, s.end, \"\", lineStart); return; }\n if (q && q[2] && q[4].trim()) { api.replaceRange(s.start, s.end, \"\\n\" + q[1] + q[2] + q[3]); return; }\n api.replaceRange(s.start, s.end, \"\\n\");\n };\n\n const keydown = (e: React.KeyboardEvent) => {\n onKeyDown && onKeyDown(e); // host first\n if (e.defaultPrevented) return;\n if ((e as unknown as { isComposing?: boolean }).isComposing || e.keyCode === 229) { composing.current = true; return; }\n\n const mod = isMac ? e.metaKey : e.ctrlKey;\n if (mod && !e.altKey) {\n const k = e.key.toLowerCase();\n if (k === \"b\") { e.preventDefault(); api.wrapSelection(\"**\", \"**\", \"bold\"); return; }\n if (k === \"i\") { e.preventDefault(); api.wrapSelection(\"_\", \"_\", \"italic\"); return; }\n if (k === \"e\") { e.preventDefault(); api.wrapSelection(\"`\", \"`\", \"code\"); return; }\n if (k === \"k\") {\n e.preventDefault();\n const s = selectionNow();\n const sel = value.slice(s.start, s.end) || \"text\";\n api.replaceRange(s.start, s.end, \"[\" + sel + \"](url)\", s.start + sel.length + 3);\n return;\n }\n }\n\n if (e.key === \"Enter\") {\n e.preventDefault(); // we own every line break\n if (e.shiftKey || !submitOnEnter) newlineAtCaret();\n else onSubmit && onSubmit(value);\n return;\n }\n if (e.key === \"Tab\") {\n const s = selectionNow();\n const fences = (value.slice(0, s.start).match(/```|~~~/g) || []).length;\n const line = value.slice(value.lastIndexOf(\"\\n\", Math.max(0, s.start - 1)) + 1, s.start);\n if (fences % 2 === 1 || RE_LI.test(line)) { e.preventDefault(); api.insert(\" \"); }\n }\n };\n\n const beforeInput = (e: React.FormEvent<HTMLDivElement> & { inputType?: string }) => {\n if (e.inputType === \"insertParagraph\" || e.inputType === \"insertLineBreak\") {\n e.preventDefault();\n newlineAtCaret();\n }\n };\n\n const input = () => {\n const root = boxRef.current;\n if (!root || composing.current) return;\n const sel = window.getSelection();\n const r = sel && sel.rangeCount ? sel.getRangeAt(0) : null;\n const read = readDom(root, r ? [{ node: r.startContainer, offset: r.startOffset }] : []);\n commit(read.text, r ? read.points[0] : read.text.length);\n };\n\n const paste = (e: React.ClipboardEvent) => {\n onPaste && onPaste(e); // host first — it may turn this into a file\n if (e.defaultPrevented) return;\n const text = e.clipboardData && e.clipboardData.getData(\"text/plain\");\n if (text == null) return;\n e.preventDefault(); // plain text only: never accept pasted HTML\n const s = selectionNow();\n api.replaceRange(s.start, s.end, text.replace(/\\r\\n?/g, \"\\n\"));\n };\n\n const lh = 1.55;\n return (\n <div className={[\"fd-rme-wrap\", disabled ? \"is-disabled\" : \"\", className].filter(Boolean).join(\" \")}>\n <div\n ref={boxRef} id={id} className=\"fd-rme\"\n contentEditable={!disabled && !readOnly}\n suppressContentEditableWarning\n role=\"textbox\" aria-multiline=\"true\" aria-label={ariaLabel}\n spellCheck={true} autoCapitalize=\"sentences\"\n style={{ minHeight: (minRows * lh) + \"em\", maxHeight: (maxRows * lh) + \"em\" }}\n onKeyDown={keydown}\n onBeforeInput={beforeInput as any}\n onInput={input}\n onPaste={paste}\n onCompositionStart={() => { composing.current = true; }}\n onCompositionEnd={() => { composing.current = false; input(); }}\n onKeyUp={() => { if (onTrigger) detect(value, caretNow()); }}\n onClick={() => { if (onTrigger) detect(value, caretNow()); }}\n />\n {!value ? <span className=\"fd-rme-ph\" aria-hidden=\"true\">{placeholder}</span> : null}\n </div>\n );\n});\n","import * as React from \"react\";\nimport { Popover } from \"../actions/Popover\";\nimport { Avatar } from \"../feedback/Avatar\";\nimport { Badge } from \"../feedback/Badge\";\nimport { SessionKit } from \"../../kits/session\";\n\n/* The account menu every flytedesk app puts in its top right.\n\n Drop-in: <AccountMenu onNavigate={(href) => …} /> renders the signed-in user from\n SessionKit and shows an Administration section only to those who can reach it — a menu\n full of items that error on click is worse than a shorter menu.\n\n `links` and `adminLinks` are overridable so each app can add its own destinations\n without forking the component. */\n\nexport interface AccountMenuLink {\n id: string; label: string; icon: string;\n href?: string;\n /** Hidden unless the signed-in user holds this permission. */\n perm?: string;\n badge?: string;\n onSelect?: () => void;\n}\nexport interface AccountMenuProps {\n links?: AccountMenuLink[];\n /** Administration section. Each entry is filtered by its own `perm`. */\n adminLinks?: AccountMenuLink[];\n /** Preferred over href navigation — lets an SPA route without a page load. */\n onNavigate?: (href: string | undefined, item: AccountMenuLink) => void;\n onSignOut?: () => void;\n showRoles?: boolean;\n /** Demo affordance: impersonate another member to see their UI. Default true. */\n allowUserSwitch?: boolean;\n className?: string;\n}\n\nconst DEFAULT_LINKS: AccountMenuLink[] = [\n { id: \"profile\", label: \"Your profile\", icon: \"user-circle\", href: \"../admin/index.html#profile\" },\n { id: \"preferences\", label: \"Preferences\", icon: \"sliders-horizontal\", href: \"../admin/index.html#preferences\" }\n];\n\nconst DEFAULT_ADMIN_LINKS: AccountMenuLink[] = [\n { id: \"users\", label: \"Users\", icon: \"users-three\", href: \"../admin/index.html#users\", perm: \"users.view\" },\n { id: \"roles\", label: \"Roles & permissions\", icon: \"shield-check\", href: \"../admin/index.html#roles\", perm: \"roles.manage\" },\n { id: \"flags\", label: \"Feature flags\", icon: \"toggle-right\", href: \"../admin/index.html#flags\", perm: \"flags.manage\" }\n];\n\ninterface ItemProps {\n item: AccountMenuLink;\n onPick: (item: AccountMenuLink) => void;\n}\n\nfunction Item({ item, onPick }: ItemProps) {\n return (\n <button type=\"button\" role=\"menuitem\" className=\"fd-acct-item\"\n onClick={() => onPick(item)}>\n <i className={\"ph ph-\" + item.icon} aria-hidden=\"true\" />\n <span style={{ flex: 1 }}>{item.label}</span>\n {item.badge ? <Badge tone=\"neutral\">{item.badge}</Badge> : null}\n </button>\n );\n}\n\n/**\n * The avatar button + popover every flytedesk app puts in its top right.\n * Reads the signed-in user from SessionKit; shows Administration only to those who can use it.\n */\nexport function AccountMenu({\n links = DEFAULT_LINKS,\n adminLinks = DEFAULT_ADMIN_LINKS,\n onNavigate,\n onSignOut,\n showRoles = true,\n allowUserSwitch = true,\n className = \"\",\n ...rest\n}: AccountMenuProps) {\n const session = SessionKit.useSession();\n const [open, setOpen] = React.useState(false);\n const [switching, setSwitching] = React.useState(false);\n const ref = React.useRef<HTMLButtonElement>(null);\n const user = session.user;\n\n const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));\n const pick = (item: AccountMenuLink) => {\n setOpen(false);\n if (item.onSelect) return item.onSelect();\n if (onNavigate) return onNavigate(item.href, item);\n if (item.href) window.location.href = item.href;\n };\n const signOut = () => {\n setOpen(false);\n if (onSignOut) return onSignOut();\n window.alert(\"Signed out. (Simulated — no auth provider is wired up.)\");\n };\n\n return (\n <>\n <button type=\"button\" ref={ref} className={[\"fd-acct-trigger\", className].filter(Boolean).join(\" \")}\n aria-haspopup=\"menu\" aria-expanded={open} aria-label={\"Account — \" + user.name}\n onClick={() => setOpen((o) => !o)} {...rest}>\n <Avatar name={user.name} size=\"sm\" />\n <i className=\"ph ph-caret-down\" aria-hidden=\"true\" style={{ fontSize: 11, color: \"var(--text-muted)\" }} />\n </button>\n <Popover open={open} anchorRef={ref} onClose={() => setOpen(false)} placement=\"bottom-end\" width={272}>\n <div role=\"menu\" className=\"fd-stack\" style={{ gap: 0 }}>\n <div className=\"fd-row\" style={{ gap: 10, padding: \"12px 14px\", borderBottom: \"1px solid var(--border)\" }}>\n <Avatar name={user.name} />\n <span className=\"fd-stack\" style={{ gap: 1, minWidth: 0, flex: 1 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 700 }}>{user.name}</span>\n <span className=\"fd-body-sm fd-muted fd-table-trunc\">{user.email}</span>\n </span>\n </div>\n\n {showRoles && session.roles.length ? (\n <div className=\"fd-row\" style={{ gap: 6, padding: \"10px 14px\", flexWrap: \"wrap\", borderBottom: \"1px solid var(--border)\" }}>\n {session.roles.map((r) => <Badge key={r.id} tone={r.id === \"owner\" ? \"success\" : \"neutral\"}>{r.name}</Badge>)}\n </div>\n ) : null}\n\n <div className=\"fd-acct-group\">\n {links.map((l) => <Item key={l.id} item={l} onPick={pick} />)}\n </div>\n\n {visibleAdmin.length ? (\n <div className=\"fd-acct-group\" style={{ borderTop: \"1px solid var(--border)\" }}>\n <span className=\"fd-overline fd-muted\" style={{ padding: \"8px 14px 4px\", display: \"block\" }}>Administration</span>\n {visibleAdmin.map((l) => <Item key={l.id} item={l} onPick={pick} />)}\n </div>\n ) : null}\n\n {/* Demo affordance: impersonate another member to see the UI their roles produce.\n A real deployment gates this behind an audited support tool, never a menu. */}\n {allowUserSwitch ? (\n <div className=\"fd-acct-group\" style={{ borderTop: \"1px solid var(--border)\" }}>\n <button type=\"button\" role=\"menuitem\" className=\"fd-acct-item\" onClick={() => setSwitching((s) => !s)}>\n <i className=\"ph ph-user-switch\" aria-hidden=\"true\" />\n <span style={{ flex: 1 }}>View as another member</span>\n <i className={\"ph ph-caret-\" + (switching ? \"up\" : \"down\")} aria-hidden=\"true\" style={{ fontSize: 11 }} />\n </button>\n {switching ? (\n <div className=\"fd-stack\" style={{ gap: 0, maxHeight: 208, overflowY: \"auto\" }}>\n {session.allUsers.filter((u) => u.status === \"active\").map((u) => (\n <button key={u.id} type=\"button\" className=\"fd-acct-item\" data-current={u.id === user.id ? \"true\" : \"false\"}\n onClick={() => { SessionKit.setActiveUser(u.id); setOpen(false); setSwitching(false); }}>\n <Avatar name={u.name} size=\"sm\" />\n <span className=\"fd-stack\" style={{ gap: 0, flex: 1, minWidth: 0, alignItems: \"flex-start\" }}>\n <span style={{ fontWeight: u.id === user.id ? 700 : 500 }}>{u.name}</span>\n <span className=\"fd-muted\" style={{ fontSize: 11.5 }}>{u.roles.join(\", \")}</span>\n </span>\n {u.id === user.id ? <i className=\"ph ph-check\" aria-hidden=\"true\" style={{ color: \"var(--ok-text)\" }} /> : null}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"fd-acct-group\" style={{ borderTop: \"1px solid var(--border)\" }}>\n <button type=\"button\" role=\"menuitem\" className=\"fd-acct-item\" data-danger=\"true\" onClick={signOut}>\n <i className=\"ph ph-sign-out\" aria-hidden=\"true\" />\n <span style={{ flex: 1 }}>Sign out</span>\n </button>\n </div>\n </div>\n </Popover>\n </>\n );\n}\n","import * as React from \"react\";\n\n/* Session, RBAC and feature flags — the front-end half of access control.\n Reusable across every flytedesk project: the planner, the platform app, the admin app.\n\n Nothing here is a security boundary. Permissions gate the UI so people are not shown\n affordances they cannot use; the server must re-check every one of them. A hidden button\n is a courtesy, not a control.\n\n Wire to a real backend by replacing loadSession() with a fetch of\n GET /me → { user, roles, permissions, flags }. Everything else is derived. */\n\nexport interface PermissionItem { key: string; label: string; detail: string }\nexport interface PermissionGroup { group: string; items: PermissionItem[] }\nexport interface Role { id: string; name: string; system: boolean; description: string; permissions: string[] }\nexport interface Flag {\n key: string; project: string; label: string; description: string;\n /** Kill switch. False means off for everyone, whatever the targeting says. */\n enabled: boolean;\n /** 0-100. Bucketed on a stable hash of the user id so answers never flicker. */\n rollout: number;\n /** Role ids the flag is forced on for. */\n roles: string[];\n /** Per-user overrides, highest precedence: { userId: true | false } */\n users: Record<string, boolean>;\n owner?: string; updated?: string;\n /* Not declared in the original session.d.ts (which only covers the fields common to every\n flag record) but present on every entry in FLAGS and read by roadmap() below — filled in\n here from the session.js implementation, same as the six SessionKit members. */\n /** Which screen this flag gates, if any. */\n screen?: string;\n /** Target ship date for an unshipped feature. */\n eta?: string | null;\n /** Date this shipped — set instead of `eta` once it's done. */\n shippedAt?: string;\n /** Build phase index into PHASES. */\n phase?: number;\n /** Human estimate, e.g. \"4 days\". */\n effort?: string;\n /** What has to be built for this to be real. */\n backend?: string;\n /** Other flag keys this depends on. */\n dependsOn?: string[];\n}\nexport interface User {\n id: string; name: string; email: string; title?: string; team?: string;\n roles: string[]; status: \"active\" | \"invited\" | \"suspended\";\n lastActive?: string; joined?: string; sso?: boolean; timezone?: string;\n phone?: string; bio?: string; notify?: Record<string, boolean>;\n}\nexport interface Session {\n user: User; roles: Role[]; permissions: string[];\n /** Resolved flag key → on/off for THIS user. */\n flags: Record<string, boolean>;\n allRoles: Role[]; allFlags: Flag[]; allUsers: User[];\n}\nexport interface FlagExplanation { on: boolean; reason: string; detail: string }\n\n/** One row of the build roadmap. Not declared in session.js's own PHASES shape but inferred\n * from how PHASES entries are constructed and consumed by roadmap() below. */\ninterface Phase { n: number; name: string; start: string; end: string; why: string }\n\n/** roadmap()'s per-flag result row. Not declared in session.d.ts (roadmap() itself is one of\n * the six SessionKit members missing from that file) — inferred from what roadmap() actually\n * builds and returns for each flag. */\nexport interface RoadmapItem {\n key: string; label: string; project: string; description: string;\n backend?: string; effort?: string; owner?: string; dependsOn: string[];\n screen: string | null; enabled: boolean;\n /** Which build phase this sits in, and why that phase comes where it does. */\n phase?: number; phaseName: string; phaseWhy: string | null; phaseStart: string | null;\n /** Derived, not stored: whether every endpoint the feature needs is wired. */\n implemented: boolean;\n date: string | null;\n /** True when the only date on record is when the UI was designed, not when it ships. */\n dateIsDesign: boolean;\n status: \"shipped\" | \"next\" | \"planned\";\n}\n/** roadmap()'s return shape. */\nexport interface RoadmapResult {\n items: RoadmapItem[];\n /** Index of the first unshipped item — everything above it is history. */\n nextIndex: number;\n shipped: number;\n remaining: number;\n}\n\nconst PERMISSION_CATALOG: PermissionGroup[] = [\n { group: \"Plans\", items: [\n { key: \"plan.view\", label: \"View plans\", detail: \"Read any plan in the workspace.\" },\n { key: \"plan.edit\", label: \"Edit plans\", detail: \"Reallocate budget, add or remove campuses, swap placements.\" },\n { key: \"plan.solve\", label: \"Run the solver\", detail: \"Trigger a solve. Consumes engine capacity.\" },\n { key: \"plan.delete\", label: \"Delete plans\", detail: \"Irreversible once the retention window closes.\" }\n ] },\n { group: \"Delivery\", items: [\n { key: \"export.run\", label: \"Export workbooks\", detail: \"Generate the client spreadsheet.\" },\n { key: \"share.manage\", label: \"Manage share links\", detail: \"Create, revoke and re-pin client links.\" },\n { key: \"client.view\", label: \"Open client view\", detail: \"See the presentation surface clients receive.\" }\n ] },\n { group: \"Model\", items: [\n { key: \"model.view\", label: \"View the model\", detail: \"Read formulas, weights and provenance.\" },\n { key: \"model.edit\", label: \"Change coefficients\", detail: \"Alter the numbers every plan is scored with.\" }\n ] },\n { group: \"Administration\", items: [\n { key: \"users.view\", label: \"View users\", detail: \"See the member directory.\" },\n { key: \"users.manage\", label: \"Manage users\", detail: \"Invite, edit, deactivate, assign roles.\" },\n { key: \"roles.manage\", label: \"Manage roles\", detail: \"Create roles and change what they grant.\" },\n { key: \"flags.manage\", label: \"Manage feature flags\", detail: \"Toggle features across projects and audiences.\" },\n { key: \"audit.view\", label: \"View the audit log\", detail: \"Read who changed what, when.\" },\n { key: \"roadmap.view\", label: \"View the roadmap\", detail: \"See which features are wired to the backend and what is next.\" }\n ] }\n];\n\nconst ALL_PERMISSIONS: string[] = PERMISSION_CATALOG.flatMap((g) => g.items.map((i) => i.key));\n\n/** Roles are named permission bundles. `system: true` roles cannot be deleted. */\nconst ROLES: Role[] = [\n { id: \"owner\", name: \"Owner\", system: true, description: \"Unrestricted. Every permission, including destructive ones.\",\n permissions: ALL_PERMISSIONS },\n { id: \"admin\", name: \"Administrator\", system: true, description: \"Runs the workspace and its people. Cannot change the scoring model.\",\n permissions: [\"plan.view\", \"plan.edit\", \"plan.solve\", \"export.run\", \"share.manage\", \"client.view\", \"model.view\", \"users.view\", \"users.manage\", \"roles.manage\", \"flags.manage\", \"audit.view\", \"roadmap.view\"] },\n { id: \"planner\", name: \"Planner\", system: false, description: \"Builds and edits plans. The default for the demand team.\",\n permissions: [\"plan.view\", \"plan.edit\", \"plan.solve\", \"export.run\", \"share.manage\", \"client.view\", \"model.view\", \"roadmap.view\"] },\n { id: \"analyst\", name: \"Analyst\", system: false, description: \"Reads everything, changes nothing. For QA and finance.\",\n permissions: [\"plan.view\", \"model.view\", \"audit.view\", \"client.view\", \"roadmap.view\"] },\n { id: \"model-admin\", name: \"Model administrator\", system: false, description: \"May change scoring coefficients — the numbers behind every plan the company ships.\",\n permissions: [\"plan.view\", \"model.view\", \"model.edit\", \"roadmap.view\"] },\n { id: \"sales\", name: \"Account lead\", system: false, description: \"Presents plans to clients without editing them.\",\n permissions: [\"plan.view\", \"client.view\", \"share.manage\", \"export.run\"] }\n];\n\n/* Feature flags. Precedence, highest first:\n 1. user override (explicit allow/deny for one person)\n 2. role targeting (on for these roles)\n 3. rollout percentage (stable hash of userId, so a user's answer never flickers)\n 4. enabled (the global switch)\n A flag with `enabled: false` is off for everyone regardless of targeting — that is the\n kill switch, and it must not be overridable or it is not a kill switch. */\n/* Every screen and every discrete feature carries its own flag, so a capability can be\n released, targeted or killed without touching its neighbours.\n\n `implemented` is a SEPARATE axis from `enabled`. All of this UI is designed and working\n against a simulated transport; `implemented` records whether the REAL backend is wired.\n enabled=false → hidden entirely. Nobody sees it.\n enabled + implemented=false → visible but inert: blurred, with a coming-soon banner.\n enabled + implemented=true → the live feature.\n That distinction is what makes the roadmap honest — it is a backend plan, not a design plan.\n\n Roadmap fields: shippedAt for what is done, eta + effort for what is not, backend for what\n actually has to be built, dependsOn so the ordering is derived rather than asserted. */\nconst PHASES: Phase[] = [\n {\n \"n\": 0,\n \"name\": \"Shipped\",\n \"start\": \"2026-08-18\",\n \"end\": \"2026-08-18\",\n \"why\": \"Documentation rendered from code. No backend, so these were done the moment the design was.\"\n },\n {\n \"n\": 1,\n \"name\": \"Identity and gating\",\n \"start\": \"2026-08-24\",\n \"end\": \"2026-09-11\",\n \"why\": \"None of this exists yet and everything else assumes it: who is acting, what they may do, and the switch that lets unfinished work ship dark. Version attribution, the audit trail and every gate in the app resolve against it.\"\n },\n {\n \"n\": 2,\n \"name\": \"Data in\",\n \"start\": \"2026-09-14\",\n \"end\": \"2026-09-25\",\n \"why\": \"Nothing can be scored until inventory is normalised and a brief exists to constrain it. Two independent surfaces, so they run in parallel.\"\n },\n {\n \"n\": 3,\n \"name\": \"The engine\",\n \"start\": \"2026-09-28\",\n \"end\": \"2026-10-09\",\n \"why\": \"The solver IS the product. Largest single piece of work, and every screen downstream is a view of its output.\"\n },\n {\n \"n\": 4,\n \"name\": \"Read the plan\",\n \"start\": \"2026-10-12\",\n \"end\": \"2026-10-30\",\n \"why\": \"Four read-only surfaces over solve output. Excluded schools ships WITH them, not later — planners will not trust a solve they cannot audit.\"\n },\n {\n \"n\": 5,\n \"name\": \"Change it safely\",\n \"start\": \"2026-11-02\",\n \"end\": \"2026-11-20\",\n \"why\": \"Version history lands before the first editing surface. Mutations without append-only snapshots are how plans get lost.\"\n },\n {\n \"n\": 6,\n \"name\": \"Get it to the client\",\n \"start\": \"2026-11-23\",\n \"end\": \"2026-12-11\",\n \"why\": \"A plan that cannot leave the tool has no value. Workbook export precedes the client view: planners live in spreadsheets.\"\n },\n {\n \"n\": 7,\n \"name\": \"Scale the tables\",\n \"start\": \"2026-12-14\",\n \"end\": \"2026-12-24\",\n \"why\": \"The pilot has 35 line items; production has 3,729. These are the ergonomics that make that difference survivable.\"\n },\n {\n \"n\": 8,\n \"name\": \"Explain the plan\",\n \"start\": \"2027-01-04\",\n \"end\": \"2027-01-22\",\n \"why\": \"The charts and nudges that turn a table of numbers into an argument. Genuinely optional — the plan is usable without them.\"\n },\n {\n \"n\": 9,\n \"name\": \"Tuning criteria and alternatives\",\n \"start\": \"2027-01-25\",\n \"end\": \"2027-02-12\",\n \"why\": \"Judgement tools. They need a stable plan and working versioning underneath them.\"\n },\n {\n \"n\": 10,\n \"name\": \"Trust the model\",\n \"start\": \"2027-02-15\",\n \"end\": \"2027-02-26\",\n \"why\": \"Showing the working, and letting the model owner tune it. Needs versioning so a coefficient change is attributable.\"\n },\n {\n \"n\": 11,\n \"name\": \"Operate at scale\",\n \"start\": \"2027-03-01\",\n \"end\": \"2027-03-12\",\n \"why\": \"The admin refinements that only matter once there are enough people and enough history to need them.\"\n },\n {\n \"n\": 12,\n \"name\": \"Creative operations\",\n \"start\": \"2027-03-15\",\n \"end\": \"2027-03-26\",\n \"why\": \"Adjacent to planning — needed before the college side can transact against a plan.\"\n },\n {\n \"n\": 13,\n \"name\": \"The assistant\",\n \"start\": \"2027-03-29\",\n \"end\": \"2027-04-16\",\n \"why\": \"Last on purpose. It is a faster path to things the app can already do, so it has no value until those things work.\"\n }\n];\n\nconst FLAGS: Flag[] = [\n // ---- Media Planner · brief and solve ----------------------------------\n { key: \"planner.setup\", project: \"Media Planner\", label: \"Campaign setup\", screen: \"setup\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-09-25\", phase: 2, effort: \"4 days\", backend: \"Campaign CRUD, brief persistence.\",\n description: \"The brief: budget, flight, geography, objective, channel priorities.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.briefParse\", project: \"Media Planner\", label: \"Describe-the-plan parsing\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"4 days\", backend: \"LLM extraction endpoint returning structured brief fields plus measurable criteria.\",\n dependsOn: [\"planner.setup\"], description: \"Turns a plain-language brief into structured fields and tuning criteria.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.goals\", project: \"Media Planner\", label: \"Tuning criteria and reviewer\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"1 week\", backend: \"Criteria store plus the reviewer that scores a solved plan against each criterion.\",\n dependsOn: [\"planner.briefParse\"], description: \"Measurable criteria the reviewer checks after every solve.\", owner: \"Dana Reyes\", updated: \"Aug 17\" },\n { key: \"planner.goalTweaks\", project: \"Media Planner\", label: \"Reviewer tweaks\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"6 days\", backend: \"Tweak records with an ordered change list, apply/revert as plan versions, and a refine prompt that re-plans under a constraint.\",\n dependsOn: [\"planner.goals\", \"planner.versions\"], description: \"Proposed plan changes attached to a missed criterion, applied or reverted as a unit.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.import\", project: \"Media Planner\", label: \"Inventory import\", screen: \"import\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-09-25\", phase: 2, effort: \"1 week\", backend: \"Workbook upload, column mapping, row validation as a job.\",\n description: \"The supply workbook: what is actually available to buy.\", owner: \"Marcus Webb\", updated: \"Aug 14\" },\n { key: \"planner.solve\", project: \"Media Planner\", label: \"Solver\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-09\", phase: 3, effort: \"2 weeks\", backend: \"The engine itself: candidate ranking, funding loop, placement fitting, CRP scoring.\",\n dependsOn: [\"planner.import\", \"planner.setup\"], description: \"Fits placements across campuses and scores the result.\", owner: \"Engineering\", updated: \"Aug 15\" },\n\n // ---- Media Planner · plan screens -------------------------------------\n { key: \"planner.overview\", project: \"Media Planner\", label: \"Plan overview\", screen: \"overview\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"4 days\", backend: \"One plan document: header, funded campuses, mix vs target, attention flags.\",\n dependsOn: [\"planner.solve\"], description: \"The plan in one screen, ordered by the three questions a planner asks.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.attentionFlags\", project: \"Media Planner\", label: \"Attention flags\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Rule pass over the solved plan producing flagged campuses with a stated cost to fix.\",\n dependsOn: [\"planner.overview\"], description: \"The 'needs your attention' list: campuses a rule says are wrong, with what fixing costs.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.saturationDistribution\", project: \"Media Planner\", label: \"Saturation distribution\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Enrollment-weighted CRP distribution with the floor percentile marked.\",\n dependsOn: [\"planner.overview\"], description: \"Where every campus sits on the saturation scale, and where the floor lands.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.mixGap\", project: \"Media Planner\", label: \"Mix vs target\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Realized channel mix against the objective's target mix, with a reason per gap.\",\n dependsOn: [\"planner.overview\"], description: \"Realized media mix against target, and why each gap exists.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.decisionTrace\", project: \"Media Planner\", label: \"Decision trace\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-26\", phase: 10, effort: \"2 weeks\", backend: \"Per-decision audit the engine emits during a solve: every campus considered, every placement weighed, and why each was taken or dropped.\",\n dependsOn: [\"planner.solve\"], description: \"The full reasoning behind a solve, readable after the fact.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.schools\", project: \"Media Planner\", label: \"School mix\", screen: \"schools\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"4 days\", backend: \"Server-side sort, filter and pagination over funded campuses.\",\n dependsOn: [\"planner.overview\"], description: \"Every funded campus with its saturation band and spend.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.reallocate\", project: \"Media Planner\", label: \"Budget reallocation\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"6 days\", backend: \"Debounced re-score preview plus a commit that snapshots a version.\",\n dependsOn: [\"planner.schools\", \"planner.versions\"], description: \"Drag budget between campuses and see the re-score before committing.\", owner: \"Dana Reyes\", updated: \"Aug 17\" },\n { key: \"planner.campusDetail\", project: \"Media Planner\", label: \"Campus detail\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"4 days\", backend: \"Per-campus rollup: channel contribution, surround-sound breadth, placement list.\",\n dependsOn: [\"planner.schools\"], description: \"Why one campus scores what it scores.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.channelContribution\", project: \"Media Planner\", label: \"Channel contribution\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Per-channel CRP contribution within a campus, weighted.\",\n dependsOn: [\"planner.campusDetail\"], description: \"Which channels built this campus's score, and how much each added.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.surroundSound\", project: \"Media Planner\", label: \"Surround sound\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Category breadth per campus and the resulting bonus multiplier.\",\n dependsOn: [\"planner.campusDetail\"], description: \"How many channel categories a campus covers, and the bonus it earns.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.campusNudges\", project: \"Media Planner\", label: \"Campus recommendations\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"6 days\", backend: \"Per-campus recommendation engine: the cheapest next move and its projected CRP effect, applyable as a version.\",\n dependsOn: [\"planner.campusDetail\",\"planner.reallocate\"], description: \"The cheapest single change that would improve this campus.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.placements\", project: \"Media Planner\", label: \"Placement book\", screen: \"placements\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"1 week\", backend: \"Line-item list with server-side filters across school, media, status, month and cost.\",\n dependsOn: [\"planner.solve\"], description: \"Every line item, with what it contributes to saturation.\", owner: \"Marcus Webb\", updated: \"Aug 17\" },\n { key: \"planner.placementSwap\", project: \"Media Planner\", label: \"Placement swap\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"4 days\", backend: \"Ranked alternatives per placement with CRP and cost deltas, plus a swap that re-scores the campus.\",\n dependsOn: [\"planner.placements\"], description: \"Replace a placement with an engine-ranked alternative.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.savedViews\", project: \"Media Planner\", label: \"Saved table views\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Per-team named column sets, filters and sort, shared across the workspace.\",\n dependsOn: [\"planner.placements\"], description: \"Named column and filter sets, shared with the team.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.bulkEdit\", project: \"Media Planner\", label: \"Bulk placement actions\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"2 days\", backend: \"Batch status change and removal, with a queued re-score.\",\n dependsOn: [\"planner.placements\"], description: \"Select many line items and change status or remove them at once.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.columnPicker\", project: \"Media Planner\", label: \"Column picker\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"1 day\", backend: \"Column preference persistence per user, per table.\",\n dependsOn: [\"planner.placements\"], description: \"Choose which of the fourteen placement columns are shown.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.groupBy\", project: \"Media Planner\", label: \"Group rows\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Server-side grouping with per-group spend and CRP subtotals.\",\n dependsOn: [\"planner.placements\"], description: \"Group the placement book by school or media, with subtotals.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.csvExport\", project: \"Media Planner\", label: \"CSV export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"1 day\", backend: \"Streamed CSV of the current query — all filters and columns applied server-side.\",\n dependsOn: [\"planner.placements\"], description: \"Export exactly the rows and columns on screen.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.excluded\", project: \"Media Planner\", label: \"Excluded schools\", screen: \"excluded\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"4 days\", backend: \"Every considered-but-unfunded campus with its reason and cost-to-include.\",\n dependsOn: [\"planner.solve\"], description: \"The trust screen: what was considered and why it lost.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.addCampus\", project: \"Media Planner\", label: \"Add an excluded campus\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"4 days\", backend: \"Funding plan that pulls from unallocated then trims the strongest campus, as a version.\",\n dependsOn: [\"planner.excluded\", \"planner.reallocate\"], description: \"Fund a campus the engine excluded, and see what it costs.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.map\", project: \"Media Planner\", label: \"Geographic map\", screen: \"map\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"1 week\", backend: \"Campus coordinates and state rollups; geometry is static.\",\n dependsOn: [\"planner.schools\"], description: \"Campus map with saturation-scaled markers.\", owner: \"Dana Reyes\", updated: \"Aug 17\" },\n { key: \"planner.flights\", project: \"Media Planner\", label: \"Flight calendar\", screen: \"flights\", enabled: true, rollout: 60,\n roles: [\"planner\", \"owner\"], users: { u_marcus: false },\n eta: \"2027-01-22\", phase: 8, effort: \"6 days\", backend: \"Per-week spend distribution and a flight-shift mutation that preserves CRP.\",\n dependsOn: [\"planner.placements\"], description: \"Placements as flight bars over the campaign weeks.\", owner: \"Marcus Webb\", updated: \"Aug 17\" },\n\n // ---- Media Planner · analysis ----------------------------------------\n { key: \"planner.scenarios\", project: \"Media Planner\", label: \"Scenario compare\", screen: \"scenarios\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"7 days\", backend: \"Solve the same brief under multiple strategies, persist each as a scenario, promote one to working.\",\n dependsOn: [\"planner.solve\", \"planner.versions\"], description: \"Three strategies side by side with a campus matrix.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.versions\", project: \"Media Planner\", label: \"Version history\", screen: \"versions\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"6 days\", backend: \"Append-only snapshots with per-campus diffs and restore-as-new-head.\",\n dependsOn: [\"planner.solve\"], description: \"Append-only plan snapshots with pairwise diff and restore.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.versionDiff\", project: \"Media Planner\", label: \"Version compare\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"3 days\", backend: \"Pairwise diff between any two snapshots, per campus, with CRP and spend deltas.\",\n dependsOn: [\"planner.versions\"], description: \"Pick two versions and see exactly what changed.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.versionRestore\", project: \"Media Planner\", label: \"Restore a version\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"2 days\", backend: \"Append-only restore: snapshots the chosen version as a new head so history is never rewritten.\",\n dependsOn: [\"planner.versions\"], description: \"Make an earlier version current without losing anything.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.scenarioPromote\", project: \"Media Planner\", label: \"Promote a scenario\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"3 days\", backend: \"Swap the working plan to a scenario's allocation as a new version.\",\n dependsOn: [\"planner.scenarios\",\"planner.versions\"], description: \"Make an alternative strategy the working plan.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.scenarioDuplicate\", project: \"Media Planner\", label: \"Duplicate a scenario\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"2 days\", backend: \"Scenario CRUD so a planner can branch and adjust one independently.\",\n dependsOn: [\"planner.scenarios\"], description: \"Branch a scenario and adjust it without touching the plan.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.flightShift\", project: \"Media Planner\", label: \"Shift a flight\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"3 days\", backend: \"Flight window mutation with weekly spend recomputation. Pacing only — CRP is flight-length invariant.\",\n dependsOn: [\"planner.flights\"], description: \"Move a placement's run dates and re-pace the week.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.algorithm\", project: \"Media Planner\", label: \"Algorithm documentation\", screen: \"algorithm\", enabled: true, rollout: 100, roles: [], users: {},\n eta: null, shippedAt: \"2026-08-18\", phase: 0, effort: \"1 week\", backend: \"Read-only model config: weights, exponents, thresholds and provenance.\",\n description: \"How every number is produced, with each constant's provenance.\", owner: \"Priya Raman\", updated: \"Aug 17\" },\n { key: \"planner.algorithmConfig\", project: \"Media Planner\", label: \"Live coefficient editing\", enabled: false, rollout: 0,\n roles: [\"model-admin\"], users: {},\n eta: \"2027-02-26\", phase: 10, effort: \"6 days\", backend: \"Audited coefficient writes, a simulate endpoint that re-scores without saving, and per-plan coefficient pinning.\",\n dependsOn: [\"planner.algorithm\", \"planner.versions\"], description: \"Edit scoring coefficients from the UI. Off until the audit trail ships.\", owner: \"Engineering\", updated: \"Aug 15\" },\n { key: \"planner.algorithmSimulate\", project: \"Media Planner\", label: \"Coefficient simulation\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-02-26\", phase: 10, effort: \"1 week\", backend: \"Re-score the working plan under proposed coefficients without saving them.\",\n dependsOn: [\"planner.algorithmConfig\"], description: \"See what a weight change would do before committing it.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.apiSpec\", project: \"Media Planner\", label: \"API specification\", screen: \"api\", enabled: true, rollout: 100, roles: [], users: {},\n eta: null, shippedAt: \"2026-08-18\", phase: 0, effort: \"3 days\", backend: \"None — generated from the same declarations the client calls.\",\n description: \"The backend contract, rendered from the spec the front end calls.\", owner: \"Engineering\", updated: \"Aug 17\" },\n { key: \"planner.roadmap\", project: \"Media Planner\", label: \"Roadmap\", screen: \"roadmap\", enabled: true, rollout: 100, roles: [], users: {},\n eta: null, shippedAt: \"2026-08-18\", phase: 0, effort: \"3 days\", backend: \"None — derived from the flag registry.\",\n description: \"What is wired to the backend, and what is next.\", owner: \"Engineering\", updated: \"Today\" },\n\n // ---- Media Planner · delivery ----------------------------------------\n { key: \"planner.export\", project: \"Media Planner\", label: \"Export and share\", screen: \"export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"3 days\", backend: \"Workbook generation as a job, returning a signed download URL.\",\n dependsOn: [\"planner.overview\"], description: \"The spreadsheet, treated as a first-class deliverable.\", owner: \"Ana Duarte\", updated: \"Aug 12\" },\n { key: \"planner.clientView\", project: \"Media Planner\", label: \"Client view\", screen: \"client\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"1 week\", backend: \"Token-scoped read-only payload carrying presence bands only — CRP must never leave authenticated surfaces.\",\n dependsOn: [\"planner.export\"], description: \"The presentation surface clients receive. No CRP figures.\", owner: \"Ana Duarte\", updated: \"Aug 12\" },\n { key: \"planner.shareLinks\", project: \"Media Planner\", label: \"Share links\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"sales\"], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"4 days\", backend: \"Version-pinned tokens with expiry, revocation and view analytics.\",\n dependsOn: [\"planner.clientView\", \"planner.versions\"], description: \"Client links pinned to a version, with expiry and view counts.\", owner: \"Ana Duarte\", updated: \"Today\" },\n { key: \"planner.exportXlsx\", project: \"Media Planner\", label: \"Workbook export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"4 days\", backend: \"Sheet-for-sheet workbook build matching the legacy template, as a job returning a signed URL.\",\n dependsOn: [\"planner.export\"], description: \"The client spreadsheet, sheet for sheet.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.exportPdf\", project: \"Media Planner\", label: \"PDF export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"3 days\", backend: \"Server-side render of the client view to a paginated PDF at a pinned version.\",\n dependsOn: [\"planner.clientView\"], description: \"The client-facing plan as a PDF, pinned to a version.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.clientPreview\", project: \"Media Planner\", label: \"Client view preview\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Read-only render of the client payload inside the admin surface.\",\n dependsOn: [\"planner.clientView\"], description: \"See what the client sees without leaving the planner.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.clientPresentation\", project: \"Media Planner\", label: \"Presentation settings\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"3 days\", backend: \"Per-link presentation options persisted on the share link: narrative, placement detail, spend visibility.\",\n dependsOn: [\"planner.shareLinks\"], description: \"Choose what the client sees: narrative, placement detail, spend figures.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.clientPlacementDetail\", project: \"Media Planner\", label: \"Client placement lists\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Per-campus placement lists in the client payload, band language only.\",\n dependsOn: [\"planner.clientView\"], description: \"What runs where, per campus, on the client page.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.assistant\", project: \"Media Planner\", label: \"Plan assistant\", enabled: true, rollout: 40,\n roles: [\"owner\", \"admin\", \"planner\"], users: { u_priya: true },\n eta: \"2027-04-16\", phase: 13, effort: \"2 weeks\", backend: \"Threaded chat over the plan, job escalation for engine questions, and packets the planner can apply as real mutations.\",\n dependsOn: [\"planner.overview\", \"chat.agentPanel\"], description: \"Docked chat that can propose and apply plan changes.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.assistantApply\", project: \"Media Planner\", label: \"Assistant apply\", enabled: true, rollout: 40, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"6 days\", backend: \"Validate a packet against the live plan, then route it to the matching mutation endpoint.\",\n dependsOn: [\"planner.assistant\", \"planner.reallocate\"], description: \"Turn an assistant proposal into a committed plan change.\", owner: \"Dana Reyes\", updated: \"Today\" },\n\n // ---- Platform --------------------------------------------------------\n { key: \"planner.assistantHistory\", project: \"Media Planner\", label: \"Assistant thread history\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"3 days\", backend: \"Thread list, rename and delete scoped to a context, with transcript persistence.\",\n dependsOn: [\"planner.assistant\"], description: \"Past conversations, resumable and deletable.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"platform.creativeReview\", project: \"Platform\", label: \"Creative review\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-03-26\", phase: 12, effort: \"6 days\", backend: \"Creative upload, approval states, reviewer assignment.\",\n description: \"College-side creative approval flow.\", owner: \"Ana Duarte\", updated: \"Aug 09\" },\n { key: \"platform.verification\", project: \"Platform\", label: \"Screen verification\", enabled: true, rollout: 80, roles: [], users: {},\n eta: \"2027-03-26\", phase: 12, effort: \"1 week\", backend: \"Photo upload with EXIF and geo validation against the placement's location.\",\n dependsOn: [\"platform.creativeReview\"], description: \"Photo proof-of-posting on physical placements.\", owner: \"Ana Duarte\", updated: \"Aug 14\" },\n\n // ---- Admin -----------------------------------------------------------\n { key: \"admin.users\", project: \"Admin\", label: \"User directory\", screen: \"users\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\"], users: {},\n eta: \"2026-09-11\", phase: 1, effort: \"4 days\", backend: \"Member CRUD, invitations, status transitions.\",\n description: \"Who is in the workspace and what they hold.\", owner: \"Engineering\", updated: \"Aug 16\" },\n { key: \"admin.roles\", project: \"Admin\", label: \"Roles and permissions\", screen: \"roles\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\"], users: {},\n eta: \"2026-09-11\", phase: 1, effort: \"1 week\", backend: \"Role definitions, permission grants, and server-side enforcement on every route.\",\n dependsOn: [\"admin.users\"], description: \"Named permission bundles, and what each one grants.\", owner: \"Engineering\", updated: \"Aug 16\" },\n { key: \"admin.flags\", project: \"Admin\", label: \"Feature flags\", screen: \"flags\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\"], users: {},\n eta: \"2026-09-11\", phase: 1, effort: \"4 days\", backend: \"Flag registry with rollout bucketing, role targeting and per-user overrides.\",\n description: \"Every project's flags, with their targeting rules.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"admin.audit\", project: \"Admin\", label: \"Audit log\", screen: \"audit\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"analyst\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"4 days\", backend: \"Append-only change records with an 18-month retention window.\",\n dependsOn: [\"admin.roles\"], description: \"Every administrative change, append-only.\", owner: \"Engineering\", updated: \"Aug 16\" },\n { key: \"admin.bulkInvite\", project: \"Admin\", label: \"Bulk invite\", enabled: false, rollout: 0, roles: [\"owner\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"2 days\", backend: \"CSV parse, per-row validation, and a partial-success invitation batch.\",\n dependsOn: [\"admin.users\"], description: \"CSV upload to invite many members at once.\", owner: \"Engineering\", updated: \"Aug 11\" },\n { key: \"admin.ssoEnforcement\", project: \"Admin\", label: \"Enforce SSO\", enabled: false, rollout: 0, roles: [], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"3 days\", backend: \"SAML assertion handling, just-in-time provisioning, and a break-glass path.\",\n dependsOn: [\"admin.roles\"], description: \"Require SAML for every member. Locks out password sign-in.\", owner: \"Engineering\", updated: \"Aug 05\" },\n\n // ---- Agent Chat ------------------------------------------------------\n { key: \"admin.roleEditor\", project: \"Admin\", label: \"Role permission editor\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"4 days\", backend: \"Role CRUD with a permission matrix and an effective-permission resolver.\",\n dependsOn: [\"admin.roles\"], description: \"Change what a role grants, permission by permission.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"admin.flagTargeting\", project: \"Admin\", label: \"Flag targeting\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"4 days\", backend: \"Evaluation order: user override, role, rollout percentage by stable hash, then the global switch.\",\n dependsOn: [\"admin.flags\"], description: \"Target a flag by user, role or rollout percentage.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"admin.auditExport\", project: \"Admin\", label: \"Audit export\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"1 day\", backend: \"Streamed CSV of the audit query, with retention-window enforcement.\",\n dependsOn: [\"admin.audit\"], description: \"Export the audit trail for a date range.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"chat.agentPanel\", project: \"Agent Chat\", label: \"Agent panel\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"1 week\", backend: \"Thread resolution, message send, job polling, and cancellation.\",\n description: \"The embeddable assistant surface itself.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"chat.attachments\", project: \"Agent Chat\", label: \"Chat attachments\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"3 days\", backend: \"Staged upload with virus scanning, then reference by id in the turn.\",\n dependsOn: [\"chat.agentPanel\"], description: \"Attach files to a question.\", owner: \"Engineering\", updated: \"Today\" }\n];\n\nconst USERS: User[] = [\n { id: \"u_dana\", name: \"Dana Reyes\", email: \"dana@flytedesk.com\", title: \"Senior media planner\", team: \"Demand\",\n roles: [\"planner\", \"admin\"], status: \"active\", lastActive: \"2 minutes ago\", joined: \"Mar 2024\", sso: true,\n timezone: \"America/Denver\", phone: \"+1 303 555 0142\" },\n { id: \"u_marcus\", name: \"Marcus Webb\", email: \"marcus@flytedesk.com\", title: \"Media planner\", team: \"Demand\",\n roles: [\"planner\"], status: \"active\", lastActive: \"Yesterday\", joined: \"Sep 2024\", sso: true, timezone: \"America/New_York\" },\n { id: \"u_priya\", name: \"Priya Raman\", email: \"priya@flytedesk.com\", title: \"Data scientist\", team: \"Engineering\",\n roles: [\"model-admin\", \"analyst\"], status: \"active\", lastActive: \"4 hours ago\", joined: \"Jan 2025\", sso: true, timezone: \"America/Los_Angeles\" },\n { id: \"u_ana\", name: \"Ana Duarte\", email: \"ana@flytedesk.com\", title: \"Account lead\", team: \"Revenue\",\n roles: [\"sales\"], status: \"active\", lastActive: \"1 hour ago\", joined: \"Jun 2023\", sso: true, timezone: \"America/Chicago\" },\n { id: \"u_jules\", name: \"Jules Okonkwo\", email: \"jules@flytedesk.com\", title: \"VP Revenue\", team: \"Revenue\",\n roles: [\"owner\"], status: \"active\", lastActive: \"3 days ago\", joined: \"Feb 2022\", sso: true, timezone: \"America/New_York\" },\n { id: \"u_sam\", name: \"Sam Whitfield\", email: \"sam@flytedesk.com\", title: \"Finance analyst\", team: \"Finance\",\n roles: [\"analyst\"], status: \"active\", lastActive: \"Aug 14\", joined: \"Nov 2024\", sso: false, timezone: \"America/Denver\" },\n { id: \"u_tess\", name: \"Tess Nakamura\", email: \"tess@flytedesk.com\", title: \"Media planner\", team: \"Demand\",\n roles: [\"planner\"], status: \"invited\", lastActive: \"—\", joined: \"Invited Aug 16\", sso: false, timezone: \"America/Denver\" },\n { id: \"u_ben\", name: \"Ben Alvarez\", email: \"ben@flytedesk.com\", title: \"Account lead\", team: \"Revenue\",\n roles: [\"sales\"], status: \"suspended\", lastActive: \"Jul 02\", joined: \"Apr 2023\", sso: true, timezone: \"America/Chicago\" }\n];\n\n/** Stable 0–99 bucket from a string, so rollout answers never flicker between reloads. */\nfunction bucket(seed: string): number {\n let h = 2166136261;\n for (let i = 0; i < seed.length; i++) { h ^= seed.charCodeAt(i); h = Math.imul(h, 16777619); }\n return Math.abs(h) % 100;\n}\n\nconst STORE = \"fd.session.v1\";\n\ninterface StoredSession { userId?: string; profile?: Partial<User> }\n\nfunction readStored(): StoredSession | null {\n try { return JSON.parse(localStorage.getItem(STORE) || \"null\"); } catch { return null; }\n}\nfunction writeStored(patch: Partial<StoredSession>): StoredSession | null {\n try {\n const next = Object.assign({}, readStored(), patch);\n localStorage.setItem(STORE, JSON.stringify(next));\n return next;\n } catch { return null; }\n}\n\n/** Build the session document a real GET /me would return. */\nfunction buildSession(userId: string, overrides?: { users?: User[]; roles?: Role[]; flags?: Flag[] }): Session {\n const users = (overrides && overrides.users) || USERS;\n const roles = (overrides && overrides.roles) || ROLES;\n const flags = (overrides && overrides.flags) || FLAGS;\n const user = users.find((u) => u.id === userId) || users[0];\n const held = roles.filter((r) => user.roles.indexOf(r.id) >= 0);\n const permissions = [...new Set(held.flatMap((r) => r.permissions))];\n const resolved: Record<string, boolean> = {};\n flags.forEach((f) => { resolved[f.key] = evaluateFlag(f, user); });\n return { user, roles: held, permissions, flags: resolved, allRoles: roles, allFlags: flags, allUsers: users };\n}\n\n/** The precedence rule, in one place so the admin UI and the app can never disagree. */\nfunction evaluateFlag(flag: Flag, user: User): boolean {\n if (!flag.enabled) return false; // kill switch wins\n if (user && flag.users && flag.users[user.id] != null) return !!flag.users[user.id];\n if (flag.roles && flag.roles.length) {\n if (user && user.roles.some((r) => flag.roles.indexOf(r) >= 0)) return true;\n if (flag.rollout >= 100) return true;\n return false;\n }\n if (flag.rollout >= 100) return true;\n if (flag.rollout <= 0) return false;\n return user ? bucket(flag.key + \":\" + user.id) < flag.rollout : false;\n}\n\n/** Why a flag resolved the way it did — shown in the admin UI, invaluable in support. */\nfunction explainFlag(flag: Flag, user: User): FlagExplanation {\n if (!flag.enabled) return { on: false, reason: \"Globally off\", detail: \"The kill switch overrides all targeting.\" };\n if (user && flag.users && flag.users[user.id] != null) {\n const on = !!flag.users[user.id];\n return { on, reason: on ? \"User override — on\" : \"User override — off\", detail: \"Set explicitly for \" + user.name + \".\" };\n }\n if (flag.roles && flag.roles.length && user && user.roles.some((r) => flag.roles.indexOf(r) >= 0)) {\n return { on: true, reason: \"Role targeted\", detail: \"Held role matches \" + flag.roles.join(\", \") + \".\" };\n }\n if (flag.rollout >= 100) return { on: true, reason: \"Fully rolled out\", detail: \"100% of users.\" };\n if (flag.rollout <= 0) {\n return flag.roles && flag.roles.length\n ? { on: false, reason: \"Not targeted\", detail: \"Limited to \" + flag.roles.join(\", \") + \"; rollout is 0%.\" }\n : { on: false, reason: \"Rollout 0%\", detail: \"Enabled but not released to anyone.\" };\n }\n const b = user ? bucket(flag.key + \":\" + user.id) : null;\n return b != null && b < flag.rollout\n ? { on: true, reason: \"In rollout\", detail: \"Bucket \" + b + \" is below the \" + flag.rollout + \"% threshold.\" }\n : { on: false, reason: \"Outside rollout\", detail: \"Bucket \" + b + \" is at or above the \" + flag.rollout + \"% threshold.\" };\n}\n\nconst listeners = new Set<(s: Session) => void>();\nlet current: Session | null = null;\n\ndeclare global {\n interface Window {\n /** Admin-app-injected overrides for the demo dataset, read by loadSession(). */\n __FD_ADMIN_OVERRIDES?: { users?: User[]; roles?: Role[]; flags?: Flag[] };\n }\n}\n\n/** Replace this with `fetch(API + \"/me\")` to go live. */\nfunction loadSession(userId?: string): Session {\n const stored = readStored();\n const id = userId || (stored && stored.userId) || USERS[0].id;\n current = buildSession(id, window.__FD_ADMIN_OVERRIDES);\n if (stored && stored.profile) Object.assign(current.user, stored.profile);\n return current;\n}\n\nfunction getSession(): Session { return current || loadSession(); }\n\nfunction setActiveUser(userId: string): Session {\n writeStored({ userId });\n current = null;\n const s = loadSession(userId);\n listeners.forEach((fn) => fn(s));\n return s;\n}\n\n/** Local profile edits persist so the demo keeps them across reloads. */\nfunction saveProfile(patch: Partial<User>): User {\n const s = getSession();\n Object.assign(s.user, patch);\n const stored: StoredSession = readStored() || {};\n writeStored({ profile: Object.assign({}, stored.profile, patch) });\n listeners.forEach((fn) => fn(getSession()));\n return s.user;\n}\n\n/** Recompute after the admin app mutates users/roles/flags. */\nfunction refresh(): Session {\n const id = getSession().user.id;\n current = null;\n const s = loadSession(id);\n listeners.forEach((fn) => fn(s));\n return s;\n}\n\nfunction subscribe(fn: (s: Session) => void): () => void { listeners.add(fn); return () => listeners.delete(fn); }\n\nfunction can(permission: string | string[]): boolean {\n if (!permission) return true;\n const s = getSession();\n const list = Array.isArray(permission) ? permission : [permission];\n return list.every((p) => s.permissions.indexOf(p) >= 0);\n}\nfunction canAny(permissions: string[]): boolean {\n const s = getSession();\n return (permissions || []).some((p) => s.permissions.indexOf(p) >= 0);\n}\nfunction hasRole(roleId: string): boolean { return getSession().user.roles.indexOf(roleId) >= 0; }\nfunction flagOn(key: string): boolean { return !!getSession().flags[key]; }\n\n/** The flag registry entry, whatever the session shape.\n * Not declared in session.d.ts — see the module doc comment on SessionKit below. */\nfunction findFlag(key: string): Flag | null { return (getSession().allFlags || []).find((f) => f.key === key) || null; }\n\n/* Release state ONLY: is this feature turned on for this member (kill switch, rollout bucket,\n role, per-user override). Whether its backend exists is a different question with a different\n owner — RuntimeKit.status() computes it from the endpoints the feature declares, so no record\n anywhere claims to be implemented. Mixing the two here is what let a typed `implemented: true`\n outrank the code. */\nfunction flagState(key: string): \"on\" | \"off\" {\n if (!key) return \"on\";\n const f = findFlag(key);\n if (!f) return \"on\"; // unknown key: never hide working UI\n return flagOn(key) ? \"on\" : \"off\";\n}\nfunction isEnabled(key: string): boolean { return flagState(key) !== \"off\"; }\nfunction flagVisible(key: string): boolean { return isEnabled(key); }\n/* Deprecated: \"live\" used to mean released AND wired. Ask RuntimeKit.isComplete() for the second\n half — kept only so older call sites do not break. */\nfunction flagLive(key: string): boolean { return isEnabled(key); }\n\n/* Roadmap, derived from the registry rather than maintained beside it — a roadmap kept in a\n second place is a roadmap that goes stale. Ordered by date so the timeline is chronological\n regardless of how the flags happen to be listed. */\nfunction roadmap(overrides?: { flags?: Flag[]; isComplete?: (key: string) => boolean }): RoadmapResult {\n const flags = (overrides && overrides.flags) || (getSession().allFlags || []);\n // Injected rather than imported: session.ts must not depend on runtime.ts (runtime.ts has no\n // opinion about sessions, and a cycle between them would be the wrong shape). The consumer\n // passes RuntimeKit.isComplete; without it every feature reads as pending, which is the safe\n // direction — it under-claims instead of over-claiming.\n const isComplete = (overrides && overrides.isComplete) || (() => false);\n const items: RoadmapItem[] = flags.map((f): RoadmapItem => {\n const done = !!isComplete(f.key);\n /* Fall back to shippedAt when a record has no eta. Filtering on a missing date used to be\n harmless because shipped records were `done` and used shippedAt; with completeness derived,\n nothing is done, so 36 records lost their date and vanished from the page — including the\n very features whose coming-soon cards link here. A designed-on date is still a real date;\n it is labelled as one rather than pretended to be a ship date. */\n const date = done ? (f.shippedAt || f.eta) : (f.eta || f.shippedAt);\n const phaseInfo: Partial<Phase> = (f.phase != null ? PHASES[f.phase] : undefined) || {};\n return {\n key: f.key, label: f.label, project: f.project, description: f.description,\n backend: f.backend, effort: f.effort, owner: f.owner, dependsOn: f.dependsOn || [],\n screen: f.screen || null, enabled: f.enabled,\n /* Which build phase this sits in, and why that phase comes where it does. */\n phase: f.phase, phaseName: phaseInfo.name || \"Unscheduled\",\n phaseWhy: phaseInfo.why || null,\n phaseStart: phaseInfo.start || null,\n /* Derived, not stored. */\n implemented: done,\n date: date || null,\n /* True when the only date we have is when the UI was designed, not when it ships. */\n dateIsDesign: !done && !f.eta && !!f.shippedAt,\n status: done ? \"shipped\" : (f.enabled ? \"next\" : \"planned\")\n };\n }).filter((i) => i.date);\n /* Phase order, not date order. Two features in the same phase are deliberately unordered\n relative to each other — the phase is the commitment, the day inside it is not. */\n items.sort((a, b) => ((a.phase ?? 0) - (b.phase ?? 0)) || String(a.date).localeCompare(String(b.date)) || a.label.localeCompare(b.label));\n // The first unshipped item is where the reader should land: everything above is history.\n const nextIndex = items.findIndex((i) => !i.implemented);\n return {\n items, nextIndex: nextIndex < 0 ? items.length : nextIndex,\n shipped: items.filter((i) => i.implemented).length,\n remaining: items.filter((i) => !i.implemented).length\n };\n}\n\n/** React binding. Re-renders on user switch, profile save, or admin mutation. */\nfunction useSession(): Session {\n const [s, setS] = React.useState<Session>(getSession);\n React.useEffect(() => subscribe(setS), []);\n return s;\n}\n\n/**\n * Session, RBAC and feature flags for every flytedesk app.\n *\n * Not a security boundary: permissions gate the UI so people aren't shown affordances they\n * cannot use. The server must re-check all of it.\n *\n * To go live, replace loadSession() with a fetch of GET /me → { user, roles, permissions, flags }.\n */\nexport const SessionKit = {\n PERMISSION_CATALOG, ALL_PERMISSIONS, ROLES, FLAGS, USERS,\n loadSession, getSession, setActiveUser, saveProfile, refresh, subscribe,\n can, canAny, hasRole, flagOn, useSession,\n findFlag, flagState, isEnabled, flagVisible, flagLive, roadmap,\n evaluateFlag, explainFlag, bucket, buildSession\n};\n","import * as React from \"react\";\nimport { Card } from \"../surfaces/Card\";\nimport { Badge } from \"../feedback/Badge\";\nimport { Tag } from \"../feedback/Tag\";\nimport { Flag } from \"../feedback/Flag\";\nimport { Button } from \"../actions/Button\";\nimport { Input } from \"../forms/Input\";\nimport { Collapsible } from \"../surfaces/Collapsible\";\n\n/* A drop-in browser for a simulated API contract.\n\n Every flytedesk app that ships a simulated backend needs the same screen: the endpoint\n list engineers build from. Rather than fork the planner's version per app, this takes the\n spec as data.\n\n Required:\n spec — [{ id, method, path, title, purpose, usedBy[], latency:[lo,hi],\n request, response, notes?, isList? }]\n onRequest — (id, params) => Promise<any> the app's simulated transport\n\n Optional:\n modules — [{ id, label, icon, endpoints:[id] }] maps app screens to the endpoints\n they call. Rendered as the primary filter, because \"what does this screen\n need\" is the question engineers actually arrive with.\n groups — [[label, [id]]] lifecycle grouping for the list itself\n conventions — [[label, text]] cross-cutting rules (auth, errors, pagination)\n*/\n\nexport interface EndpointSpec {\n id: string;\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n path: string;\n title: string;\n purpose: string;\n usedBy?: string[];\n /** [lo, hi] ms. Doubles as the latency SLO the UI's loading states are designed around. */\n latency: [number, number];\n request?: unknown;\n query?: unknown;\n response: unknown;\n notes?: string;\n /** Marks a paged list returning the { rows, pager, sort, filter } envelope. */\n isList?: boolean;\n}\nexport interface SpecModule { id: string; label: string; icon?: string; endpoints: string[] }\n\nexport interface ApiSpecBrowserProps {\n spec?: EndpointSpec[];\n /** The app's simulated transport: (id, params) => Promise<any>. Powers \"Try it\". */\n onRequest: (id: string, params: unknown) => Promise<unknown>;\n /** Screen → endpoints map. Rendered as the primary filter. */\n modules?: SpecModule[];\n /** Lifecycle grouping: [[label, endpointIds]] */\n groups?: Array<[string, string[]]>;\n title?: string;\n kicker?: string;\n lede?: string;\n /** Where the spec lives and how to swap in the real transport. */\n sourceNote?: string;\n conventions?: Array<[string, string]>;\n openQuestions?: Array<[string, string, string]>;\n className?: string;\n}\n\nconst METHOD_TONE: Record<string, \"success\" | \"info\" | \"warning\" | \"danger\"> = { GET: \"success\", POST: \"info\", PATCH: \"warning\", PUT: \"warning\", DELETE: \"danger\" };\n\nexport function Json({ obj }: { obj: unknown }) {\n return <pre className=\"fd-json\">{JSON.stringify(obj, null, 2)}</pre>;\n}\n\ntype TriedState = \"busy\" | { ms: number; data?: unknown; error?: string } | null;\n\ninterface EndpointProps {\n s: EndpointSpec;\n onRequest: (id: string, params: unknown) => Promise<unknown>;\n}\n\nfunction Endpoint({ s, onRequest }: EndpointProps) {\n const [tried, setTried] = React.useState<TriedState>(null);\n const run = async () => {\n setTried(\"busy\");\n const t0 = (window.performance || Date).now();\n try {\n const data = await onRequest(s.id, s.request || (s.isList ? { page: 1, pageSize: 5 } : {}));\n setTried({ ms: Math.round((window.performance || Date).now() - t0), data });\n } catch (e) {\n setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String((e as any) && (e as any).message || e) });\n }\n };\n return (\n <Card elevation=\"flat\" padded={false}>\n <div className=\"fd-stack\" style={{ gap: 0 }}>\n <div className=\"fd-row\" style={{ gap: 10, padding: \"14px 18px\", flexWrap: \"wrap\" }}>\n <Badge tone={METHOD_TONE[s.method] || \"neutral\"}>{s.method}</Badge>\n <code className=\"fd-mono\" style={{ fontSize: 12.5, fontWeight: 600, color: \"var(--text)\", wordBreak: \"break-all\" }}>{s.path}</code>\n {s.isList ? <Badge tone=\"neutral\" icon=\"rows\">Paged list</Badge> : null}\n <span style={{ flex: 1 }} />\n <span className=\"fd-body-sm fd-muted fd-mono\">{s.latency[0]}–{s.latency[1]}ms</span>\n <Button size=\"sm\" variant=\"secondary\" icon=\"play\" loading={tried === \"busy\"} onClick={run}>Try it</Button>\n </div>\n <div className=\"fd-stack\" style={{ gap: 14, padding: \"0 18px 16px\" }}>\n <div className=\"fd-stack\" style={{ gap: 6 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 700 }}>{s.title}</span>\n <p className=\"fd-body-sm fd-secondary\" style={{ margin: 0, textWrap: \"pretty\" }}>{s.purpose}</p>\n {s.usedBy && s.usedBy.length ? (\n <span className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\" }}>{s.usedBy.map((u) => <Tag key={u}>{u}</Tag>)}</span>\n ) : null}\n </div>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(280px,1fr))\", gap: 12, alignItems: \"start\" }}>\n {s.request ? <div className=\"fd-stack\" style={{ gap: 6 }}><span className=\"fd-overline fd-muted\">Request body</span><Json obj={s.request} /></div> : null}\n {s.query ? <div className=\"fd-stack\" style={{ gap: 6 }}><span className=\"fd-overline fd-muted\">Query</span><Json obj={s.query} /></div> : null}\n <div className=\"fd-stack\" style={{ gap: 6 }}><span className=\"fd-overline fd-muted\">Response 200</span><Json obj={s.response} /></div>\n </div>\n {s.notes ? <Flag tone=\"info\" statement=\"Implementation note\" cost={s.notes} actions={null} /> : null}\n {tried && tried !== \"busy\" ? (\n <div className=\"fd-stack\" style={{ gap: 6 }}>\n <span className=\"fd-row\" style={{ gap: 8 }}>\n <span className=\"fd-overline fd-muted\">Simulated response</span>\n <Badge tone={tried.error ? \"danger\" : \"success\"} icon=\"timer\">{tried.ms}ms</Badge>\n </span>\n <Json obj={tried.error ? { error: tried.error } : tried.data} />\n </div>\n ) : null}\n </div>\n </div>\n </Card>\n );\n}\n\n/** Drop-in browser for a simulated API contract. Takes the spec as data. */\nexport function ApiSpecBrowser({\n spec = [],\n onRequest,\n modules,\n groups,\n title = \"API specification\",\n kicker = \"Architecture\",\n lede,\n sourceNote,\n conventions,\n openQuestions,\n className = \"\",\n ...rest\n}: ApiSpecBrowserProps) {\n const [q, setQ] = React.useState(\"\");\n const [method, setMethod] = React.useState<string | null>(null);\n const [mod, setMod] = React.useState<string | null>(null);\n const [listOnly, setListOnly] = React.useState(false);\n\n const activeModule = modules && modules.find((m) => m.id === mod);\n const hits = spec.filter((s) =>\n (!method || s.method === method) &&\n (!listOnly || s.isList) &&\n (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) &&\n (!q || (s.path + \" \" + s.title + \" \" + s.purpose + \" \" + (s.usedBy || []).join(\" \")).toLowerCase().includes(q.toLowerCase())));\n\n const effGroups: Array<[string, string[]]> = groups && groups.length\n ? groups\n : [[\"All endpoints\", spec.map((s) => s.id)]];\n const methods = [...new Set(spec.map((s) => s.method))];\n const listCount = spec.filter((s) => s.isList).length;\n\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 20, maxWidth: 1100 }} {...rest}>\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n {kicker ? <span className=\"fd-overline fd-muted\">{kicker}</span> : null}\n <h1 className=\"fd-h1\" style={{ margin: 0 }}>{title}</h1>\n {lede ? <p className=\"fd-body fd-secondary fd-prose\" style={{ margin: 0 }}>{lede}</p> : null}\n </div>\n\n {modules && modules.length ? (\n <div className=\"fd-stack\" style={{ gap: 8 }}>\n <span className=\"fd-overline fd-muted\">Filter by screen — every endpoint that screen depends on</span>\n <div className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\" }}>\n <Tag icon=\"stack\" selected={!mod} onClick={() => setMod(null)}>All screens <span className=\"fd-mono\">{spec.length}</span></Tag>\n {modules.map((m) => (\n <Tag key={m.id} icon={m.icon} selected={mod === m.id} onClick={() => setMod(mod === m.id ? null : m.id)}>\n {m.label} <span className=\"fd-mono\">{m.endpoints.length}</span>\n </Tag>\n ))}\n </div>\n {/* With one screen selected the list becomes an integration checklist — the most\n useful thing this page can be to someone picking up a ticket. */}\n {activeModule ? (\n <Flag tone=\"info\" statement={activeModule.label + \" calls \" + activeModule.endpoints.length + \" endpoints.\"}\n cost={\"Integration checklist for this screen: \" + activeModule.endpoints.join(\", \") + \". Wire these and the screen is done.\"}\n actions={<Button size=\"sm\" variant=\"ghost\" icon=\"x\" onClick={() => setMod(null)}>Show all screens</Button>} />\n ) : null}\n </div>\n ) : null}\n\n {sourceNote ? <Flag tone=\"info\" statement=\"Design-first: this page is the spec.\" cost={sourceNote} actions={null} /> : null}\n\n <div className=\"fd-row\" style={{ gap: 10, flexWrap: \"wrap\" }}>\n <Input icon=\"magnifying-glass\" placeholder=\"Find an endpoint, screen, or behavior\" value={q} onChange={(e) => setQ(e.target.value)} style={{ width: 300 }} />\n {methods.map((m) => (\n <Tag key={m} selected={method === m} onClick={() => setMethod(method === m ? null : m)}>\n {m} <span className=\"fd-mono\">{spec.filter((s) => s.method === m).length}</span>\n </Tag>\n ))}\n {listCount ? (\n <Tag icon=\"rows\" selected={listOnly} onClick={() => setListOnly(!listOnly)}>\n Paged lists <span className=\"fd-mono\">{listCount}</span>\n </Tag>\n ) : null}\n <span style={{ flex: 1 }} />\n <span className=\"fd-body-sm fd-muted\">{hits.length} of {spec.length} endpoints{listCount ? \" · \" + listCount + \" paged\" : \"\"}</span>\n </div>\n\n {hits.length === 0 ? (\n <Card elevation=\"flat\"><p className=\"fd-body-sm fd-muted\" style={{ margin: 0 }}>No endpoint matches those filters.</p></Card>\n ) : effGroups.map(([g, ids]) => {\n const items = hits.filter((s) => ids.indexOf(s.id) >= 0);\n if (!items.length) return null;\n return (\n <div key={g} className=\"fd-stack\" style={{ gap: 12 }}>\n <span className=\"fd-label-lg\">{g}</span>\n {items.map((s) => <Endpoint key={s.id} s={s} onRequest={onRequest} />)}\n </div>\n );\n })}\n\n {conventions && conventions.length ? (\n <Card title=\"Cross-cutting conventions\" elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n {conventions.map(([k, v]) => (\n <div key={k} className=\"fd-row\" style={{ gap: 12, alignItems: \"flex-start\" }}>\n <span className=\"fd-overline fd-muted\" style={{ width: 110, flex: \"none\", paddingTop: 2 }}>{k}</span>\n <span className=\"fd-body-sm fd-secondary\" style={{ textWrap: \"pretty\" }}>{v}</span>\n </div>\n ))}\n </div>\n </Card>\n ) : null}\n\n {openQuestions && openQuestions.length ? (\n <Collapsible icon=\"list-checks\" title=\"Open questions before implementation\" subtitle={openQuestions.length + \" unresolved\"}>\n <div className=\"fd-stack\" style={{ gap: 8 }}>\n {openQuestions.map(([id, question, why]) => (\n <div key={id} className=\"fd-row\" style={{ gap: 10, alignItems: \"flex-start\", padding: \"8px 0\", borderTop: \"1px solid var(--border)\" }}>\n <Badge tone=\"danger\">{id}</Badge>\n <span className=\"fd-stack\" style={{ gap: 2, flex: 1 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 600 }}>{question}</span>\n <span className=\"fd-body-sm fd-muted\">{why}</span>\n </span>\n </div>\n ))}\n </div>\n </Collapsible>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Card, CardRow } from \"../surfaces/Card\";\nimport { Badge } from \"../feedback/Badge\";\nimport { Button } from \"../actions/Button\";\nimport { Avatar } from \"../feedback/Avatar\";\nimport { Input } from \"../forms/Input\";\nimport { Select } from \"../forms/Select\";\nimport { Switch } from \"../forms/Switch\";\nimport { Textarea } from \"../forms/Textarea\";\nimport { SessionKit } from \"../../kits/session\";\nimport type { User } from \"../../kits/session\";\n\n/* The profile page, shared by every flytedesk app.\n\n Deliberately narrow: identity, working preferences, notifications, sessions. Anything\n billing- or plan-shaped belongs to the platform's own settings, not here.\n\n Roles are shown but never editable — a user promoting themselves is the whole reason RBAC\n exists. The card points at the admin surface instead.\n\n Pass `onSave` to persist through your own endpoint; the default writes through\n SessionKit.saveProfile so the demo keeps edits across reloads. */\n\nexport interface DeviceSession { id: string; device: string; where: string; when: string; current?: boolean }\nexport interface ProfilePageProps {\n /** Defaults to the signed-in user from SessionKit. */\n user?: User;\n /** Persist through your own endpoint. Defaults to SessionKit.saveProfile. */\n onSave?: (draft: Partial<User>) => void | Promise<void>;\n onNavigate?: (href: string) => void;\n sessions?: DeviceSession[];\n showSessions?: boolean;\n className?: string;\n}\n\nconst TIMEZONES = [\"America/New_York\", \"America/Chicago\", \"America/Denver\", \"America/Los_Angeles\", \"America/Anchorage\", \"Pacific/Honolulu\", \"Europe/London\", \"Europe/Berlin\"];\nconst NOTIFY = [\n { key: \"planShared\", label: \"A plan is shared with me\", detail: \"Someone sends you a plan or a client link.\" },\n { key: \"planChanged\", label: \"A plan I own changes\", detail: \"Budget moves, campuses added or removed.\" },\n { key: \"goalMissed\", label: \"The reviewer flags a missed criterion\", detail: \"After every solve, if a criterion is short.\" },\n { key: \"flagChanged\", label: \"A feature flag affecting me changes\", detail: \"Someone toggles a feature you can see.\" },\n { key: \"weekly\", label: \"Weekly digest\", detail: \"Monday summary of plan activity.\" }\n];\n\ninterface ProfileDraft {\n name: string; title: string; email: string; phone: string; timezone: string; bio: string;\n notify: Record<string, boolean>;\n}\n\n/**\n * The shared profile page: identity, working preferences, notifications, devices.\n * Roles are shown but never editable — self-promotion is the reason RBAC exists.\n */\nexport function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = \"\", ...rest }: ProfilePageProps) {\n const session = SessionKit.useSession();\n const user = userProp || session.user;\n const [draft, setDraft] = React.useState<ProfileDraft>(() => ({\n name: user.name || \"\", title: user.title || \"\", email: user.email || \"\",\n phone: user.phone || \"\", timezone: user.timezone || TIMEZONES[2],\n bio: user.bio || \"\", notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }\n }));\n const [saving, setSaving] = React.useState(false);\n const [saved, setSaved] = React.useState(false);\n const set = <K extends keyof ProfileDraft>(k: K, v: ProfileDraft[K]) => { setDraft((d) => Object.assign({}, d, { [k]: v })); setSaved(false); };\n const setNotify = (k: string) => { setDraft((d) => Object.assign({}, d, { notify: Object.assign({}, d.notify, { [k]: !d.notify[k] }) })); setSaved(false); };\n\n const dirty = draft.name !== (user.name || \"\") || draft.title !== (user.title || \"\") ||\n draft.phone !== (user.phone || \"\") || draft.timezone !== (user.timezone || TIMEZONES[2]) ||\n draft.bio !== (user.bio || \"\") || JSON.stringify(draft.notify) !== JSON.stringify(user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true });\n\n const save = async () => {\n setSaving(true);\n if (onSave) await onSave(draft); else SessionKit.saveProfile(draft);\n setSaving(false); setSaved(true);\n };\n\n const liveSessions: DeviceSession[] = sessions || [\n { id: \"s1\", device: \"MacBook Pro · Chrome\", where: \"Denver, CO\", when: \"Active now\", current: true },\n { id: \"s2\", device: \"iPhone 15 · Safari\", where: \"Denver, CO\", when: \"2 hours ago\" },\n { id: \"s3\", device: \"Windows · Edge\", where: \"Chicago, IL\", when: \"Aug 12\" }\n ];\n\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 20, maxWidth: 860 }} {...rest}>\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n <span className=\"fd-overline fd-muted\">Account</span>\n <h1 className=\"fd-h1\" style={{ margin: 0 }}>Your profile</h1>\n <p className=\"fd-body fd-secondary fd-prose\" style={{ margin: 0 }}>\n How you appear to colleagues and clients across every flytedesk app, and what we send you.\n </p>\n </div>\n\n <Card elevation=\"flat\">\n <div className=\"fd-row\" style={{ gap: 16, flexWrap: \"wrap\", alignItems: \"flex-start\" }}>\n <Avatar name={draft.name || user.name} size=\"lg\" />\n <div className=\"fd-stack\" style={{ gap: 4, flex: 1, minWidth: 200 }}>\n <span className=\"fd-h3\" style={{ margin: 0 }}>{draft.name || user.name}</span>\n <span className=\"fd-body-sm fd-muted\">{draft.title || \"No title set\"} · {user.team || \"No team\"}</span>\n <span className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\", paddingTop: 4 }}>\n {session.roles.map((r) => <Badge key={r.id} tone={r.id === \"owner\" ? \"success\" : \"neutral\"}>{r.name}</Badge>)}\n {user.sso ? <Badge tone=\"info\" icon=\"shield-check\">SSO</Badge> : null}\n </span>\n </div>\n <Button variant=\"secondary\" size=\"sm\" icon=\"image\">Change photo</Button>\n </div>\n </Card>\n\n {/* Card has no `subtitle` slot in the ported component (source bug) — composed here as a\n two-line title node using the same fd-body-sm/fd-muted idiom AccountMenu uses elsewhere. */}\n <Card\n title={\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span>Identity</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontWeight: 400 }}>Name and title appear on plans you share</span>\n </span>\n }\n elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 14 }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(220px,1fr))\", gap: 14 }}>\n <Input label=\"Full name\" value={draft.name} onChange={(e) => set(\"name\", e.target.value)} />\n <Input label=\"Job title\" value={draft.title} onChange={(e) => set(\"title\", e.target.value)} placeholder=\"e.g. Senior media planner\" />\n </div>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(220px,1fr))\", gap: 14 }}>\n <Input label=\"Work email\" value={draft.email} readOnly disabled\n help={user.sso ? \"Managed by your identity provider — change it there.\" : \"Contact an administrator to change this.\"} />\n <Input label=\"Phone\" value={draft.phone} onChange={(e) => set(\"phone\", e.target.value)} placeholder=\"Optional\" />\n </div>\n <Textarea label=\"Short bio\" value={draft.bio} onChange={(e) => set(\"bio\", e.target.value)} rows={3}\n placeholder=\"Optional — shown to colleagues on shared plans.\"\n help=\"Never shown to clients.\" />\n </div>\n </Card>\n\n <Card title=\"Working preferences\" elevation=\"flat\">\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(220px,1fr))\", gap: 14 }}>\n <Select label=\"Time zone\" value={draft.timezone} onChange={(e) => set(\"timezone\", e.target.value)} options={TIMEZONES}\n help=\"Flight dates and schedules render in this zone.\" />\n <Select label=\"Start of week\" options={[\"Monday\", \"Sunday\"]} placeholder=\"Monday\" />\n </div>\n </Card>\n\n <Card\n title={\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span>Notifications</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontWeight: 400 }}>Email only for now — in-app notifications are on the roadmap</span>\n </span>\n }\n elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 14 }}>\n {NOTIFY.map((n) => (\n <Switch key={n.key} checked={!!draft.notify[n.key]} onChange={() => setNotify(n.key)} label={n.label} description={n.detail} />\n ))}\n </div>\n </Card>\n\n <Card\n title={\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span>Access</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontWeight: 400 }}>What your roles grant you</span>\n </span>\n }\n elevation=\"flat\"\n action={<Button size=\"sm\" variant=\"ghost\" icon=\"arrow-right\"\n onClick={() => onNavigate && onNavigate(\"#roles\")}>See role definitions</Button>}>\n <div className=\"fd-stack\" style={{ gap: 0 }}>\n <CardRow label=\"Roles\">{session.roles.map((r) => r.name).join(\", \") || \"None\"}</CardRow>\n <CardRow label=\"Permissions\">{session.permissions.length} granted</CardRow>\n <CardRow label=\"Member since\">{user.joined || \"—\"}</CardRow>\n </div>\n <p className=\"fd-body-sm fd-muted\" style={{ margin: \"12px 0 0\" }}>\n You cannot change your own roles — that is the point of them. An administrator manages roles from Admin → Users.\n </p>\n </Card>\n\n {showSessions ? (\n <Card title=\"Signed-in devices\" elevation=\"flat\"\n action={<Button size=\"sm\" variant=\"ghost\" icon=\"sign-out\">Sign out everywhere</Button>}>\n <div className=\"fd-stack\" style={{ gap: 0 }}>\n {liveSessions.map((s) => (\n <div key={s.id} className=\"fd-row\" style={{ gap: 12, padding: \"10px 0\", borderTop: \"1px solid var(--border)\", flexWrap: \"wrap\" }}>\n <i className=\"ph ph-device-mobile\" style={{ fontSize: 16, color: \"var(--text-muted)\" }} aria-hidden=\"true\" />\n <span className=\"fd-stack\" style={{ gap: 1, flex: 1, minWidth: 160 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 600 }}>{s.device}</span>\n <span className=\"fd-body-sm fd-muted\">{s.where} · {s.when}</span>\n </span>\n {s.current ? <Badge tone=\"success\" dot>This device</Badge> : <Button size=\"sm\" variant=\"ghost\">Revoke</Button>}\n </div>\n ))}\n </div>\n </Card>\n ) : null}\n\n <div className=\"fd-row\" style={{ gap: 10, flexWrap: \"wrap\", position: \"sticky\", bottom: 0, padding: \"12px 14px\",\n borderRadius: 10, background: \"var(--surface)\", border: \"1px solid var(--border)\", boxShadow: \"0 -4px 16px rgba(11,13,17,.06)\" }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 600, flex: 1 }}>\n {saved ? \"Saved.\" : dirty ? \"Unsaved changes\" : \"No pending changes\"}\n </span>\n <Button size=\"sm\" variant=\"ghost\" disabled={!dirty || saving}\n onClick={() => { setDraft({ name: user.name || \"\", title: user.title || \"\", email: user.email || \"\", phone: user.phone || \"\", timezone: user.timezone || TIMEZONES[2], bio: user.bio || \"\", notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true } }); setSaved(false); }}>\n Discard\n </Button>\n <Button size=\"sm\" icon=\"check\" disabled={!dirty} loading={saving} onClick={save}>Save changes</Button>\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Card } from \"../surfaces/Card\";\nimport { Badge } from \"../feedback/Badge\";\nimport { Tag } from \"../feedback/Tag\";\nimport { Flag } from \"../feedback/Flag\";\nimport { Button } from \"../actions/Button\";\nimport { Input } from \"../forms/Input\";\nimport { Select } from \"../forms/Select\";\nimport { StatTile } from \"../data/StatTile\";\nimport { SessionKit } from \"../../kits/session\";\nimport type { RoadmapItem } from \"../../kits/session\";\nimport { RuntimeKit } from \"../../kits/runtime\";\n\n/* The roadmap is DERIVED from the flag registry, not maintained beside it — a roadmap kept in\n a second file is a roadmap that goes stale within a fortnight. Every entry's date, status and\n dependency list comes from the flag that gates the feature.\n\n The reading order is the argument: the whole UI is already designed and working against a\n simulated transport, so this timeline only ever describes BACKEND work. Shipped items sit\n above the \"you are here\" line, upcoming ones below, and the scroll container opens at that\n line so the first thing in view is what comes next rather than what is finished. */\n\nexport interface RoadmapTimelineProps {\n /** Called with a flag key when the reader clicks one — route it to your flag admin. */\n onOpenFlag?: (flagKey: string) => void;\n /** Heading. Default \"Roadmap\". */\n title?: string;\n /** Replaces the default explanation of what the timeline covers. */\n lede?: string;\n}\n\nconst STATUS: Record<string, { tone: \"success\" | \"warning\" | \"neutral\"; icon: string; label: string }> = {\n shipped: { tone: \"success\", icon: \"check-circle\", label: \"Wired\" },\n next: { tone: \"warning\", icon: \"traffic-cone\", label: \"Not wired\" },\n planned: { tone: \"neutral\", icon: \"circle-dashed\", label: \"Not released\" }\n};\nconst PROJECT_ICON: Record<string, string> = { \"Media Planner\": \"chart-line-up\", Platform: \"buildings\", Admin: \"shield-check\", \"Agent Chat\": \"chat-circle-dots\" };\n\nconst fmtDate = (iso: string | null) => {\n const d = new Date(String(iso) + \"T00:00:00\");\n return isNaN(d as unknown as number) ? iso : d.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", year: \"numeric\" });\n};\n\ninterface RoadmapCardProps {\n item: RoadmapItem;\n byKey: Record<string, RoadmapItem>;\n onOpenFlag?: (flagKey: string) => void;\n}\n\nfunction RoadmapCard({ item, byKey, onOpenFlag }: RoadmapCardProps) {\n const s = STATUS[item.status] || STATUS.planned;\n const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);\n const blocking = deps.filter((d) => !d.implemented);\n return (\n <Card elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n <div className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\" }}>\n <span className=\"fd-body\" style={{ fontWeight: 700, flex: 1, minWidth: 140 }}>{item.label}</span>\n <Badge tone=\"neutral\" icon={PROJECT_ICON[item.project] || \"squares-four\"}>{item.project}</Badge>\n <Badge tone={s.tone} icon={s.icon}>{s.label}</Badge>\n </div>\n <p className=\"fd-body-sm fd-secondary\" style={{ margin: 0, textWrap: \"pretty\" }}>{item.description}</p>\n {item.backend ? (\n <div className=\"fd-row\" style={{ gap: 10, alignItems: \"flex-start\" }}>\n <span className=\"fd-overline fd-muted\" style={{ width: 62, flex: \"none\", paddingTop: 2 }}>Backend</span>\n <span className=\"fd-body-sm\" style={{ flex: 1, textWrap: \"pretty\" }}>{item.backend}</span>\n </div>\n ) : null}\n <div className=\"fd-row\" style={{ gap: 12, flexWrap: \"wrap\" }}>\n {item.effort ? <span className=\"fd-body-sm fd-muted\"><i className=\"ph ph-hourglass-medium\" /> {item.effort}</span> : null}\n <span className=\"fd-body-sm fd-muted\"><i className=\"ph ph-user\" /> {item.owner}</span>\n {item.screen ? <Badge tone=\"neutral\" icon=\"browser\">screen</Badge> : null}\n <span style={{ flex: 1 }} />\n <button type=\"button\" onClick={() => onOpenFlag && onOpenFlag(item.key)}\n style={{ all: \"unset\", cursor: \"pointer\", display: \"inline-flex\", alignItems: \"center\", gap: 5 }}>\n <code className=\"fd-mono\" style={{ fontSize: 11, color: \"var(--brand)\" }}>{item.key}</code>\n </button>\n </div>\n {deps.length ? (\n <div className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\", paddingTop: 6, borderTop: \"1px solid var(--border)\" }}>\n <span className=\"fd-overline fd-muted\" style={{ paddingTop: 3 }}>After</span>\n {deps.map((d) => (\n <Tag key={d.key} icon={d.implemented ? \"check\" : \"clock\"}>{d.label}</Tag>\n ))}\n </div>\n ) : null}\n {blocking.length && !item.implemented ? (\n <span className=\"fd-body-sm\" style={{ color: \"var(--warn-text)\" }}>\n Blocked until {blocking.map((d) => d.label).join(\" and \")} {blocking.length === 1 ? \"is\" : \"are\"} wired.\n </span>\n ) : null}\n </div>\n </Card>\n );\n}\n\n/**\n * A vertical, chronological map of what is wired to the real backend and what is next.\n *\n * Derived entirely from the feature-flag registry (`SessionKit.roadmap()`) — status is each\n * flag's `implemented` field, ordering comes from its date, and blocking relationships come\n * from its `dependsOn`. Nothing here is maintained separately, so it cannot drift from what\n * the apps actually do.\n *\n * Shipped work sits above a \"you are here\" marker and upcoming work below it; the scroll\n * container opens at that marker, so the first thing in view is what comes next.\n */\nexport function RoadmapTimeline({ onOpenFlag, title = \"Roadmap\", lede }: RoadmapTimelineProps) {\n const session = SessionKit.useSession();\n const [project, setProject] = React.useState(\"\");\n const [q, setQ] = React.useState(\"\");\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const nowRef = React.useRef<HTMLDivElement>(null);\n\n const rm = React.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);\n const byKey = React.useMemo(() => {\n const m: Record<string, RoadmapItem> = {};\n rm.items.forEach((i: RoadmapItem) => { m[i.key] = i; });\n return m;\n }, [rm]);\n\n const items: RoadmapItem[] = rm.items.filter((i: RoadmapItem) =>\n (!project || i.project === project) &&\n (!q || (i.label + \" \" + i.description + \" \" + (i.backend || \"\") + \" \" + i.key).toLowerCase().includes(q.toLowerCase())));\n const projects = [...new Set(rm.items.map((i: RoadmapItem) => i.project))];\n\n // Open at the \"you are here\" line: history above, what's next in view. Runs on the filtered\n // list too, since filtering moves the boundary. Two frames, because era headers and card text\n // change the track's height after the first paint — measuring too early lands in the wrong place.\n React.useEffect(() => {\n let raf1 = 0, raf2 = 0;\n const place = () => {\n const box = scrollRef.current, mark = nowRef.current;\n if (!box) return;\n // No pending work: show the end of the timeline rather than leaving it at the top.\n if (!mark) { box.scrollTop = box.scrollHeight; return; }\n // Put the marker just under the top edge so its label is readable — an offset large\n // enough to scroll it out of view defeats the purpose of having a label at all.\n box.scrollTop = Math.max(0, mark.offsetTop - 28);\n };\n raf1 = requestAnimationFrame(() => { place(); raf2 = requestAnimationFrame(place); });\n return () => { cancelAnimationFrame(raf1); cancelAnimationFrame(raf2); };\n }, [project, q, rm.nextIndex]);\n\n const firstPending = items.findIndex((i) => !i.implemented);\n const shippedShown = items.filter((i) => i.implemented).length;\n /* parseInt(\"1 week\") is 1 and parseInt(\"4 days\") is 4, so summing the raw numbers mixed two\n units and labelled the result \"wk\". Normalise to working days first. */\n const days = items.filter((i) => !i.implemented).reduce((s, i) => {\n const m = String(i.effort).match(/(\\d+)\\s*(day|week)/);\n return s + (m ? Number(m[1]) * (m[2] === \"week\" ? 5 : 1) : 0);\n }, 0);\n const nextPhase = items.find((i) => !i.implemented);\n\n let lastPhase: number | null | undefined = null;\n return (\n <div className=\"fd-stack\" style={{ gap: 16, maxWidth: 1000 }}>\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n <span className=\"fd-overline fd-muted\">Architecture</span>\n <h1 className=\"fd-h1\" style={{ margin: 0 }}>{title}</h1>\n <p className=\"fd-body fd-secondary fd-prose\" style={{ margin: 0 }}>\n {lede || \"Every screen and feature in these tools is already designed and working against a simulated backend. This is the plan for connecting them to the real one — so the only work described here is server work.\"}\n </p>\n </div>\n\n <div className=\"fd-grid-stats is-thin\">\n <StatTile compact label=\"Wired\" value={String(rm.shipped)} sub={\"of \" + rm.items.length + \" features\"} />\n <StatTile compact label=\"Remaining\" value={String(rm.remaining)} sub=\"backend work\" />\n <StatTile compact label=\"Est. effort\" value={days ? days + \" days\" : \"—\"} sub=\"sum of estimates, not calendar\" />\n <StatTile compact label=\"Up next\" value={nextPhase ? \"Phase \" + nextPhase.phase : \"—\"} sub={nextPhase ? nextPhase.phaseName : \"all wired\"} />\n </div>\n\n <div className=\"fd-row\" style={{ gap: 10, flexWrap: \"wrap\" }}>\n <Input icon=\"magnifying-glass\" placeholder=\"Find a feature or a piece of backend work\" value={q} onChange={(e) => setQ(e.target.value)} style={{ width: 300 }} />\n <Select placeholder=\"All projects\" value={project} onChange={(e) => setProject(e.target.value)} options={projects} style={{ width: 190 }} />\n <span style={{ flex: 1 }} />\n <Button size=\"sm\" variant=\"secondary\" icon=\"arrow-down\"\n onClick={() => { const b = scrollRef.current, m = nowRef.current; if (b) b.scrollTop = m ? Math.max(0, m.offsetTop - 28) : b.scrollHeight; }}>\n Jump to now\n </Button>\n </div>\n\n <Flag tone=\"info\" statement=\"Shipped means its endpoints are live — nothing here is marked done by hand.\"\n cost=\"A feature counts as shipped only when every endpoint it declares is served by the real backend, so this page cannot drift from the app. Dates are targets, not commitments; effort is the size of the backend work, and the ordering follows each feature's dependencies — a slip early in the list moves everything below it.\"\n actions={null} />\n\n <div className=\"fd-rm\">\n <div className=\"fd-rm-scroll\" ref={scrollRef}>\n <div className=\"fd-rm-track\">\n <span className=\"fd-rm-spine\">\n <span className=\"fd-rm-spine-done\" style={{ height: items.length ? (100 * shippedShown / items.length) + \"%\" : \"0%\" }} />\n </span>\n {items.map((item, n) => {\n /* Group by build phase, not by quarter. A quarter header says when; a phase header\n says what unblocks what, which is the only reason the order is what it is. */\n const showPhase = item.phase !== lastPhase;\n lastPhase = item.phase;\n const inPhase = items.filter((i) => i.phase === item.phase).length;\n const isBoundary = n === firstPending;\n return (\n <React.Fragment key={item.key}>\n {showPhase ? (\n <div className=\"fd-rm-era\">\n <span className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\", alignItems: \"baseline\" }}>\n <span style={{ fontWeight: 700 }}>{item.phase === 0 ? \"Shipped\" : \"Phase \" + item.phase + \" — \" + item.phaseName}</span>\n {item.phase === 0 ? null : (\n <span className=\"fd-mono\" style={{ opacity: 0.7, fontWeight: 400 }}>\n {fmtDate(item.phaseStart)} – {fmtDate(item.date)}\n </span>)}\n <span style={{ opacity: 0.7, fontWeight: 400 }}>· {inPhase} feature{inPhase === 1 ? \"\" : \"s\"}</span>\n </span>\n {item.phaseWhy ? <p className=\"fd-rm-era-why\">{item.phaseWhy}</p> : null}\n </div>\n ) : null}\n {isBoundary ? (\n <div className=\"fd-rm-now\" ref={nowRef}>\n <span className=\"fd-rm-now-pill\"><i className=\"ph ph-map-pin\" /> You are here — everything above is wired</span>\n </div>\n ) : null}\n <div className=\"fd-rm-row\">\n <span className={\"fd-rm-dot \" + (item.implemented ? \"is-shipped\" : item.status === \"next\" ? \"is-next\" : \"\")} />\n <div className=\"fd-rm-date\">\n {fmtDate(item.date)}\n <br />\n <span style={{ opacity: 0.75 }}>{item.implemented ? \"shipped\" : \"phase \" + item.phase}</span>\n </div>\n <RoadmapCard item={item} byKey={byKey} onOpenFlag={onOpenFlag} />\n </div>\n </React.Fragment>\n );\n })}\n {!items.length ? <p className=\"fd-body-sm fd-muted\">Nothing matches that filter.</p> : null}\n </div>\n </div>\n </div>\n\n <p className=\"fd-body-sm fd-muted\" style={{ margin: 0 }}>\n Derived from the feature-flag registry — each entry's status is its flag's <code className=\"fd-mono\">implemented</code> field,\n so this page cannot drift from what the apps actually do.\n </p>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/* Runtime mode and feature completeness.\n\n The correction this file exists to make: completeness is NOT a field on a feature record.\n A row in a table saying `implemented: true` is a claim someone typed; it drifts the moment\n code changes, and nothing enforces it. The code already knows — a feature is complete when\n the endpoints it depends on are served by a real backend. So that is where it is declared,\n and everything else is derived.\n\n Two code-owned lists, both here, both meant to be edited by whoever ships the backend:\n\n WIRED_ENDPOINTS endpoint ids the REAL service answers. Empty today: every request in this\n build goes to the simulated transport. Add an id the day it goes live.\n CLIENT_ONLY features that need no backend at all — pure front-end behaviour. These are\n complete by construction and must never be obstructed.\n\n A feature declares the endpoints it needs via `RuntimeKit.declare()`. It is complete when\n every one of those endpoints is wired. Nothing to keep in sync, nothing to forget: ship the\n endpoint, add its id, and every feature that depended on it stops being under construction.\n\n This package ships with WIRED_ENDPOINTS permanently empty — it has no way to know which\n endpoints any given consuming app has actually wired up. A consumer that has shipped real\n backend work for a feature tells this module so via `RuntimeKit.wireEndpoints(ids)`, the\n mirror of `declare()`: call it once, early (before first render), with the real list. Additive\n and idempotent, same as `declare()` — safe to call from more than one place in a consuming\n app without one caller clobbering another's ids.\n\n MODE is the other half. Under construction is the honest state for a demo, but it is useless\n for design review — you cannot evaluate a screen through a blur. So:\n\n live what a user would see today. Every incomplete feature is obstructed.\n test every feature usable, no obstruction, all data simulated.\n\n Test mode is not a bypass of a specific gate — it is a statement about the whole build, which\n is why it is one switch and not a per-feature escape. Admins only: a member seeing test mode\n would be looking at a product that does not exist yet. */\n\n/** Runtime mode and computed feature completeness. */\nexport interface FeatureStatus {\n /** Every endpoint this feature needs is served by the real backend. */\n complete: boolean;\n /** Endpoint ids still unserved. */\n missing: string[];\n /** No requirements were declared — treated as incomplete (fails closed). */\n undeclared?: boolean;\n /** Needs no backend at all. */\n clientOnly?: boolean;\n}\nexport interface RuntimeSummary { total: number; complete: number; incomplete: number; endpointsWired: number }\n\nconst WIRED_ENDPOINTS: string[] = [\n // Nothing yet. Every id below would come from a real service:\n // \"plan.get\", \"placements.list\", …\n];\n\nconst CLIENT_ONLY: string[] = [\n // Rendered from code and the flag registry — no request, so nothing to wait for.\n \"planner.apiSpec\", \"planner.algorithm\", \"planner.roadmap\"\n];\n\n/* What each feature needs. This is the artifact that replaces `implemented` on the record: it is\n read by engineers as a checklist and by the UI as truth. Endpoint ids match the API spec.\n A feature not listed here fails closed — see status(). */\nconst FEATURE_NEEDS: Record<string, string[]> = {\n // Media Planner · brief and solve\n \"planner.setup\": [\"brief.update\"],\n \"planner.briefParse\": [\"brief.parse\"],\n \"planner.goals\": [\"goals.create\", \"goals.update\", \"goals.delete\", \"goals.review\"],\n \"planner.goalTweaks\": [\"tweaks.list\", \"goals.applyTweak\", \"tweaks.revert\", \"tweaks.refine\", \"goals.dismissTweak\"],\n \"planner.import\": [\"inventory.import\", \"inventory.mapMediaType\", \"inventory.ackWarning\", \"inventory.request\"],\n \"planner.solve\": [\"plan.solve\"],\n\n // Media Planner · plan screens\n \"planner.overview\": [\"plan.get\"],\n \"planner.attentionFlags\": [\"plan.get\"],\n \"planner.saturationDistribution\": [\"plan.get\"],\n \"planner.mixGap\": [\"plan.get\"],\n \"planner.decisionTrace\": [\"plan.model\"],\n \"planner.schools\": [\"schools.list\"],\n \"planner.reallocate\": [\"reallocate.preview\", \"reallocate.commit\"],\n \"planner.campusDetail\": [\"schools.list\", \"placements.list\"],\n \"planner.channelContribution\": [\"placements.list\"],\n \"planner.surroundSound\": [\"placements.list\"],\n \"planner.campusNudges\": [\"campus.applyRecommendation\"],\n \"planner.placements\": [\"placements.list\"],\n \"planner.placementSwap\": [\"placements.alternatives\", \"placements.swap\"],\n \"planner.savedViews\": [\"views.save\"],\n \"planner.bulkEdit\": [\"placements.update\"],\n \"planner.columnPicker\": [\"prefs.update\"],\n \"planner.groupBy\": [\"placements.list\"],\n \"planner.csvExport\": [\"placements.list\"],\n \"planner.excluded\": [\"excluded.list\"],\n \"planner.addCampus\": [\"excluded.include\"],\n \"planner.map\": [\"geo.campuses\", \"geo.states\"],\n \"planner.flights\": [\"flights.list\"],\n \"planner.flightShift\": [\"flights.shift\"],\n \"planner.scenarios\": [\"scenarios.list\", \"scenarios.matrix\"],\n \"planner.scenarioPromote\": [\"scenarios.promote\"],\n \"planner.scenarioDuplicate\": [\"scenarios.create\", \"scenarios.delete\"],\n \"planner.versions\": [\"versions.list\"],\n \"planner.versionDiff\": [\"versions.list\"],\n \"planner.versionRestore\": [\"versions.restore\"],\n \"planner.algorithmConfig\": [\"config.get\", \"config.update\", \"config.reset\"],\n \"planner.algorithmSimulate\": [\"config.simulate\"],\n\n // Media Planner · delivery\n \"planner.export\": [\"plan.get\"],\n \"planner.exportXlsx\": [\"export.xlsx\"],\n \"planner.exportPdf\": [\"export.pdf\"],\n \"planner.clientView\": [\"client.view\"],\n \"planner.clientPreview\": [\"client.view\"],\n \"planner.clientPresentation\": [\"presentation.update\"],\n \"planner.clientPlacementDetail\": [\"client.view\"],\n \"planner.shareLinks\": [\"share.list\", \"share.create\", \"share.update\", \"share.revoke\"],\n\n // Assistant\n \"planner.assistant\": [\"chat.resolveThread\", \"chat.sendMessage\", \"chat.getJob\", \"chat.getThread\"],\n \"planner.assistantApply\": [\"chat.sendMessage\", \"plan.undo\"],\n \"planner.assistantHistory\": [\"chat.listThreads\", \"chat.createThread\", \"chat.deleteThread\"],\n \"chat.agentPanel\": [\"chat.resolveThread\", \"chat.sendMessage\"],\n \"chat.attachments\": [\"chat.uploadAttachment\"],\n\n // Admin\n \"admin.users\": [\"users.list\"],\n \"admin.roles\": [\"roles.list\", \"permissions.list\"],\n \"admin.flags\": [\"flags.list\"],\n \"admin.audit\": [\"audit.list\"],\n \"admin.bulkInvite\": [\"users.invite\"],\n \"admin.ssoEnforcement\": [\"users.update\"],\n \"admin.roleEditor\": [\"roles.create\", \"roles.update\", \"roles.delete\"],\n \"admin.flagTargeting\": [\"flags.update\", \"flags.evaluate\"],\n \"admin.auditExport\": [\"audit.export\"],\n\n // Platform (college-side)\n \"platform.creativeReview\": [\"plan.get\"],\n \"platform.verification\": [\"plan.get\"]\n};\n\nconst MODE_STORE = \"fd.runtime.mode.v1\";\nconst listeners = new Set<(mode: \"live\" | \"test\") => void>();\nlet needs: Record<string, string[]> = {}; // featureKey -> endpoint ids\n\nfunction read(): \"live\" | \"test\" {\n try {\n const v = localStorage.getItem(MODE_STORE);\n return v === \"test\" || v === \"live\" ? v : \"live\";\n } catch { return \"live\"; }\n}\nfunction emit(): void { listeners.forEach((fn) => fn(mode)); }\n\nlet mode: \"live\" | \"test\" = read();\n\nexport const RuntimeKit = {\n WIRED_ENDPOINTS,\n CLIENT_ONLY,\n FEATURE_NEEDS,\n\n /** Register what each feature needs: { \"planner.flights\": [\"flights.list\", \"flights.shift\"] } */\n declare(map: Record<string, string[]>): void { needs = Object.assign({}, needs, map || {}); },\n needsOf(key: string): string[] { return needs[key] || []; },\n /** Every declared feature, for the admin surface. */\n declared(): string[] { return Object.keys(needs); },\n\n /** Tell this module which endpoints the consuming app has actually wired to a real backend.\n * Additive — merges into WIRED_ENDPOINTS, never replaces it, so multiple call sites in a\n * consuming app (or a call that runs more than once, e.g. React strict-mode double-invoke)\n * compose safely instead of one clobbering another. Call once, early, before first render:\n * status() reads WIRED_ENDPOINTS live but nothing here triggers a re-render on its own. */\n wireEndpoints(ids: string[]): void {\n (ids || []).forEach((id) => { if (WIRED_ENDPOINTS.indexOf(id) < 0) WIRED_ENDPOINTS.push(id); });\n },\n\n isEndpointWired(id: string): boolean { return WIRED_ENDPOINTS.indexOf(id) >= 0; },\n\n /** The whole point: complete is computed, never stored. */\n status(key: string): FeatureStatus {\n if (CLIENT_ONLY.indexOf(key) >= 0) return { complete: true, clientOnly: true, missing: [] };\n const req = needs[key];\n // A feature nobody declared is treated as needing a backend. Failing closed is right here:\n // an undeclared feature quietly reading as \"done\" is exactly the drift this file removes.\n if (!req || !req.length) return { complete: false, undeclared: true, missing: [] };\n const missing = req.filter((id) => WIRED_ENDPOINTS.indexOf(id) < 0);\n return { complete: missing.length === 0, missing: missing };\n },\n isComplete(key: string): boolean { return RuntimeKit.status(key).complete; },\n\n getMode(): \"live\" | \"test\" { return mode; },\n isTest(): boolean { return mode === \"test\"; },\n setMode(next: \"live\" | \"test\"): void {\n const m: \"live\" | \"test\" = next === \"test\" ? \"test\" : \"live\";\n if (m === mode) return;\n mode = m;\n try { localStorage.setItem(MODE_STORE, m); } catch { /* private mode */ }\n emit();\n },\n subscribe(fn: (mode: \"live\" | \"test\") => void): () => void { listeners.add(fn); return () => listeners.delete(fn); },\n\n /** Counts for the admin surface and the mode popover. */\n summary(): RuntimeSummary {\n const keys = Object.keys(needs).concat(CLIENT_ONLY.filter((k) => !needs[k]));\n let complete = 0;\n keys.forEach((k) => { if (RuntimeKit.isComplete(k)) complete++; });\n return { total: keys.length, complete: complete, incomplete: keys.length - complete,\n endpointsWired: WIRED_ENDPOINTS.length };\n }\n};\n\nRuntimeKit.declare(FEATURE_NEEDS);\n\nexport function useRuntimeMode(): \"live\" | \"test\" {\n const [m, setM] = React.useState<\"live\" | \"test\">(RuntimeKit.getMode());\n React.useEffect(() => RuntimeKit.subscribe(setM), []);\n return m;\n}\n/** True when this feature should be shown obstructed right now. */\nexport function useFeatureStatus(key: string): FeatureStatus & { mode: \"live\" | \"test\"; obstruct: boolean } {\n const m = useRuntimeMode();\n const st = RuntimeKit.status(key);\n return { mode: m, complete: st.complete, missing: st.missing, undeclared: !!st.undeclared,\n clientOnly: !!st.clientOnly, obstruct: m === \"live\" && !st.complete };\n}\n\n/* Capital-initial aliases: only names starting with a capital reach window.<Namespace>, so a\n consuming app destructuring these hooks from the bundle would get undefined. The lowercase\n names stay for in-bundle imports; these are what a consumer reads. */\nexport const UseRuntimeMode = useRuntimeMode;\nexport const UseFeatureStatus = useFeatureStatus;\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/* Wraps a feature that is designed and working against the simulated transport but not yet\n wired to the real backend. The point is to let people SEE what is coming without being able\n to act on it — a disabled button teaches nothing, and hiding it entirely teaches nothing\n either. So: the real UI, blurred, behind a construction banner, fully inert.\n\n Inert is enforced three ways, because any one of them alone leaks:\n pointer-events stops mouse and touch\n inert attribute removes descendants from the tab order and the a11y tree\n aria-hidden keeps screen readers out of a surface nobody can use\n The banner itself sits outside the inert subtree so it stays readable.\n\n `bypassKey` opens a deliberate exception for the people building the thing: an administrator\n can unblur and use it. That is not a hole in the gate — the gate protects users from acting on\n a surface whose writes go nowhere, and an admin already knows. The escape stays honest: a\n persistent bar remains on screen saying the data is simulated, so nobody forgets which side of\n the line they are on, and re-blurring is one click away. */\n\nconst BYPASS_STORE = \"fd.soon.bypass.v1\";\n\nfunction readBypassed(): string[] {\n try { return JSON.parse(sessionStorage.getItem(BYPASS_STORE) || \"[]\"); } catch (e) { return []; }\n}\nfunction writeBypassed(list: string[]): void {\n try { sessionStorage.setItem(BYPASS_STORE, JSON.stringify(list)); } catch (e) { /* private mode */ }\n}\n/* Session-scoped, not local: the bypass is for one working session. Persisting it across days\n would quietly become the default state and the warning would stop being read. */\nfunction useBypass(key?: string): [boolean, (next: boolean) => void] {\n const [on, setOn] = React.useState(() => !!key && readBypassed().indexOf(key) >= 0);\n React.useEffect(() => { setOn(!!key && readBypassed().indexOf(key) >= 0); }, [key]);\n const set = (next: boolean) => {\n if (!key) return;\n const list = readBypassed().filter((k) => k !== key);\n if (next) list.push(key);\n writeBypassed(list);\n setOn(next);\n };\n return [on, set];\n}\n\ninterface SoonCardProps {\n label?: string;\n detail?: string;\n backend?: string | null;\n eta?: string | null;\n effort?: string;\n onRoadmap?: () => void;\n allowed?: boolean;\n onBypass?: () => void;\n}\nfunction SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }: SoonCardProps) {\n return (\n <>\n <span className=\"fd-soon-badge\">\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n {label}\n </span>\n {detail ? <span className=\"fd-soon-detail\">{detail}</span> : null}\n {backend ? <span className=\"fd-soon-backend\"><span className=\"fd-overline\">Needs</span> {backend}</span> : null}\n {eta || effort || onRoadmap ? (\n <span className=\"fd-soon-meta\">\n {eta ? <span><i className=\"ph ph-calendar-blank\" aria-hidden=\"true\" /> {eta}</span> : null}\n {effort ? <span><i className=\"ph ph-hourglass-medium\" aria-hidden=\"true\" /> {effort}</span> : null}\n {onRoadmap ? (\n <button type=\"button\" className=\"fd-soon-link\" onClick={onRoadmap}>\n See the roadmap <i className=\"ph ph-arrow-right\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </span>\n ) : null}\n {allowed ? (\n <button type=\"button\" className=\"fd-soon-view\" onClick={onBypass}>\n <i className=\"ph ph-eye\" aria-hidden=\"true\" /> View and use it anyway\n </button>\n ) : null}\n </>\n );\n}\n\ninterface HoverCardPos {\n left: number;\n top?: number;\n bottom?: number;\n width: number;\n}\n/* The inline popover is positioned fixed from the trigger's rect, not absolutely inside it:\n these markers sit in toolbars and table rows that scroll and clip, and an absolutely\n positioned card gets cut off or drags the row's width around. */\nfunction useHoverCard(open: boolean): [React.RefObject<HTMLSpanElement>, HoverCardPos | null] {\n const anchor = React.useRef<HTMLSpanElement>(null);\n const [pos, setPos] = React.useState<HoverCardPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !anchor.current) { setPos(null); return; }\n const place = () => {\n if (!anchor.current) return;\n const r = anchor.current.getBoundingClientRect();\n const W = 340, GAP = 10, PAD = 12;\n const below = window.innerHeight - r.bottom;\n const up = below < 190 && r.top > below;\n setPos({\n left: Math.max(PAD, Math.min(r.left + r.width / 2 - W / 2, window.innerWidth - W - PAD)),\n top: up ? undefined : r.bottom + GAP,\n bottom: up ? window.innerHeight - r.top + GAP : undefined,\n width: W\n });\n };\n place();\n window.addEventListener(\"scroll\", place, true);\n window.addEventListener(\"resize\", place);\n return () => { window.removeEventListener(\"scroll\", place, true); window.removeEventListener(\"resize\", place); };\n }, [open]);\n return [anchor, pos];\n}\n\nexport interface ComingSoonProps {\n /** Banner headline. Default \"Coming soon\". */\n label?: string;\n /** Target date, already formatted for display. */\n eta?: string | null;\n /** Rough size of the remaining work, e.g. \"3 weeks\". */\n effort?: string;\n /** What has to be built on the server for this to go live. */\n backend?: string | null;\n /** One line describing the feature itself. */\n detail?: string;\n /** Blur radius in px. Default 3 — enough to stop reading, not enough to hide the shape. */\n blur?: number;\n minHeight?: number | string;\n /** \"block\" wraps a panel; \"inline\" wraps a single control (button, chip, menu item). */\n variant?: \"block\" | \"inline\";\n /** Renders a \"See the roadmap\" link when supplied. */\n onRoadmap?: () => void;\n /**\n * Flag key identifying this feature. Supply it together with `canBypass` to offer a\n * \"View and use it anyway\" escape — the choice is remembered for the session (sessionStorage,\n * not localStorage: a bypass that survives days becomes the silent default).\n */\n bypassKey?: string;\n /**\n * Whether this viewer may unblur. Gate on a permission the people building the feature hold\n * (`flags.manage`). While bypassed the feature is fully interactive, with a persistent,\n * non-dismissible bar stating that writes go to the simulated backend.\n */\n canBypass?: boolean;\n children?: React.ReactNode;\n className?: string;\n}\n\n/**\n * A feature that is designed and working but not yet wired to the real backend: the real UI,\n * blurred, behind a construction banner, and fully inert (`pointer-events`, the `inert`\n * attribute, and `aria-hidden`). Lets people see what is coming without acting on it.\n *\n * Usually reached through `FeatureGate`, which resolves the flag state for you. Use this\n * directly only when the gating decision is already made elsewhere.\n */\nexport function ComingSoon({\n label = \"Coming soon\",\n eta,\n effort,\n backend,\n detail,\n blur = 3,\n minHeight,\n /** \"block\" wraps a panel; \"inline\" wraps a single control (button, chip, menu item). */\n variant = \"block\",\n onRoadmap,\n /** Flag key. Supplying it AND `canBypass` lets the viewer unblur and use the feature. */\n bypassKey,\n canBypass = false,\n children,\n className = \"\",\n ...rest\n}: ComingSoonProps): JSX.Element {\n const [bypassed, setBypassed] = useBypass(bypassKey);\n const allowed = canBypass && !!bypassKey;\n const inline = variant === \"inline\";\n const tip = [label, detail, backend ? \"Needs \" + backend : null, eta ? \"ETA \" + eta : null, effort]\n .filter(Boolean).join(\" · \");\n\n if (inline) {\n if (allowed && bypassed) {\n return (\n <span className={[\"fd-soon-inline-on\", className].filter(Boolean).join(\" \")} {...rest}>\n {children}\n <button type=\"button\" className=\"fd-soon-cone\" title={\"Unwired — writes go to the simulated backend. \" + tip + \" Click to re-blur.\"}\n onClick={() => setBypassed(false)} aria-label=\"Re-blur this unwired feature\">\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n </button>\n </span>\n );\n }\n return (\n <InlineSoon label={label} detail={detail} backend={backend} eta={eta} effort={effort}\n onRoadmap={onRoadmap} allowed={allowed} onBypass={() => setBypassed(true)}\n blur={blur} tip={tip} className={className} rest={rest}>\n {children}\n </InlineSoon>\n );\n }\n\n if (allowed && bypassed) {\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 14 }} {...rest}>\n <div className=\"fd-soon-bar\" role=\"status\">\n <span className=\"fd-soon-badge\">\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n Unwired feature — you are using it anyway\n </span>\n <span className=\"fd-soon-bar-detail\">\n Every action here writes to the simulated backend, so nothing you do persists beyond this session.\n </span>\n <span className=\"fd-soon-bar-actions\">\n {onRoadmap ? (\n <button type=\"button\" className=\"fd-soon-link\" onClick={onRoadmap}>\n Roadmap <i className=\"ph ph-arrow-right\" aria-hidden=\"true\" />\n </button>\n ) : null}\n <button type=\"button\" className=\"fd-soon-link\" onClick={() => setBypassed(false)}>\n <i className=\"ph ph-eye-slash\" aria-hidden=\"true\" /> Re-blur\n </button>\n </span>\n </div>\n {children}\n </div>\n );\n }\n\n return (\n <div className={[\"fd-soon\", className].filter(Boolean).join(\" \")} style={minHeight ? { minHeight } : undefined} {...rest}>\n <div className=\"fd-soon-under\" style={{ filter: \"blur(\" + blur + \"px) saturate(.62)\" }} {...{ inert: \"\" } as any} aria-hidden=\"true\">\n {children}\n </div>\n <div className=\"fd-soon-veil\" />\n <div className=\"fd-soon-note\" role=\"note\">\n <SoonCard label={label} detail={detail} backend={backend} eta={eta} effort={effort}\n onRoadmap={onRoadmap} allowed={allowed} onBypass={() => setBypassed(true)} />\n </div>\n </div>\n );\n}\n\ninterface InlineSoonProps {\n label?: string;\n detail?: string;\n backend?: string | null;\n eta?: string | null;\n effort?: string;\n onRoadmap?: () => void;\n allowed?: boolean;\n onBypass?: () => void;\n blur: number;\n tip: string;\n className?: string;\n /** Leftover DOM attributes forwarded from ComingSoon's own `...rest` — untyped, same as upstream. */\n rest: any;\n children?: React.ReactNode;\n}\nfunction InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }: InlineSoonProps) {\n const [open, setOpen] = React.useState(false);\n const [anchor, pos] = useHoverCard(open);\n const close = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const show = () => {\n if (close.current) { clearTimeout(close.current); close.current = null; }\n setOpen(true);\n };\n /* A short grace period so moving the pointer from the cone into the card does not dismiss it —\n the card carries a link and a button, so it has to be reachable. */\n const hide = () => {\n if (close.current) clearTimeout(close.current);\n close.current = setTimeout(() => {\n const a = document.activeElement;\n // Focus may have moved from the cone into the card (roadmap link, bypass button) — that is\n // still \"inside\", so do not dismiss.\n if (a && (a.closest(\".fd-soon-inline\") || a.closest(\".fd-soon-hovercard\"))) return;\n setOpen(false);\n }, 140);\n };\n React.useEffect(() => () => { if (close.current) clearTimeout(close.current); }, []);\n\n return (\n <span ref={anchor} className={[\"fd-soon\", \"fd-soon-inline\", className].filter(Boolean).join(\" \")}\n onMouseEnter={show} onMouseLeave={hide} onFocus={show} onBlur={hide} {...rest}>\n <span className=\"fd-soon-under\" style={{ filter: \"blur(\" + Math.min(blur, 1.1) + \"px) saturate(.66)\" }} {...{ inert: \"\" } as any} aria-hidden=\"true\">\n {children}\n </span>\n <button type=\"button\" className=\"fd-soon-cone-mark\" aria-label={tip} title={tip}\n aria-expanded={open} onFocus={show} onBlur={hide}\n onClick={() => (open ? setOpen(false) : show())}>\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n </button>\n {open && pos ? createPortal(\n <div className=\"fd-soon-note fd-soon-hovercard\" role=\"tooltip\"\n style={{ position: \"fixed\", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width }}\n onMouseEnter={show} onMouseLeave={hide}>\n <SoonCard label={label} detail={detail} backend={backend} eta={eta} effort={effort}\n onRoadmap={onRoadmap} allowed={allowed} onBypass={onBypass} />\n </div>, document.body) : null}\n </span>\n );\n}\n\nexport function formatEta(iso?: string | null): string | null {\n if (!iso) return null;\n const d = new Date(iso + \"T00:00:00\");\n if (isNaN(d.getTime())) return iso;\n return d.toLocaleDateString(undefined, { month: \"short\", year: \"numeric\" });\n}\n\n/* Capital-initial alias: only names starting with a capital reach window.<Namespace>, so\n consuming apps could not call formatEta and were printing raw ISO dates instead. */\nexport const FormatEta = formatEta;\n","import * as React from \"react\";\nimport { SessionKit, type Flag } from \"../../kits/session\";\nimport { ComingSoon, formatEta } from \"./ComingSoon\";\nimport { useFeatureStatus } from \"../../kits/runtime\";\n\n/* Permission and feature gating. Two deliberately different failure modes:\n\n Gate — the user is not allowed. Say so, because silence reads as a bug and\n generates a support ticket. `silent` hides instead, for chrome like a\n toolbar button where an explanation would be noise.\n FeatureGate — the feature does not exist for this user, so it leaves no trace: silence,\n not an explanation, or you have leaked the roadmap. Its third state is the\n interesting one — released but not yet wired to the backend, which renders\n the real UI inert behind a coming-soon banner. */\n\nexport interface PermissionDeniedProps {\n permission?: string | string[];\n title?: string;\n detail?: string;\n compact?: boolean;\n className?: string;\n}\n/** Explains a block rather than hiding it — silence reads as a bug and files a ticket. */\nexport function PermissionDenied({ permission, title, detail, compact = false, className = \"\", ...rest }: PermissionDeniedProps) {\n const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")}\n style={{ gap: 10, alignItems: \"flex-start\", padding: compact ? \"14px 16px\" : \"28px 24px\",\n borderRadius: 10, border: \"1px dashed var(--border-strong)\", background: \"var(--surface-2)\",\n maxWidth: 560, textAlign: \"left\" }} {...rest}>\n <span className=\"fd-row\" style={{ gap: 8 }}>\n <i className=\"ph ph-lock-simple\" style={{ fontSize: 16, color: \"var(--text-muted)\" }} aria-hidden=\"true\" />\n <span className={compact ? \"fd-label-lg\" : \"fd-h3\"}>{title || \"You do not have access to this\"}</span>\n </span>\n <p className=\"fd-body-sm fd-secondary\" style={{ margin: 0, textWrap: \"pretty\" }}>\n {detail || \"Your roles do not grant this. An administrator can change that from Admin → Users.\"}\n </p>\n {need.length ? (\n <span className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\" }}>\n <span className=\"fd-overline fd-muted\">Requires</span>\n {need.map((p) => (\n <code key={p} className=\"fd-mono\" style={{ fontSize: 11.5, padding: \"2px 7px\", borderRadius: 5,\n border: \"1px solid var(--border)\", background: \"var(--surface)\" }}>{p}</code>\n ))}\n </span>\n ) : null}\n </div>\n );\n}\n\nexport interface GateProps {\n /** All of these must be held. */\n perm?: string | string[];\n /** At least one of these must be held. */\n anyOf?: string[];\n role?: string | string[];\n /** Render nothing instead of an explanation — for chrome like toolbar buttons. */\n silent?: boolean;\n fallback?: React.ReactNode;\n compact?: boolean;\n children?: React.ReactNode;\n}\n/** Permission gate. Denied by default shows PermissionDenied. */\nexport function Gate({ perm, anyOf, role, silent = false, fallback, compact = false, children }: GateProps): React.ReactNode {\n SessionKit.useSession();\n let ok = true;\n if (perm) ok = ok && SessionKit.can(perm);\n if (anyOf) ok = ok && SessionKit.canAny(anyOf);\n if (role) ok = ok && (Array.isArray(role) ? role.some(SessionKit.hasRole) : SessionKit.hasRole(role));\n if (ok) return children;\n if (fallback !== undefined) return fallback;\n if (silent) return null;\n return <PermissionDenied permission={perm || anyOf} compact={compact} />;\n}\n\nexport interface FeatureGateProps {\n flag: string;\n fallback?: React.ReactNode;\n children?: React.ReactNode;\n /** Renders a \"See the roadmap\" link inside the ComingSoon banner when supplied. */\n onRoadmap?: () => void;\n /** Blur radius in px for the underlying, inert UI. Passed through to ComingSoon. */\n blur?: number;\n minHeight?: number | string;\n /** Overrides the ComingSoon banner headline. Defaults to the flag's own label (or a generic one). */\n label?: string;\n /** \"block\" wraps a panel; \"inline\" wraps a single control (button, chip, menu item). Default \"block\". */\n variant?: \"block\" | \"inline\";\n /** When false, an incomplete-in-live-mode feature renders `fallback` instead of the ComingSoon banner. Default true. */\n preview?: boolean;\n /** Permission that lets the viewer bypass the ComingSoon veil and use the feature early. Default \"flags.manage\". */\n bypassPerm?: string;\n}\n/** Feature gate. ALWAYS silent when off — an unreleased feature should leave no trace. */\nexport function FeatureGate({ flag, fallback = null, children, onRoadmap, blur, minHeight, label,\n variant = \"block\", preview = true, bypassPerm = \"flags.manage\" }: FeatureGateProps): React.ReactNode {\n SessionKit.useSession();\n const rt = useFeatureStatus(flag);\n // Rollout, roles and per-user overrides — the only thing the flag record decides.\n if (!SessionKit.isEnabled(flag)) return fallback;\n // Test mode: the whole build is understood to be simulated, so nothing is obstructed.\n if (rt.complete || rt.mode === \"test\") return children;\n // Incomplete in live mode. `preview={false}` opts a call site out — use it where a blurred\n // panel would be worse than nothing, e.g. a single toolbar button.\n if (!preview) return fallback;\n const f: Partial<Flag> = SessionKit.findFlag(flag) || {};\n const missing = rt.missing || [];\n return (\n <ComingSoon label={label || (variant === \"inline\" ? f.label || \"Not wired yet\" : \"Designed — backend not wired yet\")}\n detail={f.description}\n backend={f.backend || (missing.length\n ? missing.length + \" endpoint\" + (missing.length === 1 ? \"\" : \"s\") + \" not yet served: \" + missing.join(\", \")\n : null)}\n variant={variant}\n eta={formatEta(f.eta)} effort={f.effort} blur={blur} minHeight={minHeight} onRoadmap={onRoadmap}\n bypassKey={flag} canBypass={!bypassPerm || SessionKit.can(bypassPerm)}>\n {children}\n </ComingSoon>\n );\n}\n\n/** Inline \"why is this disabled\" affordance for buttons that must stay visible. */\nexport function PermissionHint({ perm, children }: { perm: string | string[]; children?: React.ReactNode }): React.ReactNode {\n SessionKit.useSession();\n if (SessionKit.can(perm)) return children;\n return (\n <span title={\"Requires \" + (Array.isArray(perm) ? perm.join(\", \") : perm)}\n style={{ display: \"inline-flex\", opacity: 0.45, cursor: \"not-allowed\" }} aria-disabled=\"true\">\n <span style={{ pointerEvents: \"none\" }}>{children}</span>\n </span>\n );\n}\n","import * as React from \"react\";\nimport { RuntimeKit, useRuntimeMode } from \"../../kits/runtime\";\n\n/* The build-mode control. Lives in the header where the request log used to, because they are\n two views of one fact: what this build is talking to.\n\n live a lightning bolt. The default, and what a user would see. Clicking explains why so much\n is under construction and offers test mode.\n test a flask with a live request count. Everything is usable, nothing is obstructed, and the\n count makes it impossible to forget that every response is simulated. The same popover\n carries the request log and the way back.\n\n Admin-only by call site (`canToggle`) — a member switching to test mode would be evaluating a\n product that does not exist. When they cannot toggle, the control is not rendered at all\n rather than shown disabled: the mode is not their concern. */\n\nexport interface ModeSwitchProps {\n /** Render nothing unless true. Pass SessionKit.can(\"flags.manage\"). */\n canToggle?: boolean;\n /** Simulated requests this session — shown as a count badge in test mode. */\n requestCount?: number;\n onClearLog?: () => void;\n /** Request-log body, rendered inside the popover in test mode only. */\n renderLog?: () => React.ReactNode;\n onOpenSpec?: () => void;\n summary?: { total: number; complete: number; incomplete: number; endpointsWired: number };\n}\n/** Header control: lightning in live mode, flask + request count in test mode. */\nexport function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }: ModeSwitchProps): React.ReactNode {\n const mode = useRuntimeMode();\n const [open, setOpen] = React.useState(false);\n const ref = React.useRef<HTMLSpanElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n if (!canToggle) return null;\n\n const test = mode === \"test\";\n const s = summary || RuntimeKit.summary();\n const go = (next: \"live\" | \"test\") => { RuntimeKit.setMode(next); setOpen(false); };\n\n return (\n <span style={{ position: \"relative\", display: \"inline-flex\" }} ref={ref}>\n <button type=\"button\" onClick={() => setOpen(!open)}\n aria-label={test ? \"Test mode — \" + requestCount + \" simulated requests\" : \"Live mode\"}\n aria-expanded={open}\n title={test ? \"Test mode — every response is simulated. Click to inspect requests or return to live mode.\"\n : \"Live mode — incomplete features are shown under construction. Click for test mode.\"}\n className={\"fd-mode-btn\" + (test ? \" is-test\" : \"\") + (open ? \" is-open\" : \"\")}>\n <i className={\"ph \" + (test ? \"ph-flask\" : \"ph-lightning\")} style={{ fontSize: 17 }} />\n {test && requestCount ? (\n <span key={requestCount} className=\"fd-mono fd-mode-count\">{requestCount > 99 ? \"99+\" : requestCount}</span>\n ) : null}\n </button>\n\n {open ? (\n <span className=\"fd-view-enter fd-mode-pop\">\n <span className=\"fd-row\" style={{ gap: 10, padding: \"12px 14px\", borderBottom: \"1px solid var(--border)\" }}>\n <span className={\"fd-badge \" + (test ? \"fd-badge-warning\" : \"fd-badge-neutral\")}>\n <i className={\"ph \" + (test ? \"ph-flask\" : \"ph-lightning\")} aria-hidden=\"true\" />\n {test ? \"Test mode\" : \"Live mode\"}\n </span>\n {test ? <span className=\"fd-body-sm fd-muted fd-mono\">{requestCount} simulated request{requestCount === 1 ? \"\" : \"s\"}</span> : null}\n <span style={{ flex: 1 }} />\n {test && onClearLog ? (\n <button type=\"button\" className=\"fd-soon-link\" onClick={onClearLog}>Clear</button>\n ) : null}\n </span>\n\n <span style={{ display: \"block\", padding: \"12px 14px\", borderBottom: \"1px solid var(--border)\" }}>\n <span className=\"fd-body-sm fd-secondary\" style={{ display: \"block\", textWrap: \"pretty\" }}>\n {test\n ? \"Every feature is usable and nothing is obstructed, but no response comes from a real service — nothing you do here persists. Use this to review and demo the design.\"\n : \"This is what a user would see today. \" + s.incomplete + \" of \" + s.total + \" features depend on backend work that is not wired yet, so they render under construction.\"}\n </span>\n <span className=\"fd-row\" style={{ gap: 8, marginTop: 10, flexWrap: \"wrap\" }}>\n <span className=\"fd-body-sm fd-muted fd-mono\">\n {s.endpointsWired} endpoint{s.endpointsWired === 1 ? \"\" : \"s\"} live · {s.complete}/{s.total} features complete\n </span>\n {onOpenSpec ? (\n <>\n <span style={{ flex: 1 }} />\n <button type=\"button\" className=\"fd-soon-link\" onClick={() => { setOpen(false); onOpenSpec(); }}>\n API spec <i className=\"ph ph-arrow-right\" aria-hidden=\"true\" />\n </button>\n </>\n ) : null}\n </span>\n </span>\n\n <span className=\"fd-mode-choice\">\n <button type=\"button\" className={\"fd-mode-opt\" + (!test ? \" is-on\" : \"\")} onClick={() => go(\"live\")}>\n <i className=\"ph ph-lightning\" aria-hidden=\"true\" />\n <span className=\"fd-mode-opt-text\">\n <span className=\"fd-mode-opt-title\">Live mode</span>\n <span className=\"fd-mode-opt-desc\">Incomplete features under construction</span>\n </span>\n {!test ? <i className=\"ph ph-check\" aria-hidden=\"true\" /> : null}\n </button>\n <button type=\"button\" className={\"fd-mode-opt\" + (test ? \" is-on\" : \"\")} onClick={() => go(\"test\")}>\n <i className=\"ph ph-flask\" aria-hidden=\"true\" />\n <span className=\"fd-mode-opt-text\">\n <span className=\"fd-mode-opt-title\">Test mode</span>\n <span className=\"fd-mode-opt-desc\">Everything usable, all data simulated</span>\n </span>\n {test ? <i className=\"ph ph-check\" aria-hidden=\"true\" /> : null}\n </button>\n </span>\n\n {test && renderLog ? (\n <span style={{ display: \"block\", maxHeight: 340, overflowY: \"auto\", borderTop: \"1px solid var(--border)\" }}>\n {renderLog()}\n </span>\n ) : null}\n </span>\n ) : null}\n </span>\n );\n}\n\n/* A persistent strip for test mode. The header icon is easy to stop noticing; a bar at the top of\n the app is not. Rendered by the shell, above everything. */\nexport interface TestModeBarProps { onExit?: () => void }\n/** Persistent strip shown only in test mode. Render at the top of the app frame. */\nexport function TestModeBar({ onExit }: TestModeBarProps): React.ReactNode {\n const mode = useRuntimeMode();\n if (mode !== \"test\") return null;\n return (\n <div className=\"fd-testbar\" role=\"status\">\n <span className=\"fd-badge fd-badge-warning\">\n <i className=\"ph ph-flask\" aria-hidden=\"true\" />\n Test mode\n </span>\n <span className=\"fd-testbar-detail\">\n Every feature is unlocked and every response is simulated — nothing here persists.\n </span>\n <button type=\"button\" className=\"fd-soon-link\" onClick={() => (onExit ? onExit() : RuntimeKit.setMode(\"live\"))}>\n <i className=\"ph ph-lightning\" aria-hidden=\"true\" /> Back to live mode\n </button>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The canonical channel taxonomy. One icon and one hue per medium, used\n * everywhere a channel is named — table cells, charts, legends, filters, the\n * client view. The colour is part of the label, not decoration.\n *\n * Hue families: blues = large format, violets = moving, ambers = paper,\n * roses = direct, slate = digital.\n *\n * `physical` is a descriptive family property, NOT a weight. The model spec\n * (v2026-07-21 §4) assigns each channel its own weight from four factor scores —\n * 23 to 50, with persistence separating the tiers. Read weights from\n * window.CHANNEL_WEIGHT / MODEL.weights, never from this flag.\n */\n/* Channel weights, spec v2026-07-21 §4: weight = (visual + invasiveness) x persistence\n x social + 20. Duplicated here (not read from window.MODEL) so the component works in\n any consuming project, with or without the planner kit loaded. */\nexport const CHANNEL_WEIGHTS: Record<string, number> = {\n \"OOH\": 50, \"DOOH\": 50, \"Transit\": 48, \"Posters\": 44, \"Mobile Billboards\": 34,\n \"Flyers\": 33, \"SMS\": 26, \"Email\": 25.5, \"Print\": 24.5,\n \"Website (takeover)\": 24.5, \"Website (CPM)\": 23,\n \"Street Team\": 33, \"Print-Ribbon\": 24.5 // aliases, spec §9\n};\nconst W = CHANNEL_WEIGHTS;\n\n/** Spec §4 weight for a channel name, resolving §9 aliases. 0 = unmodeled (contributes no CRP). */\nexport function channelWeightOf(channel: string): number {\n const k = String(channel || \"\").trim();\n return W[k] != null ? W[k] : 0;\n}\n/* Capital-initial alias: only names starting with a capital reach window.<Namespace>, so a\n consuming project destructuring the lowercase form off the bundle would get undefined. */\nexport const ChannelWeightOf = channelWeightOf;\n\nexport interface ChannelMetaRecord {\n label: string;\n /** Phosphor icon name, without the `ph-` prefix. */\n icon: string;\n /** CSS custom-property reference, e.g. \"var(--ch-ooh)\". */\n color: string;\n /** Hue family: Large format | Moving | Paper | Direct | Digital | Other. */\n family: string;\n /** Descriptive family property, not a weight. Channel weights live in MODEL.weights (spec §4). */\n physical: boolean;\n name?: string;\n}\n\n/**\n * The canonical channel taxonomy — one icon and one hue per medium. Every screen\n * that names a channel reads from this, so a colour always means the same thing.\n */\nexport const CHANNELS: Record<string, ChannelMetaRecord> = {\n \"OOH\": { label: \"OOH\", icon: \"flag-banner\", color: \"var(--ch-ooh)\", family: \"Large format\", physical: true },\n \"DOOH\": { label: \"DOOH\", icon: \"television-simple\", color: \"var(--ch-dooh)\", family: \"Large format\", physical: true },\n \"Transit\": { label: \"Transit\", icon: \"bus\", color: \"var(--ch-transit)\", family: \"Moving\", physical: true },\n \"Mobile Billboards\": { label: \"Mobile\", icon: \"truck\", color: \"var(--ch-mobile)\", family: \"Moving\", physical: true },\n \"Print\": { label: \"Print\", icon: \"newspaper\", color: \"var(--ch-print)\", family: \"Paper\", physical: true },\n \"Posters\": { label: \"Posters\", icon: \"push-pin\", color: \"var(--ch-posters)\", family: \"Paper\", physical: true },\n \"Flyers\": { label: \"Flyers\", icon: \"note\", color: \"var(--ch-flyers)\", family: \"Paper\", physical: true },\n \"Email\": { label: \"Email\", icon: \"envelope-simple\", color: \"var(--ch-email)\", family: \"Direct\", physical: false },\n \"SMS\": { label: \"SMS\", icon: \"chat-centered-text\", color: \"var(--ch-sms)\", family: \"Direct\", physical: false },\n \"Website (CPM)\": { label: \"Web · CPM\", icon: \"browser\", color: \"var(--ch-web)\", family: \"Digital\", physical: false },\n \"Website (takeover)\": { label: \"Web · takeover\", icon: \"browsers\", color: \"var(--ch-web)\", family: \"Digital\", physical: false },\n \"Web\": { label: \"Web\", icon: \"browser\", color: \"var(--ch-web)\", family: \"Digital\", physical: false }\n};\n\nconst FALLBACK: ChannelMetaRecord = { label: \"Other\", icon: \"tag\", color: \"var(--ch-other)\", family: \"Other\", physical: false };\n\n/** Resolve any channel spelling (exact, lowercase key, partial) to its record. */\nexport function ChannelMeta(name?: string | null): ChannelMetaRecord {\n if (!name) return FALLBACK;\n if (CHANNELS[name]) return { ...CHANNELS[name], name };\n const k = String(name).toLowerCase().trim();\n const hit = Object.keys(CHANNELS).find((key) => key.toLowerCase() === k);\n if (hit) return { ...CHANNELS[hit], name: hit };\n // partial: \"website\", \"outdoor\", \"poster\"\n const loose = Object.keys(CHANNELS).find((key) => key.toLowerCase().startsWith(k) || k.startsWith(key.toLowerCase()));\n if (loose) return { ...CHANNELS[loose], name: loose };\n if (/web|site|display|banner/.test(k)) return { ...CHANNELS[\"Web\"], name };\n return { ...FALLBACK, label: String(name), name };\n}\n\nexport interface ChannelTagProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Channel name — \"OOH\", \"Website (CPM)\", \"transit\"… */\n channel?: string | null;\n size?: \"sm\" | \"md\";\n /** Hide the text and show icon only (dense tables). */\n showLabel?: boolean;\n /** Render as a bare colour swatch, for chart legends. */\n dot?: boolean;\n /** Append the channel's spec §4 weight after the label. */\n weight?: boolean;\n className?: string;\n}\n\n/**\n * The standard way to render a channel name. Icon + hue + label, in a tinted\n * chip. Use `dot` for a bare colour swatch in dense legends.\n */\nexport function ChannelTag({ channel, size = \"md\", showLabel = true, dot = false, weight = false, className = \"\", ...rest }: ChannelTagProps) {\n const m = ChannelMeta(channel);\n const wt = channelWeightOf(channel || \"\");\n if (dot) {\n return (\n <span className={[\"fd-chan-dot\", className].filter(Boolean).join(\" \")} title={m.name} style={{ background: m.color }} {...rest} />\n );\n }\n return (\n <span className={[\"fd-chan\", size === \"sm\" ? \"fd-chan-sm\" : \"\", className].filter(Boolean).join(\" \")}\n title={m.name + \" · \" + m.family + (wt ? \" · weight \" + wt : \" · unmodeled, 0 CRP\")}\n style={{ \"--chan\": m.color } as React.CSSProperties} {...rest}>\n <i className={\"ph ph-\" + m.icon} aria-hidden=\"true\" />\n {showLabel ? <span className=\"fd-chan-label\">{m.label}</span> : null}\n {weight ? <span className=\"fd-chan-weight\">{wt || 0}</span> : null}\n </span>\n );\n}\n","\ninterface Band {\n key: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n label: string;\n n: number;\n range: string;\n}\n\nconst BANDS: Band[] = [\n { key: \"weak\", label: \"Weak\", n: 1, range: \"< 50\" },\n { key: \"adequate\", label: \"Adequate\", n: 2, range: \"50–100\" },\n { key: \"strong\", label: \"Strong\", n: 3, range: \"100–200\" },\n { key: \"dominant\", label: \"Dominant\", n: 4, range: \"200+\" }\n];\n\n/**\n * The plan's shape: how funded campuses spread across the four CSI bands.\n * Each campus is one labelled block stacked in its band's column, so the\n * distribution reads as a silhouette before any number is parsed. Columns are\n * clickable to filter the school mix by band.\n */\nexport interface SaturationDistributionCampus {\n name: string;\n /** Short label shown inside the block, e.g. \"Michigan State\" */\n short?: string;\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n crp?: number;\n}\nexport interface SaturationDistributionProps {\n campuses: SaturationDistributionCampus[];\n /** Band of the plan-level floor score. Renders the floor explainer strip. */\n floorBand?: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n /** The plan floor figure, e.g. 157.2 */\n floorScore?: number | string;\n onSelectBand?: (band: string | null) => void;\n selectedBand?: string | null;\n loading?: boolean;\n className?: string;\n}\n\nexport function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelectBand, selectedBand, loading = false, className = \"\" }: SaturationDistributionProps) {\n const grouped = BANDS.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));\n const tallest = Math.max(1, ...grouped.map((g) => g.items.length));\n const floor = BANDS.find((b) => b.key === floorBand) || BANDS[0];\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 16 }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(4,1fr)\", gap: 12, alignItems: \"end\" }}>\n {grouped.map((g) => {\n const mark = \"var(--csi-\" + g.n + \"-mark)\";\n const active = selectedBand === g.key;\n return (\n <button key={g.key} type=\"button\" onClick={onSelectBand ? () => onSelectBand(active ? null : g.key) : undefined}\n style={{ display: \"flex\", flexDirection: \"column\", justifyContent: \"flex-end\", gap: 10, padding: 12, border: \"1px solid \" + (active ? \"var(--border-strong)\" : \"var(--border)\"), borderRadius: \"var(--r-lg)\", background: active ? \"var(--surface-2)\" : \"var(--surface)\", cursor: onSelectBand ? \"pointer\" : \"default\", textAlign: \"left\", minHeight: 190, transition: \"background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)\" }}>\n <span style={{ display: \"flex\", flexDirection: \"column-reverse\", gap: 4, minHeight: tallest * 24 }}>\n {loading\n ? Array.from({ length: 3 }).map((_, i) => <span key={i} className=\"fd-skel\" style={{ height: 16, borderRadius: 4 }} />)\n : g.items.map((c) => (\n <span key={c.name} title={c.name + \" · \" + c.crp}\n style={{ height: 18, borderRadius: 4, background: \"var(--csi-\" + g.n + \"-fill)\", border: \"1px solid var(--csi-\" + g.n + \"-edge)\", color: \"var(--csi-\" + g.n + \"-text)\", display: \"flex\", alignItems: \"center\", padding: \"0 7px\", fontSize: 10, fontWeight: 700, overflow: \"hidden\", whiteSpace: \"nowrap\" }}>\n {c.short || c.name}\n </span>\n ))}\n </span>\n <span className=\"fd-row\" style={{ gap: 8, alignItems: \"baseline\" }}>\n <span className=\"fd-num-hero\" style={{ fontSize: 30, color: g.items.length ? \"var(--text)\" : \"var(--text-disabled)\" }}>\n {loading ? \"–\" : g.items.length}\n </span>\n <span className=\"fd-meter\" style={{ gap: 2, color: mark }} aria-hidden=\"true\">\n {[1, 2, 3, 4].map((i) => <span key={i} className={\"fd-meter-seg\" + (i <= g.n ? \" is-on\" : \"\")} style={{ width: 4, height: 9 }} />)}\n </span>\n </span>\n <span className=\"fd-stack\" style={{ gap: 1 }}>\n <span className=\"fd-label-lg\">{g.label}</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontSize: 11.5 }}>CRP {g.range}</span>\n </span>\n </button>\n );\n })}\n </div>\n {floorBand ? (\n <div className=\"fd-row\" style={{ gap: 10, padding: \"12px 14px\", borderRadius: \"var(--r-md)\", background: \"var(--surface-2)\", border: \"1px solid var(--border)\", flexWrap: \"wrap\" }}>\n <span className=\"fd-meter\" style={{ gap: 2, color: \"var(--csi-\" + floor.n + \"-mark)\" }} aria-hidden=\"true\">\n {[1, 2, 3, 4].map((i) => <span key={i} className={\"fd-meter-seg\" + (i <= floor.n ? \" is-on\" : \"\")} style={{ width: 5, height: 12 }} />)}\n </span>\n <span className=\"fd-body-sm fd-secondary\" style={{ flex: 1, minWidth: 240 }}>\n <strong style={{ color: \"var(--text)\" }}>Plan floor {floorScore}</strong> — the saturation about 70% of students in this plan reach or exceed. Enrollment-weighted 30th percentile, not an average.\n </span>\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { ChannelTag } from \"./ChannelMeta\";\n\n/**\n * Realized media mix against the strategic target, one row per channel.\n * Realized is a solid brand bar, target a neutral tick on the same row, and the\n * gap is labelled directly on the bar — the gap is the story, so it never hides\n * in a legend.\n */\nexport interface MixGapRow {\n channel: string;\n /** Target share, percent */\n target: number;\n /** Realized share, percent */\n realized: number;\n /** Why the gap exists, e.g. \"Limited inventory at target campuses\" — shown in the hover tooltip. */\n note?: string;\n}\nexport interface MixGapProps {\n rows: MixGapRow[];\n loading?: boolean;\n className?: string;\n}\n\nexport function MixGap({ rows = [], loading = false, className = \"\" }: MixGapProps) {\n const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));\n const [hover, setHover] = React.useState<string | null>(null);\n const toneOf = (gap: number) => gap >= -1 ? \"ok\" : gap >= -4 ? \"warn\" : \"danger\";\n const TONE: Record<string, string> = { ok: \"var(--ok-solid)\", warn: \"var(--warn-solid)\", danger: \"var(--danger-solid)\" };\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 4 }}>\n <div className=\"fd-row\" style={{ gap: 16, justifyContent: \"flex-end\", paddingBottom: 6, flexWrap: \"wrap\" }}>\n {[[\"On target\", TONE.ok], [\"Close\", TONE.warn], [\"Short\", TONE.danger]].map(([l, c]) => (\n <span key={l} className=\"fd-row fd-body-sm fd-muted\" style={{ gap: 6 }}>\n <span style={{ width: 14, height: 9, borderRadius: 2, background: c }} />{l}\n </span>\n ))}\n <span className=\"fd-row fd-body-sm fd-muted\" style={{ gap: 6 }}>\n <span style={{ width: 3, height: 14, background: \"var(--n-500)\" }} />Target\n </span>\n </div>\n {rows.map((r) => {\n const gap = r.realized - r.target;\n const tone = toneOf(gap);\n const tip = \"Realized \" + r.realized + \"% vs \" + r.target + \"% target\" +\n (gap < -1 ? \" · \" + Math.abs(gap).toFixed(0) + \" pts short\" : gap > 1 ? \" · \" + gap.toFixed(0) + \" pts over\" : \" · on target\") +\n (r.note ? \" — \" + r.note : \"\");\n return (\n <div key={r.channel} className=\"fd-row\" style={{ gap: 12, padding: \"7px 0\", borderBottom: \"1px solid var(--border)\" }}\n onMouseEnter={() => setHover(r.channel)} onMouseLeave={() => setHover(null)}>\n <span style={{ width: 128, flex: \"none\" }}><ChannelTag channel={r.channel} size=\"sm\" /></span>\n <span style={{ position: \"relative\", flex: 1, height: 22, minWidth: 120 }}>\n {loading ? <span className=\"fd-skel\" style={{ position: \"absolute\", inset: \"5px 0\", borderRadius: 3 }} /> : <>\n <span style={{ position: \"absolute\", left: 0, top: 5, height: 12, width: (r.realized / max * 100) + \"%\", background: TONE[tone], borderRadius: \"2px 3px 3px 2px\", transition: \"width var(--dur-slow) var(--ease), background var(--dur-base) var(--ease)\" }} />\n <span style={{ position: \"absolute\", left: (r.target / max * 100) + \"%\", top: 0, width: 3, height: 22, background: \"var(--n-500)\", borderRadius: 1 }} />\n <span className=\"fd-num\" style={{ position: \"absolute\", right: Math.max(r.realized, r.target) / max > 0.82 ? 0 : \"auto\", left: Math.max(r.realized, r.target) / max > 0.82 ? \"auto\" : \"calc(\" + (Math.max(r.realized, r.target) / max * 100) + \"% + 10px)\", top: 2, fontSize: 12, color: \"var(--text-muted)\", whiteSpace: \"nowrap\", background: Math.max(r.realized, r.target) / max > 0.82 ? \"var(--surface)\" : \"none\", paddingLeft: 3 }}>{r.realized}%</span>\n {hover === r.channel ? (\n <span className=\"fd-tooltip\" role=\"tooltip\" style={{ position: \"absolute\", left: 0, right: \"auto\", bottom: 26, maxWidth: \"min(340px, 100%)\", whiteSpace: \"normal\", textAlign: \"left\", width: \"max-content\" }}>{tip}</span>\n ) : null}\n </>}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n","import { channelWeightOf, ChannelMeta, ChannelTag } from \"./ChannelMeta\";\n\nconst money = (n: number) => \"$\" + Math.round(n).toLocaleString();\n\n/**\n * How one campus's CRP was built, channel by channel, with the surround-sound\n * bonus as its own hatched segment. This is the most valuable visualization in\n * the planner: it answers why a campus scores what it scores and where the\n * headroom is.\n */\nexport interface ChannelContributionChannel {\n name: string;\n /** CRP contributed by this channel */\n crp: number;\n /** Formatted spend, e.g. \"$12,400\" */\n spend?: string;\n /** Physical formats (OOH, transit, posters) carry roughly 2x the weight of feed-based digital. */\n physical?: boolean;\n color?: string;\n}\nexport interface ChannelContributionProps {\n channels: ChannelContributionChannel[];\n /** Surround-sound bonus actually earned, as a percent of the channel base. */\n bonusPct?: number;\n /** The model's ceiling. Defaults to 40. */\n bonusMax?: number;\n /** Override the computed total when the engine's figure differs from base + bonus. */\n total?: number;\n loading?: boolean;\n showTable?: boolean;\n className?: string;\n}\n\nexport function ChannelContribution({\n channels = [], bonusPct = 0, bonusMax = 40, total, loading = false, showTable = true, className = \"\"\n}: ChannelContributionProps) {\n const base = channels.reduce((s, c) => s + c.crp, 0);\n const bonus = base * (bonusPct / 100);\n const grand = total !== undefined ? total : base + bonus;\n const pct = (v: number) => (grand ? (v / grand) * 100 : 0);\n const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, \"\")), 0);\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 16 }}>\n {loading ? <span className=\"fd-skel\" style={{ height: 34, borderRadius: \"var(--r-sm)\" }} /> : (\n <div className=\"fd-row\" style={{ height: 34, borderRadius: \"var(--r-sm)\", overflow: \"hidden\", gap: 2, background: \"var(--surface-3)\" }}>\n {channels.map((c) => (\n <span key={c.name} title={c.name + \" · \" + c.crp.toFixed(1) + \" CRP\"}\n style={{ width: pct(c.crp) + \"%\", background: c.color || ChannelMeta(c.name).color, display: \"grid\", placeItems: \"center\", fontSize: 10.5, fontWeight: 700, color: \"#fff\", overflow: \"hidden\", transition: \"width var(--dur-slow) var(--ease)\" }}>\n {pct(c.crp) > 9 ? c.crp.toFixed(0) : \"\"}\n </span>\n ))}\n {bonus > 0 ? (\n <span title={\"Surround-sound bonus +\" + bonusPct + \"%\"}\n style={{ width: pct(bonus) + \"%\", background: \"repeating-linear-gradient(135deg,var(--csi-3-mark) 0 6px,var(--csi-2-mark) 6px 12px)\", display: \"grid\", placeItems: \"center\", fontSize: 10.5, fontWeight: 700, color: \"#fff\" }}>\n {pct(bonus) > 9 ? \"+\" + bonus.toFixed(0) : \"\"}\n </span>\n ) : null}\n </div>\n )}\n\n {showTable ? (\n <table className=\"fd-table\" style={{ fontSize: \"var(--body-sm-size)\" }}>\n <thead><tr>\n <th style={{ width: \"34%\" }}>Channel</th>\n <th style={{ width: \"16%\" }}>Weight</th>\n <th className=\"is-num\" style={{ width: \"16%\" }}>Spend</th>\n <th className=\"is-num\" style={{ width: \"17%\" }}>CRP</th>\n <th className=\"is-num\" style={{ width: \"17%\" }}>Share</th>\n </tr></thead>\n <tbody>\n {channels.map((c) => (\n <tr key={c.name}>\n <td><ChannelTag channel={c.name} size=\"sm\" /></td>\n <td><span className=\"fd-badge fd-badge-neutral\" style={{ height: 20, fontSize: 11 }}\n title={\"Spec §4 channel weight\" + (c.physical ? \" · physical format\" : \"\")}>{\"weight \" + (channelWeightOf(c.name) || 0)}</span></td>\n <td className=\"is-num\">{c.spend}</td>\n <td className=\"is-num\">{c.crp.toFixed(1)}</td>\n <td className=\"is-num\">{pct(c.crp).toFixed(0)}%</td>\n </tr>\n ))}\n {bonus > 0 ? (\n <tr>\n <td><span className=\"fd-row\" style={{ gap: 9, fontWeight: 600 }}>\n <span style={{ width: 9, height: 9, borderRadius: 2, background: \"repeating-linear-gradient(135deg,var(--csi-3-mark) 0 3px,var(--csi-2-mark) 3px 6px)\", flex: \"none\" }} />\n Surround-sound bonus\n </span></td>\n <td><span className=\"fd-badge fd-badge-success\" style={{ height: 20, fontSize: 11 }}>+{bonusPct}% of +{bonusMax}%</span></td>\n <td className=\"is-num fd-muted\">—</td>\n <td className=\"is-num\">{bonus.toFixed(1)}</td>\n <td className=\"is-num\">{pct(bonus).toFixed(0)}%</td>\n </tr>\n ) : null}\n <tr style={{ background: \"var(--surface-2)\" }}>\n <td style={{ fontWeight: 700 }}>Campus total</td>\n <td />\n <td className=\"is-num\" style={{ fontWeight: 700 }}>{money(spendTotal)}</td>\n <td className=\"is-num\" style={{ fontWeight: 700 }}>{grand.toFixed(1)}</td>\n <td className=\"is-num\" style={{ fontWeight: 700 }}>100%</td>\n </tr>\n </tbody>\n </table>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { CsiBadge } from \"../data/CsiBadge\";\n\nconst bandFor = (crp: number) => crp >= 200 ? \"dominant\" : crp >= 100 ? \"strong\" : crp >= 50 ? \"adequate\" : \"weak\";\n\n/**\n * The planner's signature interaction: move budget at one campus and watch its\n * saturation band re-score live. The previewed band renders at 70% opacity with\n * a dashed edge until the change is committed; Escape reverts.\n */\nexport interface BudgetReallocatorProps {\n campus: string;\n /** Committed spend. */\n spend: number;\n /** Committed CRP. */\n crp: number;\n min?: number;\n max: number;\n /** Defaults to 100 — the same increment as an arrow-key step. */\n step?: number;\n /** The engine's re-score for a candidate spend. Required for a live preview. */\n scoreFor?: (spend: number) => number;\n onPreview?: (spend: number, crp: number) => void;\n onCommit?: (spend: number, crp: number) => void;\n onCancel?: () => void;\n className?: string;\n}\n\nexport function BudgetReallocator({\n campus, spend, crp, min = 0, max, step = 100, scoreFor,\n onPreview, onCommit, onCancel, className = \"\"\n}: BudgetReallocatorProps) {\n const [draft, setDraft] = React.useState(spend);\n React.useEffect(() => setDraft(spend), [spend]);\n const dirty = draft !== spend;\n const nextCrp = scoreFor ? scoreFor(draft) : crp;\n const nextBand = bandFor(nextCrp);\n const nowBand = bandFor(crp);\n const delta = draft - spend;\n const set = (v: number) => { setDraft(v); if (onPreview) onPreview(v, scoreFor ? scoreFor(v) : crp); };\n const pct = max === min ? 0 : ((draft - min) / (max - min)) * 100;\n const revert = () => { setDraft(spend); if (onCancel) onCancel(); };\n\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")}\n style={{ gap: 14, padding: 18, border: \"1px solid \" + (dirty ? \"var(--border-brand)\" : \"var(--border)\"), borderRadius: \"var(--r-lg)\", background: dirty ? \"var(--surface-brand)\" : \"var(--surface)\", color: \"var(--text)\", transition: \"background var(--dur-base) var(--ease),border-color var(--dur-base) var(--ease)\" }}>\n <div className=\"fd-row\" style={{ gap: 12, flexWrap: \"wrap\" }}>\n <span className=\"fd-h4\" style={{ flex: 1, minWidth: 140 }}>{campus}</span>\n <CsiBadge band={nowBand} crp={crp} size=\"medium\" />\n {dirty ? <>\n <i className=\"ph ph-arrow-right fd-muted\" aria-hidden=\"true\" />\n <CsiBadge band={nextBand} crp={nextCrp} size=\"medium\" preview />\n </> : null}\n </div>\n\n <div className=\"fd-slider\">\n <span className=\"fd-slider-fill\" style={{ width: pct + \"%\" }} />\n {dirty ? (\n <span className=\"fd-slider-chip\" style={{ left: pct + \"%\", background: delta < 0 ? \"var(--danger-solid)\" : \"var(--ok-solid)\" }}>\n {(delta < 0 ? \"−$\" : \"+$\") + Math.abs(delta).toLocaleString()}\n </span>\n ) : null}\n <input type=\"range\" min={min} max={max} step={step} value={draft}\n onChange={(e) => set(Number(e.target.value))}\n onKeyDown={(e) => { if (e.key === \"Escape\") revert(); }}\n aria-label={\"Budget at \" + campus} />\n </div>\n\n <div className=\"fd-row\" style={{ gap: 12, flexWrap: \"wrap\" }}>\n <span className=\"fd-stack\" style={{ gap: 2, flex: 1, minWidth: 150 }}>\n <span className=\"fd-num\" style={{ fontSize: 19, fontWeight: 700 }}>{\"$\" + draft.toLocaleString()}</span>\n <span className=\"fd-body-sm fd-muted\">Arrow keys step $100, shift+arrow $1,000. Escape reverts.</span>\n </span>\n <button type=\"button\" className=\"fd-btn fd-btn-ghost\" disabled={!dirty} onClick={revert}>Cancel</button>\n <button type=\"button\" className=\"fd-btn fd-btn-primary\" disabled={!dirty}\n onClick={() => { if (onCommit) onCommit(draft, nextCrp); }}>Commit reallocation</button>\n </div>\n </div>\n );\n}\n","\n// Categories mirror the canonical channel taxonomy in ChannelMeta — same icon,\n// same hue, so a colour means the same medium here as in every table.\nconst CATEGORIES = [\n { key: \"ooh\", label: \"OOH\", icon: \"flag-banner\", color: \"var(--ch-ooh)\" },\n { key: \"transit\", label: \"Transit\", icon: \"bus\", color: \"var(--ch-transit)\" },\n { key: \"posters\", label: \"Posters\", icon: \"push-pin\", color: \"var(--ch-posters)\" },\n { key: \"print\", label: \"Print\", icon: \"newspaper\", color: \"var(--ch-print)\" },\n { key: \"email\", label: \"Email\", icon: \"envelope-simple\", color: \"var(--ch-email)\" },\n { key: \"web\", label: \"Web\", icon: \"browser\", color: \"var(--ch-web)\" }\n];\n\n/**\n * Channel-diversity breadth at one campus and the bonus it earned or forgave.\n * The engine rewards reaching a campus through multiple reinforcing categories\n * with up to +40% on its score; thin-breadth campuses forgo most of it.\n */\nexport interface SurroundSoundProps {\n /** Category keys present: \"ooh\" | \"transit\" | \"posters\" | \"print\" | \"email\" | \"web\" */\n present: string[];\n /** Bonus actually earned, in points of percent. */\n bonusPct?: number;\n /** Model ceiling. Defaults to 40. */\n bonusMax?: number;\n /** One sentence naming what the missed breadth costs, e.g. \"+$3,000 into OOH earns +12%.\" */\n missedCost?: string;\n className?: string;\n}\n\nexport function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = \"\" }: SurroundSoundProps) {\n const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));\n const single = present.length <= 2;\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 14 }}>\n <div className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\" }}>\n {CATEGORIES.map((c) => {\n const on = present.includes(c.key);\n return (\n <span key={c.key} title={c.label + (on ? \" — present\" : \" — not bought\")}\n style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 5, width: 62, padding: \"10px 0\", borderRadius: \"var(--r-md)\", border: \"1px solid \" + (on ? \"var(--csi-2-edge)\" : \"var(--border)\"), background: on ? \"var(--csi-2-fill)\" : \"var(--surface-2)\", color: on ? \"var(--csi-2-text)\" : \"var(--text-disabled)\" }}>\n <i className={\"ph ph-\" + c.icon} style={{ fontSize: 19, color: on ? c.color : \"var(--text-muted)\" }} aria-hidden=\"true\" />\n <span style={{ fontSize: 10.5, fontWeight: 700 }}>{c.label}</span>\n </span>\n );\n })}\n </div>\n <div className=\"fd-stack\" style={{ gap: 8 }}>\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n <span className=\"fd-label-lg\">Surround-sound bonus earned</span>\n <span className=\"fd-num\" style={{ color: single ? \"var(--warn-text)\" : \"var(--csi-3-mark)\", fontWeight: 700 }}>\n +{bonusPct}% of +{bonusMax}%\n </span>\n </div>\n <div style={{ height: 8, borderRadius: \"var(--r-xs)\", background: \"var(--surface-3)\", overflow: \"hidden\" }}>\n <div style={{ height: \"100%\", width: (earned * 100) + \"%\", background: \"var(--csi-3-mark)\", borderRadius: \"inherit\", transition: \"width var(--dur-slow) var(--ease)\" }} />\n </div>\n <span className=\"fd-body-sm fd-secondary\" style={{ textWrap: \"pretty\" }}>\n {present.length} of 6 channel categories present.{\" \"}\n {single\n ? \"Thin breadth forgoes most of the bonus — the same dollars spread across another category score higher.\"\n : \"Students pass the same spaces daily, so reinforcing channels compound.\"}\n {missedCost ? \" \" + missedCost : \"\"}\n </span>\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { useChatEngine } from \"./chatEngine\";\nimport type { ChatAdapter, ChatMessage, Packet, PacketSchema } from \"./chatEngine\";\nimport { ChatTranscript } from \"./ChatTranscript\";\nimport { ChatComposer } from \"./ChatComposer\";\nimport { ChatSessionBar, ModelControls } from \"./ChatSessionBar\";\nimport { MenuButton } from \"../actions/Popover\";\nimport type { MenuItem } from \"../actions/Popover\";\nimport { formatRelative } from \"../data/RelativeTime\";\nimport type { Attachment } from \"../../kits/files\";\nimport type { FileUploadHandler } from \"../forms/Dropzone\";\nimport type { MeterSegmentInput } from \"../data/SegmentedMeter\";\n\nconst SURFACES: Record<string, string> = { sidebar: \"is-sidebar\", inline: \"is-inline\", page: \"is-page\", modal: \"is-modal\", sheet: \"is-sheet\" };\n\nexport interface Suggestion { id?: string; label: string; text?: string; description?: string; icon?: string }\nexport interface SlashCommand { id: string; label: string; description?: string; icon?: string; shortcut?: string; /** Send immediately on pick. */ immediate?: boolean; run?: () => void }\nexport interface MentionSource { id?: string; label: string; value?: string; description?: string; icon?: string; meta?: React.ReactNode }\nexport interface Model { id: string; label: string; description?: string; /** Key HINT only. */ shortcut?: string; group?: string; meta?: React.ReactNode; disabled?: boolean }\nexport interface ContextUsage { total: number; segments: MeterSegmentInput[]; label?: string; format?: \"count\" | \"compact\" | \"bytes\" }\nexport interface UsageLimit { id: string; label: string; percent: number; resetsAt?: string; note?: string }\nexport interface SessionStats { elapsedMs?: number; tokens?: number; runningTasks?: number; costUsd?: number; turns?: number }\nexport interface ThreadSummary { id: string; title?: string; description?: string; updatedAt?: string }\n\nexport type VoiceHandler = (controls: { onText: (text: string, meta?: { replace?: boolean }) => void; onEnd?: () => void }) => (() => void) | void;\n\nexport interface AgentChatPanelProps {\n /* required */\n contextType: string;\n contextId: string;\n apiAdapter: ChatAdapter | null;\n /** Show this exact thread instead of resolving one from context. Set it from\n * onNewThread / onSelectThread to make history switching work. */\n threadId?: string | null;\n\n /* chrome */\n title?: string;\n subtitle?: React.ReactNode;\n showHeader?: boolean;\n headerActions?: React.ReactNode;\n onClose?: () => void;\n assistantName?: string;\n userName?: string;\n assistantAvatar?: string;\n userAvatar?: string;\n /** Phosphor name for the assistant mark. Default \"sparkle\". */\n assistantIcon?: string;\n showAvatars?: boolean;\n\n /* transcript */\n markdown?: boolean;\n /** Clamp threshold before Show more. Default 600; 0 disables. */\n maxVisibleChars?: number;\n messageActions?: boolean;\n showSteps?: boolean;\n showThinking?: boolean;\n emptyTitle?: string;\n emptyDescription?: string;\n emptyIcon?: string;\n suggestions?: Array<Suggestion | string>;\n renderEmpty?: () => React.ReactNode;\n packetSchemas?: Record<string, PacketSchema>;\n packetRenderers?: Record<string, (p: Packet) => React.ReactNode>;\n onApplyPacket?: (p: Packet) => void;\n onOpenAttachment?: (a: Attachment) => void;\n /** Map a backend error code to human copy. */\n errorCopy?: (code: string) => React.ReactNode;\n\n /* composer */\n placeholder?: string;\n maxLength?: number;\n hint?: React.ReactNode;\n /** Omit and there is no attach affordance — a pasted image falls through. */\n fileUploadHandler?: FileUploadHandler;\n acceptFiles?: string;\n maxFileSize?: number;\n /** Chars above which a paste becomes a .txt attachment. Default 4000. */\n largePasteThreshold?: number;\n slashCommands?: SlashCommand[];\n mentionSources?: MentionSource[] | ((query: string) => Promise<MentionSource[]>);\n voiceHandler?: VoiceHandler;\n initialMessage?: string | null;\n\n /* session bar — supply none of these and no bar renders */\n contextUsage?: ContextUsage;\n sessionStats?: SessionStats;\n usageLimits?: UsageLimit[];\n models?: Model[];\n moreModels?: Model[];\n model?: string;\n onModelChange?: (id: string) => void;\n effortLevels?: string[];\n effort?: string;\n onEffortChange?: (level: string) => void;\n fastMode?: boolean;\n onFastModeChange?: (on: boolean) => void;\n\n /* threads */\n threads?: ThreadSummary[];\n onSelectThread?: (t: ThreadSummary) => void;\n onNewThread?: () => void;\n /** Supply to put a delete affordance on each history row. Omit and none renders. */\n onDeleteThread?: (t: ThreadSummary) => void;\n\n /* layout — behaviour is identical across all five surfaces */\n surface?: \"sidebar\" | \"inline\" | \"page\" | \"modal\" | \"sheet\";\n width?: number;\n minWidth?: number;\n maxWidth?: number;\n resizable?: boolean;\n height?: number | string;\n className?: string;\n style?: React.CSSProperties;\n\n /* events */\n onPacket?: (p: Packet) => void;\n onThreadReady?: (id: string) => void;\n onError?: (e: unknown) => void;\n onSend?: (text: string) => void;\n onClear?: () => void;\n onFeedback?: (x: { message?: ChatMessage; feedback?: string | null }) => void;\n onEditMessage?: (m: ChatMessage) => void;\n}\n\n/**\n * Agent chat panel.\n *\n * Ships no backend: without `apiAdapter` it loads nothing and says so. Every\n * optional surface — usage meters, model picker, attachments, avatars, steps —\n * renders only when its input is supplied. A panel with no telemetry shows no\n * telemetry, not zeroes.\n */\nexport function AgentChatPanel({\n /* required */\n contextType, contextId, apiAdapter,\n threadId,\n /* identity + chrome */\n title = \"Assistant\", subtitle, showHeader = true, headerActions, onClose,\n assistantName = \"Assistant\", userName = \"You\", assistantAvatar, userAvatar,\n assistantIcon = \"sparkle\", showAvatars = true,\n /* transcript */\n markdown = true, maxVisibleChars = 600, messageActions = true,\n showSteps = true, showThinking = true,\n emptyTitle, emptyDescription, emptyIcon, suggestions = [], renderEmpty,\n packetSchemas, packetRenderers, onApplyPacket, onOpenAttachment, errorCopy,\n /* composer */\n placeholder = \"Ask a question…\", maxLength, hint,\n fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold = 4000,\n slashCommands, mentionSources, voiceHandler, initialMessage,\n /* session bar */\n contextUsage, sessionStats, usageLimits,\n models, model, onModelChange, effortLevels, effort, onEffortChange,\n fastMode, onFastModeChange, moreModels,\n /* threads */\n threads, onSelectThread, onNewThread, onDeleteThread,\n /* layout */\n surface = \"sidebar\", width = 420, minWidth = 340, maxWidth = 760, resizable = true,\n height, className = \"\", style,\n /* events */\n onPacket, onThreadReady, onError, onSend, onClear, onFeedback, onEditMessage,\n}: AgentChatPanelProps) {\n const [panelWidth, setPanelWidth] = React.useState(width);\n const [applied, setApplied] = React.useState<Record<string, boolean>>({});\n const [draft, setDraft] = React.useState(\"\");\n const dragging = React.useRef<{ x: number; w: number } | null>(null);\n React.useEffect(() => setPanelWidth(width), [width]);\n\n const engine = useChatEngine({\n contextType, contextId, apiAdapter, initialMessage, threadId,\n onPacket, onThreadReady, onError, onSend, onClear, onFeedback,\n });\n\n /* resize (sidebar only) — pointer events so it works with touch and pen */\n const startDrag = (e: React.PointerEvent) => {\n if (!resizable) return;\n e.preventDefault();\n dragging.current = { x: e.clientX, w: panelWidth };\n const move = (ev: PointerEvent) => {\n if (!dragging.current) return;\n const dx = dragging.current.x - ev.clientX;\n setPanelWidth(Math.max(minWidth, Math.min(maxWidth, dragging.current.w + dx)));\n };\n const up = () => {\n dragging.current = null;\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n document.body.style.userSelect = \"\";\n };\n document.body.style.userSelect = \"none\";\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n };\n\n const narrow = surface === \"sidebar\" ? panelWidth < 420 : surface === \"sheet\";\n\n const ctx = {\n assistantName, userName, assistantAvatar, userAvatar, assistantIcon, showAvatars,\n markdown, maxVisibleChars, messageActions, showSteps, showThinking,\n packetSchemas, packetRenderers, appliedPackets: applied, narrow,\n onOpenAttachment, errorCopy,\n onRetry: engine.retry,\n onFeedback: (id: string, v: \"up\" | \"down\") => engine.setFeedback(id, v),\n onEdit: (m: ChatMessage) => { setDraft(m.text || \"\"); onEditMessage && onEditMessage(m); },\n onApplyPacket: onApplyPacket ? (p: Packet) => {\n const carrier = [...engine.visible].reverse().find((m) => m.packet === p);\n if (carrier) setApplied((a) => Object.assign({}, a, { [carrier.id]: true }));\n onApplyPacket(p);\n } : undefined,\n onReconnect: engine.reload,\n deadTitle: \"The assistant isn’t reachable\",\n };\n\n const sessionBar = (\n <ChatSessionBar\n sessionStats={sessionStats} contextUsage={contextUsage} usageLimits={usageLimits}\n onClear={engine.visible.length ? engine.clear : undefined}\n />\n );\n\n const modelControls = (\n <ModelControls\n models={models} model={model} onModelChange={onModelChange}\n effortLevels={effortLevels} effort={effort} onEffortChange={onEffortChange}\n fastMode={fastMode} onFastModeChange={onFastModeChange} moreModels={moreModels}\n narrow={narrow}\n />\n );\n\n const threadMenu = threads && threads.length ? (\n <MenuButton\n variant=\"ghost\" icon=\"clock-counter-clockwise\" trailingIcon={null} placement=\"bottom-end\"\n ariaLabel=\"Conversation history\" title=\"History\" minWidth={300}\n items={([{ kind: \"section\", label: \"Recent\" }] as MenuItem[]).concat(threads.map((t) => ({\n id: t.id, label: t.title || \"Untitled\",\n description: t.updatedAt ? formatRelative(t.updatedAt) : t.description,\n checked: t.id === engine.threadId,\n onSelect: () => onSelectThread && onSelectThread(t),\n /* Delete sits on the row rather than behind a submenu, so removing a stale thread is\n one gesture. Only offered when the host can actually persist it. */\n trailingAction: onDeleteThread ? {\n icon: \"trash\", label: \"Delete “\" + (t.title || \"Untitled\") + \"”\", danger: true,\n onSelect: () => onDeleteThread(t)\n } : undefined,\n })))}\n />\n ) : null;\n\n return (\n <aside\n className={[\"fdc-panel\", SURFACES[surface] || SURFACES.sidebar, narrow ? \"is-narrow\" : \"\", className].filter(Boolean).join(\" \")}\n style={{\n ...(surface === \"sidebar\" ? { width: panelWidth } : {}),\n ...(height ? { height } : {}),\n ...style,\n }}\n aria-label={title}\n >\n {surface === \"sidebar\" && resizable ? (\n <div\n className=\"fdc-grip\" onPointerDown={startDrag} role=\"separator\"\n aria-orientation=\"vertical\" aria-label=\"Resize panel\" tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"ArrowLeft\") setPanelWidth((w) => Math.min(maxWidth, w + 24));\n if (e.key === \"ArrowRight\") setPanelWidth((w) => Math.max(minWidth, w - 24));\n }}\n />\n ) : null}\n\n {showHeader ? (\n <header className=\"fdc-head\">\n <span className=\"fdc-head-mark\" aria-hidden=\"true\"><i className={\"ph ph-\" + assistantIcon} /></span>\n <span className=\"fdc-head-titles\">\n <span className=\"fdc-head-title\">{title}</span>\n {subtitle ? <span className=\"fdc-head-sub\">{subtitle}</span> : null}\n </span>\n <span className=\"fdc-head-acts\">\n {headerActions}\n {threadMenu}\n {onNewThread ? (\n <button type=\"button\" className=\"fdc-iconbtn\" onClick={onNewThread} aria-label=\"New conversation\" title=\"New conversation\">\n <i className=\"ph ph-plus\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {onClose ? (\n <button type=\"button\" className=\"fdc-iconbtn\" onClick={onClose} aria-label=\"Close panel\" title=\"Close\">\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </span>\n </header>\n ) : null}\n\n <ChatTranscript\n messages={engine.visible} ctx={ctx} status={engine.status} fatal={engine.fatal}\n suggestions={suggestions} onPick={(t) => engine.send(t as string)}\n emptyTitle={emptyTitle} emptyDescription={emptyDescription} emptyIcon={emptyIcon}\n renderEmpty={renderEmpty}\n />\n\n <ChatComposer\n onSubmit={(text, atts) => engine.send(text, atts)}\n onStop={engine.stop}\n busy={engine.busy}\n disabled={engine.status === \"disconnected\" || engine.status === \"idle\"}\n placeholder={placeholder} maxLength={maxLength} hint={hint}\n fileUploadHandler={fileUploadHandler} acceptFiles={acceptFiles}\n maxFileSize={maxFileSize} largePasteThreshold={largePasteThreshold}\n slashCommands={slashCommands} mentionSources={mentionSources} voiceHandler={voiceHandler}\n queue={engine.queue} onRemoveQueued={engine.removeQueued}\n sessionBar={sessionBar} toolbarExtras={modelControls}\n onOpenAttachment={onOpenAttachment}\n draft={draft} onDraftChange={setDraft} narrow={narrow}\n />\n </aside>\n );\n}\n","import * as React from \"react\";\nimport type { Attachment } from \"../../kits/files\";\nimport type { Step } from \"../data/StepList\";\n\n/**\n * Chat state machine. Framework-shaped as a React hook, but the rules it encodes\n * are the portable part: thread resolution, serial sending, escalation polling,\n * recovery, abort semantics and retry truncation.\n *\n * It ships no HTTP client. Without an adapter it resolves nothing and renders\n * nothing — every app's proxy differs in auth, routing and host.\n */\n\n/* ── types ────────────────────────────────────────────────────────────────── */\n\n/** Tri-state `valid`: only an explicit false blocks Apply. */\nexport interface Citation { id?: string; marker?: string | number; title?: string; url?: string; detail?: string }\n\n/** Tri-state `valid`: only an explicit false blocks Apply. */\nexport interface Packet { type: string; payload: unknown; valid?: boolean; error?: string; repaired?: boolean }\nexport interface PacketSchema { heading?: string; icon?: string; applyLabel?: string }\n\nexport interface JobStatus {\n id?: string;\n /** queued | running keep polling · completed | recovered are success · anything else fails loudly. */\n status: string;\n detail?: string;\n error?: string;\n}\n\nexport interface ChatMessage {\n id: string;\n role: \"user\" | \"assistant\" | \"system\";\n text?: string | null;\n packet?: Packet | null;\n /** Escalation in flight. */\n working?: boolean;\n /** Tokens arriving — renders a live caret. */\n streaming?: boolean;\n /** Optimistic, not yet confirmed. */\n pending?: boolean;\n /** The turn was stopped by the user. */\n stopped?: boolean;\n jobId?: string;\n job?: JobStatus;\n error?: string;\n retryable?: boolean;\n timestamp?: string;\n author?: string;\n steps?: Step[];\n citations?: Citation[];\n attachments?: Attachment[];\n thinking?: string;\n thinkingMs?: number;\n feedback?: \"up\" | \"down\" | null;\n model?: string;\n usage?: unknown;\n resumed?: boolean;\n metadata?: { type?: string; [k: string]: unknown };\n}\n\nexport interface SendMessageResult {\n /** true = escalated to a background job. */\n dispatched?: boolean;\n job_id?: string;\n reply?: string | null;\n packet?: Packet;\n steps?: Step[];\n citations?: Citation[];\n usage?: unknown;\n model?: string;\n}\n\nexport interface StreamHandlers {\n /** Chunks APPEND, never replace. */\n onToken(chunk: string): void;\n onStep?(step: Step): void;\n onThinking?(chunk: string): void;\n}\n\n/**\n * The app-supplied backend. There is no default: every proxy differs in auth,\n * routing and host. Reject with the backend's stable error code as the message —\n * the panel matches codes by exact equality, never substring sniffing.\n */\nexport interface ChatAdapter {\n resolveThread(ctx: { contextType: string; contextId: string }): Promise<{ thread_id: string | null }>;\n getThread(threadId: string): Promise<{ messages: ChatMessage[] }>;\n sendMessage(threadId: string, text: string, signal?: AbortSignal, attachments?: Attachment[]): Promise<SendMessageResult>;\n getJob(jobId: string): Promise<JobStatus>;\n /** Preferred when present. */\n streamMessage?(threadId: string, text: string, handlers: StreamHandlers, signal: AbortSignal, attachments?: Attachment[]): Promise<SendMessageResult>;\n /** Cancels upstream only. It must not gate whether Stop appears. */\n cancelJob?(jobId: string): Promise<void>;\n}\n\nexport interface ChatEngineOptions {\n contextType: string;\n contextId: string;\n apiAdapter?: ChatAdapter | null;\n initialMessage?: string | null;\n threadId?: string | null;\n pollIntervalMs?: number;\n pollMaxAttempts?: number;\n store?: { get(k: string): string | null; set(k: string, v: string): void; del(k: string): void };\n onPacket?: (p: Packet) => void;\n onThreadReady?: (id: string) => void;\n onError?: (e: unknown) => void;\n onSend?: (text: string) => void;\n onClear?: () => void;\n onFeedback?: (x: { message?: ChatMessage; feedback?: string | null }) => void;\n}\n\nexport interface QueuedTurn { id: string; text: string; attachments?: Attachment[] }\n\nexport interface ChatEngine {\n status: \"idle\" | \"resolving\" | \"loading\" | \"ready\" | \"disconnected\";\n threadId: string | null;\n messages: ChatMessage[];\n visible: ChatMessage[];\n queue: QueuedTurn[];\n busy: boolean;\n fatal: string | null;\n turnStartedAt: number | null;\n send(text: string, attachments?: Attachment[]): void;\n stop(): void;\n retry(): void;\n clear(): void;\n removeQueued(id: string): void;\n setFeedback(id: string, value: \"up\" | \"down\"): void;\n reload(): Promise<void>;\n canSend: boolean;\n}\n\n/* ── constants / helpers ──────────────────────────────────────────────────── */\n\nexport const CHAT_UNAVAILABLE = \"chat_unavailable\";\nconst JOB_PENDING = [\"queued\", \"running\"];\nconst JOB_SUCCESS = [\"completed\", \"recovered\"]; // `recovered` IS success\nconst STORAGE_PREFIX = \"fdchat:job:\";\n\nlet seq = 0;\nconst uid = (p: string) => p + \"_\" + (++seq) + \"_\" + Date.now().toString(36);\nconst sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\ntype Store = { get(k: string): string | null; set(k: string, v: string): void; del(k: string): void };\n\n/** sessionStorage that cannot throw — private-mode browsers expose it and throw on use. */\nconst safeStore: Store = {\n get(k) { try { return window.sessionStorage.getItem(k); } catch (e) { return null; } },\n set(k, v) { try { window.sessionStorage.setItem(k, v); } catch (e) { /* noop */ } },\n del(k) { try { window.sessionStorage.removeItem(k); } catch (e) { /* noop */ } },\n};\n\nexport const isSystemMessage = (m: ChatMessage | null | undefined): boolean =>\n !!m && (m.role === \"system\" || (m.metadata != null && m.metadata.type === \"system\"));\nexport const visibleMessages = (list: ChatMessage[] | null | undefined): ChatMessage[] =>\n (list || []).filter((m) => !isSystemMessage(m));\n\nexport function jobBucket(status?: string): \"pending\" | \"success\" | \"failure\" {\n const s = String(status || \"\").toLowerCase();\n if (JOB_PENDING.indexOf(s) !== -1) return \"pending\";\n if (JOB_SUCCESS.indexOf(s) !== -1) return \"success\";\n return \"failure\"; // including anything unrecognised\n}\n\n/* An AbortController-shaped fallback for environments without one — its `signal`\n is deliberately undefined; callers that require a real AbortSignal cast it. */\ntype AbortLike = AbortController | { abort(): void; signal?: undefined };\n\nexport function useChatEngine(opts: ChatEngineOptions): ChatEngine {\n const {\n contextType, contextId, apiAdapter, initialMessage, threadId: threadIdProp,\n pollIntervalMs = 1500, pollMaxAttempts = 120, store = safeStore,\n onPacket, onThreadReady, onError, onSend, onClear, onFeedback,\n } = opts || ({} as ChatEngineOptions);\n\n const [status, setStatus] = React.useState<ChatEngine[\"status\"]>(\"idle\"); // idle|resolving|loading|ready|disconnected\n const [threadId, setThreadId] = React.useState<string | null>(null);\n const [messages, setMessages] = React.useState<ChatMessage[]>([]);\n const [queue, setQueue] = React.useState<QueuedTurn[]>([]);\n const [fatal, setFatal] = React.useState<string | null>(null);\n const [busy, setBusy] = React.useState(false);\n const [turnStartedAt, setTurnStartedAt] = React.useState<number | null>(null);\n\n const listRef = React.useRef<ChatMessage[]>([]);\n const queueRef = React.useRef<QueuedTurn[]>([]);\n const busyRef = React.useRef(false);\n const stoppedRef = React.useRef(false);\n const abortRef = React.useRef<AbortLike | null>(null);\n const serverCount = React.useRef(0);\n const threadRef = React.useRef<string | null>(null);\n const mounted = React.useRef(true);\n\n // React 18 Strict Mode double-invokes this effect in dev (mount, cleanup, remount)\n // without discarding the ref, so the cleanup alone leaves `mounted.current` stuck\n // false forever unless the body also resets it true — without this, every commit()\n // after the phantom unmount is silently dropped and the transcript never renders.\n React.useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n\n const commit = (next: ChatMessage[]) => { listRef.current = next; if (mounted.current) setMessages(next); };\n const patch = (id: string, p: Partial<ChatMessage> | ((m: ChatMessage) => Partial<ChatMessage>)) =>\n commit(listRef.current.map((m) => (m.id === id ? Object.assign({}, m, typeof p === \"function\" ? p(m) : p) : m)));\n const push = (...msgs: ChatMessage[]) => commit(listRef.current.concat(msgs));\n\n const fail = (err: unknown): boolean => {\n const code = ((err as { message?: string })?.message) || String(err || \"error\");\n onError && onError(err);\n if (code === CHAT_UNAVAILABLE) { setStatus(\"disconnected\"); setFatal(code); return true; }\n return false;\n };\n\n /* ── thread lifecycle ─────────────────────────────────────────────────── */\n\n const loadThread = React.useCallback(async (id: string): Promise<ChatMessage[]> => {\n const data = await apiAdapter!.getThread(id);\n // Copy: an adapter may hand back a live store array, and this panel pushes\n // optimistic messages onto its list. Aliasing it double-renders every turn.\n const list = [...((data && data.messages) || [])];\n serverCount.current = list.length;\n commit(list);\n return list;\n }, [apiAdapter]);\n\n React.useEffect(() => {\n if (!apiAdapter) {\n // No adapter: load nothing, show nothing. Drop anything a previous adapter left.\n setStatus(\"idle\"); setFatal(null);\n commit([]); queueRef.current = []; setQueue([]); serverCount.current = 0;\n return;\n }\n let dead = false;\n // Abandon anything in flight for the thread we are leaving.\n if (abortRef.current) { try { abortRef.current.abort(); } catch (e) { /* already settled */ } abortRef.current = null; }\n busyRef.current = false; setBusy(false); setTurnStartedAt(null);\n queueRef.current = []; setQueue([]);\n stoppedRef.current = false;\n setStatus(\"resolving\"); setFatal(null);\n (async () => {\n try {\n // An explicit id wins: the host has already created or picked the thread.\n const id = threadIdProp || await (async () => {\n const res = await apiAdapter.resolveThread({ contextType, contextId });\n return res && res.thread_id;\n })();\n if (dead) return;\n if (!id) { setStatus(\"disconnected\"); setFatal(CHAT_UNAVAILABLE); return; }\n threadRef.current = id; setThreadId(id);\n setStatus(\"loading\");\n await loadThread(id);\n if (dead) return;\n setStatus(\"ready\");\n onThreadReady && onThreadReady(id);\n const stored = store.get(STORAGE_PREFIX + id);\n if (stored) resumeJob(stored); // escalation survives remount\n else if (initialMessage) send(initialMessage);\n } catch (err) {\n if (dead) return;\n if (!fail(err)) { setStatus(\"disconnected\"); setFatal(((err as { message?: string })?.message) || \"load_failed\"); }\n }\n })();\n return () => { dead = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [apiAdapter, contextType, contextId, threadIdProp]);\n\n /* ── job polling ──────────────────────────────────────────────────────── */\n\n async function pollJob(jobId: string, placeholderId: string): Promise<void> {\n store.set(STORAGE_PREFIX + threadRef.current, jobId);\n let attempts = 0;\n while (attempts++ < pollMaxAttempts) {\n if (stoppedRef.current) break;\n await sleep(pollIntervalMs);\n if (!mounted.current) return;\n let job: JobStatus | undefined;\n try {\n job = await apiAdapter!.getJob(jobId);\n } catch (err) {\n // A job can succeed, write its result, then age out of the registry — so\n // the next poll 404s even though the work landed. Check the thread first.\n const landed = await didResultLand();\n if (landed) { finishJob(jobId); return; }\n recordFailure(placeholderId, ((err as { message?: string })?.message) || \"job_unavailable\", true);\n return;\n }\n patch(placeholderId, { job });\n const bucket = jobBucket(job && job.status);\n if (bucket === \"pending\") continue;\n if (bucket === \"success\") {\n finishJob(jobId, job);\n return;\n }\n recordFailure(placeholderId, (job && (job.error || job.status)) || \"job_failed\", true, job);\n return;\n }\n if (!stoppedRef.current) recordFailure(placeholderId, \"timeout\", true);\n }\n\n async function didResultLand(): Promise<boolean> {\n const before = serverCount.current;\n try {\n const list = await loadThread(threadRef.current!);\n return list.length > before; // count, not object identity\n } catch (e) { return false; }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- signature mirrors both call sites (pollJob success, and the post-getJob-404 recovery path)\n async function finishJob(_jobId: string, _job?: JobStatus): Promise<void> {\n store.del(STORAGE_PREFIX + threadRef.current);\n try {\n const list = await loadThread(threadRef.current!);\n const withPacket = [...list].reverse().find((m) => m && m.packet);\n if (withPacket && onPacket && withPacket.packet) onPacket(withPacket.packet);\n } catch (err) { fail(err); }\n }\n\n function recordFailure(placeholderId: string, code: string, retryable: boolean, job?: JobStatus): void {\n store.del(STORAGE_PREFIX + threadRef.current);\n // A recovery reload replaces the whole list and can detach the placeholder.\n // Re-attach it by id, or the error lands on an object nothing renders.\n if (!listRef.current.some((m) => m.id === placeholderId)) {\n push({ id: placeholderId, role: \"assistant\", text: null });\n }\n patch(placeholderId, { working: false, streaming: false, error: code, retryable: !!retryable, job: job || undefined });\n onError && onError(new Error(code));\n }\n\n function resumeJob(jobId: string): void {\n const id = uid(\"a\");\n push({ id, role: \"assistant\", working: true, jobId, resumed: true });\n setBusy(true); busyRef.current = true; setTurnStartedAt(Date.now());\n pollJob(jobId, id).finally(() => { busyRef.current = false; setBusy(false); setTurnStartedAt(null); });\n }\n\n /* ── sending ──────────────────────────────────────────────────────────── */\n\n async function dispatchTurn(turn: QueuedTurn): Promise<void> {\n const id = threadRef.current;\n if (!id) return;\n busyRef.current = true; setBusy(true); setTurnStartedAt(Date.now());\n const userId = uid(\"u\");\n const holderId = uid(\"a\");\n push(\n { id: userId, role: \"user\", text: turn.text || null, attachments: turn.attachments, pending: true, timestamp: new Date().toISOString() },\n { id: holderId, role: \"assistant\", text: \"\", streaming: !!apiAdapter!.streamMessage, working: !apiAdapter!.streamMessage, timestamp: new Date().toISOString() },\n );\n const ac: AbortLike = typeof AbortController !== \"undefined\" ? new AbortController() : { abort() {}, signal: undefined };\n abortRef.current = ac;\n onSend && onSend(turn.text);\n\n try {\n let res: SendMessageResult | undefined;\n if (apiAdapter!.streamMessage) {\n res = await apiAdapter!.streamMessage(id, turn.text, {\n onToken: (chunk: string) => patch(holderId, (m) => ({ text: (m.text || \"\") + chunk, streaming: true })), // chunks append\n onStep: (step) => patch(holderId, (m) => {\n const steps = (m.steps || []).slice();\n const at = steps.findIndex((s) => s.id === step.id);\n if (at === -1) steps.push(step); else steps[at] = Object.assign({}, steps[at], step);\n return { steps };\n }),\n onThinking: (chunk: string) => patch(holderId, (m) => ({ thinking: (m.thinking || \"\") + chunk })),\n }, ac.signal as AbortSignal, turn.attachments && turn.attachments.length ? turn.attachments : undefined);\n } else if (turn.attachments && turn.attachments.length) {\n res = await apiAdapter!.sendMessage(id, turn.text, ac.signal, turn.attachments);\n } else {\n res = await apiAdapter!.sendMessage(id, turn.text, ac.signal); // same three args as always\n }\n\n patch(userId, { pending: false });\n const r: SendMessageResult = res || {};\n if (r.dispatched && r.job_id) {\n patch(holderId, { streaming: false, working: true, jobId: r.job_id, text: r.reply || \"\" });\n await pollJob(r.job_id, holderId);\n } else {\n patch(holderId, {\n streaming: false, working: false,\n text: r.reply != null ? r.reply : listRef.current.find((m) => m.id === holderId)?.text || \"\",\n packet: r.packet, steps: r.steps || listRef.current.find((m) => m.id === holderId)?.steps,\n citations: r.citations, usage: r.usage, model: r.model,\n timestamp: new Date().toISOString(),\n });\n serverCount.current += 2;\n if (r.packet && onPacket) onPacket(r.packet);\n }\n } catch (err) {\n const aborted = (err && ((err as { name?: string }).name === \"AbortError\" || (err as { message?: string }).message === \"aborted\")) || stoppedRef.current;\n patch(userId, { pending: false });\n if (aborted) {\n patch(holderId, (m) => ({ streaming: false, working: false, stopped: true, retryable: true, text: m.text || null }));\n } else if (!fail(err)) {\n patch(holderId, { streaming: false, working: false, error: ((err as { message?: string })?.message) || \"send_failed\", retryable: true });\n } else {\n commit(listRef.current.filter((m) => m.id !== holderId));\n }\n } finally {\n abortRef.current = null;\n busyRef.current = false; setBusy(false); setTurnStartedAt(null);\n }\n }\n\n async function drain(): Promise<void> {\n if (busyRef.current) return;\n while (queueRef.current.length) {\n if (stoppedRef.current) return; // Stop halts the pipeline, not just the request\n const turn = queueRef.current[0];\n queueRef.current = queueRef.current.slice(1);\n setQueue(queueRef.current.slice());\n await dispatchTurn(turn);\n }\n }\n\n const send = React.useCallback((text: string, attachments?: Attachment[]) => {\n const body = (text || \"\").trim();\n if (!body && !(attachments && attachments.length)) return; // nothing to send\n if (status === \"disconnected\") return;\n const turn: QueuedTurn = { id: uid(\"q\"), text: body, attachments: attachments && attachments.length ? attachments.slice() : undefined };\n queueRef.current = queueRef.current.concat(turn);\n setQueue(queueRef.current.slice());\n stoppedRef.current = false; // a fresh send always resets the flag\n drain();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n const stop = React.useCallback(() => {\n stoppedRef.current = true;\n const ac = abortRef.current;\n if (ac) { try { ac.abort(); } catch (e) { /* noop */ } }\n const holder = [...listRef.current].reverse().find((m) => m.working || m.streaming);\n if (holder) {\n patch(holder.id, (m) => ({ working: false, streaming: false, stopped: true, retryable: true, text: m.text || null }));\n if (holder.jobId && apiAdapter && apiAdapter.cancelJob) {\n // cancelJob gates only the upstream cancel — never the Stop button itself.\n Promise.resolve(apiAdapter.cancelJob(holder.jobId)).catch(() => {});\n }\n store.del(STORAGE_PREFIX + threadRef.current);\n }\n // The queue is text the user typed: leave it standing, visible and removable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [apiAdapter]);\n\n const removeQueued = React.useCallback((id: string) => {\n queueRef.current = queueRef.current.filter((t) => t.id !== id);\n setQueue(queueRef.current.slice());\n }, []);\n\n const retry = React.useCallback(() => {\n const list = listRef.current;\n let at = -1;\n for (let i = list.length - 1; i >= 0; i--) if (list[i].role === \"user\") { at = i; break; }\n if (at === -1) return;\n const turn = list[at];\n commit(list.slice(0, at)); // a retry reads as one attempt, not a pile\n serverCount.current = Math.max(0, serverCount.current - 1);\n stoppedRef.current = false;\n queueRef.current = ([{ id: uid(\"q\"), text: turn.text || \"\", attachments: turn.attachments }] as QueuedTurn[]).concat(queueRef.current);\n setQueue(queueRef.current.slice());\n drain();\n }, []);\n\n const clear = React.useCallback(() => {\n commit([]); serverCount.current = 0;\n queueRef.current = []; setQueue([]);\n onClear && onClear();\n }, [onClear]);\n\n const setFeedback = React.useCallback((id: string, value: \"up\" | \"down\") => {\n patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));\n const msg = listRef.current.find((m) => m.id === id);\n onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [onFeedback]);\n\n const reload = React.useCallback(async () => {\n if (!threadRef.current) return;\n setStatus(\"loading\");\n try { await loadThread(threadRef.current!); setStatus(\"ready\"); }\n catch (err) { if (!fail(err)) setStatus(\"ready\"); }\n }, [loadThread]);\n\n return {\n status, threadId, messages, visible: visibleMessages(messages), queue,\n busy, fatal, turnStartedAt,\n send, stop, retry, clear, removeQueued, setFeedback, reload,\n canSend: status === \"ready\",\n };\n}\n\n/**\n * Namespace export. The bundle exposes only capital-initial names, so this is how a\n * consuming project reaches the state machine to build its own shell:\n *\n * const { useChatEngine } = window.<Namespace>.ChatKit;\n * const chat = useChatEngine({ contextType, contextId, apiAdapter });\n */\nexport const ChatKit = {\n useChatEngine,\n visibleMessages,\n isSystemMessage,\n jobBucket,\n CHAT_UNAVAILABLE,\n};\n","import * as React from \"react\";\nimport { ChatTurn } from \"./ChatTurn\";\nimport type { ChatRenderContext, MessageGroup } from \"./ChatTurn\";\nimport type { ChatMessage } from \"./chatEngine\";\nimport type { Suggestion } from \"./AgentChatPanel\";\n\nconst GROUP_WINDOW = 60e3;\nconst STICK_PX = 100;\n\n/** Consecutive messages from one sender inside 60s share a head. Anything\n * carrying a packet, steps or an error always starts its own group. */\nexport function groupMessages(list: ChatMessage[]): MessageGroup[] {\n const groups: Array<MessageGroup & { t: number | null }> = [];\n (list || []).forEach((m) => {\n const solo = !!(m.packet || (m.steps && m.steps.length) || m.error || m.working || m.stopped);\n const prev = groups[groups.length - 1];\n const t = m.timestamp ? Date.parse(m.timestamp) : null;\n const close = prev && prev.t != null && t != null ? Math.abs(t - prev.t) < GROUP_WINDOW : !!prev;\n if (prev && !prev.solo && !solo && prev.role === m.role && (prev.author || \"\") === (m.author || \"\") && close) {\n prev.messages.push(m);\n prev.t = t == null ? prev.t : t;\n return;\n }\n groups.push({ role: m.role, author: m.author, messages: [m], t, solo, key: m.id });\n });\n return groups;\n}\n\nconst dayKey = (iso: string | undefined): string | null => {\n const d = iso ? new Date(iso) : null;\n return d && !isNaN(d.getTime()) ? d.toDateString() : null;\n};\n\nfunction dayLabel(key: string): string {\n const d = new Date(key);\n const today = new Date().toDateString();\n const yest = new Date(Date.now() - 864e5).toDateString();\n if (key === today) return \"Today\";\n if (key === yest) return \"Yesterday\";\n return d.toLocaleDateString([], { weekday: \"long\", day: \"numeric\", month: \"long\" });\n}\n\nfunction Suggestions({ items = [], onPick }: { items?: Array<Suggestion | string>; onPick?: (s: Suggestion | string) => void }) {\n if (!items.length) return null;\n return (\n <div className=\"fdc-suggest\">\n {items.map((s, i) => {\n const it: Suggestion = typeof s === \"string\" ? { label: s, text: s } : s;\n return (\n <button type=\"button\" key={it.id || i} className=\"fdc-suggest-item\" onClick={() => onPick && onPick(it.text || it.label)}>\n {it.icon ? <i className={\"ph ph-\" + it.icon} aria-hidden=\"true\" /> : null}\n <span className=\"fdc-suggest-text\">\n <span className=\"fdc-suggest-label\">{it.label}</span>\n {it.description ? <span className=\"fdc-suggest-desc\">{it.description}</span> : null}\n </span>\n <i className=\"ph ph-arrow-up-right fdc-suggest-go\" aria-hidden=\"true\" />\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction LoadingTurns() {\n return (\n <div className=\"fdc-skel\" aria-hidden=\"true\">\n {[0, 1].map((i) => (\n <div key={i} className=\"fdc-skel-turn\">\n <div className=\"fd-skel fd-skel-circle\" style={{ width: 22, height: 22 }} />\n <div className=\"fdc-skel-lines\">\n <div className=\"fd-skel\" style={{ width: i ? \"62%\" : \"44%\", height: 11 }} />\n <div className=\"fd-skel\" style={{ width: i ? \"94%\" : \"78%\", height: 11 }} />\n <div className=\"fd-skel\" style={{ width: i ? \"71%\" : \"56%\", height: 11 }} />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\n/**\n * Runs of consecutive messages from one sender, for run-vs-turn spacing.\n * `role=\"log\"` and deliberately NOT also aria-live — a live region on a\n * transcript makes a screen reader announce every token of a streaming reply.\n */\nexport interface ChatTranscriptProps {\n messages?: ChatMessage[];\n ctx: ChatRenderContext;\n status?: \"idle\" | \"resolving\" | \"loading\" | \"ready\" | \"disconnected\";\n /** Terminal error code; renders the disconnected state. */\n fatal?: string | null;\n suggestions?: Array<Suggestion | string>;\n onPick?: (s: Suggestion | string) => void;\n emptyTitle?: string;\n emptyDescription?: string;\n emptyIcon?: string;\n renderEmpty?: () => React.ReactNode;\n className?: string;\n}\n\n/**\n * The transcript: a role=\"log\" region (and deliberately not aria-live too —\n * that doubles announcements). Grouping, day dividers, and an auto-scroll that\n * follows only while the reader is already at the bottom.\n */\nexport function ChatTranscript({\n messages = [], ctx, status, fatal, suggestions = [], onPick,\n emptyTitle = \"How can I help?\", emptyDescription, emptyIcon = \"chat-teardrop-dots\",\n renderEmpty, className = \"\",\n}: ChatTranscriptProps) {\n const scroller = React.useRef<HTMLDivElement | null>(null);\n const stick = React.useRef(true);\n const [pill, setPill] = React.useState(0);\n const seen = React.useRef(0);\n\n const toBottom = (smooth?: boolean) => {\n const el = scroller.current;\n if (!el) return;\n // Scroll the container, never the page.\n el.scrollTo({ top: el.scrollHeight, behavior: smooth ? \"smooth\" : \"auto\" });\n stick.current = true;\n setPill(0);\n seen.current = messages.length;\n };\n\n const onScroll = () => {\n const el = scroller.current;\n if (!el) return;\n const gap = el.scrollHeight - el.scrollTop - el.clientHeight;\n stick.current = gap <= STICK_PX;\n if (stick.current && pill) { setPill(0); seen.current = messages.length; }\n };\n\n React.useLayoutEffect(() => {\n const el = scroller.current;\n if (!el) return;\n if (stick.current) { el.scrollTop = el.scrollHeight; seen.current = messages.length; }\n else setPill(Math.max(0, messages.length - seen.current));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n // Content that settles late — webfonts, images, a code block unfolding — must\n // not leave a \"stuck to bottom\" reader stranded mid-transcript.\n React.useEffect(() => {\n const el = scroller.current;\n const inner = el && (el.firstChild as Element | null);\n if (!el || !inner || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => { if (stick.current) el.scrollTop = el.scrollHeight; });\n ro.observe(inner);\n return () => ro.disconnect();\n }, []);\n\n const groups = React.useMemo(() => groupMessages(messages), [messages]);\n const empty = !messages.length && status === \"ready\";\n\n return (\n <div className={[\"fdc-scroll\", className].filter(Boolean).join(\" \")} ref={scroller} onScroll={onScroll}>\n <div className=\"fdc-log\" role=\"log\" aria-label=\"Conversation\">\n {status === \"loading\" || status === \"resolving\" ? <LoadingTurns /> : null}\n\n {status === \"disconnected\" ? (\n <div className=\"fdc-dead\">\n <span className=\"fdc-dead-icon\"><i className=\"ph ph-plugs\" aria-hidden=\"true\" /></span>\n <h3 className=\"fdc-dead-title\">{ctx.deadTitle || \"The assistant isn’t reachable\"}</h3>\n <p className=\"fdc-dead-body\">\n {fatal === \"chat_unavailable\"\n ? \"The service reported chat_unavailable. Nothing you type will be lost — reopen the panel once it’s back.\"\n : \"The thread couldn’t be resolved\" + (fatal ? \" (\" + fatal + \")\" : \"\") + \". The composer stays disabled until it resolves.\"}\n </p>\n {ctx.onReconnect ? (\n <button type=\"button\" className=\"fd-btn fd-btn-secondary fd-btn-sm\" onClick={ctx.onReconnect}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />Try again\n </button>\n ) : null}\n </div>\n ) : null}\n\n {empty ? (\n renderEmpty ? renderEmpty() : (\n <div className=\"fdc-empty\">\n <span className=\"fdc-empty-icon\"><i className={\"ph ph-\" + emptyIcon} aria-hidden=\"true\" /></span>\n <h3 className=\"fdc-empty-title\">{emptyTitle}</h3>\n {emptyDescription ? <p className=\"fdc-empty-body\">{emptyDescription}</p> : null}\n <Suggestions items={suggestions} onPick={onPick} />\n </div>\n )\n ) : null}\n\n {groups.map((g, i) => {\n const prev = groups[i - 1];\n const k = dayKey(g.messages[0].timestamp);\n const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);\n return (\n <React.Fragment key={g.key || i}>\n {showDay ? <div className=\"fdc-day\"><span>{dayLabel(k!)}</span></div> : null}\n <ChatTurn group={g} ctx={ctx} />\n </React.Fragment>\n );\n })}\n </div>\n\n {pill ? (\n <button type=\"button\" className=\"fdc-pill\" onClick={() => toBottom(true)}>\n <i className=\"ph ph-arrow-down\" aria-hidden=\"true\" />\n {pill} new message{pill === 1 ? \"\" : \"s\"}\n </button>\n ) : null}\n </div>\n );\n}\n\n/** Namespace export — grouping helper, for consumers rendering their own transcript. */\nexport const TranscriptKit = { groupMessages };\n","import * as React from \"react\";\nimport type { Attachment } from \"../../kits/files\";\nimport { Markdown, markdownToText } from \"../data/Markdown\";\nimport { CodeBlock } from \"../data/CodeBlock\";\nimport { StepList } from \"../data/StepList\";\nimport { FileGrid } from \"../forms/FileGrid\";\nimport { formatClock, formatDuration, RelativeTime } from \"../data/RelativeTime\";\nimport type { Citation, ChatMessage, Packet, PacketSchema } from \"./chatEngine\";\n\n/**\n * Render context, built once by AgentChatPanel and threaded into every part.\n * Assembling your own shell means supplying this yourself.\n */\nexport interface ChatRenderContext {\n assistantName?: string;\n userName?: string;\n assistantAvatar?: string;\n userAvatar?: string;\n /** Phosphor name for the assistant mark. Default \"sparkle\". */\n assistantIcon?: string;\n showAvatars?: boolean;\n markdown?: boolean;\n /** Clamp threshold before Show more. 0 disables. */\n maxVisibleChars?: number;\n messageActions?: boolean;\n showSteps?: boolean;\n showThinking?: boolean;\n packetSchemas?: Record<string, PacketSchema>;\n packetRenderers?: Record<string, (p: Packet) => React.ReactNode>;\n appliedPackets?: Record<string, boolean>;\n /** Sidebar-width layout: tighter padding, stacked controls. */\n narrow?: boolean;\n onOpenAttachment?: (a: Attachment) => void;\n /** Max height (px) of the attachment grid before it scrolls. Default 220. */\n attachmentHeight?: number;\n /** Renderer for `[^n]` citation markers inside markdown bodies. */\n renderCitation?: (marker: string) => React.ReactNode;\n /** Map a backend error code to human copy. */\n errorCopy?: (code: string) => React.ReactNode;\n onRetry?: () => void;\n onFeedback?: (id: string, value: \"up\" | \"down\") => void;\n onEdit?: (m: ChatMessage) => void;\n onApplyPacket?: (p: Packet) => void;\n onOpenCitation?: (c: Citation, e: React.MouseEvent) => void;\n extraActions?: (group: MessageGroup) => React.ReactNode;\n /** Disconnected-state heading. Default \"The assistant isn't reachable\". */\n deadTitle?: string;\n onReconnect?: () => void;\n}\n\n/** A run of consecutive messages from one sender — see groupMessages. */\nexport interface MessageGroup {\n role: string;\n author?: string;\n messages: ChatMessage[];\n /** A single-message run; affects spacing and the author label. */\n solo: boolean;\n key: string;\n}\n\n/* ── packets ──────────────────────────────────────────────────────────────── */\n\nfunction JsonView({ value }: { value: unknown }) {\n let text: string | undefined;\n try { text = JSON.stringify(value, null, 2); } catch (e) { text = String(value); }\n return <CodeBlock code={text as string} language=\"json\" collapseAfter={18} />;\n}\n\n/** A structured result. `valid: false` blocks Apply; undefined does not. */\nexport interface PacketCardProps { packet: Packet; schema?: PacketSchema; render?: (p: Packet) => React.ReactNode; onApply?: (p: Packet) => void; applied?: boolean }\n\n/**\n * A structured result carried by a message. `valid` is tri-state: only an\n * explicit `false` blocks Apply — an unvalidated packet is a legitimate result.\n */\nexport function PacketCard({ packet, schema, render, onApply, applied }: PacketCardProps) {\n if (!packet) return null;\n const s = schema || {};\n const invalid = packet.valid === false;\n const title = s.heading || packet.type;\n return (\n <section className={\"fdc-packet\" + (invalid ? \" is-invalid\" : \"\")} aria-label={title}>\n <header className=\"fdc-packet-head\">\n <i className={\"ph ph-\" + (s.icon || \"package\")} aria-hidden=\"true\" />\n <span className=\"fdc-packet-title\">{title}</span>\n {packet.repaired ? <span className=\"fdc-packet-badge\">Repaired</span> : null}\n {invalid ? <span className=\"fdc-packet-badge is-danger\">Invalid</span> : null}\n </header>\n {invalid ? (\n <div className=\"fdc-packet-alert\" role=\"alert\">\n <i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />\n <span>{packet.error || \"This result failed validation and can’t be applied.\"}</span>\n </div>\n ) : (\n <div className=\"fdc-packet-body\">\n {render ? render(packet) : <JsonView value={packet.payload} />}\n </div>\n )}\n {!invalid && onApply ? (\n <footer className=\"fdc-packet-foot\">\n {packet.repaired ? <span className=\"fdc-packet-note\">Corrected by the backend after a first attempt.</span> : <span />}\n <button type=\"button\" className=\"fd-btn fd-btn-primary fd-btn-sm\" disabled={applied} onClick={() => onApply(packet)}>\n <i className={\"ph ph-\" + (applied ? \"check\" : \"arrow-square-in\")} aria-hidden=\"true\" />\n {applied ? \"Applied\" : (s.applyLabel || \"Apply\")}\n </button>\n </footer>\n ) : null}\n </section>\n );\n}\n\n/* ── thinking ─────────────────────────────────────────────────────────────── */\n\nexport interface ThinkingBlockProps { text?: string; durationMs?: number; streaming?: boolean; defaultOpen?: boolean }\n\nexport function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }: ThinkingBlockProps) {\n const [open, setOpen] = React.useState(defaultOpen);\n if (!text) return null;\n return (\n <div className={\"fdc-think\" + (open ? \" is-open\" : \"\")}>\n <button type=\"button\" className=\"fdc-think-head\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className=\"ph ph-brain\" aria-hidden=\"true\" />\n <span>{streaming ? \"Thinking\" : durationMs ? \"Thought for \" + formatDuration(durationMs) : \"Thought process\"}</span>\n {streaming ? <span className=\"fdc-dots\" aria-hidden=\"true\"><span /><span /><span /></span> : null}\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n </button>\n {open ? <div className=\"fdc-think-body\">{text}</div> : null}\n </div>\n );\n}\n\n/* ── citations ────────────────────────────────────────────────────────────── */\n\nexport interface CitationsProps { items?: Citation[]; onOpen?: (c: Citation, e: React.MouseEvent) => void }\n\nexport function Citations({ items = [], onOpen }: CitationsProps) {\n const [open, setOpen] = React.useState(false);\n if (!items.length) return null;\n return (\n <div className=\"fdc-cites\">\n <button type=\"button\" className=\"fdc-cites-head\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className=\"ph ph-quotes\" aria-hidden=\"true\" />\n <span>{items.length} source{items.length === 1 ? \"\" : \"s\"}</span>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n </button>\n {open ? (\n <ol className=\"fdc-cites-list\">\n {items.map((c, i) => (\n <li key={c.id || i}>\n <span className=\"fdc-cite-n fd-tabular\">{c.marker || i + 1}</span>\n {c.url ? (\n <a href={c.url} target=\"_blank\" rel=\"noopener noreferrer\" onClick={onOpen ? (e) => onOpen(c, e) : undefined}>{c.title || c.url}</a>\n ) : <span>{c.title || \"Source\"}</span>}\n {c.detail ? <span className=\"fdc-cite-detail\">{c.detail}</span> : null}\n </li>\n ))}\n </ol>\n ) : null}\n </div>\n );\n}\n\n/* ── message body ─────────────────────────────────────────────────────────── */\n\nfunction clampText(text: string, max?: number): string | null {\n if (!max || !text || text.length <= max) return null;\n const cut = text.slice(0, max);\n const at = cut.lastIndexOf(\" \");\n return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + \"…\";\n}\n\n/** Message content only — markdown, code blocks, clamping. No chrome. */\nexport interface MessageBodyProps { message: ChatMessage; ctx: ChatRenderContext }\n\nexport function MessageBody({ message: m, ctx }: MessageBodyProps) {\n const [expanded, setExpanded] = React.useState(false);\n const isUser = m.role === \"user\";\n const raw = m.text || \"\";\n const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;\n const body = clamped != null ? clamped : raw;\n const showMd = ctx.markdown && !isUser;\n\n return (\n <div className=\"fdc-body\">\n {m.thinking && ctx.showThinking ? (\n <ThinkingBlock text={m.thinking} durationMs={m.thinkingMs} streaming={m.streaming && !m.text} />\n ) : null}\n\n {m.steps && m.steps.length && ctx.showSteps ? (\n <StepList steps={m.steps} defaultOpen={m.steps.some((s) => s.status === \"running\")} dense />\n ) : null}\n\n {body ? (\n <div className={\"fdc-text\" + (isUser ? \" is-user\" : \"\")}>\n {showMd\n ? <Markdown source={body} headingOffset={2} codeProps={{ collapseAfter: 22 }} renderCitation={ctx.renderCitation} />\n : <div className=\"fdc-plain\">{body}</div>}\n {m.streaming ? <span className=\"fdc-caret\" aria-hidden=\"true\" /> : null}\n </div>\n ) : null}\n\n {clamped != null ? (\n <button type=\"button\" className=\"fdc-more\" onClick={() => setExpanded(true)}>\n <i className=\"ph ph-caret-down\" aria-hidden=\"true\" />Show more\n <span className=\"fdc-more-len fd-tabular\">{raw.length < 2000 ? raw.length.toLocaleString() + \" characters\" : (Math.round(raw.length / 100) / 10) + \"k characters\"}</span>\n </button>\n ) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? (\n <button type=\"button\" className=\"fdc-more\" onClick={() => setExpanded(false)}>\n <i className=\"ph ph-caret-up\" aria-hidden=\"true\" />Show less\n </button>\n ) : null}\n\n {m.attachments && m.attachments.length ? (\n <FileGrid files={m.attachments} onOpen={ctx.onOpenAttachment} tiles maxHeight={ctx.attachmentHeight || 220} compact={ctx.narrow} />\n ) : null}\n\n {m.packet ? (\n <PacketCard\n packet={m.packet}\n schema={(ctx.packetSchemas || {})[m.packet.type]}\n render={(ctx.packetRenderers || {})[m.packet.type]}\n onApply={ctx.onApplyPacket}\n applied={ctx.appliedPackets && ctx.appliedPackets[m.id]}\n />\n ) : null}\n\n {m.citations && m.citations.length ? <Citations items={m.citations} onOpen={ctx.onOpenCitation} /> : null}\n\n {m.working ? (\n <div className=\"fdc-working\" role=\"status\">\n <span className=\"fdc-dots\" aria-hidden=\"true\"><span /><span /><span /></span>\n <span className=\"fdc-working-label\">\n {m.resumed ? \"Resuming\" : \"Working\"}\n {m.job && m.job.status ? <span className=\"fdc-working-job\"> · {m.job.status}</span> : null}\n {m.job && m.job.detail ? <span className=\"fdc-working-job\"> · {m.job.detail}</span> : null}\n </span>\n {m.jobId ? <span className=\"fdc-working-id fd-mono\">{String(m.jobId).slice(0, 12)}</span> : null}\n </div>\n ) : null}\n\n {m.stopped ? <div className=\"fdc-stopped\"><i className=\"ph ph-stop-circle\" aria-hidden=\"true\" />Stopped</div> : null}\n\n {m.error ? (\n <div className=\"fdc-error\" role=\"alert\">\n <i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />\n <span className=\"fdc-error-text\">{ctx.errorCopy ? ctx.errorCopy(m.error) : m.error}</span>\n {m.retryable && ctx.onRetry ? (\n <button type=\"button\" className=\"fdc-error-retry\" onClick={ctx.onRetry}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />Retry\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n/* ── run actions ──────────────────────────────────────────────────────────── */\n\nfunction useCopyRun(): [boolean, (text: string) => void] {\n const [done, setDone] = React.useState(false);\n const t = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => () => { if (t.current) clearTimeout(t.current); }, []);\n return [done, (text: string) => {\n const p = navigator.clipboard && navigator.clipboard.writeText ? navigator.clipboard.writeText(text) : Promise.reject();\n p.catch(() => {}).finally(() => {\n setDone(true);\n if (t.current) clearTimeout(t.current);\n t.current = setTimeout(() => setDone(false), 1600);\n });\n }];\n}\n\n/** Copy / retry / feedback / edit. Real buttons; the hover reveal is CSS only. */\nexport interface RunActionsProps { group: MessageGroup; ctx: ChatRenderContext }\n\n/**\n * One toolbar per run — copying the whole run, not one message. Buttons stay in\n * the DOM (the reveal is CSS only), so keyboard and screen-reader users, who\n * never produce a hover, can still reach them.\n */\nexport function RunActions({ group, ctx }: RunActionsProps) {\n const [copied, copy] = useCopyRun();\n const last = group.messages[group.messages.length - 1];\n const text = group.messages.map((m) => m.text || \"\").filter(Boolean).join(\"\\n\\n\");\n const isAssistant = group.role === \"assistant\";\n const fb = last.feedback;\n if (!ctx.messageActions) return null;\n return (\n <div className=\"fdc-actions\" role=\"group\" aria-label=\"Message actions\">\n <button type=\"button\" className={\"fdc-act\" + (copied ? \" is-done\" : \"\")} onClick={() => copy(markdownToText(text))} aria-label=\"Copy message\">\n <i className={\"ph ph-\" + (copied ? \"check\" : \"copy\")} aria-hidden=\"true\" />\n <span className=\"fdc-act-label\">{copied ? \"Copied\" : \"Copy\"}</span>\n </button>\n {isAssistant && ctx.onRetry ? (\n <button type=\"button\" className=\"fdc-act\" onClick={ctx.onRetry} aria-label=\"Retry this turn\">\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {group.role === \"user\" && ctx.onEdit ? (\n <button type=\"button\" className=\"fdc-act\" onClick={() => ctx.onEdit!(last)} aria-label=\"Edit and resend\">\n <i className=\"ph ph-pencil-simple\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {isAssistant && ctx.onFeedback ? (\n <React.Fragment>\n <button type=\"button\" className={\"fdc-act\" + (fb === \"up\" ? \" is-on\" : \"\")} onClick={() => ctx.onFeedback!(last.id, \"up\")} aria-pressed={fb === \"up\"} aria-label=\"Good response\">\n <i className=\"ph ph-thumbs-up\" aria-hidden=\"true\" />\n </button>\n <button type=\"button\" className={\"fdc-act\" + (fb === \"down\" ? \" is-on\" : \"\")} onClick={() => ctx.onFeedback!(last.id, \"down\")} aria-pressed={fb === \"down\"} aria-label=\"Bad response\">\n <i className=\"ph ph-thumbs-down\" aria-hidden=\"true\" />\n </button>\n </React.Fragment>\n ) : null}\n {ctx.extraActions ? ctx.extraActions(group) : null}\n </div>\n );\n}\n\n/* ── the turn ─────────────────────────────────────────────────────────────── */\n\n/** One turn: author label, body, attachments, packet, thinking, citations, actions. */\nexport interface ChatTurnProps { group: MessageGroup; ctx: ChatRenderContext }\n\nexport function ChatTurn({ group, ctx }: ChatTurnProps) {\n const isUser = group.role === \"user\";\n const name = isUser ? ctx.userName : (group.author || ctx.assistantName);\n const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;\n const stamp = group.messages[0].timestamp;\n\n return (\n <article className={\"fdc-turn is-\" + group.role} aria-label={String(name) + (stamp ? \" at \" + formatClock(stamp) : \"\")}>\n <div className=\"fdc-turn-head\">\n {ctx.showAvatars ? (\n <span className={\"fdc-avatar is-\" + group.role} aria-hidden=\"true\">\n {avatar ? <img src={avatar} alt=\"\" /> : isUser\n ? <span className=\"fdc-avatar-txt\">{(name || \"You\").slice(0, 1).toUpperCase()}</span>\n : <i className={\"ph ph-\" + (ctx.assistantIcon || \"sparkle\")} />}\n </span>\n ) : null}\n <span className=\"fdc-who\">{name}</span>\n {stamp ? <RelativeTime className=\"fdc-when\" value={stamp} /> : null}\n {group.messages.some((m) => m.model) ? <span className=\"fdc-turn-model\">{group.messages.find((m) => m.model)!.model}</span> : null}\n </div>\n <div className=\"fdc-turn-body\">\n {group.messages.map((m) => (\n <div key={m.id} className={\"fdc-msg\" + (m.pending ? \" is-pending\" : \"\")}>\n <MessageBody message={m} ctx={ctx} />\n </div>\n ))}\n <RunActions group={group} ctx={ctx} />\n </div>\n </article>\n );\n}\n","import * as React from \"react\";\nimport { MarkdownEditor } from \"../forms/MarkdownEditor\";\nimport type { MarkdownEditorHandle, EditorTrigger } from \"../forms/MarkdownEditor\";\nimport { Dropzone, FilePickButton, useStagedFiles } from \"../forms/Dropzone\";\nimport type { FileUploadHandler } from \"../forms/Dropzone\";\nimport { FileStrip } from \"../forms/FileGrid\";\nimport { Popover, Menu } from \"../actions/Popover\";\nimport type { MenuItem } from \"../actions/Popover\";\nimport { extractClipboardFiles } from \"../../kits/files\";\nimport type { Attachment, FileRejection } from \"../../kits/files\";\nimport { KeyHint } from \"../feedback/KeyHint\";\nimport type { SlashCommand, MentionSource, VoiceHandler } from \"./AgentChatPanel\";\n\n/**\n * Staged files, the queue strip, the markdown editor, slash/mention triggers, send + stop.\n * Enter sends, Shift+Enter continues the list or quote you are in, IME composition never\n * sends. Omit `fileUploadHandler` and there is no attach affordance at all — a pasted\n * image then falls through to the editor rather than stranding on a message that cannot\n * carry it.\n */\nexport interface ChatComposerProps {\n onSubmit: (text: string, attachments?: Attachment[]) => void;\n /** Offered whenever a turn is in flight, even with no upstream cancel. */\n onStop?: () => void;\n busy?: boolean;\n disabled?: boolean;\n placeholder?: string;\n maxLength?: number;\n fileUploadHandler?: FileUploadHandler;\n acceptFiles?: string;\n maxFileSize?: number;\n /** Chars above which a paste becomes a .txt attachment. Default 4000. */\n largePasteThreshold?: number;\n slashCommands?: SlashCommand[];\n mentionSources?: MentionSource[] | ((query: string) => Promise<MentionSource[]>);\n voiceHandler?: VoiceHandler;\n /** Messages waiting behind the turn in flight. Each row is removable. */\n queue?: Array<{ id: string; text: string; attachments?: Attachment[] }>;\n onRemoveQueued?: (id: string) => void;\n /** Rendered above the field — where AgentChatPanel puts the session bar. */\n sessionBar?: React.ReactNode;\n toolbarExtras?: React.ReactNode;\n /** Controlled draft, so a host can prefill (edit-a-message does this). */\n draft?: string;\n onDraftChange?: (text: string) => void;\n hint?: React.ReactNode;\n narrow?: boolean;\n autoFocus?: boolean;\n onReject?: (rejections: FileRejection[]) => void;\n onOpenAttachment?: (a: Attachment) => void;\n}\n\n/**\n * The composer: staged attachments, the visible send queue, the editor, and the\n * send/stop control. Every optional affordance appears only when its input is\n * supplied — no upload handler means no attach button at all.\n */\nexport function ChatComposer({\n onSubmit, onStop, busy, disabled, placeholder = \"Ask a question…\", maxLength,\n fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold = 4000,\n slashCommands, mentionSources, voiceHandler,\n queue = [], onRemoveQueued, sessionBar, toolbarExtras,\n draft, onDraftChange, hint, narrow, autoFocus,\n onReject, onOpenAttachment,\n}: ChatComposerProps) {\n const [text, setText] = React.useState(draft || \"\");\n const [trigger, setTrigger] = React.useState<EditorTrigger | null>(null);\n const [mentionItems, setMentionItems] = React.useState<MentionSource[]>([]);\n const [listening, setListening] = React.useState(false);\n const [notice, setNotice] = React.useState<string | null>(null);\n const editor = React.useRef<MarkdownEditorHandle>(null);\n const wrap = React.useRef<HTMLDivElement>(null);\n const stopVoice = React.useRef<(() => void) | null>(null);\n const staged = useStagedFiles(fileUploadHandler, { onError: () => {} });\n\n React.useEffect(() => { if (draft != null && draft !== text) setText(draft); }, [draft]);\n const change = (v: string) => { setText(v); onDraftChange && onDraftChange(v); };\n\n const uploading = staged.busy;\n const canSend = !disabled && !uploading && (text.trim().length > 0 || staged.items.length > 0);\n\n const flash = (msg: string) => { setNotice(msg); setTimeout(() => setNotice(null), 4000); };\n\n const submit = () => {\n if (!canSend) return;\n onSubmit(text.trim(), staged.items.map((f) => {\n const { file: _file, ...rest } = f; // drop the raw File from the wire shape\n return rest;\n }));\n change(\"\");\n staged.clear();\n setTrigger(null);\n };\n\n /* paste → attachment. The extractor reports; this host decides whether to consume. */\n const onPaste = (e: React.ClipboardEvent) => {\n if (!fileUploadHandler) return; // nowhere to put it: fall through\n const found = extractClipboardFiles(e.nativeEvent, { largePasteThreshold, accept: acceptFiles, maxFileSize });\n if (found.rejected && found.rejected.length) { flash(found.rejected[0].message); onReject && onReject(found.rejected); }\n if (!found.source || !found.files.length) return; // ordinary paste: leave the event alone\n e.preventDefault();\n staged.add(found.files);\n };\n\n /* trigger menus */\n React.useEffect(() => {\n if (!trigger || trigger.type !== \"mention\" || !mentionSources) { setMentionItems([]); return; }\n if (typeof mentionSources === \"function\") {\n let dead = false;\n Promise.resolve(mentionSources(trigger.query)).then((r) => { if (!dead) setMentionItems(r || []); }).catch(() => {});\n return () => { dead = true; };\n }\n const q = (trigger.query || \"\").toLowerCase();\n setMentionItems(mentionSources.filter((m) => !q || (m.label + \" \" + (m.description || \"\")).toLowerCase().includes(q)));\n }, [trigger, mentionSources]);\n\n const slashItems = React.useMemo(() => {\n if (!trigger || trigger.type !== \"slash\" || !slashCommands) return [] as SlashCommand[];\n const q = (trigger.query || \"\").toLowerCase();\n return slashCommands.filter((c) => !q || (c.id + \" \" + c.label + \" \" + (c.description || \"\")).toLowerCase().includes(q));\n }, [trigger, slashCommands]);\n\n const menuItems: MenuItem[] = trigger\n ? (trigger.type === \"slash\" ? slashItems : mentionItems).slice(0, 40).map((it) => {\n const slash = it as SlashCommand;\n const mention = it as MentionSource;\n return {\n id: it.id, label: trigger.type === \"slash\" ? \"/\" + slash.id : mention.label,\n description: it.description, icon: it.icon, meta: mention.meta,\n shortcut: slash.shortcut ? <KeyHint keys={slash.shortcut} size=\"sm\" /> : undefined,\n onSelect: () => {\n const insert = trigger.type === \"slash\"\n ? (slash.immediate ? \"/\" + slash.id : \"/\" + slash.id + \" \")\n : \"@\" + (mention.value || mention.label) + \" \";\n editor.current && editor.current.replaceRange(trigger.from, trigger.to, insert);\n setTrigger(null);\n if (slash.immediate) setTimeout(() => { onSubmit(\"/\" + slash.id, []); change(\"\"); }, 0);\n if (slash.run) slash.run();\n },\n };\n })\n : [];\n const menuOpen = !!trigger && menuItems.length > 0;\n\n const keydown = (e: React.KeyboardEvent) => {\n if (menuOpen) {\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n e.preventDefault();\n const active = document.querySelector<HTMLElement>(\".fdc-trigger .fd-menu-item.is-active\") || document.querySelector<HTMLElement>(\".fdc-trigger .fd-menu-item\");\n if (active) active.click(); else setTrigger(null);\n return;\n }\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n // the open menu owns vertical movement\n e.preventDefault();\n const list = document.querySelector(\".fdc-trigger .fd-menu\");\n if (list) list.dispatchEvent(new KeyboardEvent(\"keydown\", { key: e.key, bubbles: true }));\n return;\n }\n if (e.key === \"Escape\") { e.preventDefault(); setTrigger(null); return; }\n }\n const mod = e.metaKey || e.ctrlKey;\n if (mod && e.key === \"Enter\") { e.preventDefault(); submit(); return; }\n if (e.key === \"Escape\" && busy && onStop) { e.preventDefault(); onStop(); }\n };\n\n const voice = () => {\n if (!voiceHandler) return;\n if (listening) { if (stopVoice.current) stopVoice.current(); setListening(false); return; }\n setListening(true);\n const res = voiceHandler({\n onText: (t: string, meta?: { replace?: boolean }) => { change(((meta && meta.replace) ? \"\" : text ? text + \" \" : \"\") + t); },\n onEnd: () => setListening(false),\n });\n stopVoice.current = typeof res === \"function\" ? res : () => {};\n };\n\n return (\n <div className={\"fdc-composer\" + (disabled ? \" is-disabled\" : \"\") + (narrow ? \" is-narrow\" : \"\")}>\n {queue.length ? (\n <div className=\"fdc-queue\" aria-label=\"Queued messages\">\n {queue.map((q) => (\n <div className=\"fdc-queue-row\" key={q.id}>\n <i className=\"ph ph-clock-countdown\" aria-hidden=\"true\" />\n <span className=\"fdc-queue-text\">{q.text || (q.attachments ? q.attachments.length + \" file(s)\" : \"\")}</span>\n {onRemoveQueued ? (\n <button type=\"button\" className=\"fdc-queue-x\" onClick={() => onRemoveQueued(q.id)} aria-label=\"Remove queued message\">\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n ))}\n </div>\n ) : null}\n\n {sessionBar}\n\n <Dropzone\n className=\"fdc-field\"\n onFiles={fileUploadHandler ? (files) => staged.add(files) : undefined}\n onReject={(r) => { flash(r[0].message); onReject && onReject(r); }}\n accept={acceptFiles} maxFileSize={maxFileSize}\n disabled={!fileUploadHandler || disabled}\n label=\"Drop to attach\"\n hint={acceptFiles ? acceptFiles.replace(/,/g, \" · \") : undefined}\n >\n <div ref={wrap} className=\"fdc-field-inner\">\n {staged.items.length ? (\n <div className=\"fdc-staged\">\n <FileStrip files={staged.items} size={narrow ? 60 : 68} onRemove={staged.remove} onRetry={staged.retry} onOpen={onOpenAttachment} />\n </div>\n ) : null}\n\n <MarkdownEditor\n ref={editor} value={text} onChange={change} onSubmit={submit}\n onKeyDown={keydown} onPaste={onPaste} onTrigger={setTrigger}\n placeholder={disabled ? \"The assistant is unavailable\" : placeholder}\n disabled={disabled} maxLength={maxLength} autoFocus={autoFocus}\n minRows={narrow ? 1 : 2} maxRows={12} ariaLabel=\"Message\"\n />\n\n <div className=\"fdc-tools\">\n {fileUploadHandler ? (\n <FilePickButton onFiles={staged.add} onReject={(r) => flash(r[0].message)} accept={acceptFiles} maxFileSize={maxFileSize} label=\"Attach files\" icon=\"plus\" />\n ) : null}\n {voiceHandler ? (\n <button type=\"button\" className={\"fd-attachbtn\" + (listening ? \" is-live\" : \"\")} onClick={voice} aria-pressed={listening} aria-label={listening ? \"Stop dictation\" : \"Dictate\"}>\n <i className={\"ph ph-\" + (listening ? \"waveform\" : \"microphone\")} aria-hidden=\"true\" />\n </button>\n ) : null}\n {toolbarExtras}\n <span className=\"fdc-tools-gap\" />\n {maxLength && text.length > maxLength * 0.6 ? (\n <span className={\"fdc-count fd-tabular\" + (text.length > maxLength * 0.95 ? \" is-hot\" : \"\")}>{text.length}/{maxLength}</span>\n ) : null}\n {busy ? (\n <button type=\"button\" className=\"fdc-stop\" onClick={onStop} aria-label=\"Stop generating\">\n <i className=\"ph ph-stop-circle\" aria-hidden=\"true\" />\n <span>Stop</span>\n </button>\n ) : (\n <button type=\"button\" className=\"fdc-send\" onClick={submit} disabled={!canSend} aria-label=\"Send message\">\n <i className=\"ph ph-paper-plane-right\" aria-hidden=\"true\" />\n <span className=\"fdc-send-label\">Send</span>\n </button>\n )}\n </div>\n </div>\n </Dropzone>\n\n {notice ? <div className=\"fdc-notice\" role=\"status\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{notice}</div> : null}\n {hint && !notice ? <div className=\"fdc-hint\">{hint}</div> : null}\n\n <Popover\n open={menuOpen} anchorRef={wrap} placement=\"top-start\" offset={10}\n minWidth={narrow ? 260 : 320} maxHeight={300} className=\"fdc-trigger\"\n onClose={() => setTrigger(null)} returnFocus={false} closeOnOutside\n label={trigger && trigger.type === \"slash\" ? \"Commands\" : \"Mentions\"}\n >\n <Menu\n items={menuItems} autoFocus={false}\n header={<div className=\"fd-pop-group\">{trigger && trigger.type === \"slash\" ? \"Commands\" : \"Attach context\"}</div>}\n onClose={() => setTrigger(null)}\n />\n </Popover>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { SegmentedMeter, QuotaRow, meterFormats } from \"../data/SegmentedMeter\";\nimport { Popover, MenuButton } from \"../actions/Popover\";\nimport type { MenuItem } from \"../actions/Popover\";\nimport { formatDuration, formatRelative } from \"../data/RelativeTime\";\nimport { KeyHint } from \"../feedback/KeyHint\";\nimport type { SessionStats, ContextUsage, UsageLimit, Model } from \"./AgentChatPanel\";\n\nconst compact = meterFormats.compact;\n\n/**\n * Elapsed time, token spend, context window and quota rows. Renders `null` unless at\n * least one input is supplied — the bar is never an empty frame.\n */\nexport interface ChatSessionBarProps {\n sessionStats?: SessionStats;\n contextUsage?: ContextUsage;\n usageLimits?: UsageLimit[];\n onClear?: () => void;\n extras?: React.ReactNode;\n}\n\n/**\n * The strip above the composer. Every part is prop-fed: supply none of\n * sessionStats / contextUsage / usageLimits and no bar renders at all.\n */\nexport function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }: ChatSessionBarProps) {\n const [open, setOpen] = React.useState(false);\n const anchor = React.useRef<HTMLButtonElement>(null);\n const stats = sessionStats || null;\n const cu = contextUsage || null;\n const limits = usageLimits || null;\n if (!stats && !cu && !limits && !extras) return null;\n\n const total = cu && Number(cu.total) > 0 ? Number(cu.total) : 0;\n const used = cu ? (cu.segments || []).reduce((n, s) => n + (Number(s.value) || 0), 0) : 0;\n const pct = total ? Math.min(100, Math.round((used / total) * 100)) : 0;\n\n const bits: string[] = [];\n if (stats && stats.elapsedMs) bits.push(formatDuration(stats.elapsedMs));\n if (stats && stats.tokens) bits.push(compact(stats.tokens) + \" tokens\");\n if (stats && stats.costUsd != null) bits.push(\"$\" + Number(stats.costUsd).toFixed(stats.costUsd < 1 ? 3 : 2));\n if (stats && stats.runningTasks) bits.push(stats.runningTasks + \" running task\" + (stats.runningTasks === 1 ? \"\" : \"s\"));\n if (cu) bits.push(pct + \"% context\");\n\n const expandable = !!(cu || limits);\n\n return (\n <React.Fragment>\n <div className=\"fdc-bar\">\n <button\n type=\"button\" ref={anchor} className=\"fdc-bar-btn\" disabled={!expandable}\n onClick={() => setOpen((v) => !v)} aria-expanded={expandable ? open : undefined}\n aria-label={expandable ? \"Usage details\" : undefined}\n >\n {cu ? (\n <span className=\"fdc-bar-mini\" aria-hidden=\"true\">\n <SegmentedMeter total={total} segments={cu.segments} height={4} showTotal={false} />\n </span>\n ) : null}\n <span className=\"fdc-bar-text\">{bits.join(\" · \")}</span>\n {expandable ? <i className=\"ph ph-caret-right fdc-bar-caret\" aria-hidden=\"true\" /> : null}\n </button>\n {extras}\n </div>\n\n <Popover open={open} anchorRef={anchor} placement=\"top-start\" onClose={() => setOpen(false)} minWidth={330} maxHeight={460} padded label=\"Usage\">\n <div className=\"fdc-usage\">\n {cu ? (\n <section className=\"fdc-usage-sec\">\n <SegmentedMeter\n total={total} segments={cu.segments} label={cu.label || \"Context window\"}\n format={cu.format === \"bytes\" ? meterFormats.bytes : compact} height={8} legend\n remainderLabel=\"Free\"\n />\n </section>\n ) : null}\n {limits && limits.length ? (\n <section className=\"fdc-usage-sec\">\n <h4 className=\"fdc-usage-h\">{\"Usage limits\"}</h4>\n <div className=\"fdc-usage-rows\">\n {limits.map((l) => (\n <QuotaRow key={l.id} label={l.label} percent={l.percent}\n note={l.resetsAt ? \"Resets \" + formatRelative(l.resetsAt) : l.note} />\n ))}\n </div>\n </section>\n ) : null}\n {stats ? (\n <section className=\"fdc-usage-sec fdc-usage-stats\">\n {stats.elapsedMs ? <div><span>Session</span><b className=\"fd-tabular\">{formatDuration(stats.elapsedMs)}</b></div> : null}\n {stats.tokens ? <div><span>Tokens</span><b className=\"fd-tabular\">{stats.tokens.toLocaleString()}</b></div> : null}\n {stats.costUsd != null ? <div><span>Cost</span><b className=\"fd-tabular\">${Number(stats.costUsd).toFixed(3)}</b></div> : null}\n {stats.turns ? <div><span>Turns</span><b className=\"fd-tabular\">{stats.turns}</b></div> : null}\n </section>\n ) : null}\n {onClear ? (\n <footer className=\"fdc-usage-foot\">\n <button type=\"button\" className=\"fdc-usage-clear\" onClick={() => { setOpen(false); onClear(); }}>\n <i className=\"ph ph-trash\" aria-hidden=\"true\" />Clear conversation\n </button>\n </footer>\n ) : null}\n </div>\n </Popover>\n </React.Fragment>\n );\n}\n\n/**\n * Model picker, effort level and fast mode. `null` when no models are given.\n * A model's `shortcut` renders a key cap and binds nothing.\n */\nexport interface ModelControlsProps {\n models?: Model[];\n model?: string;\n onModelChange?: (id: string) => void;\n effortLevels?: string[];\n effort?: string;\n onEffortChange?: (level: string) => void;\n fastMode?: boolean;\n onFastModeChange?: (on: boolean) => void;\n fastModeLabel?: string;\n /** Collapsed into a submenu. */\n moreModels?: Model[];\n narrow?: boolean;\n}\n\n/**\n * Model picker (+ optional effort and fast-mode). Renders only when `models` is\n * supplied. Shortcuts are hints; the app registers the real keys.\n */\nexport function ModelControls({\n models, model, onModelChange,\n effortLevels, effort, onEffortChange,\n fastMode, onFastModeChange, fastModeLabel = \"Enable fast mode\",\n moreModels, narrow: _narrow,\n}: ModelControlsProps) {\n if (!models || !models.length) return null;\n const current = models.find((m) => m.id === model) || models[0];\n const grouped: Record<string, Model[]> = {};\n const flat: Model[] = [];\n models.forEach((m) => {\n if (m.group) { (grouped[m.group] = grouped[m.group] || []).push(m); return; }\n flat.push(m);\n });\n\n const item = (m: Model): MenuItem => ({\n id: m.id, label: m.label, description: m.description, disabled: m.disabled,\n checked: m.id === (current && current.id),\n meta: m.meta,\n shortcut: m.shortcut ? <KeyHint keys={m.shortcut} size=\"sm\" /> : undefined,\n onSelect: () => onModelChange && onModelChange(m.id),\n });\n\n const items: MenuItem[] = ([{ kind: \"section\", label: \"Models\" }] as MenuItem[]).concat(flat.map(item));\n Object.keys(grouped).forEach((g) => {\n items.push({ id: \"grp_\" + g, label: g, icon: \"stack\", submenu: grouped[g].map(item) });\n });\n if (moreModels && moreModels.length) items.push({ id: \"more\", label: \"More models\", submenu: moreModels.map(item) });\n if (onFastModeChange) {\n items.push({ kind: \"separator\" });\n items.push({ kind: \"section\", label: \"Fast mode\" });\n items.push({\n kind: \"custom\",\n render: () => (\n <label className=\"fdc-switchrow\">\n <span>{fastModeLabel}</span>\n <input type=\"checkbox\" className=\"fd-sr\" checked={!!fastMode} onChange={(e) => onFastModeChange(e.target.checked)} />\n <span className={\"fd-switch-track\" + (fastMode ? \" is-on\" : \"\")} aria-hidden=\"true\"><span className=\"fd-switch-thumb\" /></span>\n </label>\n ),\n });\n }\n\n return (\n <React.Fragment>\n <MenuButton\n items={items} placement=\"top-end\" minWidth={252} ariaLabel=\"Model\"\n label={current ? current.label : \"Model\"} title=\"Choose a model\"\n />\n {effortLevels && effortLevels.length ? (\n <MenuButton\n placement=\"top-end\" minWidth={180} ariaLabel=\"Reasoning effort\" trailingIcon={null}\n label={effort || effortLevels[0]} title=\"Reasoning effort\"\n items={effortLevels.map((lv) => ({\n id: lv, label: lv, checked: lv === effort,\n onSelect: () => onEffortChange && onEffortChange(lv),\n }))}\n />\n ) : null}\n </React.Fragment>\n );\n}\n","import * as React from \"react\";\n\n/* =============================================================================\n QueryKit — the one way this app asks a server for a list.\n\n Two halves:\n\n 1. QueryKit.run(rows, query, cfg)\n The SERVER side, simulated. Applies search → filters → sort → page in that\n order and returns the one envelope every list endpoint must return:\n\n {\n rows, the current page only\n pager: { page, pageSize, total, totalPages, from, to, hasPrev, hasNext },\n sort: { key, dir },\n filter: { applied, q, facets }\n }\n\n When the real API lands, this function is deleted — the endpoint returns\n the same envelope and nothing else changes.\n\n 2. useServerTable({ endpoint, params, defaults, deps })\n The CLIENT side. Owns one query object, refetches on any change, debounces\n typing, drops stale responses, and resets to page 1 whenever the result set\n changes shape (search, filter or sort). Every table in the app uses it, so\n paging/sorting/filtering behave identically everywhere.\n\n Query contract (identical for every list endpoint):\n page 1-indexed\n pageSize 10 | 25 | 50 | 100\n sort column key\n dir \"asc\" | \"desc\"\n q free-text search across the endpoint's searchable columns\n filters { [filterId]: value } — endpoint-specific, documented per endpoint\n============================================================================= */\n\nexport interface TableQuery {\n /** 1-indexed. */\n page: number;\n pageSize: number;\n sort: string | null;\n dir: \"asc\" | \"desc\";\n /** Free-text search across the endpoint's searchable columns. */\n q: string;\n filters: Record<string, unknown>;\n}\nexport interface Pager {\n page: number; pageSize: number; total: number; totalPages: number;\n from: number; to: number; hasPrev: boolean; hasNext: boolean;\n}\n/** The envelope EVERY paged list endpoint returns. */\nexport interface ListEnvelope<Row = unknown> {\n rows: Row[];\n pager: Pager;\n sort: { key: string; dir: \"asc\" | \"desc\" } | null;\n filter: { applied: Record<string, unknown>; q: string; facets: Record<string, Record<string, number>> };\n aggregate?: Record<string, unknown>;\n}\nexport interface RunConfig<Row = unknown> {\n searchKeys?: string[];\n filters?: Record<string, (row: Row, value: any) => boolean>;\n /** Sort value for a column whose key isn't a plain field. */\n accessors?: Record<string, (row: Row) => unknown>;\n /** Option counts, computed over the SEARCHED set so a filter never erases its own alternatives. */\n facets?: Record<string, (row: Row) => string | number | null>;\n defaultSort?: { key: string; dir: \"asc\" | \"desc\" };\n defaultPageSize?: number;\n}\nexport interface ServerTable<Row = unknown> {\n rows: Row[]; pager: Pager; total: number; page: number; pageSize: number;\n totalPages: number; from: number; to: number;\n facets: Record<string, Record<string, number>>;\n aggregate: Record<string, unknown>;\n query: TableQuery;\n sort?: { key: string; dir: \"asc\" | \"desc\" };\n q: string; filters: Record<string, unknown>;\n loading: boolean;\n /** True only on the FIRST load — later loads keep showing stale rows. */\n initialLoading: boolean;\n /** True while re-querying with previous rows still on screen. Pass straight to\n * DataTable's `refreshing`, or to LoadingRegion as state=\"refreshing\". */\n refreshing: boolean;\n activeFilterCount: number;\n setPage(p: number): void;\n setPageSize(n: number): void;\n setQ(q: string): void;\n toggleSort(key: string): void;\n setSortKey(key: string, dir?: \"asc\" | \"desc\"): void;\n /** Same query, unpaged — for CSV export and select-all-matching. */\n fetchAll(): Promise<Row[]>;\n /** value may be an updater fn — REQUIRED for toggles, or two fast clicks read the same\n * stale array and the first is lost. */\n setFilter(id: string, value: unknown | ((prev: unknown) => unknown)): void;\n clearFilter(id: string): void;\n setFilters(filters: Record<string, unknown>): void;\n clearFilters(): void;\n refresh(): void;\n queryString: string;\n}\nexport interface UseServerTableOptions {\n endpoint: string;\n params?: Record<string, unknown>;\n defaults?: Partial<TableQuery>;\n /** Extra values that should trigger a refetch. */\n deps?: unknown[];\n /** Opts into durable rows-per-page and default sort. Page/search/filters are deliberately\n * NOT persisted — they describe one task, and restoring them hides rows the user expects. */\n prefsKey?: string;\n}\n\n/* Filter-predicate builders for RunConfig.filters — covers the three shapes that come\n up in almost every table: equality/multi-select, tag/array membership, numeric range.\n A filter is free to skip these and write its own (row, value) => boolean instead. */\nexport function eqFilter<Row>(get: (row: Row) => unknown) {\n return (row: Row, value: unknown): boolean =>\n Array.isArray(value) ? value.includes(get(row)) : get(row) === value;\n}\nexport function anyOfFilter<Row>(get: (row: Row) => string[]) {\n return (row: Row, value: unknown): boolean => {\n const xs = get(row) ?? [];\n return Array.isArray(value)\n ? value.some((x) => xs.includes(String(x)))\n : xs.includes(String(value));\n };\n}\nexport function rangeFilter<Row>(get: (row: Row) => number) {\n return (row: Row, value: unknown): boolean => {\n const n = get(row);\n const bounds = Array.isArray(value) ? value : [0, Number.POSITIVE_INFINITY];\n const lo = Number(bounds[0] ?? 0);\n const hiRaw = bounds[1];\n const hi = hiRaw == null ? Number.POSITIVE_INFINITY : Number(hiRaw);\n return n >= lo && (hi === Number.POSITIVE_INFINITY || n <= hi);\n };\n}\n\nconst DEFAULTS: TableQuery = { page: 1, pageSize: 25, sort: null, dir: \"desc\", q: \"\", filters: {} };\n\nfunction compare(a: unknown, b: unknown, dir: \"asc\" | \"desc\"): number {\n const empty = (v: unknown) => v == null || v === \"\";\n if (empty(a) && empty(b)) return 0;\n if (empty(a)) return 1; // nulls always last, both directions\n if (empty(b)) return -1;\n const n = typeof a === \"number\" && typeof b === \"number\"\n ? a - b\n : String(a).localeCompare(String(b), undefined, { numeric: true, sensitivity: \"base\" });\n return dir === \"asc\" ? n : -n;\n}\n\n/* Transport and prefs are injected: setApi() once per app. Without this the kit would\n have to know an app-specific global, which is exactly what makes a shared kit unshareable. */\ntype Api = { request(id: string, params?: unknown): Promise<unknown> };\ntype PrefsStore = { getTable(key: string): any; setTable(key: string, patch: any): void };\n\nlet API: Api | null = null;\nlet PREFS: PrefsStore | null = null;\n\ndeclare global {\n interface Window {\n /* Legacy global fallback for QueryKit.setPrefs() — this is the name of the prefs store\n in the app query.js was extracted from. Harmless: `PREFS || window.PlannerPrefs` already\n short-circuits on PREFS first, so a consuming app that never defines this global (as most\n won't) simply falls through to \"no prefs store\" behaviour. Ported as-is, not renamed. */\n PlannerPrefs?: PrefsStore;\n }\n}\n\n/** React hook — the only way a screen should talk to a list endpoint. */\nfunction useServerTable<Row = unknown>({ endpoint, params, defaults, deps, prefsKey }: UseServerTableOptions): ServerTable<Row> {\n /* prefsKey opts a table into durable rows-per-page and default sort (prefs.js).\n Page number, search text and filters are deliberately NOT persisted: they\n describe one task, and restoring them would hide rows the user expects. */\n const [query, setQuery] = React.useState<TableQuery>(() => {\n const store = PREFS || window.PlannerPrefs;\n const saved = prefsKey && store ? store.getTable(prefsKey) : {};\n return { ...DEFAULTS, ...(defaults || {}), ...(saved.pageSize ? { pageSize: saved.pageSize } : {}), ...(saved.sort ? { sort: saved.sort, dir: saved.dir || \"desc\" } : {}) };\n });\n const savePref = React.useCallback((patch: { pageSize?: number; sort?: string; dir?: \"asc\" | \"desc\" }) => {\n const store = PREFS || window.PlannerPrefs;\n if (prefsKey && store) store.setTable(prefsKey, patch);\n }, [prefsKey]);\n const [res, setRes] = React.useState<ListEnvelope<Row> | null>(null);\n const [loading, setLoading] = React.useState(true);\n const seq = React.useRef(0);\n const depKey = (deps || []).join(\"|\");\n const paramKey = JSON.stringify(params || {});\n const queryKey = JSON.stringify(query);\n\n React.useEffect(() => {\n const id = ++seq.current;\n setLoading(true);\n // Debounced so typing in a search box is one request, not one per keystroke —\n // exactly what we want against the real endpoint.\n const t = setTimeout(() => {\n QueryKit.getApi().request(endpoint, { ...(params || {}), ...query }).then((r) => {\n if (id !== seq.current) return; // stale response, drop it\n setRes(r as ListEnvelope<Row>);\n setLoading(false);\n });\n }, query.q ? 220 : 60);\n return () => clearTimeout(t);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [endpoint, queryKey, paramKey, depKey]);\n\n const patch = (p: Partial<TableQuery>, resetPage = true) =>\n setQuery((s) => ({ ...s, ...p, page: resetPage ? 1 : (p.page != null ? p.page : s.page) }));\n const defaultPager: Pager = { page: query.page, pageSize: query.pageSize, total: 0, totalPages: 1, from: 0, to: 0, hasPrev: false, hasNext: false };\n const pager: Pager = (res && res.pager) || defaultPager;\n const api: ServerTable<Row> = {\n rows: res ? res.rows : [],\n /** The response's pager block, verbatim. */\n pager,\n total: pager.total || 0,\n page: pager.page || query.page,\n pageSize: query.pageSize,\n totalPages: pager.totalPages || 1,\n from: pager.from || 0,\n to: pager.to || 0,\n facets: (res && res.filter && res.filter.facets) || {},\n /** Server-computed totals over the whole match, never the current page. */\n aggregate: (res && res.aggregate) || {},\n /** The live query object — pass to fetchAll-style calls that need the full match. */\n query,\n sort: query.sort ? { key: query.sort, dir: query.dir } : undefined,\n q: query.q,\n filters: query.filters,\n loading,\n /** True only on the very first load — later loads keep showing stale rows. */\n initialLoading: loading && !res,\n activeFilterCount: Object.values(query.filters).filter((v) => !(v == null || v === \"\" || v === false)).length,\n setPage: (page: number) => patch({ page }, false),\n setPageSize: (pageSize: number) => { savePref({ pageSize }); patch({ pageSize }); },\n setQ: (q: string) => patch({ q }),\n toggleSort: (key: string) => setQuery((s) => {\n const dir: \"asc\" | \"desc\" = s.sort === key && s.dir === \"desc\" ? \"asc\" : \"desc\";\n savePref({ sort: key, dir });\n return { ...s, page: 1, sort: key, dir };\n }),\n setSortKey: (key: string, dir?: \"asc\" | \"desc\") => { savePref({ sort: key, dir: dir || \"desc\" }); setQuery((s) => ({ ...s, page: 1, sort: key, dir: dir || \"desc\" })); },\n /** Same query, unpaged — for CSV export and select-all-matching. */\n fetchAll: () => QueryKit.getApi().request(endpoint, { ...(params || {}), ...query, page: 1, pageSize: 100000 }).then((r) => (r as ListEnvelope<Row>).rows),\n /** value may be an updater fn — required for toggles, or two fast clicks\n both read the same stale array and the first one is lost. */\n setFilter: (id: string, value: unknown | ((prev: unknown) => unknown)) => setQuery((s) => ({ ...s, page: 1, filters: { ...s.filters, [id]: typeof value === \"function\" ? (value as (prev: unknown) => unknown)(s.filters[id]) : value } })),\n clearFilter: (id: string) => setQuery((s) => { const f = { ...s.filters }; delete f[id]; return { ...s, page: 1, filters: f }; }),\n setFilters: (filters: Record<string, unknown>) => patch({ filters }),\n clearFilters: () => patch({ filters: {}, q: \"\" }),\n refresh: () => setQuery((s) => ({ ...s })),\n /* True on a re-query while the PREVIOUS rows are still rendered — sort, filter, page.\n Distinct from `loading` (first load, nothing on screen) because the two need different\n treatments: skeletons versus a stale overlay on real content. */\n refreshing: loading && !!res,\n queryString: QueryKit.toQueryString(query)\n };\n return api;\n}\n\nconst QueryKit = {\n DEFAULTS,\n /** Register the app's simulated (or real) transport: an object with .request(id, params). */\n setApi<T extends Api>(api: T): T { API = api; return api; },\n getApi(): Api {\n if (!API) throw new Error(\"QueryKit: call QueryKit.setApi(yourApi) once at app boot — the kit must not guess at app globals.\");\n return API;\n },\n /** Optional durable table preferences store: { getTable(key), setTable(key, patch) }. */\n setPrefs(p: PrefsStore): void { PREFS = p; },\n\n /**\n * @param rows the full static dataset (stands in for the table)\n * @param query { page, pageSize, sort, dir, q, filters }\n * @param cfg { searchKeys[], filters: {id: (row, value) => boolean},\n * accessors: {colKey: (row) => sortableValue},\n * facets: {id: (row) => facetValue} }\n */\n run<Row>(rows: Row[], query: Partial<TableQuery>, cfg: RunConfig<Row>): ListEnvelope<Row> {\n const Q: TableQuery = { ...DEFAULTS, ...(query || {}) };\n const c = cfg;\n const filters = Q.filters || {};\n const active = (v: unknown) => !(v == null || v === \"\" || v === false || (Array.isArray(v) && !v.length));\n\n // search\n let out: Row[] = rows;\n const term = (Q.q || \"\").trim().toLowerCase();\n if (term && c.searchKeys) {\n const keys = c.searchKeys;\n out = out.filter((r) => keys.some((k) => String((r as Record<string, unknown>)[k] ?? \"\").toLowerCase().includes(term)));\n }\n const searched = out;\n\n // filters\n Object.entries(filters).forEach(([id, val]) => {\n const fn = c.filters && c.filters[id];\n if (!active(val) || !fn) return;\n out = out.filter((r) => fn(r, val));\n });\n const matched = out;\n\n // facets — option counts computed over the searched set, so a filter never\n // erases its own alternatives from the UI.\n const facets: Record<string, Record<string, number>> = {};\n if (c.facets) Object.entries(c.facets).forEach(([id, get]) => {\n const counts: Record<string, number> = {};\n searched.forEach((r) => { const v = get(r); if (v != null) counts[v] = (counts[v] || 0) + 1; });\n facets[id] = counts;\n });\n\n // sort\n if (Q.sort) {\n const get = (c.accessors && c.accessors[Q.sort]) || ((r: Row) => (r as Record<string, unknown>)[Q.sort as string]);\n out = [...out].sort((a, b) => compare(get(a), get(b), Q.dir));\n }\n\n // page\n const total = matched.length;\n const pageSize = Math.max(1, Q.pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const page = Math.min(Math.max(1, Q.page), totalPages);\n const paged = out.slice((page - 1) * pageSize, page * pageSize);\n return {\n rows: paged,\n pager: {\n page, pageSize, total, totalPages,\n from: total === 0 ? 0 : (page - 1) * pageSize + 1,\n to: Math.min(total, page * pageSize),\n hasPrev: page > 1,\n hasNext: page < totalPages\n },\n sort: Q.sort ? { key: Q.sort, dir: Q.dir } : null,\n filter: { applied: filters, q: Q.q || \"\", facets }\n };\n },\n\n /** Display form of a query, for the request log and the API spec screen. */\n toQueryString(query: Partial<TableQuery>): string {\n const Q: TableQuery = { ...DEFAULTS, ...(query || {}) };\n const parts: string[] = [];\n if (Q.page !== 1) parts.push(\"page=\" + Q.page);\n if (Q.pageSize !== DEFAULTS.pageSize) parts.push(\"pageSize=\" + Q.pageSize);\n if (Q.sort) parts.push(\"sort=\" + Q.sort + \"&dir=\" + Q.dir);\n if (Q.q) parts.push(\"q=\" + encodeURIComponent(Q.q));\n Object.entries(Q.filters || {}).forEach(([k, v]) => {\n if (v == null || v === \"\" || v === false || (Array.isArray(v) && !v.length)) return;\n // Arrays serialize as repeated params — ?state=OH&state=MI — the convention\n // the real endpoints read for multi-select filters.\n if (Array.isArray(v)) v.forEach((x) => parts.push(k + \"=\" + encodeURIComponent((x === Infinity ? \"*\" : x) as string | number | boolean)));\n else parts.push(k + \"=\" + encodeURIComponent(v as string | number | boolean));\n });\n return parts.join(\"&\");\n },\n\n useServerTable\n};\n\nexport { QueryKit, useServerTable };\n","/* =============================================================================\n MockJobKit — simulates a long-running backend job so a mock/demo transport can\n answer the `{ jobId }` → poll pattern the same way a real async endpoint would:\n the initiating call returns immediately with an id, and the caller polls a\n status endpoint until the work is done.\n\n Two halves:\n\n 1. MockJobKit.schedule(prefix, latency, stages, compute)\n The SERVER side, simulated. Registers a job and advances it through `stages`\n on a jittered timer within `latency`, calling `compute()` on the final tick\n to produce the result. Returns the job id at once — exactly what a real\n endpoint returns before doing the work off the request/response cycle.\n\n 2. MockJobKit.get(jobId) / MockJobKit.poll(jobId, opts)\n The CLIENT side. `get` is the plain status lookup a jobs.get-style endpoint\n wraps. `poll` is the loop every screen that watches a job actually needs:\n re-check on an interval, report progress via onTick, resolve with the\n result once done, throw once failed. Pulled out here because two unrelated\n screens had each hand-written the identical loop.\n\n Failure: `compute` may throw. A throw is caught and turned into a \"failed\"\n status with `error` set to the thrown value's message — the honest way to make\n MockJobStatus's \"failed\" state one that can actually occur, rather than a value\n the type claims is reachable but no scheduler ever produces.\n============================================================================= */\n\nexport interface MockJobStatus<TResult = unknown> {\n id: string;\n status: \"queued\" | \"running\" | \"done\" | \"failed\";\n progress?: number;\n stage?: string;\n result?: TResult;\n /** Set only when status is \"failed\" — the thrown value's message. */\n error?: string;\n}\nexport interface PollOptions<TResult = unknown> {\n /** Delay between polls, ms. Default 400 — the rate every hand-written poller used. */\n intervalMs?: number;\n onTick?: (status: MockJobStatus<TResult>) => void;\n}\n\nlet ridSeq = 0;\nconst rid = (prefix: string) =>\n `${prefix}_${(++ridSeq).toString(36)}${Math.random().toString(36).slice(2, 6)}`;\nconst jitter = ([lo, hi]: [number, number]) => lo + Math.random() * (hi - lo);\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\nconst jobs = new Map<string, MockJobStatus>();\n\n/**\n * @param prefix id prefix, e.g. \"imp\" → \"imp_1a2b3c\"\n * @param latency [lo, hi] ms — total time across every stage, jittered within the range\n * @param stages progress labels in order, e.g. [\"Uploading\", \"Parsing\", \"Validating\"]\n * @param compute runs once, on the final stage, to produce the result — or throws to fail the job\n */\nfunction schedule<TResult>(\n prefix: string,\n latency: [number, number],\n stages: string[],\n compute: () => TResult,\n): string {\n const id = rid(prefix);\n const list = stages.length ? stages : [\"Working\"];\n const total = jitter(latency);\n jobs.set(id, { id, status: \"queued\", progress: 0, stage: list[0] });\n list.forEach((stage, i) => {\n const at = (total * (i + 1)) / list.length;\n setTimeout(() => {\n if (!jobs.has(id)) return; // job was cleared out from under this tick\n if (i === list.length - 1) {\n try {\n jobs.set(id, { id, status: \"done\", progress: 1, stage, result: compute() });\n } catch (err) {\n jobs.set(id, {\n id, status: \"failed\", progress: 1, stage,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n } else {\n jobs.set(id, { id, status: \"running\", progress: (i + 1) / list.length, stage });\n }\n }, at);\n });\n return id;\n}\n\n/** Plain status lookup — what a jobs.get-style mock endpoint wraps. Throws if the id is unknown. */\nfunction get<TResult = unknown>(jobId: string): MockJobStatus<TResult> {\n const job = jobs.get(jobId);\n if (!job) throw new Error(`MockJobKit: job \"${jobId}\" not found`);\n // The store is untyped (one Map holds every job in the app) — the caller's TResult\n // is trusted the same way a real jobs.get response's shape would be.\n return { ...job } as unknown as MockJobStatus<TResult>;\n}\n\n/** Polls until the job resolves. Resolves with the result on \"done\", throws on \"failed\". */\nasync function poll<TResult = unknown>(jobId: string, opts?: PollOptions<TResult>): Promise<TResult> {\n const intervalMs = opts?.intervalMs ?? 400;\n for (;;) {\n const status = get<TResult>(jobId);\n opts?.onTick?.(status);\n if (status.status === \"done\") return status.result as TResult;\n if (status.status === \"failed\") throw new Error(status.error || `Job failed: ${jobId}`);\n await sleep(intervalMs);\n }\n}\n\nexport const MockJobKit = { schedule, get, poll };\n","/* =============================================================================\n VersionKit — append-only version history with a full-state snapshot per\n version, so any version can be jumped back to without replaying mutations.\n\n Extracted from media-planner's plan-version pattern (commitVersion / plan.undo /\n versions.restore) and generalized: this file has no idea what TState is. A\n consuming app supplies the whole state shape it wants versioned — a plan, a\n document, a form draft, whatever — plus an optional `diff` function for\n describing what changed between two states in whatever shape it cares about.\n\n Factory, not a namespace: an app can have more than one independently-versioned\n thing open at once (two plans, a plan and a separate document), and each needs\n its own version array, its own snapshot map and its own \"current\" pointer.\n createVersionStore() returns one such instance; SessionKit/RuntimeKit's\n single-shared-store shape would make the second instance clobber the first.\n\n History is append-only on purpose: undo() and restoreTo() never delete or\n rewrite a version, they COMMIT a new one whose state happens to match an\n earlier snapshot. That is what makes \"undo the undo\" possible and what keeps\n the version list a true audit trail instead of a mutable pointer. ---------- */\n\n/** One entry in the append-only history. Never mutated after it's appended,\n * except for `current` flipping to false when a later version is committed. */\nexport interface VersionRecord<TDiff = unknown> {\n v: number;\n current: boolean;\n who: string;\n when: string;\n action: string;\n /** Human-readable change descriptions, as returned by the mutator passed to commit(). */\n changes: string[];\n /** Present only when the store was created with a `diff` option. */\n diff?: TDiff;\n /** Open bag for caller-specific before/after figures (e.g. a computed total) that\n * don't belong in `diff` because they aren't part of the state comparison itself. */\n meta?: Record<string, unknown>;\n}\n\nexport interface CreateVersionStoreOptions<TState, TDiff = unknown> {\n /** Defaults to structuredClone. Override if TState holds something it can't clone\n * (a class instance, a function) — must still produce a deep, independent copy. */\n clone?: (state: TState) => TState;\n /** Computes what a version's `diff` field holds by comparing the state before and\n * after the mutation. Omit if the caller has no use for a structured diff — the\n * `changes` string list on every record still describes what happened. */\n diff?: (before: TState, after: TState) => TDiff;\n /** Timestamp/attribution stamp for `when`. Defaults to `new Date().toISOString()`. */\n now?: () => string;\n /** Version number the initial state is recorded under. Defaults to 0. */\n initialVersion?: number;\n who?: string;\n action?: string;\n}\n\nexport interface VersionStore<TState, TDiff = unknown> {\n /** The live state. Mutating it directly bypasses versioning — always go through commit(). */\n getState(): TState;\n /** Newest first, matching the order a version-history panel reads top to bottom. */\n getVersions(): VersionRecord<TDiff>[];\n getVersion(v: number): VersionRecord<TDiff> | undefined;\n /**\n * Snapshots the state before mutation, runs `mutate` against the live state, then\n * appends a new version recording what changed and keeps a full-state snapshot of\n * the result so this version can be restored to or undone past later.\n */\n commit(who: string, action: string, mutate: (state: TState) => string[], meta?: Record<string, unknown>): VersionRecord<TDiff>;\n /** Makes version `v` current by committing its snapshot as a NEW head version —\n * history is append-only, so this never rewrites or truncates the list. */\n restoreTo(v: number, who?: string): VersionRecord<TDiff>;\n /** Restores the state one version behind the current head, committed as a new head\n * version (the inverse of the head's change, recorded rather than erased). Throws\n * if the head is already the oldest recorded version. */\n undo(who?: string): VersionRecord<TDiff>;\n}\n\nexport function createVersionStore<TState, TDiff = unknown>(\n initialState: TState,\n options?: CreateVersionStoreOptions<TState, TDiff>,\n): VersionStore<TState, TDiff> {\n const cloneFn = options?.clone ?? ((value: TState) => structuredClone(value));\n const diffFn = options?.diff;\n const now = options?.now ?? (() => new Date().toISOString());\n\n let headVersion = options?.initialVersion ?? 0;\n let state = cloneFn(initialState);\n\n let versions: VersionRecord<TDiff>[] = [\n {\n v: headVersion,\n current: true,\n who: options?.who ?? \"system\",\n when: now(),\n action: options?.action ?? \"Initial state\",\n changes: [],\n },\n ];\n const snapshots = new Map<number, TState>();\n snapshots.set(headVersion, cloneFn(state));\n\n function append(record: Omit<VersionRecord<TDiff>, \"v\" | \"current\">): VersionRecord<TDiff> {\n headVersion += 1;\n versions.forEach((v) => { v.current = false; });\n const version: VersionRecord<TDiff> = { ...record, v: headVersion, current: true };\n versions = [version, ...versions];\n snapshots.set(headVersion, cloneFn(state));\n return version;\n }\n\n return {\n getState(): TState { return state; },\n getVersions(): VersionRecord<TDiff>[] { return [...versions]; },\n getVersion(v: number): VersionRecord<TDiff> | undefined { return versions.find((x) => x.v === v); },\n\n commit(who, action, mutate, meta) {\n const before = cloneFn(state);\n const changes = mutate(state);\n return append({\n who, when: now(), action, changes, meta,\n diff: diffFn ? diffFn(before, state) : undefined,\n });\n },\n\n restoreTo(v, who = \"system\") {\n const snapshot = snapshots.get(v);\n const original = versions.find((x) => x.v === v);\n if (!snapshot || !original) throw new Error(`createVersionStore: version ${v} not found`);\n const before = cloneFn(state);\n state = cloneFn(snapshot);\n return append({\n who, when: now(),\n action: `Restored v${v}`,\n changes: [`Restored to v${v} (${original.action})`],\n diff: diffFn ? diffFn(before, state) : undefined,\n });\n },\n\n undo(who = \"system\") {\n const head = versions[0];\n const prevSnapshot = head ? snapshots.get(head.v - 1) : undefined;\n if (!head || !prevSnapshot) throw new Error(\"createVersionStore: nothing to undo\");\n const before = cloneFn(state);\n state = cloneFn(prevSnapshot);\n return append({\n who, when: now(),\n action: `Undid: ${head.action}`,\n changes: head.changes.map((c) => `↩ ${c}`),\n diff: diffFn ? diffFn(before, state) : undefined,\n });\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACyDI;AAvDJ,IAAM,WAAmC;AAAA,EACvC,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AAuBO,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,GAAG;AACL,GAAgB;AACd,QAAMA,OAAM;AACZ,QAAM,MAAM;AAAA,IACV;AAAA,IACA,SAAS,OAAO,KAAK,SAAS;AAAA,IAC9B,SAAS,OAAO,cAAc,SAAS,OAAO,cAAc;AAAA,IAC5D,QAAQ,iBAAiB;AAAA,IACzB,UAAU,mBAAmB;AAAA,IAC7B;AAAA,EACF,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACE;AAAA,IAACA;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,MACX,UAAUA,SAAQ,WAAW,YAAY,UAAU;AAAA,MACnD,iBAAe,YAAY,UAAU,SAAS;AAAA,MAC9C,aAAW,UAAU,SAAS;AAAA,MAC7B,GAAG;AAAA,MAEH;AAAA,gBAAQ,CAAC,UAAU,4CAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,IAAK;AAAA,QAC1E,UAAU,4CAAC,UAAK,WAAU,cAAa,eAAY,QAAO,IAAK;AAAA,QAChE,4CAAC,UAAM,UAAS;AAAA,QACf,gBAAgB,CAAC,QAAQ,4CAAC,OAAE,WAAW,WAAW,cAAc,eAAY,QAAO,IAAK;AAAA,QACxF,QACC,4CAAC,UAAK,WAAU,gBAAe,eAAY,QACzC,sDAAC,OAAE,WAAU,qBAAoB,GACnC,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;;;ACxCM,IAAAC,sBAAA;AApBC,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,GAAG;AACL,GAAoB;AAClB,QAAM,MAAM;AAAA,IACV;AAAA,IACA,YAAY,YAAY,wBAAwB;AAAA,IAChD,SAAS,OAAO,mBAAmB,SAAS,OAAO,mBAAmB;AAAA,IACtE,QAAQ,sBAAsB;AAAA,IAC9B;AAAA,EACF,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACE,6CAAC,YAAO,MAAK,UAAS,WAAW,KAAK,cAAY,OAAO,OAAO,OAAO,UAAqB,GAAG,MAC7F,uDAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,GACpD;AAEJ;;;ACtCA,YAAuB;AACvB,uBAA6B;AA0IzB,IAAAC,sBAAA;AAtGJ,IAAM,SAAS;AACf,IAAM,iBAAiB,CAAC,MAA0D;AAChF,QAAM,CAAC,MAAM,QAAQ,OAAO,IAAI,OAAO,KAAK,cAAc,EAAE,MAAM,GAAG;AACrE,SAAO,EAAE,MAAM,SAAS,QAAQ,QAAQ,UAAU,MAAM;AAC1D;AAOO,SAAS,mBACd,MACA,WACA,MACwB;AACxB,QAAM,IAAI,QAAQ,CAAC;AACnB,QAAM,EAAE,MAAM,UAAU,MAAM,IAAI,eAAe,EAAE,SAAS;AAC5D,QAAM,CAAC,KAAK,MAAM,IAAU,eAAiC,IAAI;AAEjE,EAAM,sBAAgB,MAAM;AAC1B,QAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,UAAU,SAAS;AAAE,aAAO,IAAI;AAAG;AAAA,IAAQ;AACvE,UAAM,OAAO,MAAM;AACjB,YAAM,KAAK,UAAU;AACrB,UAAI,CAAC,GAAI;AACT,YAAM,IAAI,GAAG,sBAAsB;AACnC,YAAM,SAAS,EAAE,UAAU,OAAO,IAAI,EAAE;AACxC,YAAM,OAAO,EAAE,aAAa;AAC5B,YAAM,QAAQ,OAAO,cAAc,EAAE,SAAS,SAAS;AACvD,YAAM,QAAQ,EAAE,MAAM,SAAS;AAC/B,UAAI,OAAO;AACX,UAAI,SAAS,YAAY,QAAQ,KAAK,IAAI,MAAM,GAAG,KAAK,QAAQ,MAAO,QAAO;AAAA,eACrE,SAAS,SAAS,QAAQ,KAAK,IAAI,MAAM,GAAG,KAAK,QAAQ,MAAO,QAAO;AAChF,YAAM,QAAQ,EAAE,aAAa,EAAE,QAAQ,KAAK,IAAI,EAAE,SAAS,GAAG,EAAE,YAAY,CAAC;AAC7E,YAAM,IAAI,SAAS,EAAE,YAAY;AACjC,UAAI,OAAO,UAAU,QAAQ,EAAE,QAAQ,IAAI,UAAU,WAAW,EAAE,OAAO,EAAE,QAAQ,IAAI,IAAI,IAAI,EAAE;AACjG,aAAO,KAAK,IAAI,QAAQ,KAAK,IAAI,MAAM,OAAO,aAAa,IAAI,MAAM,CAAC;AACtE,YAAM,OAAO,KAAK,IAAI,KAAM,SAAS,QAAQ,QAAQ,KAAM;AAC3D,aAAO;AAAA,QACL;AAAA,QAAM,OAAO,EAAE,aAAa,EAAE,QAAQ;AAAA,QAAW,UAAU,EAAE;AAAA,QAC7D,KAAK,SAAS,WAAW,EAAE,SAAS,SAAS;AAAA,QAC7C,QAAQ,SAAS,QAAQ,OAAO,cAAc,EAAE,MAAM,SAAS;AAAA,QAC/D;AAAA,QAAM;AAAA,QAAM,aAAa,EAAE;AAAA,MAC7B,CAAC;AAAA,IACH;AACA,SAAK;AACL,WAAO,iBAAiB,UAAU,MAAM,IAAI;AAC5C,WAAO,iBAAiB,UAAU,IAAI;AACtC,WAAO,MAAM;AAAE,aAAO,oBAAoB,UAAU,MAAM,IAAI;AAAG,aAAO,oBAAoB,UAAU,IAAI;AAAA,IAAG;AAAA,EAE/G,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC;AAEhF,SAAO;AACT;AAEA,IAAM,SAAS,CAAC,SAAiD;AAC/D,MAAI,OAAO,aAAa,YAAa,YAAO,+BAAa,MAAM,SAAS,IAAI;AAC5E,SAAO;AACT;AAMO,SAAS,QAAQ;AAAA,EACtB;AAAA,EAAM;AAAA,EAAW;AAAA,EAAS,YAAY;AAAA,EAAgB,SAAS;AAAA,EAC/D,aAAa;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAW,SAAS;AAAA,EACzD,OAAO;AAAA,EAAU;AAAA,EAAO,iBAAiB;AAAA,EAAM,gBAAgB;AAAA,EAC/D,cAAc;AAAA,EAAM,YAAY;AAAA,EAAI;AAAA,EAAO;AAC7C,GAAiB;AACf,QAAM,MAAY,aAAuB,IAAI;AAC7C,QAAM,MAAM,mBAAmB,CAAC,CAAC,MAAM,WAAW,EAAE,WAAW,QAAQ,YAAY,OAAO,UAAU,WAAW,aAAa,IAAI,CAAC;AACjI,QAAM,UAAgB,aAA2B,IAAI;AAErD,EAAM,gBAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,YAAQ,UAAU,OAAO,aAAa,cAAe,SAAS,gBAAuC;AACrG,WAAO,MAAM;AACX,UAAI,eAAe,QAAQ,WAAW,QAAQ,QAAQ,OAAO;AAC3D,YAAI;AAAE,kBAAQ,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,QAAG,QAAQ;AAAA,QAAa;AAAA,MAC7E;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,WAAW,CAAC;AAEtB,EAAM,gBAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,CAAC,MAAoB;AAChC,UAAI,CAAC,eAAgB;AACrB,YAAM,SAAS,EAAE;AACjB,UAAI,IAAI,WAAW,IAAI,QAAQ,SAAS,MAAM,EAAG;AACjD,UAAI,aAAa,UAAU,WAAW,UAAU,QAAQ,SAAS,MAAM,EAAG;AAC1E,UAAK,EAAE,OAAmB,WAAY,EAAE,OAAmB,QAAQ,SAAS,EAAG;AAC/E,iBAAW,QAAQ;AAAA,IACrB;AACA,UAAM,MAAM,CAAC,MAAqB;AAAE,UAAI,iBAAiB,EAAE,QAAQ,UAAU;AAAE,UAAE,gBAAgB;AAAG,mBAAW,QAAQ;AAAA,MAAG;AAAA,IAAE;AAC5H,aAAS,iBAAiB,eAAe,MAAM,IAAI;AACnD,aAAS,iBAAiB,WAAW,GAAG;AACxC,WAAO,MAAM;AAAE,eAAS,oBAAoB,eAAe,MAAM,IAAI;AAAG,eAAS,oBAAoB,WAAW,GAAG;AAAA,IAAG;AAAA,EACxH,GAAG,CAAC,MAAM,gBAAgB,eAAe,SAAS,SAAS,CAAC;AAE5D,MAAI,CAAC,QAAQ,CAAC,IAAK,QAAO;AAC1B,SAAO;AAAA,IACL;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,cAAY;AAAA,QACZ,WAAW,CAAC,UAAU,IAAI,SAAS,QAAQ,UAAU,IAAI,SAAS,kBAAkB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAC3H,OAAO;AAAA,UACL,UAAU;AAAA,UAAS,MAAM,IAAI;AAAA,UAC7B,KAAK,IAAI,OAAO,OAAO,SAAS,IAAI;AAAA,UACpC,QAAQ,IAAI,UAAU,OAAO,SAAS,IAAI;AAAA,UAC1C,OAAO,aAAa,IAAI,QAAQ;AAAA,UAChC,UAAU,aAAa,aAAa,SAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQhD,WAAW,aAAa,OAAO,KAAK,IAAI,WAAW,IAAI,IAAI,IAAI,IAAI;AAAA,UACnE,iBAAiB,IAAI,SAAS,QAAQ,kBAAkB;AAAA,UACxD,QAAQ;AAAA,UACR,GAAG;AAAA,QACL;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,EACF;AACF;AA+BA,IAAM,SAAS,CAAC,OACd,CAAC,CAAC,MAAM,GAAG,SAAS,eAAe,GAAG,SAAS,aAAa,GAAG,SAAS,YAAY,CAAC,GAAG;AAQnF,SAAS,KAAK,EAAE,QAAQ,CAAC,GAAG,UAAU,SAAS,YAAY,MAAM,YAAY,IAAI,QAAQ,OAAO,GAAc;AACnH,QAAM,UAAgB,aAAuB,IAAI;AACjD,QAAM,CAAC,QAAQ,SAAS,IAAU,eAAS,MAAM,MAAM,UAAU,MAAM,CAAC;AACxE,QAAM,CAAC,SAAS,UAAU,IAAU,eAAwB,IAAI;AAChE,QAAM,YAAkB,aAA2B,IAAI;AACvD,QAAM,QAAc,aAAiC,EAAE,GAAG,IAAI,GAAG,EAAE,CAAC;AAEpE,EAAM,gBAAU,MAAM;AAAE,QAAI,aAAa,QAAQ,QAAS,SAAQ,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,EAAG,GAAG,CAAC,SAAS,CAAC;AAExH,QAAM,OAAO,CAAC,QAAgB;AAC5B,cAAU,CAAC,MAAM;AACf,UAAI,IAAI;AACR,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,aAAK,IAAI,MAAM,MAAM,UAAU,MAAM;AACrC,YAAI,OAAO,MAAM,CAAC,CAAC,EAAG,QAAO;AAAA,MAC/B;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,CAAC,IAAiC,MAAc;AAC7D,QAAI,CAAC,MAAM,GAAG,SAAU;AACxB,QAAI,GAAG,WAAW,GAAG,QAAQ,QAAQ;AACnC,gBAAU,UAAW,QAAQ,WAAW,QAAQ,QAAQ,cAAc,cAAc,IAAI,IAAI;AAC5F,iBAAW,CAAC;AACZ;AAAA,IACF;AACA,OAAG,YAAY,GAAG,SAAS,EAAE;AAC7B,gBAAY,SAAS,EAAE;AACvB,eAAW,QAAQ;AAAA,EACrB;AAEA,QAAM,QAAQ,CAAC,MAA2C;AACxD,QAAI,EAAE,QAAQ,aAAa;AAAE,QAAE,eAAe;AAAG,WAAK,CAAC;AAAA,IAAG,WACjD,EAAE,QAAQ,WAAW;AAAE,QAAE,eAAe;AAAG,WAAK,EAAE;AAAA,IAAG,WACrD,EAAE,QAAQ,QAAQ;AAAE,QAAE,eAAe;AAAG,gBAAU,MAAM,UAAU,MAAM,CAAC;AAAA,IAAG,WAC5E,EAAE,QAAQ,OAAO;AAAE,QAAE,eAAe;AAAG,eAAS,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,IAAK,KAAI,OAAO,MAAM,CAAC,CAAC,GAAG;AAAE,kBAAU,CAAC;AAAG;AAAA,MAAO;AAAA,IAAE,WAClI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AAAE,QAAE,eAAe;AAAG,aAAO,MAAM,MAAM,GAAG,MAAM;AAAA,IAAG,WACzF,EAAE,QAAQ,cAAc;AAAE,YAAM,KAAK,MAAM,MAAM;AAAG,UAAI,MAAM,GAAG,SAAS;AAAE,UAAE,eAAe;AAAG,eAAO,IAAI,MAAM;AAAA,MAAG;AAAA,IAAE,WACtH,EAAE,QAAQ,aAAa;AAAE,UAAI,WAAW,MAAM;AAAE,UAAE,eAAe;AAAG,mBAAW,IAAI;AAAA,MAAG;AAAA,IAAE,WACxF,EAAE,IAAI,WAAW,KAAK,KAAK,KAAK,EAAE,GAAG,GAAG;AAC/C,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,UAAU,EAAE,IAAI,MAAM,MAAM,QAAQ,IAAI,MAAM,MAAM,QAAQ,IAAI,MAAM,EAAE,IAAI,YAAY,GAAG,GAAG,IAAI;AACxG,YAAM,MAAM,MAAM,UAAU,CAAC,OAAO,OAAO,EAAE,KAAK,OAAO,GAAG,SAAS,EAAE,EAAE,YAAY,EAAE,WAAW,MAAM,QAAQ,CAAC,CAAC;AAClH,UAAI,OAAO,EAAG,WAAU,GAAG;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,MAAM,WAAW,OAAO,MAAM,OAAO,IAAI;AAE/C,SACE,8CAAO,gBAAN,EACE;AAAA;AAAA,IACD;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QAAS,UAAU;AAAA,QAAI,MAAK;AAAA,QAAO,WAAW;AAAA,QACnD,WAAW,CAAC,eAAe,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAExE,gBAAM,IAAI,CAAC,IAAI,MAAM;AACpB,cAAI,CAAC,GAAI,QAAO;AAChB,cAAI,GAAG,SAAS,YAAa,QAAO,6CAAC,SAAkB,WAAU,eAAc,MAAK,eAAtC,MAAM,CAA4C;AAChG,cAAI,GAAG,SAAS,UAAW,QAAO,6CAAC,SAAkB,WAAU,gBAAe,MAAK,gBAAgB,aAAG,SAA1D,MAAM,CAA0D;AAC5G,cAAI,GAAG,SAAS,SAAU,QAAO,6CAAC,SAAkB,WAAU,kBAAkB,aAAG,SAAS,GAAG,OAAO,IAAI,QAA/D,MAAM,CAA8D;AAC/G,gBAAM,KAAK,CAAC,CAAC,GAAG;AAChB,gBAAM,MACJ;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cAAqD,UAAQ;AAAA,cAClE,MAAM,GAAG,WAAW,OAAO,kBAAkB;AAAA,cAC7C,gBAAc,GAAG,WAAW,OAAO,KAAK;AAAA,cACxC,iBAAe,GAAG,UAAU,SAAS;AAAA,cACrC,iBAAe,GAAG,UAAU,YAAY,IAAI;AAAA,cAC5C,iBAAe,GAAG,YAAY;AAAA,cAC9B,WAAW,CAAC,UAAU,gBAAgB,MAAM,SAAS,cAAc,IAAI,KAAK,gBAAgB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,cACxH,cAAc,MAAM;AAAE,0BAAU,CAAC;AAAG,oBAAI,WAAW,QAAQ,YAAY,EAAG,YAAW,IAAI;AAAA,cAAG;AAAA,cAC5F,SAAS,MAAM,OAAO,IAAI,CAAC;AAAA,cAE1B;AAAA,mBAAG,OAAO,6CAAC,UAAK,WAAU,gBAAe,uDAAC,OAAE,WAAW,WAAW,GAAG,MAAM,eAAY,QAAO,GAAE,IAAU;AAAA,gBAC3G,8CAAC,UAAK,WAAU,gBACd;AAAA,+DAAC,UAAK,WAAU,gBAAgB,aAAG,OAAM;AAAA,kBACxC,GAAG,cAAc,6CAAC,UAAK,WAAU,eAAe,aAAG,aAAY,IAAU;AAAA,mBAC5E;AAAA,gBACC,GAAG,OAAO,6CAAC,UAAK,WAAU,eAAe,aAAG,MAAK,IAAU;AAAA,gBAC3D,GAAG,WAAW,6CAAC,UAAK,WAAU,oBAAmB,eAAY,QAAQ,aAAG,UAAS,IAAU;AAAA,gBAC3F,GAAG,UAAU,6CAAC,OAAE,WAAU,kCAAiC,eAAY,QAAO,IAAK;AAAA,gBACnF,GAAG,WAAW,OAAO,6CAAC,UAAK,WAAU,gBAAgB,eAAK,6CAAC,OAAE,WAAU,eAAc,eAAY,QAAO,IAAK,MAAK,IAAU;AAAA;AAAA;AAAA,YAlB1G,GAAG,MAAO,GAAG,SAAuB;AAAA,UAmBzD;AAEF,gBAAM,KAAK,GAAG;AACd,cAAI,CAAC,GAAI,QAAO;AAChB,iBACE,8CAAC,SAAgD,WAAU,eAAc,cAAc,MAAM,UAAU,CAAC,GACrG;AAAA;AAAA,YACD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBAAS,WAAW,CAAC,mBAAmB,GAAG,SAAS,cAAc,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,gBACnG,cAAY,GAAG;AAAA,gBAAO,OAAO,GAAG;AAAA,gBAChC,SAAS,CAAC,MAAM;AAAE,oBAAE,gBAAgB;AAAG,qBAAG,YAAY,GAAG,SAAS,EAAE;AAAG,sBAAI,GAAG,kBAAkB,OAAO;AAAE,+BAAW,QAAQ;AAAA,kBAAG;AAAA,gBAAE;AAAA,gBAEjI,uDAAC,OAAE,WAAW,YAAY,GAAG,QAAQ,UAAU,eAAY,QAAO;AAAA;AAAA,YACpE;AAAA,eARQ,GAAG,MAAO,GAAG,SAAuB,CAS9C;AAAA,QAEJ,CAAC;AAAA;AAAA,IACH;AAAA,IACC;AAAA,IACA,OAAO,IAAI,UACV;AAAA,MAAC;AAAA;AAAA,QACC,MAAI;AAAA,QAAC,WAAW,EAAE,SAAS,UAAU,QAAQ;AAAA,QAAG,WAAU;AAAA,QAAe,QAAQ;AAAA,QACjF,UAAU;AAAA,QAAK,WAAW;AAAA,QAAK,OAAO,IAAI;AAAA,QAA6B,SAAS,MAAM,WAAW,IAAI;AAAA,QACrG,WAAU;AAAA,QAEV,uDAAC,QAAK,OAAO,IAAI,SAAS,UAAU,CAAC,OAAO;AAAE,sBAAY,SAAS,EAAE;AAAG,qBAAW,QAAQ;AAAA,QAAG,GAAG,SAAS,MAAM,WAAW,IAAI,GAAG;AAAA;AAAA,IACpI,IACE;AAAA,KACN;AAEJ;AAsBO,SAAS,WAAW;AAAA,EACzB;AAAA,EAAO;AAAA,EAAM,eAAe;AAAA,EAAc,QAAQ,CAAC;AAAA,EAAG;AAAA,EAAU,YAAY;AAAA,EAC5E,UAAU;AAAA,EAAQ,OAAO;AAAA,EAAM;AAAA,EAAU;AAAA,EAAO;AAAA,EAAW;AAAA,EAAO,WAAW;AAAA,EAAK,YAAY;AAAA,EAC9F,YAAY;AAAA,EAAI;AAAA,EAAU;AAAA,EAAQ;AACpC,GAAoB;AAClB,QAAM,CAAC,MAAM,OAAO,IAAU,eAAS,KAAK;AAC5C,QAAM,MAAY,aAA0B,IAAI;AAChD,SACE,8CAAO,gBAAN,EACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QAAS;AAAA,QAAU;AAAA,QAAoB;AAAA,QAC5C,cAAY;AAAA,QAAW,iBAAc;AAAA,QAAO,iBAAe;AAAA,QAC3D,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,QAChC,WAAW,CAAC,cAAc,gBAAgB,SAAS,SAAS,OAAO,UAAU,IAAI,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAE1I;AAAA,iBAAO,6CAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,IAAK;AAAA,UAC9D,YAAY,OAAO,WAAW,6CAAC,UAAK,WAAU,oBAAoB,iBAAM;AAAA,UACxE,eAAe,6CAAC,OAAE,WAAW,WAAW,eAAe,qBAAqB,eAAY,QAAO,IAAK;AAAA;AAAA;AAAA,IACvG;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QAAY,WAAW;AAAA,QAAK;AAAA,QAAsB,SAAS,MAAM,QAAQ,KAAK;AAAA,QAC9E;AAAA,QAAc;AAAA,QAAoB;AAAA,QAAsB,MAAK;AAAA,QAAO,OAAQ,aAAa;AAAA,QAEzF,uDAAC,QAAK,OAAc,QAAgB,QAAgB,UAAoB,SAAS,MAAM,QAAQ,KAAK,GAAG;AAAA;AAAA,IACzG;AAAA,KACF;AAEJ;;;ACjWU,IAAAC,sBAAA;AAPH,SAAS,iBAAiB,EAAE,UAAU,CAAC,GAAG,OAAO,UAAU,YAAY,IAAI,GAAG,KAAK,GAA0B;AAClH,SACE,6CAAC,SAAI,WAAW,CAAC,UAAU,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,MAAK,SAAS,GAAG,MAC/E,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,IAAI,OAAO,MAAM,WAAW,IAAI,EAAE;AACxC,UAAM,QAAQ,OAAO,MAAM,WAAW,IAAI,EAAE;AAC5C,WACE;AAAA,MAAC;AAAA;AAAA,QAAe,MAAK;AAAA,QAAS,gBAAc,MAAM;AAAA,QAChD,SAAS,WAAW,MAAM,SAAS,CAAC,IAAI;AAAA,QACvC;AAAA;AAAA,MAFU;AAAA,IAGb;AAAA,EAEJ,CAAC,GACH;AAEJ;;;ACeQ,IAAAC,sBAAA;AApBD,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,GAAG;AACL,GAAc;AACZ,QAAM,MAAM;AAAA,IACV;AAAA,IACA,cAAc,SAAS,iBAAiB,cAAc,WAAW,mBAAmB;AAAA,IACpF,YAAY,sBAAsB;AAAA,IAClC;AAAA,EACF,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC1B,SACE,8CAAC,SAAI,WAAW,KAAM,GAAG,MACtB;AAAA,YACC,8CAAC,SAAI,WAAU,gBACb;AAAA,mDAAC,UAAK,WAAU,sBAAsB,iBAAM;AAAA,MAC3C;AAAA,OACH,IACE;AAAA,IACH,SAAS,6CAAC,SAAI,WAAU,gBAAgB,UAAS,IAAS;AAAA,IAC1D,SAAS,6CAAC,SAAI,WAAU,gBAAgB,kBAAO,IAAS;AAAA,KAC3D;AAEJ;AAQO,SAAS,QAAQ,EAAE,OAAO,UAAU,YAAY,GAAG,GAAiB;AACzE,SACE,8CAAC,SAAI,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACjE;AAAA,iDAAC,UAAK,WAAU,qBAAqB,iBAAM;AAAA,IAC3C,6CAAC,UAAK,WAAU,qBAAqB,UAAS;AAAA,KAChD;AAEJ;;;AC/DA,IAAAC,SAAuB;AA4CX,IAAAC,sBAAA;AAvBL,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,GAAqB;AACnB,QAAM,CAAC,UAAU,WAAW,IAAU,gBAAS,WAAW;AAC1D,QAAM,SAAS,SAAS,SAAY,WAAW;AAC/C,QAAM,SAAS,MAAM;AACnB,QAAI,SAAS,OAAW,aAAY,CAAC,MAAM;AAC3C,QAAI,SAAU,UAAS,CAAC,MAAM;AAAA,EAChC;AACA,SACE,8CAAC,SAAI,WAAW,CAAC,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,aAAW,SAAS,SAAS,SAAU,GAAG,MAC1G;AAAA,kDAAC,YAAO,MAAK,UAAS,WAAU,mBAAkB,iBAAe,QAAQ,SAAS,QAC/E;AAAA,aACC,6CAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,YAAY,qBAAqB,OAAO,gBAAgB,WAAW,OAAO,GACjH,uDAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,GACpD,IACE;AAAA,MACJ,8CAAC,UAAK,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GAClC;AAAA,qDAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,SAAS,QAAQ,GAAI,iBAAM;AAAA,QACnE,WAAW,6CAAC,UAAK,WAAU,eAAc,OAAO,EAAE,SAAS,QAAQ,GAAI,oBAAS,IAAU;AAAA,SAC7F;AAAA,MACC;AAAA,MACD,6CAAC,UAAK,WAAU,iBAAgB,uDAAC,OAAE,WAAU,oBAAmB,eAAY,QAAO,GAAE;AAAA,OACvF;AAAA,IACA,6CAAC,SAAI,WAAU,iBAAgB,uDAAC,SAAI,uDAAC,SAAI,WAAU,mBAAmB,UAAS,GAAM,GAAM;AAAA,KAC7F;AAEJ;;;ACzDA,IAAAC,SAAuB;AACvB,IAAAC,oBAA6B;AA+BzB,IAAAC,sBAAA;AAlBG,SAAS,OAAO,EAAE,OAAO,MAAM,OAAO,SAAS,QAAQ,UAAU,YAAY,IAAI,GAAG,KAAK,GAAgB;AAC9G,QAAM,CAAC,SAAS,UAAU,IAAU,gBAAS,KAAK;AAClD,QAAM,QAAc,mBAAY,MAAM;AACpC,QAAI,CAAC,QAAS;AACd,eAAW,IAAI;AACf,eAAW,SAAS,GAAG;AAAA,EACzB,GAAG,CAAC,OAAO,CAAC;AACZ,EAAM,iBAAU,MAAM;AACpB,QAAI,CAAC,QAAQ,CAAC,QAAS;AACvB,UAAM,IAAI,CAAC,MAAqB;AAAE,UAAI,EAAE,QAAQ,SAAU,OAAM;AAAA,IAAG;AACnE,aAAS,iBAAiB,WAAW,CAAC;AACtC,WAAO,MAAM,SAAS,oBAAoB,WAAW,CAAC;AAAA,EACxD,GAAG,CAAC,MAAM,SAAS,KAAK,CAAC;AACzB,MAAI,CAAC,KAAM,QAAO;AAIlB,aAAO;AAAA,IACL,8EACE;AAAA,mDAAC,SAAI,WAAW,cAAc,UAAU,gBAAgB,KAAK,OAAO,EAAE,SAAS,QAAQ,GAAG,SAAS,OAAO;AAAA,MAC1G,8CAAC,WAAM,WAAW,CAAC,aAAa,UAAU,eAAe,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,MAAK,UAAS,cAAW,QAAQ,GAAG,MACrI;AAAA,sDAAC,SAAI,WAAU,gBAAe,OAAO,EAAE,MAAM,OAAO,GAClD;AAAA,uDAAC,UAAK,WAAU,sBAAsB,iBAAM;AAAA,UAC3C,UAAU,6CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,cAAW,SAAQ,SAAS,OAAO,uDAAC,OAAE,WAAU,WAAU,GAAE,IAAY;AAAA,WACnI;AAAA,QACA,6CAAC,SAAI,OAAO,EAAE,MAAM,YAAY,WAAW,GAAG,UAAU,QAAQ,SAAS,GAAG,GAAI,UAAS;AAAA,QACxF,SAAS,6CAAC,SAAI,WAAU,gBAAe,OAAO,EAAE,MAAM,OAAO,GAAI,iBAAO,WAAW,aAAa,OAAO,KAAK,IAAI,QAAO,IAAS;AAAA,SACnI;AAAA,OACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;AC7CA,IAAAC,SAAuB;AACvB,IAAAC,oBAA6B;AA8CjB,IAAAC,sBAAA;AA9BL,SAAS,MAAM,EAAE,OAAO,MAAM,OAAO,aAAa,SAAS,QAAQ,OAAO,OAAO,UAAU,YAAY,IAAI,GAAG,KAAK,GAAe;AACvI,QAAM,CAAC,SAAS,UAAU,IAAU,gBAAS,KAAK;AAClD,QAAM,QAAc,mBAAY,MAAM;AACpC,QAAI,CAAC,QAAS;AACd,eAAW,IAAI;AACf,eAAW,SAAS,GAAG;AAAA,EACzB,GAAG,CAAC,OAAO,CAAC;AACZ,EAAM,iBAAU,MAAM;AACpB,QAAI,CAAC,QAAQ,CAAC,QAAS;AACvB,UAAM,IAAI,CAAC,MAAqB;AAAE,UAAI,EAAE,QAAQ,SAAU,OAAM;AAAA,IAAG;AACnE,aAAS,iBAAiB,WAAW,CAAC;AACtC,WAAO,MAAM,SAAS,oBAAoB,WAAW,CAAC;AAAA,EACxD,GAAG,CAAC,MAAM,SAAS,KAAK,CAAC;AACzB,MAAI,CAAC,KAAM,QAAO;AAGlB,aAAO;AAAA,IACL;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,cAAc,UAAU,gBAAgB;AAAA,QACnD,SAAS,UAAU,CAAC,MAAwC;AAAE,cAAI,EAAE,WAAW,EAAE,cAAe,OAAM;AAAA,QAAG,IAAI;AAAA,QAE7G;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,CAAC,YAAY,UAAU,eAAe,IAAI,OAAO,kBAAkB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,YACrH,MAAK;AAAA,YACL,cAAW;AAAA,YACX,cAAY,OAAO,UAAU,WAAW,QAAQ;AAAA,YAC/C,GAAG;AAAA,YAEH;AAAA,sBACC,8CAAC,SAAI,WAAU,iBACb;AAAA,8DAAC,UAAK,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GAClC;AAAA,+DAAC,UAAK,WAAU,kBAAiB,OAAO,EAAE,SAAS,QAAQ,GAAI,iBAAM;AAAA,kBACpE,cAAc,6CAAC,UAAK,WAAU,2BAA0B,OAAO,EAAE,SAAS,SAAS,WAAW,EAAE,GAAI,uBAAY,IAAU;AAAA,mBAC7H;AAAA,gBACC,UAAU,6CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,cAAW,SAAQ,SAAS,OAAO,uDAAC,OAAE,WAAU,WAAU,GAAE,IAAY;AAAA,iBACnI,IACE;AAAA,cACJ,6CAAC,SAAI,WAAU,iBAAiB,UAAS;AAAA,cACxC,SAAS,6CAAC,SAAI,WAAU,iBAAiB,iBAAO,WAAW,aAAa,OAAO,KAAK,IAAI,QAAO,IAAS;AAAA;AAAA;AAAA,QAC3G;AAAA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;AC7BM,IAAAC,sBAAA;AAZC,SAAS,cAAc;AAAA,EAC5B,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,GAAuB;AACrB,MAAI,UAAU,WAAW,UAAU,SAAS;AAC1C,WACE,8CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACrE;AAAA,mDAAC,UAAK,WAAU,iBACd,uDAAC,OAAE,WAAW,UAAU,UAAU,kBAAkB,cAAc,eAAY,QAAO,GACvF;AAAA,MACA,6CAAC,UAAK,WAAU,kBAAkB,oBAAU,UAAU,qBAAqB,oBAAmB;AAAA,MAC9F,6CAAC,UAAK,WAAU,iBAAiB,mBAAS,yCAAwC;AAAA,MACjF,UAAU,6CAAC,YAAO,MAAK,UAAS,WAAU,2BAA0B,SAAS,SAAS,uBAAS,IAAY;AAAA,OAC9G;AAAA,EAEJ;AACA,MAAI,UAAU,WAAW;AACvB,WACE,8CAAC,SAAI,WAAsB,MAAK,UAAS,aAAU,QAAO,cAAY,OAAQ,GAAG,MAC/E;AAAA,mDAAC,UAAK,WAAU,SAAS,iBAAM;AAAA,MAC9B;AAAA,OACH;AAAA,EAEJ;AACA,QAAM,QAAQ,UAAU;AACxB,SACE;AAAA,IAAC;AAAA;AAAA,MAAI,WAAW,CAAC,QAAQ,oBAAoB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAClF,aAAW,QAAQ,SAAS;AAAA,MAAY,GAAG;AAAA,MAC3C,uDAAC,SAAI,WAAW,QAAQ,aAAa,cAAe,UAAS;AAAA;AAAA,EAC/D;AAEJ;;;ACxCmB,IAAAC,uBAAA;AAPZ,SAAS,YAAY,EAAE,OAAO,OAAO,YAAY,OAAO,YAAY,IAAI,GAAG,KAAK,GAAqB;AAC1G,QAAM,gBAAgB,UAAU,UAAa,UAAU;AACvD,QAAM,MAAM,gBAAgB,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,CAAC;AAChE,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,EAAE,GAChF;AAAA,aAAS,YACR,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,gBAAgB,iBAAiB,KAAK,GAAG,GACvE;AAAA,cAAQ,8CAAC,UAAK,WAAU,eAAe,iBAAM,IAAU,8CAAC,UAAK;AAAA,MAC7D,aAAa,CAAC,gBAAgB,+CAAC,UAAK,WAAU,uBAAuB;AAAA;AAAA,QAAI;AAAA,SAAC,IAAU;AAAA,OACvF,IACE;AAAA,IACJ;AAAA,MAAC;AAAA;AAAA,QAAI,WAAW,CAAC,eAAe,gBAAgB,8BAA8B,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QACxG,MAAK;AAAA,QAAc,iBAAe,gBAAgB,SAAY;AAAA,QAC9D,iBAAe;AAAA,QAAG,iBAAe;AAAA,QAAK,cAAY;AAAA,QAAQ,GAAG;AAAA,QAC7D,wDAAC,SAAI,WAAU,oBAAmB,OAAO,gBAAgB,SAAY,EAAE,OAAO,MAAM,IAAI,GAAG;AAAA;AAAA,IAC7F;AAAA,KACF;AAEJ;;;ACNS,IAAAC,uBAAA;AANF,SAAS,SAAS,EAAE,IAAI,QAAQ,IAAI,IAAI,QAAQ,SAAS,QAAQ,OAAO,YAAY,IAAI,GAAG,KAAK,GAAkB;AACvH,QAAM,MAAM;AAAA,IACV;AAAA,IACA,UAAU,WAAW,mBAAmB,UAAU,SAAS,iBAAiB,UAAU,SAAS,iBAAiB;AAAA,IAChH;AAAA,EACF,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC1B,SAAO;AAAA,IAAC;AAAA;AAAA,MAAK,eAAY;AAAA,MAAO,WAAW;AAAA,MACzC,OAAO,EAAE,SAAS,SAAS,OAAO,GAAG,QAAQ,OAAO,MAAM,WAAW,IAAI,OAAO,GAAG,cAAc,QAAQ,GAAG,MAAM;AAAA,MAAI,GAAG;AAAA;AAAA,EAAM;AACnI;AAWO,SAAS,aAAa,EAAE,QAAQ,GAAG,QAAQ,CAAC,QAAQ,OAAO,KAAK,GAAG,OAAO,IAAI,MAAM,GAAG,YAAY,GAAG,GAAsB;AACjI,SACE,8CAAC,UAAK,eAAY,QAAO,WAAsB,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,MAAM,KAAK,GAC/G,gBAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,MACrC;AAAA,IAAC;AAAA;AAAA,MAAa,WAAU;AAAA,MACtB,OAAO,EAAE,SAAS,SAAS,QAAQ,OAAO,MAAM,OAAO,MAAM,IAAI,MAAM,MAAM,EAAE;AAAA;AAAA,IADtE;AAAA,EACyE,CACrF,GACH;AAEJ;;;AC/BI,IAAAC,uBAAA;AAFG,SAAS,QAAQ,EAAE,OAAO,MAAM,QAAQ,WAAW,YAAY,IAAI,OAAO,GAAG,KAAK,GAAiB;AACxG,SACE;AAAA,IAAC;AAAA;AAAA,MAAK,MAAK;AAAA,MAAS,cAAY;AAAA,MAC9B,WAAW,CAAC,cAAc,SAAS,OAAO,kBAAkB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MACnG;AAAA,MAAe,GAAG;AAAA;AAAA,EAAM;AAE9B;;;ACmBS,IAAAC,uBAAA;AADT,SAAS,IAAI,EAAE,OAAO,SAAS,GAAkD;AAC/E,SAAO,8CAAC,UAAK,OAAO,OAAO,OAAO,EAAE,SAAS,eAAe,MAAM,OAAO,GAAI,UAAS;AACxF;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,CAAC,GAAG,SAAAC,UAAS,YAAY,QAAQ,OAAO,OAAO,YAAY,IAAI,GAAG,KAAK,GAAoB;AACtI,SACE,+CAAC,SAAI,WAAW,CAAC,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,aAAW,OAAO,SAAS,SAAU,GAAG,MACvG;AAAA,YAAQ,8CAAC,SAAI,OAAO,EAAE,QAAQ,mBAAmB,SAAS,QAAQ,YAAY,UAAU,SAAS,UAAU,cAAc,2BAA2B,MAAM,QAAQ,UAAU,SAAS,GAAI,iBAAM,IAAS;AAAA,IACzM,8CAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,QAAQ,SAAS,gBAAgB,GAC/D,iBAAO,IAAI,CAAC,GAAG,OACd,+CAAC,SACE;AAAA,QAAE,QAAQ,8CAAC,SAAI,WAAU,iBAAiB,YAAE,OAAM,IAAS;AAAA,MAC5D,8CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACvC,YAAE,MAAM,IAAI,CAAC,OACZ;AAAA,QAAC;AAAA;AAAA,UAAsB,MAAK;AAAA,UAAS,WAAU;AAAA,UAC7C,gBAAcA,aAAY,GAAG,QAAQ,SAAS;AAAA,UAC9C,SAAS,aAAa,MAAM,WAAW,GAAG,KAAK,IAAI;AAAA,UACnD;AAAA,0DAAC,UAAK,WAAU,qBAAoB,wDAAC,OAAE,WAAW,WAAW,GAAG,MAAM,eAAY,QAAO,GAAE;AAAA,YAC3F,8CAAC,UAAK,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,UAAU,cAAc,YAAY,YAAY,SAAS,GAAI,aAAG,OAAM;AAAA,YAGpH,GAAG,UAAU,8CAAC,OAAI,OAAM,mCAAkC,wDAAC,OAAE,WAAU,sBAAqB,OAAO,EAAE,UAAU,IAAI,OAAO,qBAAqB,MAAM,OAAO,GAAG,GAAE,IAAS;AAAA,YAC1K,GAAG,SAAS,8CAAC,OAAI,OAAM,uCAAsC,wDAAC,OAAE,WAAU,qBAAoB,OAAO,EAAE,UAAU,IAAI,OAAO,qBAAqB,MAAM,OAAO,GAAG,GAAE,IAAS;AAAA,YAC5K,GAAG,UAAU,SAAY,8CAAC,UAAK,WAAU,sBAAsB,aAAG,OAAM,IAAU;AAAA,YAClF,GAAG,UAAU,8CAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,OAAO,IAAI,QAAQ,IAAI,YAAY,OAAO,GAAG,IAAK;AAAA;AAAA;AAAA,QAVrG,GAAG;AAAA,MAWhB,CACD,GACH;AAAA,SAjBQ,EAkBV,CACD,GACH;AAAA,IACC,SAAS,8CAAC,SAAI,OAAO,EAAE,WAAW,2BAA2B,SAAS,IAAI,MAAM,OAAO,GAAI,kBAAO,IAAS;AAAA,KAC9G;AAEJ;;;AChDM,IAAAC,uBAAA;AAbN,IAAM,WACJ;AASK,SAAS,cAAc,EAAE,OAAO,MAAM,YAAY,IAAI,GAAG,KAAK,GAAuB;AAC1F,SACE,8CAAC,UAAK,WAAW,CAAC,iBAAiB,SAAS,OAAO,mBAAmB,OAAO,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACzH,wDAAC,SAAI,KAAK,UAAU,KAAI,aAAY,GACtC;AAEJ;AAWO,SAAS,eAAe,EAAE,SAAS,OAAO,MAAM,YAAY,IAAI,GAAG,KAAK,GAAwB;AACrG,SACE,+CAAC,UAAK,WAAW,CAAC,YAAY,SAAS,OAAO,cAAc,OAAO,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MAC/G;AAAA,kDAAC,iBAAc,MAAY;AAAA,IAC3B,8CAAC,UAAK,WAAU,wBAAwB,mBAAQ;AAAA,KAClD;AAEJ;;;ACtBU,IAAAC,uBAAA;AARH,SAAS,KAAK,EAAE,OAAO,CAAC,GAAG,OAAO,UAAU,YAAY,IAAI,GAAG,KAAK,GAAc;AACvF,SACE,8CAAC,SAAI,WAAW,CAAC,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,MAAK,WAAW,GAAG,MAClF,eAAK,IAAI,CAAC,MAAM;AACf,UAAM,IAAI,OAAO,MAAM,WAAW,IAAI,EAAE;AACxC,UAAM,QAAQ,OAAO,MAAM,WAAW,IAAI,EAAE;AAC5C,UAAM,QAAQ,OAAO,MAAM,WAAW,SAAY,EAAE;AACpD,WACE;AAAA,MAAC;AAAA;AAAA,QAAe,MAAK;AAAA,QAAS,MAAK;AAAA,QAAM,WAAU;AAAA,QAAS,iBAAe,MAAM;AAAA,QAC/E,SAAS,WAAW,MAAM,SAAS,CAAC,IAAI;AAAA,QACvC;AAAA;AAAA,UACA,UAAU,SAAY,8CAAC,UAAK,WAAU,6BAA4B,OAAO,EAAE,QAAQ,IAAI,SAAS,QAAQ,GAAI,iBAAM,IAAU;AAAA;AAAA;AAAA,MAHlH;AAAA,IAIb;AAAA,EAEJ,CAAC,GACH;AAEJ;;;AC5BA,IAAAC,SAAuB;AAoB0E,IAAAC,uBAAA;AAH1F,SAAS,OAAO,EAAE,SAAS,CAAC,GAAG,SAAS,UAAU,OAAO,QAAQ,YAAY,IAAI,GAAG,KAAK,GAAgB;AAC9G,SACE,+CAAC,YAAO,WAAW,CAAC,aAAa,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACxE;AAAA,aAAS,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,cAAW,QAAO,SAAS,QAAQ,wDAAC,OAAE,WAAU,cAAa,GAAE,IAAY;AAAA,IACnI,8CAAC,SAAI,WAAU,YAAW,cAAW,cAClC,iBAAO,IAAI,CAAC,GAAG,MACd,+CAAO,iBAAN,EACE;AAAA,UAAI,IAAI,8CAAC,OAAE,WAAU,qBAAoB,OAAO,EAAE,UAAU,IAAI,SAAS,IAAG,GAAG,eAAY,QAAO,IAAK;AAAA,MACvG,MAAM,OAAO,SAAS,IACrB,8CAAC,UAAK,WAAU,oBAAoB,YAAE,OAAM,IAE5C;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,EAAE,QAAQ;AAAA,UAChB,SACE,EAAE,UACE,CAAC,MAAM;AACL,cAAE,eAAe;AACjB,cAAE,QAAS;AAAA,UACb,IACA;AAAA,UAGL,YAAE;AAAA;AAAA,MACL;AAAA,SAjBiB,CAmBrB,CACD,GACH;AAAA,IACA,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,IACzB;AAAA,IACA,UAAU,8CAAC,UAAK,WAAU,cAAa,eAAY,QAAO,IAAK;AAAA,KAClE;AAEJ;;;ACpCa,IAAAC,uBAAA;AALN,SAAS,OAAO,EAAE,OAAO,IAAI,KAAK,OAAO,MAAM,YAAY,IAAI,GAAG,KAAK,GAAgB;AAC5F,QAAM,WAAW,KAAK,MAAM,KAAK,EAAE,OAAO,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY;AACrG,SACE;AAAA,IAAC;AAAA;AAAA,MAAK,WAAW,CAAC,aAAa,SAAS,OAAO,iBAAiB,SAAS,OAAO,iBAAiB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MACtI,OAAO,QAAQ;AAAA,MAAY,GAAG;AAAA,MAC7B,gBAAM,8CAAC,SAAI,KAAU,KAAK,MAAM,IAAK,YAAY,8CAAC,OAAE,WAAU,cAAa,eAAY,QAAO;AAAA;AAAA,EACjG;AAEJ;AASO,SAAS,YAAY,EAAE,SAAS,CAAC,GAAG,OAAO,MAAM,MAAM,GAAG,YAAY,GAAG,GAAqB;AACnG,QAAM,QAAQ,OAAO,MAAM,GAAG,GAAG;AACjC,QAAM,OAAO,OAAO,SAAS,MAAM;AACnC,SACE,+CAAC,UAAK,WAAW,CAAC,mBAAmB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACrE;AAAA,UAAM,IAAI,CAAC,GAAG,MAAM,8CAAC,UAAe,MAAM,OAAO,MAAM,WAAW,IAAI,EAAE,MAAM,KAAK,OAAO,MAAM,WAAW,SAAY,EAAE,KAAK,QAA7F,CAAyG,CAAE;AAAA,IAC5I,OAAO,IAAI,8CAAC,UAAO,MAAM,MAAM,MAAM,MAAY,IAAK;AAAA,KACzD;AAEJ;;;AChBI,IAAAC,uBAAA;AAjBJ,IAAM,QAAgC,EAAE,SAAS,oBAAoB,MAAM,iBAAiB,SAAS,oBAAoB,SAAS,oBAAoB,QAAQ,mBAAmB,MAAM,iBAAiB,UAAU,qBAAqB,OAAO,iBAAiB;AAexP,SAAS,MAAM,EAAE,UAAU,OAAO,WAAW,MAAM,OAAO,MAAM,YAAY,IAAI,GAAG,KAAK,GAAe;AAC5G,SACE,+CAAC,UAAK,WAAW,CAAC,YAAY,MAAM,IAAI,KAAK,MAAM,SAAS,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACnG;AAAA,UAAM,8CAAC,UAAK,WAAU,gBAAe,eAAY,QAAO,IAAK;AAAA,IAC7D,OAAO,8CAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,IAAK;AAAA,IAC9D;AAAA,KACH;AAEJ;;;ACXI,IAAAC,uBAAA;AAFG,SAAS,WAAW,EAAE,OAAO,QAAQ,OAAO,UAAU,QAAQ,YAAY,IAAI,GAAG,KAAK,GAAoB;AAC/G,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACrE;AAAA,kDAAC,UAAK,WAAU,iBAAgB,wDAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,GAAE;AAAA,IACpF,8CAAC,UAAK,WAAU,kBAAkB,iBAAM;AAAA,IACvC,WAAW,8CAAC,UAAK,WAAU,iBAAiB,UAAS,IAAU;AAAA,IAC/D;AAAA,KACH;AAEJ;;;ACCgB,IAAAC,uBAAA;AALT,SAAS,KAAK,EAAE,WAAW,MAAM,SAAS,OAAO,WAAW,YAAY,IAAI,GAAG,KAAK,GAAc;AACvG,SACE,+CAAC,SAAI,WAAW,CAAC,WAAW,aAAa,MAAM,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,MAAK,UAAU,GAAG,MACrG;AAAA,mDAAC,UAAK,WAAU,gBACb;AAAA;AAAA,MACA,OAAO,gFAAE;AAAA;AAAA,QAAC,8CAAC,UAAK,WAAU,gBAAgB,gBAAK;AAAA,SAAO,IAAM;AAAA,OAC/D;AAAA,IACC,UAAU,8CAAC,UAAK,WAAU,mBAAmB,mBAAQ,IAAU;AAAA,KAClE;AAEJ;;;ACDe,IAAAC,uBAAA;AAxBf,IAAM,SAAS,OAAO,cAAc,eAAe,kBAAkB,KAAK,UAAU,YAAY,UAAU,aAAa,EAAE;AAEzH,IAAM,QAAgC;AAAA,EACpC,KAAK,SAAS,WAAM;AAAA,EAAQ,KAAK;AAAA,EAAK,MAAM;AAAA,EAAK,MAAM,SAAS,WAAM;AAAA,EACtE,KAAK,SAAS,WAAM;AAAA,EAAO,KAAK;AAAA,EAAK,QAAQ;AAAA,EAAK,OAAO;AAAA,EACzD,OAAO;AAAA,EAAK,QAAQ;AAAA,EAAK,KAAK;AAAA,EAAO,QAAQ;AAAA,EAAO,KAAK;AAAA,EAAK,OAAO;AAAA,EACrE,WAAW;AAAA,EAAK,QAAQ;AAAA,EAAK,IAAI;AAAA,EAAK,MAAM;AAAA,EAAK,MAAM;AAAA,EAAK,OAAO;AAAA,EAAK,OAAO;AACjF;AASO,SAAS,QAAQ,EAAE,MAAM,OAAO,MAAM,OAAO,SAAS,YAAY,IAAI,GAAG,KAAK,GAAiB;AACpG,QAAM,QAAQ,OAAO,QAAQ,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAC/E,QAAM,MAAM,CAAC,cAAc,SAAS,OAAO,kBAAkB,IAAI,SAAS,UAAU,qBAAqB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAChJ,SACE,8CAAC,UAAK,WAAW,KAAK,eAAY,QAAQ,GAAG,MAC1C,gBAAM,IAAI,CAAC,GAAG,MAAM;AACnB,UAAM,IAAI,EAAE,YAAY;AACxB,UAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,IAAI,EAAE,YAAY,IAAI;AAC9D,WAAO,8CAAC,SAAa,mBAAJ,CAAU;AAAA,EAC7B,CAAC,GACH;AAEJ;AAGO,SAAS,gBAAwB;AAAE,SAAO,MAAM;AAAK;AAErD,SAAS,YAAY,GAAiD;AAAE,SAAO,SAAS,EAAE,UAAU,EAAE;AAAS;;;ACdlH,IAAAC,uBAAA;AAhBJ,IAAMC,SAAgC,EAAE,MAAM,eAAe,SAAS,kBAAkB,SAAS,kBAAkB,QAAQ,gBAAgB;AAcpI,SAAS,IAAI,EAAE,UAAU,MAAM,WAAW,OAAO,OAAO,WAAW,UAAU,SAAS,YAAY,IAAI,GAAG,KAAK,GAAa;AAChI,SACE;AAAA,IAAC;AAAA;AAAA,MAAO,MAAK;AAAA,MAAS,WAAW,CAAC,UAAU,WAAWA,OAAM,IAAI,IAAI,MAAM,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC5G,gBAAc;AAAA,MAAU;AAAA,MAAmB,GAAG;AAAA,MAC7C;AAAA,eAAO,8CAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,IAAK;AAAA,QAC9D;AAAA,QACA,WACC;AAAA,UAAC;AAAA;AAAA,YAAK,WAAU;AAAA,YAAgB,MAAK;AAAA,YAAS,cAAW;AAAA,YACvD,SAAS,CAAC,MAAM;AAAE,gBAAE,gBAAgB;AAAG,uBAAS;AAAA,YAAG;AAAA,YAAG,wDAAC,OAAE,WAAU,WAAU;AAAA;AAAA,QAAE,IAC/E;AAAA;AAAA;AAAA,EACN;AAEJ;;;ACP8B,IAAAC,uBAAA;AAtB9B,IAAM,OAAkD;AAAA,EACtD,SAAS,EAAE,GAAG,SAAS,IAAI,kBAAkB;AAAA,EAC7C,OAAO,EAAE,GAAG,KAAK,IAAI,sBAAsB;AAAA,EAC3C,MAAM,EAAE,GAAG,QAAQ,IAAI,oBAAoB;AAAA,EAC3C,SAAS,EAAE,GAAG,IAAI,IAAI,eAAe;AACvC;AAYO,SAAS,MAAM,EAAE,OAAO,UAAU,OAAO,WAAW,QAAQ,WAAW,YAAY,IAAI,GAAG,KAAK,GAAe;AACnH,QAAM,KAAK,KAAK,IAAI,KAAK,KAAK;AAC9B,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,MAAK,UAAU,GAAG,MACnF;AAAA,kDAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,YAAY,GAAG,GAAG,GAAG,eAAY,QACvE,mBAAS,YAAY,8CAAC,UAAK,WAAU,cAAa,OAAO,EAAE,OAAO,IAAI,QAAQ,IAAI,aAAa,GAAG,OAAO,OAAO,GAAG,IAAK,8CAAC,OAAE,WAAW,WAAW,GAAG,GAAG,GAC1J;AAAA,IACA,+CAAC,UAAK,WAAU,iBACd;AAAA,oDAAC,UAAK,WAAU,kBAAiB,OAAO,EAAE,SAAS,QAAQ,GAAI,iBAAM;AAAA,MACpE,WAAW,8CAAC,UAAK,WAAU,gBAAe,OAAO,EAAE,SAAS,SAAS,WAAW,EAAE,GAAI,UAAS,IAAU;AAAA,MACzG,SAAS,8CAAC,YAAO,MAAK,UAAS,WAAU,sBAAqB,OAAO,EAAE,WAAW,EAAE,GAAG,SAAS,QAAQ,kBAAI,IAAY;AAAA,OAC3H;AAAA,IACC,YAAY,8CAAC,YAAO,MAAK,UAAS,WAAU,8BAA6B,cAAW,WAAU,SAAS,WAAW,wDAAC,OAAE,WAAU,WAAU,GAAE,IAAY;AAAA,KAC1J;AAEJ;;;AClCA,IAAAC,SAAuB;AAgBnB,IAAAC,uBAAA;AANG,SAAS,QAAQ,EAAE,OAAO,YAAY,OAAO,UAAU,YAAY,GAAG,GAAiB;AAC5F,QAAM,CAAC,MAAM,OAAO,IAAU,gBAAS,KAAK;AAC5C,QAAM,MAAM,cAAc,WACtB,EAAE,KAAK,oBAAoB,MAAM,OAAO,WAAW,mBAAmB,IACtE,EAAE,QAAQ,oBAAoB,MAAM,OAAO,WAAW,mBAAmB;AAC7E,SACE;AAAA,IAAC;AAAA;AAAA,MAAK,OAAO,EAAE,UAAU,YAAY,SAAS,cAAc;AAAA,MAC1D,cAAc,MAAM,QAAQ,IAAI;AAAA,MAAG,cAAc,MAAM,QAAQ,KAAK;AAAA,MACpE,SAAS,MAAM,QAAQ,IAAI;AAAA,MAAG,QAAQ,MAAM,QAAQ,KAAK;AAAA,MACxD;AAAA;AAAA,QACA,OAAO,8CAAC,UAAK,WAAW,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,MAAK,WAAU,OAAO,KAAM,iBAAM,IAAU;AAAA;AAAA;AAAA,EAC5H;AAEJ;;;ACvBA,IAAAC,SAAuB;AAsDjB,IAAAC,uBAAA;AApCC,SAAS,MAAM;AAAA,EACpB;AAAA,EAAU;AAAA,EAAM;AAAA,EAAU,YAAY;AAAA,EACtC,YAAY;AAAA,EAAa,YAAY;AAAA,EACrC;AAAA,EAAU,YAAY;AACxB,GAAe;AACb,QAAM,CAAC,MAAM,OAAO,IAAU,gBAAS,KAAK;AAC5C,QAAM,CAAC,WAAW,YAAY,IAAU,gBAAS,KAAK;AACtD,QAAM,UAAgB,cAAuB,IAAI;AAEjD,QAAM,cAAoB,eAAQ,MAAM;AACtC,QAAI,QAAQ,CAAC,YAAY,OAAO,SAAS,YAAY,KAAK,UAAU,SAAU,QAAO;AACrF,UAAM,MAAM,KAAK,MAAM,GAAG,QAAQ;AAClC,UAAM,KAAK,IAAI,YAAY,GAAG;AAC9B,YAAQ,KAAK,WAAW,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK,QAAQ,IAAI;AAAA,EACpE,GAAG,CAAC,MAAM,UAAU,IAAI,CAAC;AAEzB,EAAM,uBAAgB,MAAM;AAC1B,UAAM,OAAO,QAAQ;AACrB,QAAI,YAAY,CAAC,QAAQ,CAAC,UAAW;AACrC,UAAM,UAAU,MAAM;AACpB,YAAM,KAAK,QAAQ;AACnB,UAAI,GAAI,cAAa,GAAG,eAAe,YAAY,EAAE;AAAA,IACvD;AACA,YAAQ;AACR,UAAM,KAAK,OAAO,mBAAmB,cAAc,iBAAiB;AACpE,QAAI,CAAC,GAAI;AACT,UAAM,KAAK,IAAI,GAAG,OAAO;AACzB,OAAG,QAAQ,IAAI;AACf,WAAO,MAAM,GAAG,WAAW;AAAA,EAC7B,GAAG,CAAC,WAAW,UAAU,UAAU,IAAI,CAAC;AAExC,QAAM,UAAU,WAAW,CAAC,CAAC,cAAc,aAAa,CAAC;AACzD,QAAM,SAAS,MAAM;AAAE,YAAQ,CAAC,MAAM;AAAE,kBAAY,SAAS,CAAC,CAAC;AAAG,aAAO,CAAC;AAAA,IAAG,CAAC;AAAA,EAAG;AAEjF,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,UAAU,eAAe,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC3F;AAAA,kDAAC,SAAI,WAAU,iBAAgB,KAAK,SAAS,OAAO,CAAC,YAAY,UAAU,EAAE,UAAU,IAAI,QACxF,qBAAY,eAAe,OAAO,cAAe,QAAQ,OAAO,OAAO,WAAa,UACvF;AAAA,KACE,WAAY,eAAe,QAAQ,OAAQ,aAC3C,+CAAC,YAAO,MAAK,UAAS,WAAU,iBAAgB,SAAS,QAAQ,iBAAe,MAC9E;AAAA,oDAAC,OAAE,WAAW,kBAAkB,OAAO,OAAO,SAAS,eAAY,QAAO;AAAA,MACzE,OAAO,YAAY;AAAA,OACtB,IACE;AAAA,KACN;AAEJ;;;ACtCQ,IAAAC,uBAAA;AAzBR,IAAM,QAAsD;AAAA,EAC1D,MAAM,EAAE,GAAG,GAAG,OAAO,OAAO;AAAA,EAC5B,UAAU,EAAE,GAAG,GAAG,OAAO,WAAW;AAAA,EACpC,QAAQ,EAAE,GAAG,GAAG,OAAO,SAAS;AAAA,EAChC,UAAU,EAAE,GAAG,GAAG,OAAO,WAAW;AACtC;AAIA,SAAS,UAAU,KAAqB;AACtC,SAAO,IAAI,QAAQ,CAAC;AACtB;AASO,SAAS,SAAS,EAAE,OAAO,QAAQ,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE,GAAkB;AACvF,QAAM,KAAK,MAAM,IAAI,KAAK,MAAM,MAAM;AACtC,SACE,8CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,MAAM,KAAK,GAAG,eAAY,QAChE,WAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACjB;AAAA,IAAC;AAAA;AAAA,MAEC,WAAW,kBAAkB,KAAK,IAAI,WAAW;AAAA,MACjD,OAAO,EAAE,OAAO,QAAQ,MAAM,QAAQ,OAAO,KAAK;AAAA;AAAA,IAF7C;AAAA,EAGP,CACD,GACH;AAEJ;AAmBO,SAAS,SAAS,EAAE,OAAO,QAAQ,KAAK,OAAO,WAAW,UAAU,OAAO,QAAQ,OAAO,YAAY,IAAI,GAAG,KAAK,GAAkB;AACzI,QAAM,IAAI,MAAM,IAAI,KAAK,MAAM;AAC/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,CAAC,UAAU,YAAY,EAAE,GAAG,SAAS,WAAW,kBAAkB,kBAAkB,UAAU,mBAAmB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAClK,GAAG;AAAA,MAEH;AAAA,gBAAQ,8CAAC,UAAK,WAAU,gBAAe,OAAO,EAAE,YAAY,mBAAmB,GAAG,cAAW,WAAU,IAAK;AAAA,QAC7G,8CAAC,YAAS,MAAY,MAAM,SAAS,WAAW,KAAK,GAAG,OAAO,SAAS,WAAW,IAAI,GAAG;AAAA,QACzF,EAAE;AAAA,QACF,QAAQ,UAAa,QAAQ,OAAO,8CAAC,UAAK,WAAU,cAAc,oBAAU,GAAG,GAAE,IAAU;AAAA;AAAA;AAAA,EAC9F;AAEJ;AASO,SAAS,QAAQ,EAAE,OAAO,QAAQ,KAAK,OAAO,YAAY,GAAG,GAAiB;AACnF,QAAM,IAAI,MAAM,IAAI,KAAK,MAAM;AAC/B,QAAM,OAAO,eAAe,EAAE,IAAI;AAClC,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,GAAG,GAClF;AAAA,kDAAC,UAAK,WAAU,mBAAkB,OAAO,EAAE,OAAO,KAAK,GACpD,kBAAQ,UAAa,QAAQ,OAAO,UAAU,GAAG,IAAI,IACxD;AAAA,IACA,8CAAC,UAAK,WAAU,eAAc,OAAO,EAAE,OAAO,gBAAgB,GAAI,mBAAS,EAAE,OAAM;AAAA,IACnF,8CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,OAAO,MAAM,OAAO,IAAI,GACjE,WAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACjB,8CAAC,UAAa,WAAW,kBAAkB,KAAK,EAAE,IAAI,WAAW,KAAK,OAAO,EAAE,QAAQ,GAAG,MAAM,EAAE,KAAvF,CAA0F,CACtG,GACH;AAAA,KACF;AAEJ;;;AC9BkB,IAAAC,uBAAA;AA3BX,SAAS,UAAU;AAAA,EACxB,UAAU,CAAC;AAAA,EAAG,OAAO,CAAC;AAAA,EAAG,SAAAC,WAAU;AAAA,EAAO;AAAA,EAAY;AAAA,EAAY,SAAS;AAAA,EAC3E,UAAU;AAAA,EAAO,aAAa;AAAA,EAAO,eAAe;AAAA,EAAG;AAAA,EAAM;AAAA,EAAQ,YAAY;AAAA,EAAI,GAAG;AAC1F,GAAmB;AAMjB,QAAM,QAAQ,cAAc,CAAC;AAM7B,SACE,+CAAC,SAAI,WAAU,iBACb;AAAA;AAAA,MAAC;AAAA;AAAA,QAAI,WAAW,CAAC,iBAAiB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QACnE,aAAW,WAAW,aAAa,SAAS;AAAA,QAAY,GAAG;AAAA,QAC7D,yDAAC,WAAM,WAAW,CAAC,YAAYA,WAAU,qBAAqB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACxF;AAAA,wDAAC,WACC,wDAAC,QACE,kBAAQ,IAAI,CAAC,MACZ;AAAA,YAAC;AAAA;AAAA,cAAe,OAAM;AAAA,cAAM,OAAO,EAAE,OAAO,EAAE,MAAM;AAAA,cAClD,WAAW,CAAC,EAAE,UAAU,WAAW,IAAI,QAAQ,KAAK,QAAQ,EAAE,MAAM,cAAc,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,cAC9G,aAAW,QAAQ,KAAK,QAAQ,EAAE,MAAO,KAAK,QAAQ,QAAQ,cAAc,eAAgB;AAAA,cAC3F,YAAE,YAAY,SACb,+CAAC,YAAO,MAAK,UAAS,SAAS,MAAM,OAAO,EAAE,GAAG,GAC9C;AAAA,kBAAE;AAAA,gBACF,QAAQ,KAAK,QAAQ,EAAE,MAAM,8CAAC,OAAE,WAAW,2BAA2B,KAAK,QAAQ,QAAQ,OAAO,SAAS,IAAK;AAAA,iBACnH,IACE,EAAE;AAAA;AAAA,YARC,EAAE;AAAA,UASX,CACD,GACH,GACF;AAAA,UACA,8CAAC,WAAM,WAAW,QAAQ,aAAa,QACpC,oBACG,MAAM,KAAK,EAAE,QAAQ,aAAa,CAAC,EAAE,IAAI,CAAC,GAAG,MAC7C,8CAAC,QACE,kBAAQ,IAAI,CAAC,MACZ,8CAAC,QAAe,WAAW,EAAE,UAAU,WAAW,IAChD,wDAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,SAAS,gBAAgB,QAAQ,IAAI,OAAO,EAAE,UAAU,KAAM,IAAI,MAAM,IAAI,QAAQ,MAAO,GAAG,KADvI,EAAE,GAEX,CACD,KALM,CAMT,CACD,IACC,KAAK,IAAI,CAAC,MACV;AAAA,YAAC;AAAA;AAAA,cAAmB,iBAAe,eAAe,EAAE,MAAM,IAAI,SAAS;AAAA,cACrE,SAAS,aAAa,MAAM,WAAW,CAAC,IAAI;AAAA,cAC5C,OAAO,aAAa,EAAE,QAAQ,UAAU,IAAI;AAAA,cAC3C,kBAAQ,IAAI,CAAC,MACZ,8CAAC,QAAe,WAAW,EAAE,UAAU,WAAW,IAC/C,YAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,KAD1B,EAAE,GAEX,CACD;AAAA;AAAA,YAPM,EAAE,MAAM;AAAA,UAQjB,CACD,GACL;AAAA,WACF;AAAA;AAAA,IACA;AAAA,IACC,QACC,8CAAC,SAAI,WAAU,kBACb,yDAAC,UAAK,WAAU,uBAAsB,MAAK,UAAS;AAAA,oDAAC,UAAK,WAAU,cAAa,eAAY,QAAO;AAAA,MAAE;AAAA,OAAU,GAClH,IACE;AAAA,KACN;AAEJ;;;ACvGA,IAAAC,SAAuB;AAoHX,IAAAC,uBAAA;AAlEZ,IAAM,QAAQ,CAAC,MAAwB,EAAE,KAAK,QAAQ,MAAM,MAAM,MAAM;AAkBjE,SAAS,UAAU,EAAE,SAAS,CAAC,GAAG,SAAS,gBAAgB,gBAAgB,QAAQ,QAAQ,YAAY,IAAI,GAAG,KAAK,GAAmB;AAC3I,QAAM,CAAC,OAAO,QAAQ,IAAU,gBAAgB,IAAI;AACpD,QAAM,UAAgB,cAAwB,IAAI;AAClD,QAAM,eAAqB,cAAyB,IAAI;AACxD,QAAM,aAAmB,cAAwB,IAAI;AAErD,QAAM,eAAe,SAAS,MAAM,SAAS,SAAS,OAAO,KAAK,CAAC,MAAM,EAAE,QAAQ,MAAM,GAAG,IAAI;AAIhG,QAAM,cAAc,CAAC,CAAC,UAAU,MAAM,SAAS,SAAU,MAAM,SAAS,UAAU,cAAc,SAAS;AAEzG,EAAM,iBAAU,MAAM;AACpB,QAAI,CAAC,YAAa;AAClB,UAAM,OAAO,CAAC,MAAoB;AAAE,UAAI,QAAQ,WAAW,CAAC,QAAQ,QAAQ,SAAS,EAAE,MAAc,EAAG,UAAS,IAAI;AAAA,IAAG;AACxH,UAAM,MAAM,CAAC,MAAqB;AAAE,UAAI,EAAE,QAAQ,SAAU,UAAS,IAAI;AAAA,IAAG;AAC5E,aAAS,iBAAiB,eAAe,IAAI;AAC7C,aAAS,iBAAiB,WAAW,GAAG;AACxC,WAAO,MAAM;AAAE,eAAS,oBAAoB,eAAe,IAAI;AAAG,eAAS,oBAAoB,WAAW,GAAG;AAAA,IAAG;AAAA,EAClH,GAAG,CAAC,WAAW,CAAC;AAIhB,EAAM,iBAAU,MAAM;AACpB,QAAI,CAAC,SAAS,MAAM,SAAS,OAAQ;AACrC,QAAI,cAAc,SAAS,QAAQ;AACjC,mBAAa,SAAS,MAAM;AAAA,IAC9B,WAAW,cAAc,SAAS,YAAY,WAAW,SAAS;AAChE,YAAM,SACJ,WAAW,QAAQ,cAAiC,wBAAwB,KAC5E,WAAW,QAAQ,cAAiC,QAAQ;AAC9D,cAAQ,MAAM;AAAA,IAChB;AAAA,EAEF,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,gBAAgB,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,QAAQ,EAAE,GAAG,CAAC,CAAC;AAEjE,QAAM,eAAe,CAAC,QAAgB,SAAS,EAAE,MAAM,QAAQ,IAAI,CAAC;AAEpE,SACE,+CAAC,UAAK,WAAsB,OAAO,EAAE,UAAU,YAAY,SAAS,eAAe,UAAU,QAAQ,YAAY,UAAU,KAAK,EAAE,GAAG,KAAK,SAAU,GAAG,MACpJ;AAAA,WAAO,IAAI,CAAC,UAAU;AACrB,YAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,YAAM,UAAU,OAAO,SAAS,UAAU,MAAM,QAAQ,MAAM;AAE9D,UAAI,WAAW,MAAM,SAAS,QAAQ;AACpC,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,WAAU;AAAA,YACV,OAAO,EAAE,YAAY,wBAAwB,aAAa,uBAAuB,QAAQ,OAAO;AAAA,YAEhG;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAK;AAAA,kBACL,OAAQ,SAAgC;AAAA,kBACxC,aAAa,MAAM,eAAe,MAAM;AAAA,kBACxC,cAAY,MAAM;AAAA,kBAClB,UAAU,CAAC,MAAM,eAAe,MAAM,KAAK,EAAE,OAAO,KAAK;AAAA,kBACzD,WAAW,CAAC,MAAM;AAChB,wBAAI,EAAE,QAAQ,QAAS,UAAS,IAAI;AAAA,6BAC3B,EAAE,QAAQ,UAAU;AAAE,wBAAE,gBAAgB;AAAG,+BAAS,IAAI;AAAA,oBAAG;AAAA,kBACtE;AAAA,kBACA,QAAQ,MAAM,SAAS,IAAI;AAAA,kBAC3B,OAAO,EAAE,KAAK,SAAS,UAAU,IAAI,OAAO,+BAA+B;AAAA;AAAA,cAC7E;AAAA,cACC,MAAM,KAAK,IACV;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,MAAK;AAAA,kBACL,cAAY,YAAY,MAAM;AAAA,kBAC9B,SAAS,CAAC,MAAM;AAAE,sBAAE,gBAAgB;AAAG,mCAAe,MAAM,GAAG;AAAG,6BAAS,IAAI;AAAA,kBAAG;AAAA,kBAElF,wDAAC,OAAE,WAAU,WAAU,eAAY,QAAO;AAAA;AAAA,cAC5C,IACE;AAAA;AAAA;AAAA,UA1BC,MAAM;AAAA,QA2Bb;AAAA,MAEJ;AAEA,UAAI,WAAW,MAAM,SAAS,UAAU;AACtC,cAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK;AAC1D,eACE,+CAAC,UAAqB,OAAO,EAAE,UAAU,YAAY,SAAS,cAAc,GAC1E;AAAA,yDAAC,OAAI,UAAQ,MAAC,SAAS,MAAM,SAAS,IAAI,GAAG,UAAU,MAAM;AAAE,gBAAI,MAAM,KAAK,EAAG,gBAAe,MAAM,GAAG;AAAG,qBAAS,IAAI;AAAA,UAAG,GACzH;AAAA,kBAAM;AAAA,YAAO,SAAS,OAAO,OAAO,QAAQ;AAAA,aAC/C;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,EAAE,UAAU,YAAY,KAAK,oBAAoB,MAAM,GAAG,QAAQ,KAAK,UAAU,KAAK,UAAU,sBAAsB,SAAS,SAAS,YAAY,kBAAkB,QAAQ,2BAA2B,cAAc,IAAI,WAAW,kCAAkC,SAAS,EAAE;AAAA,cAE1R,wDAAC,UAAK,WAAU,YAAW,MAAK,WAAU,cAAY,MAAM,OAAO,KAAK,YAAY,OAAO,EAAE,KAAK,EAAE,GACjG,gBAAM,QAAQ,IAAI,CAAC,MAAM;AACxB,sBAAM,KAAK,EAAE,UAAU;AACvB,uBACE;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBAAuB,MAAK;AAAA,oBAAS,iBAAe;AAAA,oBACzD,WAAU;AAAA,oBACV,SAAS,MAAM;AAAE,qCAAe,MAAM,KAAK,EAAE,KAAK;AAAG,+BAAS,IAAI;AAAA,oBAAG;AAAA,oBACrE,OAAO,EAAE,KAAK,GAAG,SAAS,WAAW,cAAc,GAAG,QAAQ,GAAG,OAAO,QAAQ,WAAW,QAAQ,QAAQ,WAAW,YAAY,KAAK,yBAAyB,cAAc;AAAA,oBAE9K,wDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,MAAM,GAAG,YAAY,KAAK,MAAM,KAAK,OAAO,KAAK,iCAAiC,cAAc,GAAI,YAAE,OAAM;AAAA;AAAA,kBAL/H,EAAE;AAAA,gBAMvB;AAAA,cAEJ,CAAC,GACH;AAAA;AAAA,UACF;AAAA,aAvBS,MAAM,GAwBjB;AAAA,MAEJ;AAEA,UAAI,MAAM,KAAK,GAAG;AAChB,cAAM,SAAS,MAAM,SAAS,WAAW,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI;AACxF,cAAM,UAAU,SAAS,OAAO,QAAQ,OAAO,KAAK;AACpD,eACE,+CAAC,OAAoB,UAAQ,MAAC,SAAS,MAAM,aAAa,MAAM,GAAG,GAAG,UAAU,MAAM,eAAe,MAAM,GAAG,GAC3G;AAAA,gBAAM;AAAA,UAAM;AAAA,UAAG;AAAA,aADR,MAAM,GAEhB;AAAA,MAEJ;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,IAEA,cAAc,SAAS,IACtB,+CAAC,UAAK,OAAO,EAAE,UAAU,YAAY,SAAS,cAAc,GAC1D;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UAAK,SAAQ;AAAA,UAAY,MAAK;AAAA,UACnC,iBAAc;AAAA,UAAO,iBAAe,OAAO,SAAS;AAAA,UACpD,SAAS,MAAM,SAAS,OAAO,SAAS,QAAQ,OAAO,EAAE,MAAM,MAAM,CAAC;AAAA,UACvE;AAAA;AAAA,MAED;AAAA,MACC,OAAO,SAAS,QACf;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,UAAU,YAAY,KAAK,oBAAoB,CAAC,KAAK,GAAG,GAAG,QAAQ,KAAK,OAAO,KAAK,UAAU,sBAAsB,SAAS,SAAS,YAAY,kBAAkB,QAAQ,2BAA2B,cAAc,IAAI,WAAW,kCAAkC,SAAS,EAAE;AAAA,UAE1R,yDAAC,UAAK,WAAU,YAAW,MAAK,QAAO,cAAW,cAAa,OAAO,EAAE,KAAK,EAAE,GAC7E;AAAA,0DAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,SAAS,cAAc,GAAG,wBAAU;AAAA,YACnF,cAAc,IAAI,CAAC,MAClB;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBAAqB,MAAK;AAAA,gBAC/B,WAAU;AAAA,gBACV,SAAS,MAAM,aAAa,EAAE,GAAG;AAAA,gBACjC,OAAO,EAAE,KAAK,GAAG,SAAS,WAAW,cAAc,GAAG,QAAQ,GAAG,OAAO,QAAQ,WAAW,QAAQ,QAAQ,WAAW,YAAY,cAAc;AAAA,gBAEhJ,wDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,MAAM,GAAG,OAAO,cAAc,GAAI,YAAE,OAAM;AAAA;AAAA,cAL7D,EAAE;AAAA,YAMvB,CACD;AAAA,aACH;AAAA;AAAA,MACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;;;AC5MU,IAAAC,uBAAA;AAJH,SAAS,SAAS,EAAE,OAAO,OAAO,KAAK,OAAO,UAAU,OAAO,SAAAC,WAAU,OAAO,YAAY,IAAI,GAAG,KAAK,GAAkB;AAC/H,SACE,+CAAC,SAAI,WAAW,CAAC,WAAWA,WAAU,oBAAoB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACrG;AAAA,cACG,8CAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,SAAS,SAAS,QAAQA,WAAU,KAAK,IAAI,OAAO,MAAM,GAAG,IAE7G,+CAAC,UAAK,WAAU,eACd;AAAA,oDAAC,UAAK,WAAU,kBAAkB,iBAAM;AAAA,MACvC,QACC,+CAAC,UAAK,WAAW,MAAM,WAAW,GAAG,IAAI,uBAAuB,oBAAoB,OAAO,EAAE,YAAY,KAAK,UAAU,uBAAuB,MAAM,OAAO,GAC1J;AAAA,sDAAC,OAAE,WAAW,kBAAkB,MAAM,WAAW,GAAG,IAAI,SAAS,QAAQ,UAAU,eAAY,QAAO;AAAA,QAAE;AAAA,QAAE;AAAA,SAC5G,IACE;AAAA,OACN;AAAA,IAEH,CAAC,WAAW,MAAM,8CAAC,UAAK,WAAU,eAAe,eAAI,IAAU;AAAA,IAC/D,UACG,8CAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,SAAS,SAAS,QAAQ,IAAI,OAAO,OAAO,WAAW,EAAE,GAAG,IAC5G,8CAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,SAAS,QAAQ,GAAI,iBAAM;AAAA,KAC1E;AAEJ;;;ACtCA,IAAAC,SAAuB;AAkId,IAAAC,uBAAA;AA5HT,IAAM,QAAQ;AAKd,IAAM,QAAgC;AAAA,EACpC,IAAI;AAAA,IACF,CAAC,eAAe,KAAK;AAAA,IAAG,CAAC,qBAAqB,KAAK;AAAA,IACnD,CAAC,wCAAwC,KAAK;AAAA,IAC9C,CAAC,8BAA8B,KAAK;AAAA,IAAG,CAAC,8BAA8B,KAAK;AAAA,IAC3E,CAAC,mDAAmD,KAAK;AAAA,IACzD,CAAC,8DAA8D,KAAK;AAAA,IACpE,CAAC,qBAAqB,CAAC,MAAO,MAAM,KAAK,CAAC,IAAI,OAAO,SAAS,KAAK,CAAC,IAAI,SAAS,IAAK;AAAA,IACtF,CAAC,iBAAiB,KAAK;AAAA,IAAG,CAAC,wBAAwB,IAAI;AAAA,EACzD;AAAA,EACA,IAAI;AAAA,IACF,CAAC,YAAY,KAAK;AAAA,IAClB,CAAC,kCAAkC,KAAK;AAAA,IACxC,CAAC,4DAA4D,KAAK;AAAA,IAClE,CAAC,4BAA4B,KAAK;AAAA,IAClC,CAAC,2BAA2B,KAAK;AAAA,IACjC,CAAC,qBAAqB,IAAI;AAAA,IAC1B,CAAC,mBAAmB,CAAC,MAAO,2LAA2L,KAAK,CAAC,IAAI,OAAO,SAAS,KAAK,CAAC,IAAI,SAAS,IAAK;AAAA,IACzQ,CAAC,kBAAkB,KAAK;AAAA,IAAG,CAAC,sBAAsB,IAAI;AAAA,EACxD;AAAA,EACA,KAAK;AAAA,IACH,CAAC,qBAAqB,KAAK;AAAA,IAC3B,CAAC,4CAA4C,KAAK;AAAA,IAClD,CAAC,aAAa,MAAM;AAAA,IACpB,CAAC,YAAY,IAAI;AAAA,IACjB,CAAC,sBAAsB,KAAK;AAAA,IAC5B,CAAC,uDAAuD,KAAK;AAAA,IAC7D,CAAC,yBAAyB,IAAI;AAAA,IAC9B,CAAC,mBAAmB,MAAM;AAAA,IAC1B,CAAC,cAAc,KAAK;AAAA,IAAG,CAAC,WAAW,IAAI;AAAA,EACzC;AAAA,EACA,MAAM;AAAA,IACJ,CAAC,oBAAoB,KAAK;AAAA,IAC1B,CAAC,uBAAuB,IAAI;AAAA,IAC5B,CAAC,4CAA4C,KAAK;AAAA,IAClD,CAAC,oBAAoB,MAAM;AAAA,IAC3B,CAAC,WAAW,KAAK;AAAA,EACnB;AAAA,EACA,MAAM;AAAA,IACJ,CAAC,mCAAmC,MAAM;AAAA,IAC1C,CAAC,2BAA2B,KAAK;AAAA,IACjC,CAAC,4BAA4B,KAAK;AAAA,IAClC,CAAC,kCAAkC,KAAK;AAAA,IACxC,CAAC,cAAc,KAAK;AAAA,EACtB;AAAA,EACA,KAAK;AAAA,IACH,CAAC,aAAa,KAAK;AAAA,IAAG,CAAC,qBAAqB,KAAK;AAAA,IACjD,CAAC,yBAAyB,KAAK;AAAA,IAC/B,CAAC,sBAAsB,KAAK;AAAA,IAC5B,CAAC,mBAAmB,CAAC,MAAO,wSAAwS,KAAK,CAAC,IAAI,OAAO,IAAK;AAAA,IAC1V,CAAC,aAAa,KAAK;AAAA,IAAG,CAAC,kBAAkB,IAAI;AAAA,EAC/C;AAAA,EACA,MAAM;AAAA,IACJ,CAAC,YAAY,KAAK;AAAA,IAClB,CAAC,kCAAkC,KAAK;AAAA,IACxC,CAAC,gCAAgC,MAAM;AAAA,IACvC,CAAC,4BAA4B,IAAI;AAAA,IACjC,CAAC,gHAAgH,IAAI;AAAA,IACrH,CAAC,cAAc,MAAM;AAAA,IACrB,CAAC,cAAc,KAAK;AAAA,EACtB;AAAA,EACA,MAAM;AAAA,IACJ,CAAC,YAAY,KAAK;AAAA,IAClB,CAAC,iCAAiC,MAAM;AAAA,IACxC,CAAC,wBAAwB,KAAK;AAAA,IAC9B,CAAC,oCAAoC,KAAK;AAAA,IAC1C,CAAC,iBAAiB,KAAK;AAAA,IACvB,CAAC,gBAAgB,KAAK;AAAA,EACxB;AAAA,EACA,SAAS;AAAA,IACP,CAAC,uBAAuB,KAAK;AAAA,IAC7B,CAAC,4CAA4C,KAAK;AAAA,IAClD,CAAC,kBAAkB,KAAK;AAAA,IACxB,CAAC,kBAAkB,KAAK;AAAA,EAC1B;AACF;AAEA,IAAM,QAAgC;AAAA,EACpC,YAAY;AAAA,EAAM,KAAK;AAAA,EAAM,IAAI;AAAA,EAAM,YAAY;AAAA,EAAM,KAAK;AAAA,EAAM,KAAK;AAAA,EAAM,MAAM;AAAA,EAAM,KAAK;AAAA,EAAQ,QAAQ;AAAA,EAChH,QAAQ;AAAA,EAAM,MAAM;AAAA,EAAO,MAAM;AAAA,EAAO,MAAM;AAAA,EAAO,KAAK;AAAA,EAAQ,KAAK;AAAA,EAAQ,KAAK;AAAA,EACpF,OAAO;AAAA,EAAQ,OAAO;AAAA,EAAQ,UAAU;AAAA,EAAO,MAAM;AAAA,EAAO,OAAO;AAAA,EACnE,IAAI;AAAA,EAAQ,OAAO;AAAA,EAAQ,KAAK;AAAA,EAAQ,SAAS;AAAA,EAAQ,KAAK;AAChE;AAEO,SAAS,cAAc,MAAuB;AACnD,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,MAA8B,EAAE,IAAI,cAAc,KAAK,OAAO,IAAI,cAAc,KAAK,OAAO,IAAI,UAAU,QAAQ,UAAU,IAAI,SAAS,MAAM,SAAS,MAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ,KAAK,QAAQ,IAAI,YAAY,MAAM,QAAQ,KAAK,OAAO,IAAI,MAAM,IAAI,QAAQ,KAAK,OAAO,MAAM,QAAQ,MAAM,QAAQ,OAAO,SAAS,IAAI,UAAU,GAAG,KAAK,KAAK,OAAO,IAAI,KAAK;AAChZ,SAAO,IAAI,KAAK,YAAY,CAAC,KAAK,KAAK,YAAY;AACrD;AAGO,SAAS,SAAS,KAAa,MAAuD;AAC3F,QAAM,MAAM,OAAO,QAAQ,IAAI,YAAY,CAAC,MAAM,OAAO,QAAQ,IAAI,YAAY,CAAC,KAAK,QAAQ,IAAI,YAAY,IAAI;AACnH,QAAM,QAAQ,MAAM,GAAG,KAAK,MAAM;AAClC,QAAM,MAA8C,CAAC;AACrD,QAAM,OAAO,IAAI,SAAS,OAAQ,IAAI,MAAM,GAAG,IAAK,IAAI;AACxD,MAAI,IAAI,GAAG,QAAQ;AACnB,QAAM,QAAQ,MAAM;AAAE,QAAI,OAAO;AAAE,UAAI,KAAK,EAAE,GAAG,OAAO,GAAG,KAAK,CAAC;AAAG,cAAQ;AAAA,IAAI;AAAA,EAAE;AAClF,SAAO,IAAI,KAAK,QAAQ;AACtB,QAAI,MAA8C;AAClD,eAAW,CAAC,IAAI,GAAG,KAAK,OAAO;AAC7B,SAAG,YAAY;AACf,YAAM,IAAI,GAAG,KAAK,IAAI;AACtB,UAAI,KAAK,EAAE,UAAU,KAAK,EAAE,CAAC,EAAE,QAAQ;AACrC,cAAM,IAAI,OAAO,QAAQ,aAAa,IAAI,EAAE,CAAC,CAAC,IAAI;AAClD,cAAM,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE;AACnB;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAK;AAAE,YAAM;AAAG,UAAI,KAAK,GAAG;AAAG,WAAK,IAAI,EAAE;AAAA,IAAQ,OACjD;AAAE,eAAS,KAAK,CAAC;AAAG;AAAA,IAAK;AAAA,EAChC;AACA,QAAM;AACN,MAAI,IAAI,SAAS,KAAK,OAAQ,KAAI,KAAK,EAAE,GAAG,sBAAiB,GAAG,MAAM,CAAC;AACvE,SAAO;AACT;AAEA,SAAS,YAAY,EAAE,MAAM,KAAK,GAAoC;AACpE,QAAM,OAAa,eAAQ,MAAM,SAAS,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC;AACnE,SAAO,+EAAG,eAAK,IAAI,CAAC,IAAI,MAAO,GAAG,IAAI,8CAAC,UAAa,WAAW,SAAS,GAAG,GAAI,aAAG,KAAjC,CAAmC,IAAU,GAAG,CAAE,GAAE;AACvG;AAEA,SAAS,UAA6C;AACpD,QAAM,CAAC,MAAM,OAAO,IAAU,gBAAS,KAAK;AAC5C,QAAM,QAAc,cAA6C,IAAI;AAGrE,EAAM,iBAAU,MAAM,MAAM;AAAE,QAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAAA,EAAG,GAAG,CAAC,CAAC;AACnF,QAAM,OAAO,CAAC,SAAiB;AAC7B,UAAM,QAAQ,UAAU,aAAa,UAAU,UAAU,YACrD,UAAU,UAAU,UAAU,IAAI,IAClC,QAAQ,OAAO;AACnB,UAAM,MAAM,MAAM;AAChB,UAAI;AACF,cAAM,KAAK,SAAS,cAAc,UAAU;AAC5C,WAAG,QAAQ;AAAM,WAAG,MAAM,WAAW;AAAS,WAAG,MAAM,UAAU;AACjE,iBAAS,KAAK,YAAY,EAAE;AAAG,WAAG,OAAO;AAAG,iBAAS,YAAY,MAAM;AAAG,WAAG,OAAO;AAAA,MACtF,QAAQ;AAAA,MAAa;AAAA,IACvB,CAAC,EAAE,QAAQ,MAAM;AACf,cAAQ,IAAI;AACZ,UAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAC7C,YAAM,UAAU,WAAW,MAAM,QAAQ,KAAK,GAAG,IAAI;AAAA,IACvD,CAAC;AAAA,EACH;AACA,SAAO,CAAC,MAAM,IAAI;AACpB;AAmBO,SAAS,UAAU;AAAA,EACxB,OAAO;AAAA,EAAI;AAAA,EAAU;AAAA,EAAU,cAAc;AAAA,EAAO,MAAM,cAAc;AAAA,EACxE,gBAAgB;AAAA,EAAI,WAAW;AAAA,EAAM;AAAA,EAAS,YAAY;AAC5D,GAAmB;AACjB,QAAM,CAAC,MAAM,OAAO,IAAU,gBAAS,CAAC,CAAC,WAAW;AACpD,QAAM,CAAC,MAAM,OAAO,IAAU,gBAAS,KAAK;AAC5C,QAAM,CAAC,QAAQ,IAAI,IAAI,QAAQ;AAC/B,QAAM,OAAO,OAAO,IAAI,EAAE,QAAQ,OAAO,EAAE;AAC3C,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,WAAW,gBAAgB,KAAK,MAAM,SAAS,gBAAgB;AACrE,QAAM,QAAQ,YAAY,CAAC,OAAO,MAAM,MAAM,GAAG,aAAa,EAAE,KAAK,IAAI,IAAI;AAE7E,SACE,+CAAC,SAAI,WAAW,CAAC,WAAW,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACpF;AAAA,mDAAC,SAAI,WAAU,gBACZ;AAAA,iBAAW,8CAAC,UAAK,WAAU,gBAAgB,oBAAS,IAAU;AAAA,MAC/D,8CAAC,UAAK,WAAU,gBAAgB,wBAAc,QAAQ,GAAE;AAAA,MACxD,8CAAC,UAAK,WAAU,kBAAiB;AAAA,MAChC;AAAA,MACD,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,gBAAc,MAAM,OAAO,OAAO,YAAY,aAC7H,wDAAC,OAAE,WAAW,iBAAiB,OAAO,YAAY,eAAe,eAAY,QAAO,GACtF;AAAA,MACC,WACC,+CAAC,YAAO,MAAK,UAAS,WAAW,iBAAiB,SAAS,aAAa,KAAK,SAAS,MAAM,KAAK,IAAI,GACnG;AAAA,sDAAC,OAAE,WAAW,YAAY,SAAS,UAAU,SAAS,eAAY,QAAO;AAAA,QACzE,8CAAC,UAAM,mBAAS,WAAW,QAAO;AAAA,SACpC,IACE;AAAA,OACN;AAAA,IACA,+CAAC,SAAI,WAAU,gBACZ;AAAA,oBACC,8CAAC,SAAI,WAAU,kBAAiB,eAAY,QAAQ,gBAAM,MAAM,IAAI,EAAE,IAAI,CAAC,GAAG,MAAO,IAAI,IAAK,IAAI,EAAE,KAAK,EAAE,GAAE,IAC3G;AAAA,MACJ,8CAAC,SAAI,WAAU,eAAc,UAAU,GAAG,wDAAC,UAAK,wDAAC,eAAY,MAAM,OAAO,MAAM,UAAU,GAAE,GAAO;AAAA,OACrG;AAAA,IACC,WACC,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,iBAAe,MAC/F;AAAA,oDAAC,OAAE,WAAW,kBAAkB,OAAO,OAAO,SAAS,eAAY,QAAO;AAAA,MACzE,OAAO,aAAa,cAAc,MAAM,SAAS;AAAA,OACpD,IACE;AAAA,KACN;AAEJ;AAQO,SAAS,UAAU,EAAE,OAAO,IAAI,UAAU,gBAAgB,IAAI,YAAY,GAAG,GAAmB;AACrG,QAAM,CAAC,MAAM,OAAO,IAAU,gBAAS,KAAK;AAC5C,QAAM,CAAC,QAAQ,IAAI,IAAI,QAAQ;AAC/B,QAAM,MAAM,OAAO,IAAI,EAAE,QAAQ,OAAO,EAAE;AAC1C,QAAM,MAAM,IAAI,MAAM,IAAI,EAAE,IAAI,CAAC,SAAS;AACxC,QAAI,+BAA+B,KAAK,IAAI,EAAG,QAAO,EAAE,GAAG,QAAQ,KAAK;AACxE,QAAI,MAAM,KAAK,IAAI,EAAG,QAAO,EAAE,GAAG,QAAQ,KAAK;AAC/C,QAAI,KAAK,WAAW,GAAG,EAAG,QAAO,EAAE,GAAG,OAAO,KAAK;AAClD,QAAI,KAAK,WAAW,GAAG,EAAG,QAAO,EAAE,GAAG,OAAO,KAAK;AAClD,WAAO,EAAE,GAAG,OAAO,KAAK;AAAA,EAC1B,CAAC;AACD,QAAM,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE;AAC9C,QAAM,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE;AAC9C,QAAM,WAAW,gBAAgB,KAAK,IAAI,SAAS,gBAAgB;AACnE,QAAM,OAAO,YAAY,CAAC,OAAO,IAAI,MAAM,GAAG,aAAa,IAAI;AAE/D,SACE,+CAAC,SAAI,WAAW,CAAC,WAAW,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACxE;AAAA,mDAAC,SAAI,WAAU,gBACb;AAAA,oDAAC,OAAE,WAAU,+BAA8B,eAAY,QAAO;AAAA,MAC7D,WAAW,8CAAC,UAAK,WAAU,gBAAgB,oBAAS,IAAU,8CAAC,UAAK,WAAU,gBAAe,kBAAI;AAAA,MAClG,+CAAC,UAAK,WAAU,2BAA0B;AAAA,uDAAC,UAAK,WAAU,UAAS;AAAA;AAAA,UAAE;AAAA,WAAK;AAAA,QAAO,+CAAC,UAAK,WAAU,UAAS;AAAA;AAAA,UAAE;AAAA,WAAK;AAAA,SAAO;AAAA,MACxH,8CAAC,UAAK,WAAU,kBAAiB;AAAA,MACjC,+CAAC,YAAO,MAAK,UAAS,WAAW,iBAAiB,SAAS,aAAa,KAAK,SAAS,MAAM,KAAK,GAAG,GAClG;AAAA,sDAAC,OAAE,WAAW,YAAY,SAAS,UAAU,SAAS,eAAY,QAAO;AAAA,QACzE,8CAAC,UAAM,mBAAS,WAAW,QAAO;AAAA,SACpC;AAAA,OACF;AAAA,IACA,8CAAC,SAAI,WAAU,gBACZ,eAAK,IAAI,CAAC,GAAG,MACZ,+CAAC,SAAY,WAAW,qBAAqB,EAAE,GAC7C;AAAA,oDAAC,UAAK,WAAU,gBAAe,eAAY,QAAQ,YAAE,MAAM,QAAQ,MAAM,EAAE,MAAM,QAAQ,WAAM,IAAG;AAAA,MAClG,8CAAC,UAAM,YAAE,MAAM,SAAS,EAAE,MAAM,QAAQ,EAAE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAK;AAAA,SAFzD,CAGV,CACD,GACH;AAAA,IACC,WACC,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,iBAAe,MAC/F;AAAA,oDAAC,OAAE,WAAW,kBAAkB,OAAO,OAAO,SAAS,eAAY,QAAO;AAAA,MACzE,OAAO,aAAa,cAAc,IAAI,SAAS;AAAA,OAClD,IACE;AAAA,KACN;AAEJ;;;AC9QA,IAAAC,UAAuB;AA+CW,IAAAC,uBAAA;AAvClC,IAAM,OAAO;AACb,IAAM,WAAW,CAAC,MAA+B,KAAK,KAAK,OAAO,KAAK,EAAE,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,EAAE,KAAK,IAAI;AAExG,IAAM,SAAkC;AAAA,EACtC,CAAC,QAAQ,aAAa;AAAA,EACtB,CAAC,SAAS,6CAA6C;AAAA,EACvD,CAAC,QAAQ,4CAA4C;AAAA,EACrD,CAAC,QAAQ,iBAAiB;AAAA,EAC1B,CAAC,YAAY,qBAAqB;AAAA,EAClC,CAAC,UAAU,+BAA+B;AAAA,EAC1C,CAAC,MAAM,6FAA6F;AAAA,EACpG,CAAC,OAAO,aAAa;AAAA,EACrB,CAAC,YAAY,oCAAoC;AAAA,EACjD,CAAC,QAAQ,mDAAmD;AAC9D;AAUA,SAAS,YAAY,KAAgC,KAAY,SAAoC;AACnG,QAAM,MAAyB,CAAC;AAChC,MAAI,OAAO,OAAO,OAAO,OAAO,KAAK,GAAG,GAAG,QAAQ;AACnD,QAAM,MAAM,MAAM,UAAU,MAAM,IAAI;AACtC,SAAO,QAAQ,UAAU,KAAK;AAC5B,QAAI,OAAoD;AACxD,eAAW,CAACC,OAAM,EAAE,KAAK,QAAQ;AAC/B,YAAMC,KAAI,GAAG,KAAK,IAAI;AACtB,UAAIA,OAAM,CAAC,QAAQA,GAAE,QAAQ,KAAK,EAAE,OAAQ,QAAO,EAAE,MAAAD,OAAM,GAAAC,GAAE;AAC7D,UAAI,QAAQ,KAAK,EAAE,UAAU,EAAG;AAAA,IAClC;AACA,QAAI,CAAC,KAAM;AACX,UAAM,EAAE,MAAM,EAAE,IAAI;AACpB,QAAI,EAAE,QAAQ,EAAG,KAAI,KAAK,KAAK,MAAM,GAAG,EAAE,KAAK,CAAC;AAChD,UAAM,IAAI,CAAC,MAAc,EAAE,CAAC;AAC5B,QAAI,SAAS,OAAQ,KAAI,KAAK,8CAAC,UAAiB,WAAU,cAAc,YAAE,CAAC,KAAlC,IAAI,CAAgC,CAAO;AAAA,aAC3E,SAAS,SAAS;AACzB,YAAM,OAAO,SAAS,EAAE,CAAC,CAAC;AAC1B,UAAI,KAAK,IAAI,eAAe,OACxB,8CAAC,SAAgB,WAAU,aAAY,KAAK,MAAM,KAAK,EAAE,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC,KAAK,QAAW,SAAQ,UAA3F,IAAI,CAA8F,IAC5G,8CAAC,UAAiB,WAAU,gBAAgB,YAAE,CAAC,KAAK,WAAzC,IAAI,CAA6C,CAAO;AAAA,IACzE,WAAW,SAAS,QAAQ;AAC1B,YAAM,OAAO,SAAS,EAAE,CAAC,CAAC;AAC1B,UAAI,KAAK,OACL,8CAAC,OAAc,MAAY,OAAO,EAAE,CAAC,KAAK,QAAW,QAAQ,YAAY,KAAK,IAAI,IAAI,WAAW,QAAW,KAAI,uBAAsB,SAAS,IAAI,aAAc,sBAAY,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,KAArL,IAAI,CAAmL,IAC/L,8CAAC,UAAkB,YAAE,CAAC,KAAX,IAAI,CAAS,CAAO;AAAA,IACrC,WAAW,SAAS,QAAQ;AAC1B,UAAI,KAAK,IAAI,iBAAiB,8CAAO,kBAAN,EAA4B,cAAI,eAAe,EAAE,CAAC,CAAC,KAA/B,IAAI,CAA6B,IAAoB,8CAAC,SAAgB,WAAU,cAAc,YAAE,CAAC,KAAlC,IAAI,CAAgC,CAAM;AAAA,IAC9J,WAAW,SAAS,WAAY,KAAI,KAAK,8CAAC,YAAmB,wDAAC,QAAI,sBAAY,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,GAAE,KAA1C,IAAI,CAA2C,CAAS;AAAA,aACrG,SAAS,SAAU,KAAI,KAAK,8CAAC,YAAoB,sBAAY,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,KAA5C,IAAI,CAA0C,CAAS;AAAA,aAChG,SAAS,KAAM,KAAI,KAAK,8CAAC,QAAgB,sBAAY,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,KAA5C,IAAI,CAA0C,CAAK;AAAA,aACpF,SAAS,MAAO,KAAI,KAAK,8CAAC,SAAiB,sBAAY,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,KAApC,IAAI,CAAkC,CAAM;AAAA,aAC/E,SAAS,cAAc,SAAS,QAAQ;AAC/C,YAAM,OAAO,SAAS,EAAE,CAAC,CAAC;AAC1B,UAAI,KAAK,OAAO,8CAAC,OAAc,MAAY,QAAO,UAAS,KAAI,uBAAsB,SAAS,IAAI,aAAc,YAAE,CAAC,EAAE,QAAQ,YAAY,EAAE,KAAnH,IAAI,CAAiH,IAAO,EAAE,CAAC,CAAC;AAAA,IAC1J;AACA,WAAO,KAAK,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM;AAAA,EACzC;AACA,MAAI,KAAM,KAAI,KAAK,IAAI;AACvB,SAAO;AACT;AAIA,IAAM,KAAK;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,UAAU;AACZ;AAEA,IAAM,WAAW,CAAC,SAA2B,KAAK,QAAQ,UAAU,EAAE,EAAE,QAAQ,UAAU,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAa5H,SAAS,YAAY,KAAsB;AACzC,QAAM,QAAQ,OAAO,OAAO,OAAO,KAAK,GAAG,EAAE,QAAQ,UAAU,IAAI,EAAE,MAAM,IAAI;AAC/E,QAAM,SAAkB,CAAC;AACzB,MAAI,IAAI;AACR,SAAO,IAAI,MAAM,QAAQ;AACvB,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,CAAC,KAAK,KAAK,GAAG;AAAE;AAAK;AAAA,IAAU;AAEnC,UAAM,IAAI,GAAG,MAAM,KAAK,IAAI;AAC5B,QAAI,GAAG;AACL,YAAM,QAAQ,IAAI,OAAO,UAAU,EAAE,CAAC,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE,SAAS,SAAS;AAC1E,YAAMC,OAAgB,CAAC;AACvB;AACA,aAAO,IAAI,MAAM,UAAU,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,EAAG,CAAAA,KAAI,KAAK,MAAM,GAAG,CAAC;AACrE;AACA,aAAO,KAAK,EAAE,GAAG,QAAQ,MAAM,EAAE,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,KAAK,IAAI,MAAMA,KAAI,KAAK,IAAI,EAAE,CAAC;AACnF;AAAA,IACF;AACA,UAAM,IAAI,GAAG,QAAQ,KAAK,IAAI;AAC9B,QAAI,GAAG;AAAE,aAAO,KAAK,EAAE,GAAG,KAAK,OAAO,EAAE,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC,EAAE,CAAC;AAAG;AAAK;AAAA,IAAU;AACjF,QAAI,GAAG,GAAG,KAAK,IAAI,GAAG;AAAE,aAAO,KAAK,EAAE,GAAG,KAAK,CAAC;AAAG;AAAK;AAAA,IAAU;AACjE,QAAI,GAAG,MAAM,KAAK,IAAI,GAAG;AACvB,YAAMA,OAAgB,CAAC;AACvB,aAAO,IAAI,MAAM,WAAW,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,KAAM,MAAM,CAAC,EAAE,KAAK,KAAKA,KAAI,UAAU,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,IAAK;AAC5I,cAAM,IAAI,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC;AAChC,QAAAA,KAAI,KAAK,IAAI,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,KAAK,CAAC;AACnC;AAAA,MACF;AACA,aAAO,KAAK,EAAE,GAAG,SAAS,UAAU,YAAYA,KAAI,KAAK,IAAI,CAAC,EAAE,CAAC;AACjE;AAAA,IACF;AACA,QAAI,KAAK,SAAS,GAAG,KAAK,MAAM,IAAI,CAAC,KAAK,QAAQ,GAAG,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AAC9G,YAAM,OAAO,SAAS,IAAI;AAC1B,YAAM,QAAQ,SAAS,MAAM,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,MAAO,SAAS,KAAK,CAAC,IAAI,WAAW,OAAO,KAAK,CAAC,IAAI,UAAU,MAAO;AACjH,WAAK;AACL,YAAM,OAAmB,CAAC;AAC1B,aAAO,IAAI,MAAM,UAAU,MAAM,CAAC,EAAE,SAAS,GAAG,KAAK,MAAM,CAAC,EAAE,KAAK,EAAG,MAAK,KAAK,SAAS,MAAM,GAAG,CAAC,CAAC;AACpG,aAAO,KAAK,EAAE,GAAG,SAAS,MAAM,OAAO,KAAK,CAAC;AAC7C;AAAA,IACF;AACA,QAAI,GAAG,GAAG,KAAK,IAAI,GAAG;AACpB,YAAM,QAA6B,CAAC;AACpC,YAAM,aAAa,GAAG,GAAG,KAAK,IAAI,EAAG,CAAC,EAAE;AACxC,YAAM,UAAU,KAAK,KAAK,GAAG,GAAG,KAAK,IAAI,EAAG,CAAC,CAAC;AAC9C,YAAM,QAAQ,UAAU,SAAS,GAAG,GAAG,KAAK,IAAI,EAAG,CAAC,GAAG,EAAE,IAAI;AAC7D,aAAO,IAAI,MAAM,QAAQ;AACvB,cAAM,IAAI,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC;AAC7B,YAAI,CAAC,KAAK,EAAE,CAAC,EAAE,SAAS,YAAY;AAClC,cAAI,MAAM,UAAU,MAAM,CAAC,KAAK,MAAM,CAAC,EAAE,KAAK,KAAK,MAAM,CAAC,EAAE,OAAO,IAAI,IAAI,YAAY;AAAE,kBAAM,MAAM,SAAS,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC;AAAG;AAAK;AAAA,UAAU;AAC3J;AAAA,QACF;AACA,YAAI,EAAE,CAAC,EAAE,SAAS,YAAY;AAAE,gBAAM,MAAM,SAAS,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,EAAE,MAAM,aAAa,CAAC,CAAC;AAAG;AAAK;AAAA,QAAU;AACjH,YAAI,YAAY,KAAK,KAAK,EAAE,CAAC,CAAC,EAAG;AACjC,cAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAC1B;AACA,eAAO,IAAI,MAAM,UAAU,MAAM,CAAC,EAAE,KAAK,KAAK,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,EAAE,OAAO,IAAI,IAAI,YAAY;AAAE,gBAAM,MAAM,SAAS,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC;AAAG;AAAA,QAAK;AAAA,MACvK;AACA,aAAO,KAAK;AAAA,QACV,GAAG;AAAA,QAAQ;AAAA,QAAS;AAAA,QACpB,OAAO,MAAM,IAAI,CAAC,OAAO;AACvB,gBAAM,SAAS,GAAG,IAAI,KAAK,IAAI;AAC/B,gBAAM,OAAO,GAAG,KAAK,KAAK,MAAM;AAChC,iBAAO,OACH,EAAE,SAAS,KAAK,CAAC,EAAE,YAAY,MAAM,KAAK,UAAU,YAAY,KAAK,CAAC,CAAC,EAAE,IACzE,EAAE,UAAU,YAAY,MAAM,EAAE;AAAA,QACtC,CAAC;AAAA,MACH,CAAC;AACD;AAAA,IACF;AACA,UAAM,MAAgB,CAAC;AACvB,WAAO,IAAI,MAAM,UAAU,MAAM,CAAC,EAAE,KAAK,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC,EAAG,KAAI,KAAK,MAAM,GAAG,CAAC;AACvM,WAAO,KAAK,EAAE,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,SAAS,aAAa,QAAiB,KAAY,MAAiC;AAClF,SAAO,OAAO,IAAI,CAAC,GAAG,MAAM;AAC1B,UAAM,IAAI,OAAO,MAAM;AACvB,YAAQ,EAAE,GAAG;AAAA,MACX,KAAK,QAAQ;AACX,aAAK,EAAE,QAAQ,IAAI,YAAY,MAAM,OAAQ,QAAO,8CAAC,aAAkB,MAAM,EAAE,MAAM,UAAU,EAAE,QAAQ,UAArC,CAAgD;AACpH,eAAO,8CAAC,aAAkB,MAAM,EAAE,MAAM,UAAU,EAAE,MAAM,UAAU,EAAE,QAAQ,QAAY,GAAI,IAAI,aAAa,CAAC,KAAzF,CAA6F;AAAA,MACtH;AAAA,MACA,KAAK,KAAK;AACR,cAAM,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,SAAS,IAAI,iBAAiB,EAAE,CAAC;AACvE,cAAMC,OAAO,MAAM;AACnB,eAAO,8CAACA,MAAA,EAAY,WAAW,oBAAoB,KAAM,sBAAY,EAAE,MAAM,KAAK,CAAC,KAAlE,CAAoE;AAAA,MACvF;AAAA,MACA,KAAK;AAAM,eAAO,8CAAC,QAAW,WAAU,cAAb,CAAwB;AAAA,MACnD,KAAK;AAAS,eAAO,8CAAC,gBAAmB,WAAU,eAAe,uBAAa,EAAE,UAAU,KAAK,CAAC,KAA3D,CAA6D;AAAA,MACnG,KAAK,QAAQ;AACX,cAAMA,OAAO,EAAE,UAAU,OAAO;AAChC,cAAM,SAAS,EAAE,MAAM,KAAK,CAAC,OAAO,GAAG,WAAW,IAAI;AACtD,eACE,8CAACA,MAAA,EAAY,WAAW,gBAAgB,SAAS,aAAa,KAAK,OAAO,EAAE,WAAW,EAAE,UAAU,IAAI,EAAE,QAAQ,QAC9G,YAAE,MAAM,IAAI,CAAC,IAAI,MAChB,+CAAC,QAAqB,WAAW,GAAG,WAAW,OAAQ,GAAG,UAAU,YAAY,YAAa,QAC1F;AAAA,aAAG,WAAW,OACb,8CAAC,UAAK,WAAU,cAAa,eAAY,QAAO,wDAAC,OAAE,WAAW,YAAY,GAAG,UAAU,iBAAiB,WAAW,GAAE,IACnH;AAAA,UACJ,8CAAC,UAAK,WAAU,YAAY,uBAAa,GAAG,UAAU,KAAK,IAAI,MAAM,CAAC,GAAE;AAAA,aAJjE,IAAI,MAAM,CAKnB,CACD,KARO,CASV;AAAA,MAEJ;AAAA,MACA,KAAK;AACH,eACE,8CAAC,SAAY,WAAU,mBACrB,yDAAC,WAAM,WAAU,eACf;AAAA,wDAAC,WAAM,wDAAC,QAAI,YAAE,KAAK,IAAI,CAAC,GAAG,MAAM,8CAAC,QAAW,OAAO,EAAE,WAAY,EAAE,MAAM,CAAC,KAAK,OAA4C,GAAI,sBAAY,GAAG,KAAK,IAAI,MAAM,CAAC,KAArH,CAAuH,CAAK,GAAE,GAAK;AAAA,UAC7K,8CAAC,WACE,YAAE,KAAK,IAAI,CAAC,GAAG,OACd,8CAAC,QAAa,YAAE,KAAK,IAAI,CAAC,GAAG,OAAO,8CAAC,QAAY,OAAO,EAAE,WAAY,EAAE,MAAM,EAAE,KAAK,OAA4C,GAAI,sBAAY,EAAE,EAAE,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,EAAE,KAAvI,EAAyI,CAAK,KAAlL,EAAoL,CAC9L,GACH;AAAA,WACF,KARQ,CASV;AAAA,MAEJ;AACE,eAAO,8CAAC,OAAU,WAAU,WAAW,sBAAY,EAAE,MAAM,KAAK,CAAC,KAAlD,CAAoD;AAAA,IACvE;AAAA,EACF,CAAC;AACH;AAqBO,SAAS,SAAS;AAAA,EACvB,SAAS;AAAA,EAAI,YAAY;AAAA,EAAI;AAAA,EAAW,cAAc;AAAA,EACtD,gBAAgB;AAAA,EAAG;AAAA,EAAgB;AACrC,GAAkB;AAChB,QAAM,MAAa,EAAE,aAAa,eAAe,gBAAgB,aAAa,UAAU;AACxF,QAAM,SAAe,gBAAQ,MAAM,YAAY,MAAM,GAAG,CAAC,MAAM,CAAC;AAChE,SAAO,8CAAC,SAAI,WAAW,CAAC,SAAS,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,uBAAa,QAAQ,KAAK,GAAG,GAAE;AACzG;AAGO,SAAS,eAAe,EAAE,SAAS,IAAI,YAAY,IAAI,YAAY,GAAwF;AAChK,SAAO,8CAAC,UAAK,WAAW,CAAC,gBAAgB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,sBAAY,QAAQ,EAAE,aAAa,OAAO,YAAY,GAAG,GAAG,GAAE;AAChJ;AAGO,SAAS,eAAe,KAAqB;AAClD,SAAO,OAAO,OAAO,OAAO,KAAK,GAAG,EACjC,QAAQ,gCAAgC,IAAI,EAC5C,QAAQ,cAAc,IAAI,EAC1B,QAAQ,2BAA2B,IAAI,EACvC,QAAQ,0BAA0B,IAAI,EACtC,QAAQ,uBAAuB,EAAE,EACjC,QAAQ,oDAAoD,QAAQ,EACpE,QAAQ,mCAAmC,QAAQ,EACnD,QAAQ,gBAAgB,IAAI,EAC5B,QAAQ,cAAc,EAAE,EACxB,KAAK;AACV;;;ACtPe,IAAAC,uBAAA;AALR,SAAS,MAAM,EAAE,WAAW,CAAC,GAAG,cAAc,GAAG,SAAS,GAAG,OAAO,SAAS,OAAO,YAAY,GAAG,GAAe;AACvH,QAAM,QAAQ,SAAS,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI;AAC1D,QAAM,MAAM,CAAC,MAAe,QAAS,IAAI,QAAS,MAAM;AACxD,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,EAAE,GAChF;AAAA,YAAQ,8CAAC,UAAK,WAAU,4BAA4B,iBAAM,IAAU;AAAA,IACrE,+CAAC,SAAI,WAAU,eAAc,OAAO,EAAE,OAAO,GAC1C;AAAA,eAAS,IAAI,CAAC,GAAG,MAChB;AAAA,QAAC;AAAA;AAAA,UAAa,WAAU;AAAA,UAAkB,OAAO,EAAE;AAAA,UACjD,OAAO,EAAE,OAAO,IAAI,EAAE,KAAK,IAAI,KAAK,YAAY,EAAE,SAAS,kBAAmB,IAAI,IAAK,KAAK,KAAK,YAAY,oCAAoC;AAAA;AAAA,QADxI;AAAA,MAC2I,CACvJ;AAAA,MACA,cAAc,IAAI,8CAAC,UAAK,WAAU,2CAA0C,OAAM,eAAc,OAAO,EAAE,OAAO,IAAI,WAAW,IAAI,IAAI,GAAG,IAAK;AAAA,OAClJ;AAAA,IACC,SACC,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,UAAU,OAAO,GACxD;AAAA,eAAS,IAAI,CAAC,GAAG,MAChB,+CAAC,UAAa,WAAU,kCAAiC,OAAO,EAAE,KAAK,EAAE,GACvE;AAAA,sDAAC,UAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,GAAG,YAAY,EAAE,SAAS,kBAAmB,IAAI,IAAK,KAAK,IAAI,GAAG;AAAA,QACnH,EAAE;AAAA,WAFM,CAGX,CACD;AAAA,MACA,cAAc,IACb,+CAAC,UAAK,WAAU,kCAAiC,OAAO,EAAE,KAAK,EAAE,GAC/D;AAAA,sDAAC,UAAK,WAAU,2BAA0B,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,EAAE,GAAG;AAAA,QAAE;AAAA,SAC/F,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;;;ACJmB,IAAAC,uBAAA;AAnBZ,SAAS,WAAW;AAAA,EACzB,OAAO;AAAA,EAAG,WAAW;AAAA,EAAI,QAAQ;AAAA,EAAG,YAAY,CAAC,IAAI,IAAI,IAAI,GAAG;AAAA,EAChE;AAAA,EAAc;AAAA,EAAkB,UAAU;AAAA,EAAO,OAAO;AAAA,EAAQ,YAAY;AAAA,EAAI,GAAG;AACrF,GAAoB;AAClB,QAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,QAAQ,CAAC;AAC1D,QAAM,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,WAAW;AACvD,QAAM,KAAK,KAAK,IAAI,OAAO,OAAO,QAAQ;AAC1C,QAAM,KAAK,CAAC,MAAc;AAAE,QAAI,gBAAgB,KAAK,KAAK,KAAK,cAAc,MAAM,KAAM,cAAa,CAAC;AAAA,EAAG;AAE1G,QAAM,OAA4B,CAAC;AACnC,QAAM,OAAO;AACb,WAAS,IAAI,GAAG,KAAK,YAAY,KAAK;AACpC,QAAI,MAAM,KAAK,MAAM,cAAc,KAAK,IAAI,IAAI,IAAI,KAAK,KAAM,MAAK,KAAK,CAAC;AAAA,aACjE,KAAK,KAAK,SAAS,CAAC,MAAM,SAAK,MAAK,KAAK,QAAG;AAAA,EACvD;AAEA,SACE,+CAAC,SAAI,WAAW,CAAC,UAAU,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACnE;AAAA,kDAAC,UAAK,WAAU,gBACb,oBAAU,8CAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,SAAS,gBAAgB,QAAQ,IAAI,OAAO,IAAI,GAAG,IAC1G,UAAU,IAAI,gFAAE;AAAA;AAAA,MAAI;AAAA,OAAK,IAAM,gFAAE;AAAA,qDAAC,YAAQ;AAAA,aAAK,eAAe;AAAA,QAAE;AAAA,QAAE,GAAG,eAAe;AAAA,SAAE;AAAA,MAAS;AAAA,MAAK,MAAM,eAAe;AAAA,MAAE;AAAA,MAAE;AAAA,OAAK,GACxI;AAAA,IACC,mBACC,+CAAC,WAAM,WAAU,eACf;AAAA,oDAAC,UAAK,kBAAI;AAAA,MACV,8CAAC,YAAO,OAAO,UAAU,UAAU,CAAC,MAAM,iBAAiB,OAAO,EAAE,OAAO,KAAK,CAAC,GAAG,cAAW,iBAC5F,oBAAU,IAAI,CAAC,MAAM,8CAAC,YAAe,OAAO,GAAI,eAAd,CAAgB,CAAS,GAC9D;AAAA,OACF,IACE;AAAA,IACJ,+CAAC,UAAK,WAAU,cACd;AAAA,oDAAC,YAAO,MAAK,UAAS,SAAS,MAAM,GAAG,CAAC,GAAG,UAAU,QAAQ,GAAG,cAAW,cAAa,wDAAC,OAAE,WAAU,2BAA0B,GAAE;AAAA,MAClI,8CAAC,YAAO,MAAK,UAAS,SAAS,MAAM,GAAG,OAAO,CAAC,GAAG,UAAU,QAAQ,GAAG,cAAW,iBAAgB,wDAAC,OAAE,WAAU,oBAAmB,GAAE;AAAA,MACpI,KAAK,IAAI,CAAC,GAAG,MAAM,MAAM,WACtB,8CAAC,UAAmB,WAAU,cAAa,eAAY,QAAO,sBAAnD,MAAM,CAA8C,IAC/D;AAAA,QAAC;AAAA;AAAA,UAAe,MAAK;AAAA,UAAS,SAAS,MAAM,GAAG,CAAW;AAAA,UAAG,gBAAc,MAAM,OAAO,SAAS;AAAA,UAChG,WAAW,MAAM,OAAO,eAAe;AAAA,UAAK;AAAA;AAAA,QADjC;AAAA,MACmC,CAAS;AAAA,MAC7D,8CAAC,YAAO,MAAK,UAAS,SAAS,MAAM,GAAG,OAAO,CAAC,GAAG,UAAU,QAAQ,YAAY,cAAW,aAAY,wDAAC,OAAE,WAAU,qBAAoB,GAAE;AAAA,MAC3I,8CAAC,YAAO,MAAK,UAAS,SAAS,MAAM,GAAG,UAAU,GAAG,UAAU,QAAQ,YAAY,cAAW,aAAY,wDAAC,OAAE,WAAU,4BAA2B,GAAE;AAAA,OACtJ;AAAA,KACF;AAEJ;;;ACrEA,IAAAC,UAAuB;AAuEnB,IAAAC,uBAAA;AArEJ,IAAM,MAAM;AAAZ,IAAkB,OAAO;AAAzB,IAA+B,MAAM;AAG9B,SAAS,eAAe,OAAsB,KAAsB;AACzE,QAAM,IAAI,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK;AACpE,MAAI,CAAC,KAAK,MAAM,CAAC,EAAG,QAAO;AAC3B,QAAM,MAAM,OAAO,KAAK,IAAI;AAC5B,QAAM,OAAO,IAAI;AACjB,QAAM,MAAM,KAAK,IAAI,IAAI;AACzB,QAAM,SAAS,OAAO;AACtB,MAAI,MAAM,KAAM,QAAO,SAAS,gBAAgB;AAChD,MAAI,MAAM,MAAM;AAAE,UAAM,IAAI,KAAK,MAAM,MAAM,GAAG;AAAG,WAAO,SAAS,QAAQ,IAAI,SAAS,IAAI;AAAA,EAAY;AACxG,MAAI,MAAM,IAAI,MAAM;AAClB,UAAM,IAAI,KAAK,MAAM,MAAM,IAAI,GAAG,IAAI,KAAK,MAAO,MAAM,OAAQ,GAAG;AACnE,UAAM,IAAI,IAAI,OAAO,IAAI,MAAM,IAAI,MAAM;AACzC,WAAO,SAAS,QAAQ,IAAI,IAAI;AAAA,EAClC;AACA,QAAM,IAAI,IAAI,KAAK,CAAC;AACpB,QAAM,UAAU,IAAI,KAAK,GAAG,EAAE,aAAa,MAAM,EAAE,aAAa;AAChE,QAAM,OAAO,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,WAAW,QAAQ,UAAU,CAAC;AAC5E,MAAI,QAAS,QAAO;AACpB,MAAI,MAAM,IAAI,IAAK,QAAO,EAAE,mBAAmB,CAAC,GAAG,EAAE,SAAS,QAAQ,CAAC,IAAI,MAAM;AACjF,SAAO,EAAE,mBAAmB,CAAC,GAAG,EAAE,KAAK,WAAW,OAAO,QAAQ,CAAC;AACpE;AAGO,SAAS,eAAe,OAA8B;AAC3D,QAAM,IAAI,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK;AACpE,MAAI,CAAC,KAAK,MAAM,CAAC,EAAG,QAAO;AAC3B,SAAO,IAAI,KAAK,CAAC,EAAE,eAAe,CAAC,GAAG,EAAE,WAAW,UAAU,WAAW,QAAQ,CAAC;AACnF;AAGO,SAAS,YAAY,OAA8B;AACxD,QAAM,IAAI,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK;AACpE,MAAI,CAAC,KAAK,MAAM,CAAC,EAAG,QAAO;AAC3B,SAAO,IAAI,KAAK,CAAC,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,WAAW,QAAQ,UAAU,CAAC;AAClF;AAGO,SAAS,eAAe,IAAoB;AACjD,MAAI,MAAM,QAAQ,MAAM,EAAE,EAAG,QAAO;AACpC,MAAI,KAAK,IAAM,QAAO,KAAK,MAAM,EAAE,IAAI;AACvC,MAAI,KAAK,KAAM;AAAE,UAAMC,KAAI,KAAK;AAAM,YAAQA,KAAI,KAAKA,GAAE,QAAQ,CAAC,IAAI,KAAK,MAAMA,EAAC,KAAK;AAAA,EAAK;AAC5F,QAAM,IAAI,KAAK,MAAM,KAAK,GAAI,GAAG,IAAI,KAAK,MAAO,KAAK,MAAQ,GAAI;AAClE,MAAI,IAAI,GAAI,QAAO,IAAI,OAAO,IAAI,MAAM,IAAI,MAAM;AAClD,QAAM,IAAI,KAAK,MAAM,IAAI,EAAE;AAC3B,SAAO,IAAI,OAAO,IAAI,KAAK,MAAO,IAAI,KAAM,MAAM;AACpD;AAQO,SAAS,aAAa,EAAE,OAAO,QAAQ,YAAY,IAAI,SAAAC,WAAU,MAAM,GAAG,KAAK,GAAsB;AAC1G,QAAM,CAAC,EAAE,KAAK,IAAU,iBAAS,CAAC;AAClC,QAAM,IAAI,iBAAiB,OAAO,MAAM,QAAQ,IAAI,KAAK,MAAM,KAAK;AACpE,EAAM,kBAAU,MAAM;AACpB,QAAI,CAACA,YAAW,CAAC,KAAK,MAAM,CAAC,EAAG;AAChC,UAAM,MAAM,KAAK,IAAI,IAAI,KAAK,IAAI,CAAC;AACnC,QAAI,MAAM,IAAK;AACf,UAAM,QAAQ,MAAM,OAAO,OAAO;AAClC,UAAM,KAAK,YAAY,MAAM,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,KAAK;AACvD,WAAO,MAAM,cAAc,EAAE;AAAA,EAC/B,GAAG,CAAC,GAAGA,QAAO,CAAC;AACf,MAAI,CAAC,KAAK,MAAM,CAAC,EAAG,QAAO;AAC3B,SACE,+CAAC,UAAK,WAAsB,UAAU,IAAI,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,eAAe,IAAI,KAAK,CAAC,CAAC,GAAI,GAAG,MACtG;AAAA,aAAS,SAAS,MAAM;AAAA,IAAI,eAAe,IAAI,KAAK,CAAC,CAAC;AAAA,KACzD;AAEJ;;;AC3EA,IAAAC,UAAuB;;;ACiChB,SAAS,YAAY,GAAmB;AAC7C,MAAI,KAAK,QAAQ,MAAM,CAAC,EAAG,QAAO;AAClC,MAAI,IAAI,KAAM,QAAO,IAAI;AACzB,QAAM,IAAI,CAAC,MAAM,MAAM,MAAM,IAAI;AACjC,MAAI,IAAI,IAAI,MAAM,IAAI;AACtB,SAAO,KAAK,QAAQ,IAAI,EAAE,SAAS,GAAG;AAAE,SAAK;AAAM;AAAA,EAAK;AACxD,UAAQ,IAAI,KAAK,EAAE,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,MAAM,EAAE,CAAC;AAC5D;AAEO,SAAS,YAAY,MAAsB;AAChD,QAAM,IAAI,oBAAoB,KAAK,QAAQ,EAAE;AAC7C,SAAO,IAAI,EAAE,CAAC,EAAE,YAAY,IAAI;AAClC;AAEA,IAAM,cAAsC;AAAA,EAC1C,KAAK;AAAA,EAAY,KAAK;AAAA,EAAY,MAAM;AAAA,EAAY,KAAK;AAAA,EACzD,KAAK;AAAA,EAAY,MAAM;AAAA,EAAY,KAAK;AAAA,EAAY,KAAK;AAAA,EACzD,KAAK;AAAA,EAAY,MAAM;AAAA,EACvB,KAAK;AAAA,EAAY,IAAI;AAAA,EAAY,KAAK;AAAA,EAAY,KAAK;AAAA,EACvD,IAAI;AAAA,EAAW,KAAK;AAAA,EAAW,IAAI;AAAA,EAAW,KAAK;AAAA,EACnD,MAAM;AAAA,EAAkB,MAAM;AAAA,EAAa,KAAK;AAAA,EAAY,IAAI;AAAA,EAChE,IAAI;AAAA,EAAW,KAAK;AAAA,EAAY,IAAI;AAAA,EAAY,KAAK;AAAA,EAAa,KAAK;AACzE;AAGO,SAAS,YAAY,MAAe,MAAuB;AAChE,QAAM,KAAK,QAAQ,IAAI,YAAY;AACnC,MAAI,EAAE,WAAW,QAAQ,EAAG,QAAO;AACnC,MAAI,EAAE,WAAW,QAAQ,EAAG,QAAO;AACnC,MAAI,EAAE,WAAW,QAAQ,EAAG,QAAO;AACnC,QAAM,QAAQ,YAAY,YAAY,QAAQ,EAAE,CAAC;AACjD,MAAI,MAAO,QAAO;AAClB,MAAI,MAAM,kBAAmB,QAAO;AACpC,MAAI,EAAE,WAAW,OAAO,EAAG,QAAO;AAClC,SAAO;AACT;AAEO,SAAS,QAAQ,MAAe,MAAwB;AAC7D,OAAK,QAAQ,IAAI,YAAY,EAAE,WAAW,QAAQ,EAAG,QAAO;AAC5D,SAAO,CAAC,OAAO,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,KAAK,EAAE,SAAS,YAAY,QAAQ,EAAE,CAAC;AACrG;AAGO,SAAS,cAAc,MAAY,QAA0B;AAClE,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,QAAQ,KAAK,QAAQ,IAAI,YAAY;AAC3C,QAAM,QAAQ,KAAK,QAAQ,IAAI,YAAY;AAC3C,SAAO,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,CAAC,SAAS;AACzF,QAAI,KAAK,WAAW,GAAG,EAAG,QAAO,KAAK,SAAS,IAAI;AACnD,QAAI,KAAK,SAAS,IAAI,EAAG,QAAO,KAAK,WAAW,KAAK,MAAM,GAAG,EAAE,CAAC;AACjE,WAAO,SAAS;AAAA,EAClB,CAAC;AACH;AAGO,SAAS,YACd,OACA,MACiD;AACjD,QAAM,IAAI,QAAQ,CAAC;AACnB,QAAM,WAAmB,CAAC,GAAG,WAA4B,CAAC;AAC1D,QAAM,KAAK,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,SAAS;AACxC,QAAI,CAAC,cAAc,MAAM,EAAE,MAAM,GAAG;AAAE,eAAS,KAAK,EAAE,MAAM,QAAQ,QAAQ,UAAU,KAAK,QAAQ,eAAe,2BAA2B,CAAC;AAAG;AAAA,IAAQ;AACzJ,QAAI,EAAE,eAAe,KAAK,OAAO,EAAE,aAAa;AAAE,eAAS,KAAK,EAAE,MAAM,QAAQ,QAAQ,UAAU,KAAK,QAAQ,eAAe,SAAS,YAAY,KAAK,IAAI,IAAI,0BAAqB,YAAY,EAAE,WAAW,IAAI,IAAI,CAAC;AAAG;AAAA,IAAQ;AAClO,aAAS,KAAK,IAAI;AAAA,EACpB,CAAC;AACD,SAAO,EAAE,UAAU,SAAS;AAC9B;AAGO,SAAS,eAAe,MAAsB;AACnD,QAAM,QAAQ,KAAK,MAAM,IAAI,EAAE;AAC/B,MAAI,UAAU,EAAG,QAAO,kBAAkB,KAAK,OAAO,eAAe,IAAI;AACzE,SAAO,kBAAkB,MAAM,eAAe,IAAI;AACpD;AAEA,SAAS,aAAa,MAAc,MAAoB;AACtD,QAAM,OAAO;AACb,MAAI;AACF,WAAO,IAAI,KAAK,CAAC,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC;AAAA,EACxC,QAAQ;AACN,UAAM,OAAO,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,KAAK,CAAC;AACtC,WAAO,OAAO,MAAM,EAAE,MAAM,cAAc,KAAK,IAAI,EAAE,CAAC;AACtD,WAAO;AAAA,EACT;AACF;AAUO,SAAS,sBACd,OACA,MAC8F;AAC9F,QAAM,IAAI,QAAQ,CAAC;AACnB,QAAM,YAAY,EAAE,uBAAuB,OAAO,MAAO,EAAE;AAC3D,QAAM,MAAM;AACZ,QAAM,KAAK,UAAU,IAAI,iBAAkB,IAAI,iBAAiB,IAAI,cAAc;AAClF,MAAI,CAAC,GAAI,QAAO,EAAE,OAAO,CAAC,GAAG,QAAQ,MAAM,UAAU,CAAC,EAAE;AAExD,QAAM,MAAM,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC;AACrC,QAAM,YAAoB,IAAI,SAC1B,MACA,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,EACtB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EACxB,OAAO,CAAC,MAAiB,MAAM,IAAI;AAE1C,MAAI,UAAU,QAAQ;AACpB,UAAM,EAAE,UAAU,SAAS,IAAI,YAAY,WAAW,CAAC;AACvD,WAAO,EAAE,OAAO,UAAU,QAAQ,SAAS,SAAS,UAAU,MAAM,SAAS;AAAA,EAC/E;AAEA,QAAM,OAAO,GAAG,UAAU,GAAG,QAAQ,YAAY,IAAI;AACrD,MAAI,YAAY,KAAK,QAAQ,KAAK,SAAS,WAAW;AACpD,UAAM,OAAO,aAAa,MAAM,EAAE,QAAQ,eAAe,IAAI,CAAC;AAC9D,UAAM,EAAE,UAAU,SAAS,IAAI,YAAY,CAAC,IAAI,GAAG,EAAE,QAAQ,EAAE,QAAQ,aAAa,EAAE,YAAY,CAAC;AACnG,WAAO,EAAE,OAAO,UAAU,QAAQ,SAAS,SAAS,SAAS,MAAM,UAAU,KAAK;AAAA,EACpF;AACA,SAAO,EAAE,OAAO,CAAC,GAAG,QAAQ,MAAM,UAAU,CAAC,EAAE;AACjD;AAEA,IAAI,gBAAgB;AAKb,SAAS,aAAa,MAAY,OAAyC;AAChF,QAAM,MAAM,OAAO,QAAQ,eAAe,IAAI,kBAAkB,IAAI,gBAAgB,IAAI,IAAI;AAC5F,QAAM,QAAQ,QAAQ,KAAK,MAAM,KAAK,IAAI;AAC1C,QAAM,OAAmB;AAAA,IACvB,IAAI,SAAU,EAAE,gBAAiB,MAAM,KAAK,IAAI,EAAE,SAAS,EAAE;AAAA,IAC7D,MAAM,KAAK,QAAQ;AAAA,IACnB,MAAM,KAAK,QAAQ;AAAA,IACnB,MAAM,KAAK,QAAQ;AAAA,IACnB;AAAA,IACA,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO,SAAS,MAAM,EAAE,IAAI,IAAI;AAAA,IAChC;AAAA,EACF;AACA,SAAO,OAAO,OAAO,MAAM,SAAS,CAAC,CAAC;AACxC;AAEO,SAAS,iBAAiB,KAAuB;AACtD,MAAI;AAAE,QAAI,OAAO,IAAI,QAAS,KAAI,gBAAgB,IAAI,OAAO;AAAA,EAAG,QAAQ;AAAA,EAAa;AACvF;AAKO,IAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AD9GmB,IAAAC,uBAAA;AAvFnB,IAAM,eAAuC;AAAA,EAC3C,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AACR;AACA,IAAM,QAAQ,CAAC,kBAAkB,kBAAkB,kBAAkB,kBAAkB,kBAAkB,kBAAkB,kBAAkB,gBAAgB;AAE7J,IAAM,UAAU,CAAC,MAAsB;AACrC,MAAI,KAAK,QAAQ,MAAM,CAAC,EAAG,QAAO;AAClC,QAAM,IAAI,KAAK,IAAI,CAAC;AACpB,MAAI,KAAK,IAAK,SAAQ,IAAI,KAAK,QAAQ,KAAK,OAAO,IAAI,CAAC,EAAE,QAAQ,QAAQ,EAAE,IAAI;AAChF,MAAI,KAAK,IAAK,SAAQ,IAAI,KAAK,QAAQ,KAAK,MAAM,IAAI,CAAC,EAAE,QAAQ,QAAQ,EAAE,IAAI;AAC/E,MAAI,KAAK,IAAK,SAAQ,IAAI,KAAK,QAAQ,KAAK,MAAM,IAAI,CAAC,EAAE,QAAQ,QAAQ,EAAE,IAAI;AAC/E,SAAO,OAAO,KAAK,MAAM,CAAC,CAAC;AAC7B;AAEO,IAAM,eAAe;AAAA,EAC1B,OAAO,CAAC,MAAc,EAAE,eAAe;AAAA,EACvC;AAAA,EACA,OAAO;AAAA,EACP,WAAW,CAAC,UAAkB,CAAC,OAAe,QAAQ,KAAK,MAAO,IAAI,QAAS,GAAG,IAAI,KAAK;AAC7F;AAmCO,SAAS,eAAe;AAAA,EAC7B,QAAQ;AAAA,EACR,WAAW,CAAC;AAAA,EACZ;AAAA,EACA,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAwB;AACtB,QAAM,YAAY,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI;AACtD,QAAM,QAAQ,SAAS,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC;AAC7D,QAAM,OAAO,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,KAAK,GAAG,CAAC;AAC1D,QAAM,MAAM,YAAY,KAAK,IAAI,KAAK,KAAK,MAAO,OAAO,YAAa,GAAG,CAAC,IAAI;AAC9E,QAAM,IAAI,CAAC,MAAe,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,OAAO,CAAC,IAAI,YAAa,GAAG,CAAC,IAAI;AAClG,QAAM,OAAO,CAAC,GAAsB,MAAc,EAAE,UAAU,EAAE,UAAU,aAAa,EAAE,OAAO,IAAI,WAAc,MAAM,IAAI,MAAM,MAAM;AACxI,QAAM,cAAoB,cAAM;AAChC,QAAMC,OAAM,MAAM;AAElB,SACE,+CAAC,SAAI,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,SAClE;AAAA,aAAS,YACT,+CAAC,SAAI,WAAU,oBACZ;AAAA,cAAQ,8CAAC,UAAK,WAAU,qBAAoB,IAAIA,OAAM,MAAO,iBAAM,IAAU,8CAAC,UAAK;AAAA,MACnF,YACC,+CAAC,UAAK,WAAU,gCACb;AAAA,eAAO,IAAI;AAAA,QAAE,8CAAC,UAAK,WAAU,mBAAkB,iBAAG;AAAA,QAAQ,YAAY,OAAO,SAAS,IAAI;AAAA,QAC1F,cAAc,+CAAC,UAAK,WAAU,mBAAkB;AAAA;AAAA,UAAG;AAAA,UAAI;AAAA,WAAE,IAAU;AAAA,SACtE,IACE;AAAA,OACN,IACE;AAAA,IACJ;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,OAAO;AAAA,QAChB,MAAK;AAAA,QACL,mBAAiB,QAAQA,OAAM,OAAO;AAAA,QACtC,cAAY,QAAQ,SAAY;AAAA,QAChC,iBAAe;AAAA,QACf,iBAAe;AAAA,QACf,iBAAe,aAAa;AAAA,QAC5B,kBAAgB,OAAO,IAAI,IAAI,UAAU,YAAY,OAAO,SAAS,IAAI,aAAa,aAAQ,MAAM;AAAA,QAEnG,gBAAM,IAAI,CAAC,GAAG,MACb;AAAA,UAAC;AAAA;AAAA,YAEC,WAAU;AAAA,YACV,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,KAAK,YAAY,KAAK,GAAG,CAAC,GAAG,iBAAkB,IAAI,KAAM,KAAK;AAAA,YAC3F,OAAO,EAAE,QAAQ,WAAQ,OAAO,EAAE,KAAK;AAAA;AAAA,UAHlC,EAAE,MAAM,EAAE,SAAS;AAAA,QAI1B,CACD;AAAA;AAAA,IACH;AAAA,IACC,SACC,+CAAC,QAAG,WAAU,sBACX;AAAA,YAAM,IAAI,CAAC,GAAG,MACb,+CAAC,QACC;AAAA,sDAAC,UAAK,WAAU,mBAAkB,OAAO,EAAE,YAAY,KAAK,GAAG,CAAC,EAAE,GAAG,eAAY,QAAO;AAAA,QACxF,8CAAC,UAAK,WAAU,mBAAmB,YAAE,OAAM;AAAA,QAC3C,8CAAC,UAAK,WAAU,8BAA8B,iBAAO,EAAE,KAAK,GAAE;AAAA,WAHvD,EAAE,MAAM,EAAE,SAAS,CAI5B,CACD;AAAA,MACA,aAAa,OAAO,YACnB,+CAAC,QAAG,WAAU,gBACZ;AAAA,sDAAC,UAAK,WAAU,4BAA2B,eAAY,QAAO;AAAA,QAC9D,8CAAC,UAAK,WAAU,mBAAmB,0BAAe;AAAA,QAClD,8CAAC,UAAK,WAAU,8BAA8B,iBAAO,YAAY,IAAI,GAAE;AAAA,SACzE,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;AAQO,SAAS,SAAS,EAAE,OAAO,UAAU,GAAG,MAAM,MAAM,YAAY,GAAG,GAAkB;AAC1F,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC;AACrE,QAAM,OAAO,KAAK,KAAK,WAAW,KAAK,KAAK,SAAS;AACrD,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC9D;AAAA,mDAAC,SAAI,WAAU,iBACb;AAAA,oDAAC,UAAK,WAAU,kBAAkB,iBAAM;AAAA,MACvC,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,MACxD,+CAAC,UAAK,WAAU,2BAA2B;AAAA;AAAA,QAAE;AAAA,SAAC;AAAA,OAChD;AAAA,IACA,8CAAC,SAAI,WAAU,iBAAgB,MAAK,SAAQ,cAAY,OAAO,UAAU,WAAW,QAAQ,QAAW,iBAAe,GAAG,iBAAe,GAAG,iBAAe,KACxJ,wDAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,OAAO,IAAI,KAAK,YAAY,aAAa,QAAQ,IAAI,EAAE,GAAG,GACrG;AAAA,KACF;AAEJ;;;AElKA,IAAAC,UAAuB;AAkEf,IAAAC,uBAAA;AAvBD,SAAS,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,QAAQ,QAAQ,SAAS,OAAO,MAAM,YAAY,IAAI,GAAG,KAAK,GAAkB;AAC5H,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,MAAY,eAAwB,IAAI;AAC9C,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,CAAC,MAAoB;AAAE,UAAI,IAAI,WAAW,CAAC,IAAI,QAAQ,SAAS,EAAE,MAAc,EAAG,SAAQ,KAAK;AAAA,IAAG;AAChH,UAAM,MAAM,CAAC,MAAqB;AAAE,UAAI,EAAE,QAAQ,SAAU,SAAQ,KAAK;AAAA,IAAG;AAC5E,aAAS,iBAAiB,eAAe,IAAI;AAC7C,aAAS,iBAAiB,WAAW,GAAG;AACxC,WAAO,MAAM;AAAE,eAAS,oBAAoB,eAAe,IAAI;AAAG,eAAS,oBAAoB,WAAW,GAAG;AAAA,IAAG;AAAA,EAClH,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,KAAK,IAAI;AAC3D,QAAM,MAAM,QAAQ,KAAK;AAEzB,QAAM,QAAQ,CAAC,GAAkB,MAAsB;AACrD,UAAM,KAAK,OAAO,IAAI,QAAQ,EAAE,OAAO,QAAQ;AAC/C,UAAM,QAAQ,MAAM,QAAS,EAAE,UAAU,iBAAiB,WAAa,EAAE,UAAU,kBAAkB;AACrG,WACE;AAAA,MAAC;AAAA;AAAA,QAAO,MAAK;AAAA,QAAS,cAAY,EAAE,QAAQ,OAAO;AAAA,QAAO,gBAAc;AAAA,QAAI,SAAS,MAAM,UAAU,OAAO,EAAE,KAAK,CAAC;AAAA,QAClH,OAAO;AAAA,UAAE,SAAS;AAAA,UAAQ,YAAY;AAAA,UAAU,OAAO;AAAA,UAAI,QAAQ;AAAA,UAAI,cAAc;AAAA,UAAG,QAAQ;AAAA,UAC9F,QAAQ,gBAAgB,KAAK,iBAAiB;AAAA,UAC9C,YAAY,KAAK,iBAAiB;AAAA,UAAkB,OAAO,KAAK,SAAS;AAAA,QAAoB;AAAA,QAC/F,wDAAC,OAAE,WAAW,kBAAkB,MAAM,QAAQ,OAAO,SAAS,OAAO,EAAE,UAAU,GAAG,GAAG;AAAA;AAAA,IACzF;AAAA,EAEJ;AAEA,SACE,+CAAC,UAAK,WAAsB,OAAO,EAAE,UAAU,YAAY,SAAS,cAAc,GAAG,KAAW,GAAG,MACjG;AAAA,mDAAC,UAAO,MAAY,SAAQ,aAAY,MAAM,QAAQ,QAAQ,mBAAmB,mBAAmB,SAAS,MAAM,QAAQ,CAAC,IAAI,GAC7H;AAAA,YAAM,IAAI,QAAQ;AAAA,MACnB,8CAAC,OAAE,WAAW,YAAY,QAAQ,QAAQ,aAAa,eAAe,OAAO,EAAE,UAAU,IAAI,YAAY,GAAG,SAAS,KAAK,GAAG;AAAA,OAC/H;AAAA,IACC,OACC,8CAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,UAAU,YAAY,KAAK,oBAAoB,CAAC,KAAK,GAAG,GAAG,QAAQ,KAAK,OAAO,KAAK,UAAU,sBAAsB,SAAS,SAAS,YAAY,kBAAkB,QAAQ,2BAA2B,cAAc,IAAI,WAAW,kCAAkC,SAAS,EAAE,GACxT,yDAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACzC;AAAA,oDAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,SAAS,cAAc,GAAG,qBAAO;AAAA,MAChF,OAAO,IAAI,CAAC,MAAM;AACjB,cAAM,SAAS,OAAO,IAAI,QAAQ,EAAE;AACpC,eACE,+CAAC,UAAiB,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,SAAS,WAAW,cAAc,GAAG,YAAY,SAAS,yBAAyB,cAAc,GACrJ;AAAA,wDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,MAAM,GAAG,YAAY,SAAS,MAAM,KAAK,OAAO,SAAS,iCAAiC,cAAc,GAAI,YAAE,OAAM;AAAA,UACzJ,MAAM,GAAG,KAAK;AAAA,UACd,MAAM,GAAG,MAAM;AAAA,aAHP,EAAE,GAIb;AAAA,MAEJ,CAAC;AAAA,OACH,GACF,IAAW;AAAA,KACf;AAEJ;;;AC/FA,IAAAC,UAAuB;AAkDJ,IAAAC,uBAAA;AA/CnB,IAAM,YAAoC,EAAE,MAAM,UAAU,QAAQ,oBAAoB,MAAM,aAAa,OAAO,iBAAiB,WAAW,SAAS,KAAK,YAAY,OAAO,mBAAmB;AAoB3L,SAAS,SAAS;AAAA,EACvB,QAAQ,CAAC;AAAA,EAAG;AAAA,EAAO,cAAc;AAAA,EAAO,MAAM;AAAA,EAAU;AAAA,EACxD,gBAAgB;AAAA,EAAM,QAAQ;AAAA,EAAO,YAAY;AACnD,GAAkB;AAChB,QAAM,CAAC,WAAW,YAAY,IAAU,iBAAS,WAAW;AAC5D,QAAM,OAAO,YAAY,OAAO,YAAY;AAC5C,QAAM,CAAC,UAAU,WAAW,IAAU,iBAAkC,CAAC,CAAC;AAC1E,MAAI,CAAC,MAAM,OAAQ,QAAO;AAE1B,QAAM,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS;AACxD,QAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AACzD,QAAM,QAAQ,MAAM,OAAO,CAAC,GAAG,MAAM,KAAK,EAAE,cAAc,IAAI,CAAC;AAC/D,QAAMC,WAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;AAEvE,QAAM,UAAU,UAAU,UACrBA,WAAUA,SAAQ,QAAQ,YAC1B,QAAQ,gBAAgB,eAAe,KAAK,IAAI;AAErD,QAAM,SAAS,MAAM;AACnB,UAAM,OAAO,CAAC;AACd,QAAI,YAAY,KAAM,cAAa,IAAI;AACvC,gBAAY,SAAS,IAAI;AAAA,EAC3B;AAEA,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,QAAQ,aAAa,IAAI,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC9G;AAAA,mDAAC,YAAO,MAAK,UAAS,WAAU,iBAAgB,SAAS,QAAQ,iBAAe,MAC7E;AAAA,gBAAU,8CAAC,UAAK,WAAU,iBAAgB,eAAY,QAAO,IAAK,8CAAC,OAAE,WAAW,YAAY,SAAS,mBAAmB,iBAAiB,eAAY,QAAO;AAAA,MAC7J,8CAAC,UAAK,WAAU,kBAAkB,mBAAQ;AAAA,MAC1C,+CAAC,UAAK,WAAU,6BACb;AAAA,cAAM;AAAA,QAAO;AAAA,QAAM,MAAM,WAAW,IAAI,KAAK;AAAA,QAC7C,SAAS,+CAAC,UAAK,WAAU,mBAAkB;AAAA;AAAA,UAAI;AAAA,UAAO;AAAA,WAAO,IAAU;AAAA,SAC1E;AAAA,MACA,8CAAC,OAAE,WAAW,kBAAkB,OAAO,OAAO,UAAU,mBAAmB,eAAY,QAAO;AAAA,OAChG;AAAA,IACC,OACC,8CAAC,QAAG,WAAU,iBACX,gBAAM,IAAI,CAAC,GAAG,MAAM;AACnB,YAAM,KAAK,EAAE,MAAM;AACnB,YAAM,SAAS,CAAC,CAAC,SAAS,EAAE;AAC5B,YAAM,OAAO,UAAU,EAAE,QAAQ,EAAE,KAAK;AACxC,aACE,+CAAC,QAAY,WAAW,iBAAiB,EAAE,UAAU,OACnD;AAAA,uDAAC,SAAI,WAAU,eACb;AAAA,wDAAC,UAAK,WAAU,gBAAe,eAAY,QACxC,YAAE,WAAW,YAAY,8CAAC,UAAK,WAAU,iBAAgB,IAAK,8CAAC,OAAE,WAAW,WAAW,MAAM,GAChG;AAAA,UACC,EAAE,SACD;AAAA,YAAC;AAAA;AAAA,cAAO,MAAK;AAAA,cAAS,WAAU;AAAA,cAAgB,iBAAe;AAAA,cAC7D,SAAS,MAAM,YAAY,CAAC,MAAM,OAAO,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;AAAA,cACzE;AAAA,8DAAC,UAAM,YAAE,OAAM;AAAA,gBACf,8CAAC,OAAE,WAAW,kBAAkB,SAAS,OAAO,SAAS,eAAY,QAAO;AAAA;AAAA;AAAA,UAC9E,IACE,8CAAC,UAAK,WAAU,2BAA2B,YAAE,OAAM;AAAA,UACtD,EAAE,WAAW,UAAU,8CAAC,UAAK,WAAU,0BAAyB,oBAAM,IAAU;AAAA,UAChF,iBAAiB,EAAE,aAAa,8CAAC,UAAK,WAAU,0BAA0B,yBAAe,EAAE,UAAU,GAAE,IAAU;AAAA,WACpH;AAAA,QACC,EAAE,UAAU,SAAS,8CAAC,SAAI,WAAU,kBAAkB,YAAE,QAAO,IAAS;AAAA,WAflE,EAgBT;AAAA,IAEJ,CAAC,GACH,IACE;AAAA,KACN;AAEJ;;;ACxFA,IAAAC,UAAuB;AAuNf,IAAAC,uBAAA;AAlND,IAAM,2BAA2B;AA6BjC,SAAS,qBAAqB,MAMnB;AAChB,QAAM,EAAE,WAAW,gBAAgB,YAAY,WAAW,aAAa,yBAAyB,IAAI;AAEpG,MAAI,aAAa,KAAK,cAAc,GAAG;AACrC,WAAO,EAAE,cAAc,GAAG,YAAY,IAAI,YAAY,GAAG,UAAU,IAAI,aAAa,GAAG,SAAS,EAAE;AAAA,EACpG;AAEA,QAAM,eAAe,YAAY;AACjC,QAAM,eAAe,KAAK,IAAI,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,UAAU,CAAC,CAAC;AAC3F,QAAM,cAAc,KAAK,IAAI,GAAG,KAAK,KAAK,iBAAiB,UAAU,CAAC;AACtE,QAAM,aAAa,KAAK,IAAI,cAAc,eAAe,cAAc,CAAC;AAExE,QAAM,aAAa,KAAK,IAAI,GAAG,eAAe,UAAU;AACxD,QAAM,WAAW,KAAK,IAAI,cAAc,aAAa,UAAU;AAE/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,YAAY;AAAA,IACzB,SAAS,aAAa;AAAA,EACxB;AACF;AASO,SAAS,gBACd,KACA,WACA,aAAqB,0BACa;AAClC,MAAI,aAAa,EAAG,QAAO,EAAE,OAAO,MAAM,KAAK,KAAK;AACpD,SAAO;AAAA,IACL,OAAO,IAAI,gBAAgB;AAAA,IAC3B,KAAK,YAAY,IAAI,IAAI,cAAc;AAAA,EACzC;AACF;AAgEO,SAAS,YAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAwB;AACtB,QAAM,CAAC,WAAW,YAAY,IAAU,iBAAS,CAAC;AAIlD,QAAM,YAAkB,eAAqD,EAAE,OAAO,MAAM,KAAK,KAAK,CAAC;AAEvG,QAAM,MAAY;AAAA,IAChB,MAAM,qBAAqB,EAAE,WAAW,gBAAgB,QAAQ,YAAY,WAAW,MAAM,OAAO,CAAC;AAAA,IACrG,CAAC,WAAW,QAAQ,YAAY,MAAM,MAAM;AAAA,EAC9C;AACA,QAAM,OAAa,gBAAQ,MAAM,gBAAgB,KAAK,MAAM,MAAM,GAAG,CAAC,KAAK,MAAM,MAAM,CAAC;AAExF,QAAM,YAAY,KAAK,SAAS,SAAS,UAAU;AACnD,QAAM,UAAU,KAAK,OAAO,SAAS,QAAQ;AAE7C,EAAM,kBAAU,MAAM;AACpB,QAAI,WAAW,CAAC,aAAa,UAAU,QAAQ,UAAU,MAAM,OAAQ;AACvE,cAAU,QAAQ,QAAQ,MAAM;AAChC,eAAW,OAAO;AAAA,EACpB,GAAG,CAAC,WAAW,SAAS,MAAM,QAAQ,UAAU,CAAC;AAEjD,EAAM,kBAAU,MAAM;AACpB,QAAI,WAAW,CAAC,WAAW,UAAU,QAAQ,QAAQ,MAAM,OAAQ;AACnE,cAAU,QAAQ,MAAM,MAAM;AAC9B,eAAW,KAAK;AAAA,EAClB,GAAG,CAAC,SAAS,SAAS,MAAM,QAAQ,UAAU,CAAC;AAS/C,QAAM,cAAoB,eAAoC,IAAI;AAClE,QAAM,UAAgB,gBAAQ,MAAM;AAClC,UAAM,OAAO,YAAY;AACzB,QAAI,CAAC,KAAM,QAAO,oBAAI,IAAqB;AAC3C,UAAM,QAAQ,oBAAI,IAAqB;AACvC,eAAW,QAAQ,OAAO;AACxB,YAAM,IAAI,MAAM,IAAI;AACpB,UAAI,CAAC,KAAK,IAAI,CAAC,EAAG,OAAM,IAAI,CAAC;AAAA,IAC/B;AACA,WAAO;AAAA,EAET,GAAG,CAAC,KAAK,CAAC;AACV,EAAM,kBAAU,MAAM;AACpB,gBAAY,UAAU,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;AAAA,EAEhD,GAAG,CAAC,KAAK,CAAC;AAEV,MAAI,CAAC,MAAM,UAAU,CAAC,WAAW,CAAC,cAAc,YAAY;AAC1D,WACE,8CAAC,SAAI,WAAW,CAAC,iBAAiB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,QAAQ,UAAU,YAAY,GAAG,MAAM,GACtH,wDAAC,SAAI,WAAU,yBAAwB,OAAO,EAAE,QAAQ,QAAQ,UAAU,OAAO,GAC9E,sBACH,GACF;AAAA,EAEJ;AAEA,QAAM,OAA0B,CAAC;AACjC,WAAS,IAAI,IAAI,YAAY,KAAK,IAAI,UAAU,KAAK;AACnD,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,SAAS,OAAW;AACxB,UAAM,MAAM,MAAM,IAAI;AACtB,SAAK;AAAA,MACH;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UACV,OAAO,EAAE,QAAQ,YAAY,WAAW,cAAc,WAAW,gBAAgB,IAAI,aAAa,MAAM;AAAA,UAExG,wDAAC,SAAI,WAAW,QAAQ,IAAI,GAAG,IAAI,4CAA4C,wBAC5E,qBAAW,MAAM,CAAC,GACrB;AAAA;AAAA,QANK;AAAA,MAOP;AAAA,IACF;AAAA,EACF;AAEA,SACE,+CAAC,SAAI,WAAW,CAAC,iBAAiB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,QAAQ,UAAU,YAAY,GAAG,MAAM,GACtH;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,QAAQ,QAAQ,WAAW,QAAQ,WAAW,UAAU,UAAU,WAAW;AAAA,QACtF,UAAU,CAAC,MAAM,aAAa,EAAE,cAAc,SAAS;AAAA,QAEvD;AAAA,wDAAC,SAAI,OAAO,EAAE,QAAQ,IAAI,aAAa,UAAU,WAAW,GAAI,gBAAK;AAAA,UACpE,UACC,8CAAC,SAAI,OAAO,EAAE,UAAU,UAAU,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,QAAQ,YAAY,UAAU,SAAS,SAAS,YAAY,iBAAiB,GACpJ,wDAAC,UAAK,WAAU,cAAa,eAAY,QAAO,GAClD,IACE;AAAA;AAAA;AAAA,IACN;AAAA,IACC,aACC,8CAAC,SAAI,WAAU,0BACb,yDAAC,SAAI,WAAU,yBACb;AAAA,oDAAC,UAAK,WAAU,cAAa,eAAY,QAAO;AAAA,MAChD,8CAAC,UAAK,WAAU,cAAc,2BAAgB;AAAA,OAChD,GACF,IACE;AAAA,KACN;AAEJ;;;AC1LQ,IAAAC,uBAAA;AAnBD,SAAS,UAAU,EAAE,OAAO,MAAM,QAAQ,YAAY,OAAO,eAAe,OAAO,YAAY,GAAG,GAAmB;AAC1H,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,CAAC,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC1D,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ,YAAY,SAAS;AAAA;AAAA;AAAA,QAG7B,aAAa,YAAY,SAAS;AAAA,QAClC,GAAG;AAAA,MACL;AAAA,MAEC;AAAA,oBACC,8CAAC,OAAE,WAAU,2BAA0B,eAAY,QAAO,OAAO,EAAE,UAAU,IAAI,MAAM,QAAQ,OAAO,oBAAoB,GAAG,IAC3H;AAAA,QACJ,+CAAC,UAAK,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAE,GACpF;AAAA,wDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,YAAY,KAAK,OAAO,eAAe,YAAY,UAAU,UAAU,UAAU,cAAc,WAAW,GAC7I,iBACH;AAAA,UACC,OACC,8CAAC,UAAK,OAAO,EAAE,UAAU,wBAAwB,OAAO,qBAAqB,YAAY,UAAU,UAAU,UAAU,cAAc,WAAW,GAC7I,gBACH,IACE;AAAA,WACN;AAAA,QACC,SACC;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,OAAO;AAAA,YACb,OAAO,OAAO;AAAA,YACd,MAAK;AAAA,YACL,SAAS,OAAO;AAAA,YAChB,OAAO,EAAE,OAAO,OAAO,SAAS,QAAQ,mBAAmB,OAAO,SAAS,WAAW,uBAAuB,OAAU;AAAA;AAAA,QACzH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;;;ACrGA,IAAAC,UAAuB;AACvB,IAAAC,oBAA6B;;;AC4CrB,IAAAC,uBAAA;AAjBD,SAAS,MAAM;AAAA,EACpB;AAAA,EAAO;AAAA,EAAM;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAM,UAAU;AAAA,EAAO,WAAW;AAAA,EACtE,OAAO;AAAA,EAAM,UAAU;AAAA,EAAO,WAAW;AAAA,EAAO;AAAA,EAAI,YAAY;AAAA,EAAI;AAAA,EAAO;AAAA,EAAY,GAAG;AAC5F,GAAe;AACb,QAAM,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AACvD,QAAM,MAAM;AAAA,IACV;AAAA,IACA,UAAU,iBAAiB;AAAA,IAC3B,QAAQ,mBAAmB;AAAA,IAC3B,WAAW,sBAAsB;AAAA,IACjC,SAAS,OAAO,gBAAgB;AAAA,IAChC;AAAA,EACF,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACE,+CAAC,SAAI,WAAU,YAAW,OACvB;AAAA,YACC,+CAAC,WAAM,WAAU,kBAAiB,SAAS,SACxC;AAAA;AAAA,MAAO,WAAW,8CAAC,UAAK,WAAU,gBAAe,eAAY,QAAO,eAAC,IAAU;AAAA,OAClF,IACE;AAAA,IACJ,+CAAC,SAAI,WAAW,KACb;AAAA,aAAO,8CAAC,UAAK,WAAU,iBAAgB,wDAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO,GAAE,IAAU;AAAA,MACrG,SAAS,8CAAC,UAAK,WAAU,kBAAkB,kBAAO,IAAU;AAAA,MAC7D,8CAAC,WAAM,IAAI,SAAS,UAAoB,OAAO,YAAY,gBAAc,QAAQ,SAAS,QAAY,GAAG,MAAM;AAAA,MAC9G,UAAU,8CAAC,UAAK,WAAU,cAAa,OAAO,EAAE,OAAO,oBAAoB,GAAG,cAAW,WAAU,IAAK;AAAA,MACxG,UAAU,CAAC,UAAU,8CAAC,UAAK,WAAU,kBAAkB,kBAAO,IAAU;AAAA,OAC3E;AAAA,IACC,QACC,+CAAC,UAAK,WAAU,kBAAiB;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG;AAAA,OAAM,IAC/F,OACF,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IACpC;AAAA,KACN;AAEJ;;;ACFY,IAAAC,uBAAA;AAxBL,SAAS,YAAY;AAAA,EAC1B;AAAA,EAAO;AAAA,EAAU;AAAA,EAAa;AAAA,EAAS;AAAA,EAAO;AAAA,EAAW;AAAA,EAAO;AAAA,EAAU;AAAA,EAAI;AAAA,EAAM,GAAG;AACzF,GAAqB;AACnB,QAAM,QAAQ,YAAY,MAAM,SAAS,EAAE;AAC3C,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,MACxC,QACE,QACE;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,cAAW;AAAA,UACX,SAAS;AAAA,UACT,OAAO,EAAE,KAAK,SAAS,QAAQ,WAAW,OAAO,qBAAqB,SAAS,QAAQ,YAAY,UAAU,SAAS,EAAE;AAAA,UAExH,wDAAC,OAAE,WAAU,kBAAiB,OAAO,EAAE,UAAU,GAAG,GAAG,eAAY,QAAO;AAAA;AAAA,MAC5E,IACE;AAAA,MAEL,GAAG;AAAA;AAAA,EACN;AAEJ;;;AF8MU,IAAAC,uBAAA;AAzNV,IAAM,eAAmD,CAAC;AAM1D,IAAM,oBAAoB;AAsDnB,SAAS,aAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,aAAa;AAAA,EACb,YAAY;AACd,GAAyB;AACvB,QAAM,CAAC,MAAM,OAAO,IAAU,iBAA8B,IAAI;AAChE,QAAM,CAAC,cAAc,eAAe,IAAU,iBAAkC,IAAI;AACpF,QAAM,UAAgB,eAA4B,IAAI;AACtD,QAAM,WAAiB,eAWb,IAAI;AACd,QAAM,WAAiB,eAAwD,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC;AAE1G,QAAM,cAAoB,oBAAY,CAAC,GAAW,MAAuC;AACvF,eAAW,QAAQ,CAAC,QAAQ,OAAO,GAAyB;AAC1D,YAAM,KAAK,SAAS,QAAQ,IAAI;AAChC,UAAI,CAAC,GAAI;AACT,YAAM,IAAI,GAAG,sBAAsB;AACnC,UAAI,KAAK,EAAE,QAAQ,KAAK,EAAE,SAAS,KAAK,EAAE,OAAO,KAAK,EAAE,OAAQ,QAAO;AAAA,IACzE;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,WAAiB;AAAA,IACrB,CAAC,MAAwB,SACtB,SAAS,SAAS,KAAK,QAAQ,MAAM,OAAO,KAAK,CAAC,OAAO,MAAM,EAAE,MAAM,GAAG;AAAA,IAC7E,CAAC,KAAK,OAAO,MAAM,OAAO,KAAK;AAAA,EACjC;AAEA,QAAM,YAAY,CAAC,GAAuC,MAAS,SAA2B;AAC5F,QAAI,EAAE,WAAW,EAAG;AAGpB,QAAK,EAAE,OAAuB,WAAY,EAAE,OAAuB,QAAQ,QAAQ,EAAG;AAItF,MAAE,eAAe;AACjB,UAAM,OAAO,EAAE,cAAc,sBAAsB;AACnD,aAAS,UAAU;AAAA,MACjB;AAAA,MACA;AAAA,MACA,KAAK,MAAM,IAAI;AAAA,MACf,WAAW,EAAE;AAAA,MACb,QAAQ,EAAE;AAAA,MACV,QAAQ,EAAE;AAAA,MACV,SAAS,EAAE,UAAU,KAAK;AAAA,MAC1B,SAAS,EAAE,UAAU,KAAK;AAAA,MAC1B,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,EAAM,kBAAU,MAAM;AACpB,UAAM,gBAAgB,CAAC,MAAoB;AACzC,YAAM,QAAQ,SAAS;AACvB,UAAI,CAAC,SAAS,EAAE,cAAc,MAAM,UAAW;AAC/C,UAAI,CAAC,QAAQ,SAAS;AACpB,cAAM,KAAK,EAAE,UAAU,MAAM;AAC7B,cAAM,KAAK,EAAE,UAAU,MAAM;AAC7B,YAAI,KAAK,MAAM,IAAI,EAAE,IAAI,kBAAmB;AAC5C,cAAM,UAAwB;AAAA,UAC5B,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,KAAK,MAAM;AAAA,UACX,WAAW,MAAM;AAAA,UACjB,SAAS,MAAM;AAAA,UACf,SAAS,MAAM;AAAA,UACf,OAAO,MAAM;AAAA,UACb,QAAQ,MAAM;AAAA,UACd,GAAG,EAAE;AAAA,UACL,GAAG,EAAE;AAAA,QACP;AACA,gBAAQ,UAAU;AAClB,gBAAQ,OAAO;AAAA,MACjB,OAAO;AACL,gBAAQ,UAAU,EAAE,GAAG,QAAQ,SAAS,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ;AACnE,gBAAQ,QAAQ,OAAO;AAAA,MACzB;AACA,YAAM,MAAM,YAAY,EAAE,SAAS,EAAE,OAAO;AAC5C,sBAAgB,OAAO,QAAQ,MAAM,OAAO,MAAM,IAAI;AAAA,IACxD;AAEA,UAAM,UAAU,CAAC,MAAoB;AACnC,YAAM,QAAQ,SAAS;AACvB,UAAI,CAAC,SAAS,EAAE,cAAc,MAAM,UAAW;AAC/C,YAAM,cAAc,QAAQ;AAC5B,eAAS,UAAU;AACnB,cAAQ,UAAU;AAClB,cAAQ,IAAI;AACZ,sBAAgB,IAAI;AACpB,UAAI,CAAC,YAAa;AAClB,YAAM,MAAM,YAAY,EAAE,SAAS,EAAE,OAAO;AAC5C,UAAI,OAAO,QAAQ,MAAM,MAAM;AAC7B,cAAM,OAAO,SAAS,MAAM,MAAM,MAAM,GAAG;AAC3C,YAAI,SAAS,OAAW,QAAO,MAAM,MAAM,MAAM,GAAG;AAAA,MACtD;AAAA,IACF;AAEA,WAAO,iBAAiB,eAAe,aAAa;AACpD,WAAO,iBAAiB,aAAa,OAAO;AAC5C,WAAO,iBAAiB,iBAAiB,OAAO;AAChD,WAAO,MAAM;AACX,aAAO,oBAAoB,eAAe,aAAa;AACvD,aAAO,oBAAoB,aAAa,OAAO;AAC/C,aAAO,oBAAoB,iBAAiB,OAAO;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,aAAa,UAAU,MAAM,CAAC;AAKlC,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,QAAQ,OAAO,aAAa,YAAa;AAC9C,UAAM,OAAO,SAAS,KAAK,MAAM;AACjC,aAAS,KAAK,MAAM,aAAa;AACjC,WAAO,MAAM;AACX,eAAS,KAAK,MAAM,aAAa;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,aAAa,CAAC,MAAwB,KAA+B,aAA+B;AACxG,UAAM,cAAc,QAAQ,QAAQ,iBAAiB;AACrD,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,CAAC,OAAO;AACX,mBAAS,QAAQ,IAAI,IAAI;AAAA,QAC3B;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS;AAAA,UACT,eAAe;AAAA,UACf,KAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ,gBAAgB,iBAAiB,OAAO,iBAAiB;AAAA,UACjE,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AAAA,QAEC;AAAA,cAAI,QACH,+CAAC,UAAK,WAAU,wBACb;AAAA,gBAAI;AAAA,YACJ,IAAI,SAAS,OAAO,OAAO,IAAI,MAAM,eAAe,IAAI,MAAM;AAAA,aACjE,IACE;AAAA,UACJ,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,EAAE,GACvC;AAAA,0DAAC,eAAY,OAAO,IAAI,QAAQ,UAAU,IAAI,gBAAgB,aAAY,UAAS,eAAa,IAAI,SAAS,QAAQ,WAAW,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,YACpJ,8CAAC,YAAS,QAAQ,IAAI,YAAY,MAAM,IAAI,MAAM,QAAQ,IAAI,QAAQ,OAAO,SAAS,SAAS,SAAS,SAAS;AAAA,aACnH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,IAAI;AAAA,cACX;AAAA,cACA,QAAQ;AAAA,cACR;AAAA,cACA,SAAS,IAAI;AAAA,cACb,YAAY,IAAI;AAAA,cAChB,SAAS,IAAI,WAAW;AAAA,cACxB,YAAY,IAAI;AAAA,cAChB,YAAY,8CAAC,cAAW,MAAK,QAAO,OAAM,gBAAe;AAAA,cACzD,YAAY,CAAC,SAAS;AACpB,sBAAM,iBAAiB,QAAQ,QAAQ,KAAK,SAAS,QAAQ,KAAK,QAAQ,MAAM,IAAI;AACpF,oBAAI,gBAAgB;AAIlB,yBAAO,8CAAC,SAAI,WAAU,uBAAsB,eAAY,QAAO;AAAA,gBACjE;AACA,uBACE;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO,YAAY,IAAI;AAAA,oBACvB,MAAM,aAAa,WAAW,IAAI,IAAI;AAAA,oBACtC,WAAS;AAAA,oBACT,eAAe,CAAC,MAAM,UAAU,GAAG,MAAM,IAAI;AAAA,oBAC7C,QAAQ;AAAA,sBACN,MAAM,SAAS,SAAS,SAAS;AAAA,sBACjC,QAAQ,SAAS,SAAS,aAAa,iBAAiB,SAAS,SAAS,MAAM,SAAS,mBAAmB,KAAK,SAAS;AAAA,sBAC1H,MAAM,SAAS,SAAS,QAAQ;AAAA,sBAChC,SAAS,MAAM,OAAO,MAAM,MAAM,QAAQ;AAAA,oBAC5C;AAAA;AAAA,gBACF;AAAA,cAEJ;AAAA;AAAA,UACF;AAAA,UACC,cACC,8CAAC,SAAI,WAAU,yBAAwB,eAAY,QACjD,yDAAC,UAAK,WAAU,sBACd;AAAA,0DAAC,OAAE,WAAU,yBAAwB,OAAO,EAAE,UAAU,GAAG,GAAG,eAAY,QAAO;AAAA,YACjF,8CAAC,UAAK,WAAU,cAAa,OAAO,EAAE,YAAY,IAAI,GACnD,cAAI,aAAa,eAAe,IAAI,QAAQ,aAAQ,IAAI,QAAQ,KACnE;AAAA,aACF,GACF,IACE;AAAA;AAAA;AAAA,IACN;AAAA,EAEJ;AAEA,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,SAAS,QAAQ,KAAK,IAAI,YAAY,aAAa,GAC5H;AAAA,eAAW,QAAQ,MAAM,OAAO;AAAA,IAChC,WAAW,SAAS,OAAO,MAAM;AAAA,IACjC,WACG;AAAA,MACE;AAAA,QAAC;AAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,UACV,OAAO;AAAA,YACL,UAAU;AAAA,YACV,MAAM;AAAA,YACN,KAAK;AAAA,YACL,OAAO,KAAK;AAAA,YACZ,QAAQ,KAAK;AAAA,YACb,WAAW,aAAa,KAAK,IAAI,KAAK,OAAO,OAAO,KAAK,IAAI,KAAK,OAAO;AAAA,YACzE,eAAe;AAAA,YACf,QAAQ;AAAA,UACV;AAAA,UAEA,wDAAC,aAAU,OAAO,YAAY,KAAK,IAAI,GAAG,MAAM,aAAa,WAAW,KAAK,IAAI,IAAI,QAAW,WAAS,MAAC,WAAU,oBAAmB;AAAA;AAAA,MACzI;AAAA,MACA,SAAS;AAAA,IACX,IACA;AAAA,KACN;AAEJ;;;AGtWA,IAAAC,UAAuB;AAkBjB,IAAAC,uBAAA;AALC,SAAS,SAAS,EAAE,OAAO,aAAa,OAAO,OAAO,gBAAgB,OAAO,YAAY,IAAI,GAAG,KAAK,GAAkB;AAC5H,QAAM,MAAY,eAAyB,IAAI;AAC/C,EAAM,kBAAU,MAAM;AAAE,QAAI,IAAI,QAAS,KAAI,QAAQ,gBAAgB;AAAA,EAAe,GAAG,CAAC,aAAa,CAAC;AACtG,SACE,+CAAC,WAAM,WAAW,CAAC,aAAa,OAAO,mBAAmB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC/F;AAAA,mDAAC,UAAK,WAAU,mBACd;AAAA,oDAAC,WAAM,KAAU,MAAK,YAAY,GAAG,MAAM;AAAA,MAC3C,8CAAC,UAAK,WAAU,iBAAgB,eAAY,QAC1C,wDAAC,OAAE,WAAW,gBAAgB,gBAAgB,eAAe,GAC/D;AAAA,OACF;AAAA,IACA,+CAAC,UAAK,WAAU,kBACd;AAAA,oDAAC,UAAK,WAAU,mBAAmB,iBAAM;AAAA,MACxC,cAAc,8CAAC,UAAK,WAAU,kBAAkB,uBAAY,IAAU;AAAA,OACzE;AAAA,KACF;AAEJ;;;AClBM,IAAAC,uBAAA;AAHC,SAAS,MAAM,EAAE,OAAO,aAAa,OAAO,OAAO,YAAY,IAAI,GAAG,KAAK,GAAe;AAC/F,SACE,+CAAC,WAAM,WAAW,CAAC,aAAa,OAAO,mBAAmB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC/F;AAAA,mDAAC,UAAK,WAAU,mBACd;AAAA,oDAAC,WAAM,MAAK,SAAS,GAAG,MAAM;AAAA,MAC9B,8CAAC,UAAK,WAAU,qCAAoC,eAAY,QAAO,wDAAC,UAAK,WAAU,iBAAgB,GAAE;AAAA,OAC3G;AAAA,IACA,+CAAC,UAAK,WAAU,kBACd;AAAA,oDAAC,UAAK,WAAU,mBAAmB,iBAAM;AAAA,MACxC,cAAc,8CAAC,UAAK,WAAU,kBAAkB,uBAAY,IAAU;AAAA,OACzE;AAAA,KACF;AAEJ;;;ACXM,IAAAC,uBAAA;AAHC,SAAS,OAAO,EAAE,OAAO,aAAa,YAAY,IAAI,GAAG,KAAK,GAAgB;AACnF,SACE,+CAAC,WAAM,WAAW,CAAC,aAAa,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACjE;AAAA,kDAAC,WAAM,MAAK,YAAW,MAAK,UAAU,GAAG,MAAM;AAAA,IAC/C,8CAAC,UAAK,WAAU,mBAAkB,wDAAC,UAAK,WAAU,mBAAkB,GAAE;AAAA,IACrE,QACC,+CAAC,UAAK,WAAU,kBACd;AAAA,oDAAC,UAAK,WAAU,mBAAmB,iBAAM;AAAA,MACxC,cAAc,8CAAC,UAAK,WAAU,kBAAkB,uBAAY,IAAU;AAAA,OACzE,IACE;AAAA,KACN;AAEJ;;;ACHe,IAAAC,uBAAA;AALR,SAAS,SAAS,EAAE,OAAO,MAAM,OAAO,WAAW,OAAO,OAAO,GAAG,WAAW,OAAO,IAAI,YAAY,IAAI,OAAO,GAAG,KAAK,GAAkB;AAChJ,QAAM,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AACvD,QAAM,MAAM,CAAC,YAAY,qBAAqB,QAAQ,mBAAmB,IAAI,WAAW,sBAAsB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AACrJ,SACE,+CAAC,SAAI,WAAU,YAAW,OACvB;AAAA,YAAQ,+CAAC,WAAM,WAAU,kBAAiB,SAAS,SAAU;AAAA;AAAA,MAAO,WAAW,8CAAC,UAAK,WAAU,gBAAe,eAAC,IAAU;AAAA,OAAK,IAAW;AAAA,IAC1I,8CAAC,SAAI,WAAW,KACd,wDAAC,cAAS,IAAI,SAAS,MAAY,UAAoB,gBAAc,QAAQ,SAAS,QAAY,GAAG,MAAM,GAC7G;AAAA,IACC,QAAQ,+CAAC,UAAK,WAAU,kBAAiB;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG;AAAA,OAAM,IACtG,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,KAC7D;AAEJ;;;AC1BA,IAAAC,UAAuB;AAgDR,IAAAC,uBAAA;AA7BR,SAAS,YAAY;AAAA,EAC1B;AAAA,EAAO;AAAA,EAAM;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ,WAAW;AAAA,EAAO,WAAW;AAAA,EACjE,MAAM;AAAA,EAAW,MAAM;AAAA,EAAU,OAAO;AAAA,EAAG;AAAA,EAAS;AAAA,EAAO;AAAA,EAC3D,SAAS;AAAA,EAAM,YAAY;AAAA,EAAI;AAAA,EAAO;AACxC,GAAqB;AACnB,QAAM,MAAM,CAAC,MAA0B;AAAE,UAAM,IAAI,OAAO,OAAO,KAAK,OAAO,KAAK,CAAC,EAAE,QAAQ,aAAa,EAAE,CAAC;AAAG,WAAO,MAAM,CAAC,IAAI,OAAO;AAAA,EAAG;AAC5I,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,SAAS,QAAQ,UAAU,KAAK,KAAK,OAAO,KAAK,CAAC;AACzF,QAAM,CAAC,SAAS,UAAU,IAAU,iBAAS,KAAK;AAClD,QAAM,QAAc,eAA6C,IAAI;AACrE,EAAM,kBAAU,MAAM;AAAE,QAAI,CAAC,QAAS,SAAQ,SAAS,QAAQ,UAAU,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,EAAG,GAAG,CAAC,OAAO,OAAO,CAAC;AACtH,QAAM,QAAQ,CAAC,MAAc,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC;AAC3D,QAAM,OAAO,CAAC,MAAc,YAAY,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;AACzE,QAAM,OAAO,CAAC,KAAa,OAAO,MAAM;AACtC,UAAM,MAAM,IAAI,IAAI,KAAK,IAAI,KAAK,MAAM,QAAQ,YAAY,IAAI;AAChE,UAAM,OAAO,MAAM,MAAM,OAAO,WAAW,OAAO,IAAI,UAAU,SAAS,UAAU,IAAI,KAAK;AAC5F,YAAQ,OAAO,IAAI,CAAC;AAAG,SAAK,IAAI;AAAA,EAClC;AACA,QAAM,OAAO,CAAC,QAAgB;AAC5B,SAAK,GAAG;AACR,QAAI,IAAI;AACR,UAAM,OAAO,MAAM;AAAE;AAAK,WAAK,KAAK,IAAI,IAAI,IAAI,CAAC;AAAG,YAAM,UAAU,WAAW,MAAM,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG;AAAA,IAAG;AACtH,UAAM,UAAU,WAAW,MAAM,GAAG;AAAA,EACtC;AACA,QAAM,UAAU,MAAM;AAAE,QAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAAA,EAAG;AACxE,EAAM,kBAAU,MAAM,MAAM;AAAE,QAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAAA,EAAG,GAAG,CAAC,CAAC;AACnF,QAAM,QAAQ,UAAU,QAAQ,MAAM;AAAE,UAAM,IAAI,IAAI,IAAI;AAAG,WAAO,KAAK,OAAO,KAAM,SAAS,EAAE,eAAe,IAAI,OAAO,CAAC;AAAA,EAAI,GAAG;AACnI,QAAM,MAAM,CAAC,YAAY,gBAAgB,QAAQ,mBAAmB,IAAI,WAAW,sBAAsB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AACrI,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAChE;AAAA,YAAQ,+CAAC,WAAM,WAAU,kBAAkB;AAAA;AAAA,MAAO,WAAW,8CAAC,UAAK,WAAU,gBAAe,eAAC,IAAU;AAAA,OAAK,IAAW;AAAA,IACxH,+CAAC,SAAI,WAAW,KAAK,OAAO,EAAE,KAAK,EAAE,GAClC;AAAA,eAAS,8CAAC,UAAK,WAAU,kBAAkB,kBAAO,IAAU;AAAA,MAC7D;AAAA,QAAC;AAAA;AAAA,UAAM,WAAU;AAAA,UAAU;AAAA,UAAoB;AAAA,UAA0B,OAAO;AAAA,UAC9E,SAAS,MAAM,WAAW,IAAI;AAAA,UAC9B,QAAQ,MAAM;AAAE,uBAAW,KAAK;AAAG,kBAAM,IAAI,IAAI,IAAI;AAAG,gBAAI,KAAK,MAAM;AAAE,oBAAM,IAAI,MAAM,CAAC;AAAG,sBAAQ,OAAO,CAAC,CAAC;AAAG,mBAAK,CAAC;AAAA,YAAG;AAAA,UAAE;AAAA,UAC5H,UAAU,CAAC,MAAM;AAAE,oBAAQ,EAAE,OAAO,KAAK;AAAG,kBAAM,IAAI,IAAI,EAAE,OAAO,KAAK;AAAG,gBAAI,KAAK,KAAM,MAAK,CAAC;AAAA,UAAG;AAAA,UACnG,WAAW,CAAC,MAAM;AAChB,gBAAI,EAAE,QAAQ,WAAW;AAAE,gBAAE,eAAe;AAAG,mBAAK,GAAG,EAAE,WAAW,IAAI,CAAC;AAAA,YAAG,WACnE,EAAE,QAAQ,aAAa;AAAE,gBAAE,eAAe;AAAG,mBAAK,IAAI,EAAE,WAAW,IAAI,CAAC;AAAA,YAAG;AAAA,UACtF;AAAA;AAAA,MAAG;AAAA,MACJ,SAAS,8CAAC,UAAK,WAAU,kBAAkB,kBAAO,IAAU;AAAA,MAC7D,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,MAAM,OAAO,GACrD;AAAA;AAAA,UAAC;AAAA;AAAA,YAAO,MAAK;AAAA,YAAS,WAAU;AAAA,YAAa,cAAW;AAAA,YAAW,UAAU,aAAa,IAAI,IAAI,KAAK,MAAM;AAAA,YAC3G,eAAe,MAAM,KAAK,EAAE;AAAA,YAAG,aAAa;AAAA,YAAS,gBAAgB;AAAA,YAAS,wDAAC,OAAE,WAAU,eAAc;AAAA;AAAA,QAAE;AAAA,QAC7G;AAAA,UAAC;AAAA;AAAA,YAAO,MAAK;AAAA,YAAS,WAAU;AAAA,YAAa,cAAW;AAAA,YAAW,UAAU,aAAa,IAAI,IAAI,KAAK,MAAM;AAAA,YAC3G,eAAe,MAAM,KAAK,CAAC;AAAA,YAAG,aAAa;AAAA,YAAS,gBAAgB;AAAA,YAAS,wDAAC,OAAE,WAAU,cAAa;AAAA;AAAA,QAAE;AAAA,SAC7G;AAAA,OACF;AAAA,IACC,QAAQ,+CAAC,UAAK,WAAU,kBAAiB;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG;AAAA,OAAM,IACtG,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,KAC7D;AAEJ;;;ACvEA,IAAAC,UAAuB;AACvB,IAAAC,oBAA6B;AAoKd,IAAAC,uBAAA;AAvIf,IAAM,OAAO,CAAC,MAA4C,OAAO,MAAM,WAAW,EAAE,OAAO,GAAG,OAAO,EAAE,IAAI;AAW3G,SAAS,UAAU,MAAe,KAAmC,MAAc,MAA8B;AAC/G,QAAM,CAAC,KAAK,MAAM,IAAU,iBAAwB,IAAI;AACxD,EAAM,wBAAgB,MAAM;AAC1B,QAAI,CAAC,QAAQ,CAAC,IAAI,SAAS;AAAE,aAAO,IAAI;AAAG;AAAA,IAAQ;AACnD,UAAM,OAAO,MAAM;AACjB,YAAM,IAAI,IAAI,QAAS,sBAAsB;AAC7C,YAAM,QAAQ,OAAO,cAAc,EAAE;AACrC,YAAM,KAAK,QAAQ,QAAQ,EAAE,MAAM;AACnC,YAAM,IAAI,KAAK,IAAI,EAAE,OAAO,QAAQ,CAAC;AACrC,YAAM,OAAO,KAAK,IAAI,OAAO,cAAc,IAAI,KAAK,IAAI,MAAM,KAAK,EAAE,MAAM,SAAS,EAAE,CAAC;AACvF,aAAO;AAAA,QACL,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,EAAE,MAAM,OAAO,aAAa,IAAI,CAAC,CAAC;AAAA,QAAG,OAAO,EAAE;AAAA,QACzE,KAAK,KAAK,OAAO,EAAE,SAAS;AAAA,QAAG,QAAQ,KAAK,OAAO,cAAc,EAAE,MAAM,IAAI;AAAA,QAAM;AAAA,QAAI;AAAA,MACzF,CAAC;AAAA,IACH;AACA,SAAK;AACL,WAAO,iBAAiB,UAAU,MAAM,IAAI;AAC5C,WAAO,iBAAiB,UAAU,IAAI;AACtC,WAAO,MAAM;AAAE,aAAO,oBAAoB,UAAU,MAAM,IAAI;AAAG,aAAO,oBAAoB,UAAU,IAAI;AAAA,IAAG;AAAA,EAE/G,GAAG,CAAC,IAAI,CAAC;AACT,SAAO;AACT;AAEA,IAAM,WAAW,CAAC,KAAa,WAAqD;AAAA,EAClF,UAAU;AAAA,EAAS,MAAM,IAAI;AAAA,EAAM,KAAK,IAAI,OAAO,OAAO,SAAS,IAAI;AAAA,EAAK,QAAQ,IAAI,UAAU,OAAO,SAAS,IAAI;AAAA,EACtH,iBAAiB,IAAI,KAAK,kBAAkB;AAAA,EAAc,WAAW,IAAI;AAAA,EAAM,WAAW;AAAA,EAAQ,GAAG;AACvG;AAEO,SAAS,OAAO;AAAA,EACrB;AAAA,EAAO;AAAA,EAAM;AAAA,EAAO,UAAU,CAAC;AAAA,EAAG,cAAc;AAAA,EAAW,WAAW;AAAA,EACtE,WAAW;AAAA,EAAO,UAAU;AAAA,EAAO;AAAA,EAAO;AAAA,EAAU;AAAA,EAAY,YAAY;AAAA,EAC5E,WAAW;AAAA,EAAO;AAAA,EAClB;AAAA,EAAI,YAAY;AAAA,EAAI;AAAA,EAAO,GAAG;AAChC,GAAgB;AACd,QAAM,OAAO,QAAQ,IAAI,IAAI;AAC7B,QAAM,OAAO,WAAY,MAAM,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC,KAAK,IAAI,CAAC,IAAK,CAAC;AACjF,QAAM,OAAO,CAAC,MAAe,WAAW,KAAK,SAAS,CAAC,IAAI,MAAM;AACjE,QAAM,YAAY,eAAe,SAAY,KAAK,SAAS,IAAI;AAC/D,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,CAAC,GAAG,IAAI,IAAU,iBAAS,EAAE;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAU,iBAAS,EAAE;AAC7C,QAAM,UAAgB,eAAuB,IAAI;AACjD,QAAM,SAAe,eAAuB,IAAI;AAChD,QAAM,SAAe,eAAuB,IAAI;AAChD,QAAM,UAAgB,eAAuB,IAAI;AACjD,QAAM,UAAgB,eAAO,EAAE,GAAG,IAAI,GAAG,EAAE,CAAC;AAC5C,QAAM,WAAW,WAAW,OAAO,KAAK,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK;AACrE,QAAM,SAAS,WAAW,KAAK,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC;AACxE,QAAM,MAAM,UAAU,MAAM,QAAQ,YAAY,MAAM,KAAK,GAAG;AAC9D,QAAM,UAAU,WACX,OAAO,WAAW,IAAI,cACrB,OAAO,WAAW,IAAI,OAAO,CAAC,EAAE,QAC9B,UAAU,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,OAAO,SAAS,cACnE,WAAW,SAAS,QAAQ;AAEjC,QAAM,UAAU,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,QAAQ,OAAO,EAAE,eAAe,MAAM,OAAO,EAAE,SAAS,KAAK,YAAY,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,IAAI;AAElJ,QAAM,OAAO,CAAC,MAAyB;AAAE,gBAAY,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;AAAA,EAAG;AACzF,QAAM,OAAO,CAAC,MAAoB;AAChC,QAAI,EAAE,SAAU;AAChB,QAAI,UAAU;AAAE,WAAK,KAAK,SAAS,EAAE,KAAK,IAAI,KAAK,OAAO,CAAC,MAAM,MAAM,EAAE,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC;AAAG;AAAA,IAAQ;AAC/G,SAAK,EAAE,KAAK;AAAG,YAAQ,KAAK;AAAA,EAC9B;AACA,QAAM,SAAS,MAAM;AACnB,QAAI,YAAY,QAAS;AACzB,QAAI,CAAC,MAAM;AAAE,WAAK,EAAE;AAAG,gBAAU,KAAK,IAAI,GAAG,KAAK,UAAU,CAAC,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAAA,IAAG;AACrF,YAAQ,CAAC,IAAI;AAAA,EACf;AAEA,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,CAAC,MAAoB;AAChC,UAAI,QAAQ,WAAW,QAAQ,QAAQ,SAAS,EAAE,MAAc,EAAG;AACnE,UAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,EAAE,MAAc,EAAG;AACjE,cAAQ,KAAK;AAAA,IACf;AACA,aAAS,iBAAiB,eAAe,IAAI;AAC7C,WAAO,MAAM,SAAS,oBAAoB,eAAe,IAAI;AAAA,EAC/D,GAAG,CAAC,IAAI,CAAC;AAET,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,QAAQ,SAAS,KAAK,CAAC,QAAQ,QAAS;AAC7C,UAAM,KAAK,QAAQ,QAAQ,cAAc,cAAc,SAAS,IAAI;AACpE,QAAI,IAAI;AACN,YAAM,IAAI,QAAQ,SAAS,MAAM,GAAG,YAAY,EAAE;AAClD,UAAI,MAAM,EAAE,UAAW,GAAE,YAAY,MAAM;AAAA,eAClC,MAAM,GAAG,eAAe,EAAE,YAAY,EAAE,aAAc,GAAE,YAAY,MAAM,GAAG,eAAe,EAAE,eAAe;AAAA,IACxH;AAAA,EACF,GAAG,CAAC,QAAQ,IAAI,CAAC;AAEjB,QAAM,QAAQ,CAAC,MAAwC;AACrD,QAAI,SAAU;AACd,QAAI,CAAC,SAAS,EAAE,QAAQ,WAAW,EAAE,QAAQ,OAAO,EAAE,QAAQ,eAAe,EAAE,QAAQ,YAAY;AAAE,QAAE,eAAe;AAAG,aAAO;AAAG;AAAA,IAAQ;AAC3I,QAAI,CAAC,MAAM;AACT,UAAI,EAAE,IAAI,WAAW,KAAK,KAAK,KAAK,EAAE,GAAG,GAAG;AAC1C,cAAM,MAAM,KAAK,IAAI;AACrB,gBAAQ,UAAU,EAAE,IAAI,MAAM,QAAQ,QAAQ,IAAI,MAAM,QAAQ,QAAQ,IAAI,MAAM,EAAE,IAAI,YAAY,GAAG,GAAG,IAAI;AAC9G,cAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,MAAM,YAAY,EAAE,WAAW,QAAQ,QAAQ,CAAC,CAAC;AAChF,YAAI,OAAO,CAAC,SAAU,MAAK,IAAI,KAAK;AAAA,MACtC;AACA;AAAA,IACF;AACA,QAAI,EAAE,QAAQ,UAAU;AAAE,QAAE,eAAe;AAAG,cAAQ,KAAK;AAAA,IAAG,WACrD,EAAE,QAAQ,aAAa;AAAE,QAAE,eAAe;AAAG,gBAAU,CAAC,MAAM,KAAK,IAAI,QAAQ,SAAS,GAAG,IAAI,CAAC,CAAC;AAAA,IAAG,WACpG,EAAE,QAAQ,WAAW;AAAE,QAAE,eAAe;AAAG,gBAAU,CAAC,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,IAAG,WACjF,EAAE,QAAQ,QAAQ;AAAE,QAAE,eAAe;AAAG,gBAAU,CAAC;AAAA,IAAG,WACtD,EAAE,QAAQ,OAAO;AAAE,QAAE,eAAe;AAAG,gBAAU,QAAQ,SAAS,CAAC;AAAA,IAAG,WACtE,EAAE,QAAQ,SAAS;AAAE,QAAE,eAAe;AAAG,UAAI,QAAQ,MAAM,EAAG,MAAK,QAAQ,MAAM,CAAC;AAAA,IAAG,WACrF,EAAE,QAAQ,MAAO,SAAQ,KAAK;AAAA,EACzC;AAEA,QAAM,SAAmE,CAAC;AAC1E,UAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,UAAM,IAAI,EAAE,SAAS;AACrB,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,QAAI,CAAC,QAAQ,KAAK,MAAM,EAAG,QAAO,KAAK,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAAA,QAC1D,MAAK,MAAM,KAAK,EAAE,GAAG,EAAE,CAAC;AAAA,EAC/B,CAAC;AAED,QAAM,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AACvD,QAAM,MAAM,CAAC,YAAY,aAAa,QAAQ,mBAAmB,IAAI,WAAW,sBAAsB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAClI,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,eAAe,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAc,KAAK,SACzH;AAAA,YAAQ,+CAAC,WAAM,WAAU,kBAAiB,SAAS,SAAS,SAAS,QAAS;AAAA;AAAA,MAAO,WAAW,8CAAC,UAAK,WAAU,gBAAe,eAAC,IAAU;AAAA,OAAK,IAAW;AAAA,IAC3J,+CAAC,SAAI,WAAW,KAAK,OAAO,EAAE,QAAQ,WAAW,gBAAgB,UAAU,GAAG,KAAK,QACjF;AAAA;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS,IAAI;AAAA,UAAS,UAAU,YAAY;AAAA,UAAS,SAAS;AAAA,UAAQ,WAAW;AAAA,UAC5F,MAAK;AAAA,UAAW,iBAAe;AAAA,UAAM,iBAAc;AAAA,UACnD,OAAO,EAAE,KAAK,SAAS,MAAM,GAAG,UAAU,GAAG,SAAS,QAAQ,YAAY,UAAU,KAAK,GAAG,QAAQ,WAAW,UAAU,SAAS;AAAA,UACjI;AAAA,wBAAY,SAAS,OAAO,8CAAC,OAAE,WAAW,WAAW,SAAS,MAAM,OAAO,EAAE,MAAM,QAAQ,OAAO,gBAAgB,GAAG,IAAK;AAAA,YAC3H,8CAAC,UAAK,OAAO,EAAE,UAAU,UAAU,cAAc,YAAY,YAAY,UAAU,QAAQ,WAAW,OAAO,SAAS,YAAY,gBAAgB,oBAAoB,GACnK,mBACH;AAAA,YACC,YAAY,OAAO,SAAS,IAAI,8CAAC,UAAK,WAAU,WAAU,OAAO,EAAE,MAAM,QAAQ,UAAU,IAAI,YAAY,KAAK,SAAS,WAAW,cAAc,IAAI,YAAY,gBAAgB,OAAO,OAAO,GAAI,iBAAO,QAAO,IAAU;AAAA;AAAA;AAAA,MAC/N;AAAA,MACC,cAAc,WAAW,OAAO,SAAS,IAAI,aAAa,CAAC,UAC1D;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS,cAAW;AAAA,UAAQ,SAAS,CAAC,MAAM;AAAE,cAAE,gBAAgB;AAAG,iBAAK,WAAW,CAAC,IAAI,EAAE;AAAA,UAAG;AAAA,UACxG,OAAO,EAAE,KAAK,SAAS,QAAQ,WAAW,OAAO,qBAAqB,SAAS,QAAQ,YAAY,UAAU,SAAS,EAAE;AAAA,UACxH,wDAAC,OAAE,WAAU,kBAAiB,OAAO,EAAE,UAAU,GAAG,GAAG;AAAA;AAAA,MACzD,IAAa;AAAA,MACd,UACG,8CAAC,UAAK,WAAU,cAAa,OAAO,EAAE,OAAO,oBAAoB,GAAG,cAAW,mBAAkB,IACjG,8CAAC,UAAK,WAAU,mBAAkB,SAAS,QAAQ,wDAAC,OAAE,WAAU,oBAAmB,eAAY,QAAO,GAAE;AAAA,OAC9G;AAAA,IACC,QAAQ,UAAM;AAAA,MACb;AAAA,QAAC;AAAA;AAAA,UAAI,WAAW,YAAY,IAAI,KAAK,WAAW;AAAA,UAAK,KAAK;AAAA,UACxD,OAAO,SAAS,KAAK,EAAE,UAAU,KAAK,IAAI,IAAI,OAAO,GAAG,GAAG,UAAU,KAAK,QAAQ,KAAK,WAAW,SAAS,CAAC;AAAA,UAC3G;AAAA,wBACC,+CAAC,SAAI,WAAU,iBACb;AAAA,4DAAC,OAAE,WAAU,0BAAyB,OAAO,EAAE,OAAO,qBAAqB,UAAU,GAAG,GAAG;AAAA,cAC3F;AAAA,gBAAC;AAAA;AAAA,kBAAM,WAAS;AAAA,kBAAC,aAAY;AAAA,kBAAU,OAAO;AAAA,kBAAG,WAAW;AAAA,kBAC1D,UAAU,CAAC,MAAM;AAAE,yBAAK,EAAE,OAAO,KAAK;AAAG,8BAAU,CAAC;AAAA,kBAAG;AAAA;AAAA,cAAG;AAAA,cAC3D,IAAI,8CAAC,UAAK,WAAU,uBAAuB,kBAAQ,QAAO,IAAU;AAAA,eACvE,IAAU;AAAA,YACZ,8CAAC,SAAI,WAAU,eAAc,MAAK,WAAU,wBAAsB,YAAY,QAAW,KAAK,SAAS,OAAO,EAAE,WAAW,KAAK,IAAI,KAAK,IAAI,QAAQ,YAAY,KAAK,OAAO,WAAW,KAAK,EAAE,EAAE,GAC9L,kBAAQ,WAAW,IAAI,+CAAC,SAAI,WAAU,gBAAe;AAAA;AAAA,cAAkB;AAAA,cAAE;AAAA,eAAE,IAAS,OAAO,IAAI,CAAC,QAC/F,+CAAO,kBAAN,EACE;AAAA,kBAAI,IAAI,8CAAC,SAAI,WAAU,gBAAgB,cAAI,GAAE,IAAS;AAAA,cACtD,IAAI,MAAM,IAAI,CAAC,EAAE,GAAG,EAAE,MACrB;AAAA,gBAAC;AAAA;AAAA,kBAAO,MAAK;AAAA,kBAA+B,UAAQ;AAAA,kBAAG,MAAK;AAAA,kBAAS,iBAAe,KAAK,EAAE,KAAK;AAAA,kBAC9F,iBAAe,EAAE,YAAY;AAAA,kBAC7B,WAAW,CAAC,UAAU,MAAM,SAAS,cAAc,IAAI,KAAK,EAAE,KAAK,IAAI,gBAAgB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,kBACnH,cAAc,MAAM,UAAU,CAAC;AAAA,kBAAG,SAAS,MAAM,KAAK,CAAC;AAAA,kBACtD;AAAA,+BACC,8CAAC,UAAK,eAAY,QAAO,OAAO,EAAE,MAAM,QAAQ,SAAS,QAAQ,YAAY,UAAU,OAAO,IAAI,QAAQ,IAAI,cAAc,GAAG,QAAQ,kBAAkB,KAAK,EAAE,KAAK,IAAI,iBAAiB,wCAAwC,YAAY,KAAK,EAAE,KAAK,IAAI,iBAAiB,kBAAkB,OAAO,OAAO,GAC5S,eAAK,EAAE,KAAK,IAAI,8CAAC,OAAE,WAAU,eAAc,OAAO,EAAE,UAAU,GAAG,GAAG,IAAK,MAC5E,IAAW;AAAA,oBACZ,EAAE,OAAO,8CAAC,UAAK,WAAU,eAAc,wDAAC,OAAE,WAAW,WAAW,EAAE,MAAM,GAAE,IAAU;AAAA,oBACrF,+CAAC,UAAK,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GAClC;AAAA,oEAAC,UAAK,WAAU,gBAAgB,YAAE,OAAM;AAAA,sBACvC,EAAE,cAAc,8CAAC,UAAK,WAAU,eAAe,YAAE,aAAY,IAAU;AAAA,uBAC1E;AAAA,oBACC,EAAE,OAAO,8CAAC,UAAK,WAAU,eAAe,YAAE,MAAK,IAAU;AAAA,oBACzD,WAAW,OAAO,8CAAC,UAAK,WAAU,gBAAgB,YAAE,UAAU,QAAQ,8CAAC,OAAE,WAAU,eAAc,IAAK,MAAK;AAAA;AAAA;AAAA,gBAdnF,OAAO,EAAE,KAAK;AAAA,cAezC,CACD;AAAA,iBAnBkB,IAAI,KAAK,GAoB9B,CACD,GACH;AAAA,YACC,WACC,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,SAAS,YAAY,WAAW,0BAA0B,GAClG;AAAA;AAAA,gBAAC;AAAA;AAAA,kBAAO,MAAK;AAAA,kBAAS,SAAS,MAAM,KAAK,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,kBAC9F,OAAO,EAAE,KAAK,SAAS,QAAQ,WAAW,UAAU,uBAAuB,YAAY,KAAK,OAAO,eAAe;AAAA,kBAAG;AAAA;AAAA,cAAU;AAAA,cACjI,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,cAC1B,+CAAC,UAAK,WAAU,uBAAuB;AAAA,qBAAK;AAAA,gBAAO;AAAA,gBAAK,KAAK;AAAA,iBAAO;AAAA,cACpE;AAAA,gBAAC;AAAA;AAAA,kBAAO,MAAK;AAAA,kBAAS,UAAU,CAAC,KAAK;AAAA,kBAAQ,SAAS,MAAM,KAAK,CAAC,CAAC;AAAA,kBAClE,OAAO,EAAE,KAAK,SAAS,QAAQ,KAAK,SAAS,YAAY,WAAW,UAAU,uBAAuB,YAAY,KAAK,OAAO,KAAK,SAAS,kBAAkB,oBAAoB;AAAA,kBAAG;AAAA;AAAA,cAAK;AAAA,eAC7L,IAAU;AAAA;AAAA;AAAA,MACd;AAAA,MAAQ,SAAS;AAAA,IAAI,IAAI;AAAA,IAC1B,QAAQ,+CAAC,UAAK,WAAU,kBAAiB;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG;AAAA,OAAM,IACtG,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,KAC7D;AAEJ;;;AC1OA,IAAAC,UAAuB;AACvB,IAAAC,oBAA6B;AA2FvB,IAAAC,uBAAA;AAzFN,IAAM,SAAS,CAAC,WAAW,YAAY,SAAS,SAAS,OAAO,QAAQ,QAAQ,UAAU,aAAa,WAAW,YAAY,UAAU;AACxI,IAAM,MAAM,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AACrD,IAAM,MAAM,CAAC,MAAY,EAAE,YAAY,IAAI,MAAM,OAAO,EAAE,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG,IAAI,MAAM,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AACtI,IAAM,QAAQ,CAAC,MAAmC;AAAE,MAAI,CAAC,EAAG,QAAO;AAAM,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAAG,SAAO,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC;AAAG;AACnJ,IAAM,MAAM,CAAC,MAAsB;AAAE,QAAM,IAAI,MAAM,CAAC;AAAG,SAAO,IAAI,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,MAAM,EAAE,QAAQ,IAAI,OAAO,EAAE,YAAY,IAAI;AAAI;AAWxJ,SAASC,WAAU,MAAe,KAAmC,MAAc,MAA8B;AAC/G,QAAM,CAAC,KAAK,MAAM,IAAU,iBAAwB,IAAI;AACxD,EAAM,wBAAgB,MAAM;AAC1B,QAAI,CAAC,QAAQ,CAAC,IAAI,SAAS;AAAE,aAAO,IAAI;AAAG;AAAA,IAAQ;AACnD,UAAM,OAAO,MAAM;AACjB,YAAM,IAAI,IAAI,QAAS,sBAAsB;AAC7C,YAAM,QAAQ,OAAO,cAAc,EAAE;AACrC,YAAM,KAAK,QAAQ,QAAQ,EAAE,MAAM;AACnC,YAAM,IAAI,KAAK,IAAI,EAAE,OAAO,QAAQ,CAAC;AACrC,YAAM,OAAO,KAAK,IAAI,OAAO,cAAc,IAAI,KAAK,IAAI,MAAM,KAAK,EAAE,MAAM,SAAS,EAAE,CAAC;AACvF,aAAO;AAAA,QACL,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,EAAE,MAAM,OAAO,aAAa,IAAI,CAAC,CAAC;AAAA,QAAG,OAAO,EAAE;AAAA,QACzE,KAAK,KAAK,OAAO,EAAE,SAAS;AAAA,QAAG,QAAQ,KAAK,OAAO,cAAc,EAAE,MAAM,IAAI;AAAA,QAAM;AAAA,QAAI;AAAA,MACzF,CAAC;AAAA,IACH;AACA,SAAK;AACL,WAAO,iBAAiB,UAAU,MAAM,IAAI;AAC5C,WAAO,iBAAiB,UAAU,IAAI;AACtC,WAAO,MAAM;AAAE,aAAO,oBAAoB,UAAU,MAAM,IAAI;AAAG,aAAO,oBAAoB,UAAU,IAAI;AAAA,IAAG;AAAA,EAE/G,GAAG,CAAC,IAAI,CAAC;AACT,SAAO;AACT;AACA,IAAMC,YAAW,CAAC,KAAa,WAAqD;AAAA,EAClF,UAAU;AAAA,EAAS,MAAM,IAAI;AAAA,EAAM,KAAK,IAAI,OAAO,OAAO,SAAS,IAAI;AAAA,EAAK,QAAQ,IAAI,UAAU,OAAO,SAAS,IAAI;AAAA,EACtH,iBAAiB,IAAI,KAAK,kBAAkB;AAAA,EAAc,WAAW,IAAI;AAAA,EAAM,WAAW;AAAA,EAAQ,GAAG;AACvG;AAkBO,SAAS,SAAS,EAAE,OAAO,QAAQ,OAAO,QAAQ,cAAc,SAAS,EAAE,GAAkB;AAClG,QAAM,QAAQ,oBAAI,KAAK;AACvB,QAAM,MAAM,QAAQ,SAAS,CAAC,IAAI,EAAE,OAAO,OAAO,KAAK,MAAM;AAC7D,QAAM,SAAS,MAAM,IAAI,KAAK,KAAK,MAAM,YAAY,KAAK;AAC1D,QAAM,CAAC,IAAI,KAAK,IAAU,iBAAS,OAAO,YAAY,CAAC;AACvD,QAAM,CAAC,IAAI,KAAK,IAAU,iBAAS,OAAO,SAAS,CAAC;AACpD,QAAM,CAACC,OAAM,OAAO,IAAU,iBAAS,MAAM;AAC7C,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAwB,IAAI;AAC5D,QAAM,IAAI,MAAM,IAAI,KAAK,GAAG,IAAI,MAAM,IAAI,GAAG;AAC7C,QAAM,WAAW,SAAS,KAAK,CAAC,KAAK,QAAQ,MAAM,KAAK,IAAI;AAC5D,QAAM,UAAU,CAAC,MAAY;AAC3B,UAAM,KAAK,GAAG,KAAK,KAAK;AACxB,WAAO,MAAM,MAAM,KAAK,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK;AAAA,EACpE;AACA,QAAM,SAAS,CAAC,MAAa,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,KAAO,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC;AAC9E,QAAM,WAAW,CAAC,MAAY;AAC5B,UAAM,IAAI,IAAI,CAAC;AACf,QAAI,CAAC,OAAO;AAAE,aAAO,CAAC;AAAG;AAAA,IAAQ;AACjC,QAAI,CAAC,IAAI,SAAU,IAAI,SAAS,IAAI,IAAM,QAAO,EAAE,OAAO,GAAG,KAAK,GAAG,CAAC;AAAA,SACjE;AACH,YAAM,IAAI,MAAM,IAAI,KAAK;AACzB,aAAO,IAAI,IAAI,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,IAAI,EAAE,OAAO,IAAI,OAAO,KAAK,EAAE,CAAC;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,MAAM,CAAC,MAAc;AAAE,QAAI,IAAI,KAAK,GAAG,IAAI;AAAI,QAAI,IAAI,GAAG;AAAE,UAAI;AAAI;AAAA,IAAK;AAAE,QAAI,IAAI,IAAI;AAAE,UAAI;AAAG;AAAA,IAAK;AAAE,UAAM,CAAC;AAAG,UAAM,CAAC;AAAA,EAAG;AACjI,QAAM,YAAY,CAAC,GAAW,MAAc;AAC1C,UAAM,WAAW,IAAI,KAAK,GAAG,GAAG,CAAC,EAAE,OAAO;AAC1C,UAAM,QAAgB,CAAC;AACvB,aAAS,IAAI,GAAG,IAAI,IAAI,IAAK,OAAM,KAAK,IAAI,KAAK,GAAG,GAAG,IAAI,WAAW,CAAC,CAAC;AACxE,WACE,+CAAC,SAAI,WAAU,eAAc,OAAO,EAAE,OAAO,SAAS,IAAI,MAAM,QAAQ,MAAM,OAAO,GAAG,cAAc,MAAM,SAAS,IAAI,GACtH;AAAA,UAAI,IAAI,CAAC,MAAM,8CAAC,UAAa,WAAU,cAAc,eAA3B,CAA6B,CAAO;AAAA,MAC9D,MAAM,IAAI,CAAC,GAAG,MACb;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UACX,WAAW,CAAC,cAAc,EAAE,SAAS,MAAM,IAAI,WAAW,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,aAAa,IAAI,QAAQ,CAAC,IAAI,aAAa,IAAI,OAAO,CAAC,IAAI,YAAY,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,UACzL,SAAS,MAAM,SAAS,CAAC;AAAA,UAAG,cAAc,MAAM,SAAS,SAAS,IAAI,CAAC,CAAC;AAAA,UACvE,YAAE,QAAQ;AAAA;AAAA,QAHc;AAAA,MAI3B,CACD;AAAA,OACH;AAAA,EAEJ;AACA,QAAM,QAAQ,OAAO,KAAK,KAAK,IAAI,IAAI,SAAS,KAAK,KAAK;AAC1D,SACE,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,OAAO,SAAS,KAAKA,UAAS,SAAS,SAAS,OAAU,GACzF;AAAA,mDAAC,SAAI,WAAU,eACb;AAAA,oDAAC,YAAO,MAAK,UAAS,WAAU,eAAc,cAAW,YAAW,SAAS,MAAMA,UAAS,UAAU,MAAM,KAAK,EAAE,IAAIA,UAAS,WAAW,MAAM,KAAK,CAAC,IAAI,IAAI,EAAE,GAAG,wDAAC,OAAE,WAAU,oBAAmB,GAAE;AAAA,MACtM,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,MAAM,QAAQA,UAAS,SAAS,WAAWA,UAAS,WAAW,UAAU,MAAM,GACpI;AAAA,QAAAA,UAAS,SAAS,OAAO,EAAE,IAAI,MAAM,KAAKA,UAAS,WAAW,KAAM,KAAK,IAAK,cAAS,KAAK;AAAA,QAC7F,8CAAC,OAAE,WAAU,oBAAmB,OAAO,EAAE,UAAU,IAAI,YAAY,GAAG,OAAO,oBAAoB,GAAG;AAAA,SACtG;AAAA,MACC,SAAS,KAAKA,UAAS,SAAS,8CAAC,UAAK,WAAU,gBAAe,OAAO,EAAE,QAAQ,WAAW,YAAY,OAAO,GAAI,iBAAO,KAAK,IAAI,MAAM,OAAM,IAAU;AAAA,MACzJ,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,cAAW,QAAO,SAAS,MAAMA,UAAS,UAAU,MAAM,KAAK,EAAE,IAAIA,UAAS,WAAW,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,wDAAC,OAAE,WAAU,qBAAoB,GAAE;AAAA,OACpM;AAAA,IACCA,UAAS,SACR,+CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,GACpC;AAAA,gBAAU,IAAI,EAAE;AAAA,MAChB,SAAS,IAAI,UAAU,OAAO,KAAK,IAAI;AAAA,OAC1C,IACEA,UAAS,WACX,8CAAC,SAAI,WAAU,sBACZ,iBAAO,IAAI,CAAC,GAAG,MACd;AAAA,MAAC;AAAA;AAAA,QAAO,MAAK;AAAA,QAAiB,WAAW,iBAAiB,MAAM,MAAM,KAAK,EAAE,YAAY,MAAM,KAAK,YAAY;AAAA,QAC9G,SAAS,MAAM;AAAE,gBAAM,CAAC;AAAG,kBAAQ,MAAM;AAAA,QAAG;AAAA,QAAI,YAAE,MAAM,GAAG,CAAC;AAAA;AAAA,MADnC;AAAA,IACqC,CACjE,GACH,IAEA,8CAAC,SAAI,WAAU,sBACZ,gBAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC,MACrD;AAAA,MAAC;AAAA;AAAA,QAAO,MAAK;AAAA,QAAiB,WAAW,iBAAiB,MAAM,KAAK,YAAY;AAAA,QAC/E,SAAS,MAAM;AAAE,gBAAM,CAAC;AAAG,kBAAQ,QAAQ;AAAA,QAAG;AAAA,QAAI;AAAA;AAAA,MADzB;AAAA,IAC2B,CACvD,GACH;AAAA,IAEF,+CAAC,SAAI,WAAU,eACb;AAAA;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS,WAAU;AAAA,UAAqB,OAAO,EAAE,UAAU,KAAK;AAAA,UAC3E,SAAS,MAAM;AAAE,kBAAM,MAAM,YAAY,CAAC;AAAG,kBAAM,MAAM,SAAS,CAAC;AAAG,oBAAQ,MAAM;AAAA,UAAG;AAAA,UAAG;AAAA;AAAA,MAAK;AAAA,MACjG,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,MACzB,SAAS,IAAI,QAAQ,+CAAC,UAAK,WAAU,uBAAuB;AAAA,YAAI,IAAI,KAAK;AAAA,QAAG,IAAI,MAAM,aAAQ,IAAI,IAAI,GAAG,IAAI;AAAA,SAAiB,IAAU;AAAA,OAC3I;AAAA,KACF;AAEJ;AAEO,SAAS,WAAW,EAAE,OAAO,MAAM,OAAO,WAAW,OAAO,WAAW,OAAO,QAAQ,OAAO,OAAO,UAAU,aAAa,YAAY,IAAI,OAAO,GAAG,KAAK,GAAoB;AACnL,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,UAAgB,eAAuB,IAAI;AACjD,QAAM,SAAe,eAAuB,IAAI;AAChD,QAAM,SAAe,eAAuB,IAAI;AAChD,QAAM,MAAMF,WAAU,MAAM,QAAQ,KAAK,QAAQ,MAAM,GAAG;AAC1D,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,CAAC,MAAoB;AAChC,UAAI,QAAQ,WAAW,QAAQ,QAAQ,SAAS,EAAE,MAAc,EAAG;AACnE,UAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,EAAE,MAAc,EAAG;AACjE,cAAQ,KAAK;AAAA,IACf;AACA,UAAM,MAAM,CAAC,MAAqB;AAAE,UAAI,EAAE,QAAQ,SAAU,SAAQ,KAAK;AAAA,IAAG;AAC5E,aAAS,iBAAiB,eAAe,IAAI;AAC7C,aAAS,iBAAiB,WAAW,GAAG;AACxC,WAAO,MAAM;AAAE,eAAS,oBAAoB,eAAe,IAAI;AAAG,eAAS,oBAAoB,WAAW,GAAG;AAAA,IAAG;AAAA,EAClH,GAAG,CAAC,IAAI,CAAC;AACT,QAAM,UAAU,QACX,SAAS,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAK,MAAM,MAAM,eAAU,IAAI,MAAM,GAAG,IAAI,sBAAY,KAC/F,IAAI,KAAK;AACb,QAAM,SAAS,MAAM;AAAE,QAAI,CAAC,SAAU,SAAQ,CAAC,IAAI;AAAA,EAAG;AACtD,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,eAAe,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAc,KAAK,SACzH;AAAA,YAAQ,+CAAC,WAAM,WAAU,kBAAiB,SAAS,QAAS;AAAA;AAAA,MAAO,WAAW,8CAAC,UAAK,WAAU,gBAAe,eAAC,IAAU;AAAA,OAAK,IAAW;AAAA,IACzI,+CAAC,SAAI,WAAW,CAAC,YAAY,QAAQ,mBAAmB,IAAI,WAAW,sBAAsB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,QAAQ,WAAW,gBAAgB,UAAU,GAAG,SAAS,QAAQ,KAAK,QACzM;AAAA,oDAAC,UAAK,WAAU,iBAAgB,wDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO,GAAE;AAAA,MACzF;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS;AAAA,UAAoB,WAAW,CAAC,MAAM;AAAE,gBAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AAAE,gBAAE,eAAe;AAAG,qBAAO;AAAA,YAAG;AAAA,UAAE;AAAA,UACtI,OAAO,EAAE,KAAK,SAAS,MAAM,GAAG,UAAU,GAAG,UAAU,UAAU,cAAc,YAAY,YAAY,UAAU,QAAQ,WAAW,OAAO,UAAU,gBAAgB,oBAAoB;AAAA,UAAI,GAAG;AAAA,UAC/L,qBAAW,gBAAgB,QAAQ,sBAAsB;AAAA;AAAA,MAC5D;AAAA,MACA,8CAAC,UAAK,WAAU,mBAAkB,wDAAC,OAAE,WAAU,oBAAmB,eAAY,QAAO,GAAE;AAAA,OACzF;AAAA,IACC,QAAQ,UAAM;AAAA,MACb,8CAAC,SAAI,WAAW,YAAY,IAAI,KAAK,WAAW,KAAK,KAAK,QAAQ,OAAOC,UAAS,KAAK,EAAE,OAAO,eAAe,UAAU,GAAG,QAAQ,IAAI,CAAC,GACvI;AAAA,QAAC;AAAA;AAAA,UAAS;AAAA,UAAc,QAAQ,QAAQ,IAAI;AAAA,UAAG;AAAA,UAC7C,QAAQ,CAAC,MAAW;AAAE,wBAAY,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;AAAG,gBAAI,CAAC,SAAU,EAAE,SAAS,EAAE,IAAM,SAAQ,KAAK;AAAA,UAAG;AAAA;AAAA,MAAG,GAC/H;AAAA,MAAQ,SAAS;AAAA,IAAI,IAAI;AAAA,IAC1B,QAAQ,+CAAC,UAAK,WAAU,kBAAiB;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG;AAAA,OAAM,IACtG,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,KAC7D;AAEJ;;;AC5LA,IAAAE,UAAuB;AACvB,IAAAC,oBAA6B;AA0FvB,IAAAC,uBAAA;AAxFN,IAAM,MAAM,CAAC,MAAc,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AAWpD,SAASC,WAAU,MAAe,KAAmC,MAAc,MAA8B;AAC/G,QAAM,CAAC,KAAK,MAAM,IAAU,iBAAwB,IAAI;AACxD,EAAM,wBAAgB,MAAM;AAC1B,QAAI,CAAC,QAAQ,CAAC,IAAI,SAAS;AAAE,aAAO,IAAI;AAAG;AAAA,IAAQ;AACnD,UAAM,OAAO,MAAM;AACjB,YAAM,IAAI,IAAI,QAAS,sBAAsB;AAC7C,YAAM,QAAQ,OAAO,cAAc,EAAE;AACrC,YAAM,KAAK,QAAQ,QAAQ,EAAE,MAAM;AACnC,YAAM,IAAI,KAAK,IAAI,EAAE,OAAO,QAAQ,CAAC;AACrC,YAAM,OAAO,KAAK,IAAI,OAAO,cAAc,IAAI,KAAK,IAAI,MAAM,KAAK,EAAE,MAAM,SAAS,EAAE,CAAC;AACvF,aAAO;AAAA,QACL,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,EAAE,MAAM,OAAO,aAAa,IAAI,CAAC,CAAC;AAAA,QAAG,OAAO,EAAE;AAAA,QACzE,KAAK,KAAK,OAAO,EAAE,SAAS;AAAA,QAAG,QAAQ,KAAK,OAAO,cAAc,EAAE,MAAM,IAAI;AAAA,QAAM;AAAA,QAAI;AAAA,MACzF,CAAC;AAAA,IACH;AACA,SAAK;AACL,WAAO,iBAAiB,UAAU,MAAM,IAAI;AAC5C,WAAO,iBAAiB,UAAU,IAAI;AACtC,WAAO,MAAM;AAAE,aAAO,oBAAoB,UAAU,MAAM,IAAI;AAAG,aAAO,oBAAoB,UAAU,IAAI;AAAA,IAAG;AAAA,EAE/G,GAAG,CAAC,IAAI,CAAC;AACT,SAAO;AACT;AACA,IAAMC,YAAW,CAAC,KAAa,WAAqD;AAAA,EAClF,UAAU;AAAA,EAAS,MAAM,IAAI;AAAA,EAAM,KAAK,IAAI,OAAO,OAAO,SAAS,IAAI;AAAA,EAAK,QAAQ,IAAI,UAAU,OAAO,SAAS,IAAI;AAAA,EACtH,iBAAiB,IAAI,KAAK,kBAAkB;AAAA,EAAc,WAAW,IAAI;AAAA,EAAM,WAAW;AAAA,EAAQ,GAAG;AACvG;AAiBO,SAAS,UAAU,EAAE,QAAQ,SAAS,SAAS,GAAmB;AACvE,MAAI,CAAC,KAAK,CAAC,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AAC1C,MAAI,MAAM,GAAG,EAAG,OAAM;AACtB,MAAI,MAAM,CAAC,EAAG,KAAI;AAClB,QAAM,KAAK,OAAO;AAClB,QAAM,MAAM,MAAM,OAAO,IAAI,KAAK,MAAM;AACxC,QAAM,CAACC,OAAM,OAAO,IAAU,iBAAS,GAAG;AAC1C,QAAM,UAAgB,eAAuB,IAAI;AACjD,QAAM,WAAiB,eAAO,KAAK;AACnC,QAAM,MAAM,CAAC,GAAW,IAAY,SAAkB,UAAU,OAAQ,IAAI,KAAM,KAAK,IAAI,MAAM,MAAM,IAAI,EAAE,CAAC;AAC9G,QAAM,IAAI,KAAK,KAAK;AACpB,QAAM,OAAOA,UAAS,MAAM,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,MAAM,KAAK,EAAE,QAAQ,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC;AACpH,QAAM,SAASA,UAAS,MAAM,MAAM;AACpC,QAAM,UAAU,CAAC,OAAeA,UAAS,MAAO,IAAI,KAAM,KAAM,IAAI,IAAK,MAAM;AAC/E,QAAM,cAAc,CAAC,MAA0B;AAC7C,UAAM,IAAI,QAAQ,QAAS,sBAAsB;AACjD,UAAM,IAAI,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM;AAC1D,QAAI,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,MAAM,KAAK,KAAK;AAC7C,QAAI,MAAM,EAAG,QAAO;AACpB,QAAIA,UAAS,KAAK;AAChB,YAAM,IAAI,KAAK,MAAM,MAAM,EAAE,IAAI,MAAM;AACvC,UAAI,MAAM,KAAK,KAAK,GAAG,GAAG,EAAE;AAAA,IAC9B,OAAO;AACL,YAAM,KAAK,KAAK,MAAM,MAAM,CAAC,IAAI;AACjC,UAAI,KAAK,IAAI,EAAE;AAAA,IACjB;AAAA,EACF;AACA,QAAM,OAAO,CAAC,MAA0B;AAAE,aAAS,UAAU;AAAM,YAAQ,WAAW,QAAQ,QAAQ,qBAAqB,QAAQ,QAAQ,kBAAkB,EAAE,SAAS;AAAG,gBAAY,CAAC;AAAA,EAAG;AAC3L,QAAM,OAAO,CAAC,MAA0B;AAAE,QAAI,SAAS,QAAS,aAAY,CAAC;AAAA,EAAG;AAChF,QAAM,MAAM,MAAM;AAAE,QAAI,SAAS,SAAS;AAAE,eAAS,UAAU;AAAO,UAAIA,UAAS,IAAK,SAAQ,GAAG;AAAA,IAAG;AAAA,EAAE;AACxG,QAAM,YAAYA,UAAS,MAAO,MAAM,KAAM,KAAK,IAAI;AACvD,QAAM,YAAYA,UAAS,OAAO,IAAI,MAAM;AAC5C,SACE,+CAAC,SAAI,OAAO,EAAE,SAAS,gBAAgB,GACrC;AAAA,mDAAC,SAAI,WAAU,mBACb;AAAA,oDAAC,YAAO,MAAK,UAAS,WAAW,oBAAoBA,UAAS,MAAM,eAAe,KAAK,SAAS,MAAM,QAAQ,GAAG,GAAI,cAAI,GAAG,GAAE;AAAA,MAC/H,8CAAC,UAAK,OAAO,EAAE,UAAU,IAAI,YAAY,KAAK,OAAO,oBAAoB,GAAG,eAAC;AAAA,MAC7E,8CAAC,YAAO,MAAK,UAAS,WAAW,oBAAoBA,UAAS,MAAM,eAAe,KAAK,SAAS,MAAM,QAAQ,GAAG,GAAI,cAAI,CAAC,GAAE;AAAA,MAC7H,8CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,YAAY,EAAE,GACvD,WAAC,MAAM,IAAI,EAAE,IAAI,CAAC,OACjB;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAkB,SAAS,MAAM,IAAI,KAAK,GAAG,OAAO,IAAI;AAAA,UACnE,OAAO,EAAE,QAAQ,gBAAiB,OAAO,SAAU,KAAK,iBAAiB,kBAAkB,YAAa,OAAO,SAAU,KAAK,yBAAyB,kBAAkB,OAAQ,OAAO,SAAU,KAAK,iBAAiB,qBAAqB,cAAc,GAAG,MAAM,WAAW,UAAU,IAAI,YAAY,KAAK,SAAS,WAAW,QAAQ,UAAU;AAAA,UAAI;AAAA;AAAA,QAD/T;AAAA,MACkU,CAC9V,GACH;AAAA,OACF;AAAA,IACA,+CAAC,SAAI,WAAU,YAAW,KAAK,SAAS,eAAe,MAAM,eAAe,MAAM,aAAa,KAC7F;AAAA,oDAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,QAAQ,MAAM,YAAY,KAAK,KAAK,WAAW,6BAA6B,YAAY,QAAQ,QAAQ,MAAM,GAAG;AAAA,MAC1J,8CAAC,UAAK,WAAU,kBAAiB;AAAA,MAChC,YAAY,8CAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,OAAO,KAAK,OAAO,OAAO,IAAI,QAAQ,IAAI,QAAQ,IAAI,cAAc,OAAO,QAAQ,0BAA0B,YAAY,kBAAkB,WAAW,YAAY,YAAY,uBAAuB,KAAK,KAAK,OAAO,iBAAiB,UAAU,eAAe,OAAO,GAAG,IAAK;AAAA,MACtU,KAAK,IAAI,CAAC,MAAM;AACf,cAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK;AACjC,eACE;AAAA,UAAC;AAAA;AAAA,YAAa,WAAW,kBAAkB,MAAM,UAAWA,UAAS,OAAO,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,MAAM,IAAK,YAAY;AAAA,YACzI,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG;AAAA,YAC9D,UAAAA,UAAS,MAAM,IAAI,CAAC,IAAI;AAAA;AAAA,UAFhB;AAAA,QAGX;AAAA,MAEJ,CAAC;AAAA,OACH;AAAA,IACA,8CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,gBAAgB,UAAU,KAAK,EAAE,GAChE,wDAAC,UAAK,WAAU,uBAAuB,UAAAA,UAAS,MAAM,qCAAgC,mBAAkB,GAC1G;AAAA,KACF;AAEJ;AAEO,SAAS,WAAW,EAAE,OAAO,MAAM,OAAO,WAAW,OAAO,WAAW,OAAO,QAAQ,IAAI,UAAU,cAAc,eAAe,YAAY,IAAI,MAAM,GAAoB;AAChL,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,UAAgB,eAAuB,IAAI;AACjD,QAAM,SAAe,eAAuB,IAAI;AAChD,QAAM,SAAe,eAAuB,IAAI;AAChD,QAAM,MAAMF,WAAU,MAAM,QAAQ,KAAK,GAAG;AAC5C,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,CAAC,MAAoB;AAChC,UAAI,QAAQ,WAAW,QAAQ,QAAQ,SAAS,EAAE,MAAc,EAAG;AACnE,UAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,EAAE,MAAc,EAAG;AACjE,cAAQ,KAAK;AAAA,IACf;AACA,UAAM,MAAM,CAAC,MAAqB;AAAE,UAAI,EAAE,QAAQ,SAAU,SAAQ,KAAK;AAAA,IAAG;AAC5E,aAAS,iBAAiB,eAAe,IAAI;AAC7C,aAAS,iBAAiB,WAAW,GAAG;AACxC,WAAO,MAAM;AAAE,eAAS,oBAAoB,eAAe,IAAI;AAAG,eAAS,oBAAoB,WAAW,GAAG;AAAA,IAAG;AAAA,EAClH,GAAG,CAAC,IAAI,CAAC;AACT,QAAM,OAAO,MAAM;AACjB,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,CAAC,GAAG,CAAC,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AAC1C,YAAQ,IAAI,OAAO,IAAI,KAAK,IAAI,MAAM,MAAM,IAAI,CAAC,IAAI,OAAO,KAAK,KAAK,OAAO;AAAA,EAC/E;AACA,QAAM,SAAS,MAAM;AAAE,QAAI,CAAC,SAAU,SAAQ,CAAC,IAAI;AAAA,EAAG;AACtD,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,eAAe,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAc,KAAK,SACzH;AAAA,YAAQ,+CAAC,WAAM,WAAU,kBAAiB,SAAS,QAAS;AAAA;AAAA,MAAO,WAAW,8CAAC,UAAK,WAAU,gBAAe,eAAC,IAAU;AAAA,OAAK,IAAW;AAAA,IACzI,+CAAC,SAAI,WAAW,CAAC,YAAY,QAAQ,mBAAmB,IAAI,WAAW,sBAAsB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,QAAQ,WAAW,gBAAgB,UAAU,GAAG,SAAS,QAAQ,KAAK,QACzM;AAAA,oDAAC,UAAK,WAAU,iBAAgB,wDAAC,OAAE,WAAU,eAAc,eAAY,QAAO,GAAE;AAAA,MAChF;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS;AAAA,UAAoB,WAAW,CAAC,MAAM;AAAE,gBAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AAAE,gBAAE,eAAe;AAAG,qBAAO;AAAA,YAAG;AAAA,UAAE;AAAA,UACtI,OAAO,EAAE,KAAK,SAAS,MAAM,GAAG,QAAQ,WAAW,OAAO,QAAQ,gBAAgB,oBAAoB;AAAA,UACrG,eAAK,KAAK;AAAA;AAAA,MACb;AAAA,MACA,8CAAC,UAAK,WAAU,mBAAkB,wDAAC,OAAE,WAAU,oBAAmB,eAAY,QAAO,GAAE;AAAA,OACzF;AAAA,IACC,QAAQ,UAAM;AAAA,MACb,+CAAC,SAAI,WAAW,YAAY,IAAI,KAAK,WAAW,KAAK,KAAK,QAAQ,OAAOC,UAAS,KAAK,EAAE,OAAO,KAAK,UAAU,GAAG,QAAQ,IAAI,CAAC,GAC7H;AAAA,sDAAC,aAAU,OAAO,SAAS,SAAS,UAAU,CAAC,MAAM,YAAY,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG;AAAA,QACrG,+CAAC,SAAI,WAAU,eAAc,OAAO,EAAE,QAAQ,eAAe,YAAY,GAAG,GAC1E;AAAA;AAAA,YAAC;AAAA;AAAA,cAAO,MAAK;AAAA,cAAS,WAAU;AAAA,cAAqB,OAAO,EAAE,UAAU,KAAK;AAAA,cAC3E,SAAS,MAAM;AAAE,sBAAM,IAAI,oBAAI,KAAK;AAAG,4BAAY,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,IAAI,MAAM,IAAI,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC;AAAA,cAAG;AAAA,cAAG;AAAA;AAAA,UAAG;AAAA,UACtI,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,UAC1B,8CAAC,YAAO,MAAK,UAAS,WAAU,mCAAkC,SAAS,MAAM,QAAQ,KAAK,GAAG,kBAAI;AAAA,WACvG;AAAA,SACF;AAAA,MAAQ,SAAS;AAAA,IAAI,IAAI;AAAA,IAC1B,QAAQ,+CAAC,UAAK,WAAU,kBAAiB;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG;AAAA,OAAM,IACtG,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,KAC7D;AAEJ;;;AC5KA,IAAAE,UAAuB;AA8Bf,IAAAC,uBAAA;AAVD,SAAS,OAAO;AAAA,EACrB;AAAA,EAAO,MAAM;AAAA,EAAG,MAAM;AAAA,EAAK,OAAO;AAAA,EAAG;AAAA,EAAO;AAAA,EAC5C,SAAS,CAAC,MAAc,OAAO,CAAC;AAAA,EAAG,WAAW;AAAA,EAAM;AAAA,EAAM,YAAY;AAAA,EAAI,GAAG;AAC/E,GAAgB;AACd,QAAM,CAAC,UAAU,WAAW,IAAU,iBAAS,KAAK;AACpD,QAAM,IAAI,UAAU,SAAY,MAAM,OAAO,KAAK;AAClD,QAAM,MAAM,QAAQ,MAAM,KAAM,IAAI,QAAQ,MAAM,OAAQ;AAC1D,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC7D;AAAA,YACC,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,gBAAgB,iBAAiB,KAAK,GAAG,GACxE;AAAA,oDAAC,UAAK,WAAU,kBAAkB,iBAAM;AAAA,MACxC,8CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,OAAO,gBAAgB,GAAI,iBAAO,CAAC,GAAE;AAAA,OACzE,IACE;AAAA,IACJ,+CAAC,SAAI,WAAU,aACb;AAAA,oDAAC,UAAK,WAAU,kBAAiB,OAAO,EAAE,OAAO,MAAM,IAAI,GAAG;AAAA,MAC7D,YAAY,WACX,8CAAC,UAAK,WAAU,kBAAiB,OAAO,EAAE,MAAM,MAAM,IAAI,GAAI,iBAAO,CAAC,GAAE,IACtE;AAAA,MACJ;AAAA,QAAC;AAAA;AAAA,UAAM,MAAK;AAAA,UAAQ;AAAA,UAAU;AAAA,UAAU;AAAA,UAAY,OAAO;AAAA,UACzD,UAAU,WAAW,CAAC,MAAM,SAAU,OAAO,EAAE,OAAO,KAAK,CAAC,IAAI;AAAA,UAChE,eAAe,MAAM,YAAY,IAAI;AAAA,UACrC,aAAa,MAAM,YAAY,KAAK;AAAA,UACpC,QAAQ,MAAM,YAAY,KAAK;AAAA,UAC/B,cAAY;AAAA,UAAQ,GAAG;AAAA;AAAA,MAAM;AAAA,OACjC;AAAA,IACC,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,KAC1D;AAEJ;;;AClDA,IAAAC,UAAuB;AAqEjB,IAAAC,uBAAA;AA9CC,SAAS,YAAY;AAAA,EAC1B;AAAA,EAAO,MAAM;AAAA,EAAG,MAAM;AAAA,EAAK,OAAO;AAAA,EAAG;AAAA,EAAO;AAAA,EAAU,SAAS;AAAA,EAC/D,QAAQ,CAAC;AAAA,EAAG,OAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAM,YAAY;AAAA,EAAI,GAAG;AACpE,GAAwD;AAItD,QAAMC,OAAM,WAAW,CAAC,MAAc,OAAO,CAAC;AAC9C,QAAM,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,KAAK,GAAG;AACjC,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAwB,IAAI;AAC1D,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAwB,IAAI;AAC5D,QAAM,UAAgB,eAAwB,IAAI;AAClD,QAAM,MAAM,CAAC,MAAc,QAAQ,MAAM,KAAM,IAAI,QAAQ,MAAM,OAAQ;AACzE,QAAM,YAAY,CAAC,GAAW,MAAgC;AAC5D,QAAI,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC;AAC5D,QAAI,QAAQ,MAAM,QAAQ;AACxB,YAAM,OAAO,MAAM,OAAO,CAAC,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,CAAC,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,QAAQ,MAAM,QAAQ;AAC5G,UAAI,KAAK,IAAI,OAAO,CAAC,MAAM,MAAM,OAAO,MAAO,KAAI;AAAA,IACrD;AACA,UAAM,OAAyB,MAAM,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC;AACnG,WAAO;AAAA,EACT;AACA,QAAM,YAAY,CAAC,MAA2B;AAC5C,UAAM,IAAI,QAAQ,QAAS,sBAAsB;AACjD,WAAO,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,MAAM;AAAA,EACjF;AACA,EAAM,kBAAU,MAAM;AACpB,QAAI,SAAS,KAAM;AACnB,UAAM,KAAK,CAAC,MAAoB,YAAY,SAAS,UAAU,MAAM,UAAU,CAAC,CAAC,CAAC;AAClF,UAAM,MAAM,MAAM,QAAQ,IAAI;AAC9B,WAAO,iBAAiB,eAAe,EAAE;AACzC,WAAO,iBAAiB,aAAa,GAAG;AACxC,WAAO,MAAM;AAAE,aAAO,oBAAoB,eAAe,EAAE;AAAG,aAAO,oBAAoB,aAAa,GAAG;AAAA,IAAG;AAAA,EAC9G,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;AAKf,MAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,UAAM,IAA8C,MAAM,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,EAAE,OAAO,EAAE,CAAE;AAC/G,UAAM,MAAM,CAAC,MAAY,MAAM,YAAY,KAAK,OAAO,OAAO,mBAAmB;AACjF,UAAM,QAAQ,CAAC,MAAW,EAAE,OAAO,CAAC,MAAM,GAAG,MAAO,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,MAAO,CAAC;AAC1I,UAAM,UAAU,CAAC,MAAc;AAAE,YAAM,IAAI,EAAE,KAAK,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;AAAG,aAAO,EAAE,SAAS,OAAO,EAAE,QAAQ,OAAO,EAAE,KAAK;AAAA,IAAG;AACzH,UAAM,OAAO,EAAE,SAAS,IAAI,KAAK,KAAK,EAAE,SAAS,CAAC,IAAI;AACtD,UAAM,OAAO,SAAS,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,KAAK;AACxD,WACE;AAAA,MAAC;AAAA;AAAA,QAAa,GAAG;AAAA,QAAM;AAAA,QAAc;AAAA,QAAY;AAAA,QAC/C,KAAK;AAAA,QAAG,KAAK,EAAE,SAAS;AAAA,QAAG,MAAM;AAAA,QAAG;AAAA,QACpC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC;AAAA,QACtC,UAAU,CAAC,MAAM,YAAY,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC;AAAA,QACpE,OAAO,MAAM,SAAS,QAAQ,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,OAAO,GAAG,OAAQ,MAAM,KAAK,MAAM,EAAE,SAAS,KAAK,IAAI,SAAS,IAAK,QAAQ,CAAC,IAAI,OAAU,EAAE;AAAA,QAChJ,QAAQ,SAAS,CAAC,MAAc,OAAQ,EAAE,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,IAAI;AAAA;AAAA,IAAS;AAAA,EAEjF;AACA,QAAM,YAAY,CAAC,MAAc,CAAC,MAA0B;AAC1D,MAAE,eAAe;AACjB,IAAC,EAAE,OAAmB,qBAAsB,EAAE,OAAmB,kBAAkB,EAAE,SAAS;AAC9F,YAAQ,CAAC;AAAA,EACX;AACA,QAAM,aAAa,CAAC,MAA0B;AAC5C,UAAM,IAAI,UAAU,CAAC;AACrB,UAAM,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI;AACnD,gBAAY,SAAS,UAAU,GAAG,CAAC,CAAC;AACpC,YAAQ,CAAC;AAAA,EACX;AACA,QAAM,MAAM,CAAC,MAAc,CAAC,MAA2B;AACrD,UAAM,OAAO,MAAM,OAAO;AAC1B,QAAI,IAAI;AACR,QAAI,EAAE,QAAQ,eAAe,EAAE,QAAQ,YAAa,KAAI,EAAE,EAAE,WAAW,MAAM;AAAA,aACpE,EAAE,QAAQ,gBAAgB,EAAE,QAAQ,UAAW,KAAI,EAAE,WAAW,MAAM;AAAA,aACtE,EAAE,QAAQ,QAAQ;AAAE,eAAS,UAAU,GAAG,GAAG,CAAC;AAAG,QAAE,eAAe;AAAG;AAAA,IAAQ,WAC7E,EAAE,QAAQ,OAAO;AAAE,eAAS,UAAU,GAAG,GAAG,CAAC;AAAG,QAAE,eAAe;AAAG;AAAA,IAAQ,MAChF;AACL,MAAE,eAAe;AACjB,gBAAY,SAAS,UAAU,IAAI,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC;AAAA,EAC1D;AACA,QAAM,WAAW,CAAC,MAAc,SAAS,KAAK,UAAU;AACxD,QAAM,YAAY,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK;AAC3C,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACpE;AAAA,YACC,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,gBAAgB,iBAAiB,KAAK,GAAG,GACxE;AAAA,oDAAC,UAAK,WAAU,kBAAkB,iBAAM;AAAA,MACxC,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,OAAO,gBAAgB,GAAI;AAAA,QAAAA,KAAI,CAAC;AAAA,QAAE;AAAA,QAAIA,KAAI,CAAC;AAAA,SAAE;AAAA,OACjF,IACE;AAAA,IACJ,+CAAC,SAAI,WAAW,cAAc,YAAY,gBAAgB,KAAK,eAAe,YAC5E;AAAA,oDAAC,UAAK,WAAU,iBAAgB,KAAK,SAAS;AAAA,MAC9C,8CAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,MAAM,IAAI,CAAC,IAAI,KAAK,OAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,IAAK,IAAI,GAAG;AAAA,MAC9F,MAAM,IAAI,CAAC,MACV,+CAAO,kBAAN,EACC;AAAA,sDAAC,UAAK,WAAW,mBAAmB,EAAE,SAAS,KAAK,EAAE,SAAS,IAAI,WAAW,KAAK,OAAO,EAAE,MAAM,IAAI,EAAE,KAAK,IAAI,IAAI,GAAG;AAAA,QACvH,EAAE,QAAQ,8CAAC,UAAK,WAAU,uBAAsB,OAAO,EAAE,MAAM,IAAI,EAAE,KAAK,IAAI,IAAI,GAAI,YAAE,OAAM,IAAU;AAAA,WAFtF,EAAE,KAGvB,CACD;AAAA,MACA,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,MACd;AAAA,QAAC;AAAA;AAAA,UAAa,WAAW,oBAAoB,SAAS,IAAI,aAAa;AAAA,UAAK,OAAO,EAAE,MAAM,IAAI,CAAC,IAAI,IAAI;AAAA,UACtG,UAAU;AAAA,UAAG,MAAK;AAAA,UAAS,iBAAe;AAAA,UAAK,iBAAe;AAAA,UAAK,iBAAe;AAAA,UAClF,eAAa,SAAS,YAAY,MAAM,IAAI,aAAa;AAAA,UACzD,eAAe,UAAU,CAAC;AAAA,UAAG,WAAW,IAAI,CAAC;AAAA,UAC7C,SAAS,MAAM,SAAS,CAAC;AAAA,UAAG,QAAQ,MAAM,SAAS,IAAI;AAAA,UACvD,wDAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,SAAS,SAAS,CAAC,IAAI,IAAI,OAAU,GAAI,UAAAA,KAAI,CAAC,GAAE;AAAA;AAAA,QALhF;AAAA,MAMX,CACD;AAAA,OACH;AAAA,IACC,OAAO,8CAAC,UAAK,WAAU,iBAAiB,gBAAK,IAAU;AAAA,KAC1D;AAEJ;;;ACnIA,IAAAC,UAAuB;AAyDb,IAAAC,uBAAA;AAnCH,SAAS,SAAS;AAAA,EACvB;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAa,WAAW;AAAA,EAAM,WAAW;AAAA,EACpE,QAAQ;AAAA,EAAwB;AAAA,EAAM;AAAA,EAAU,YAAY;AAAA,EAAI;AAClE,GAAkB;AAChB,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,QAAc,eAAO,CAAC;AAE5B,QAAM,MAAM,CAAC,MAAuB;AAClC,UAAM,KAAK,EAAE;AACb,QAAI,CAAC,GAAI,QAAO;AAChB,WAAO,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,EAAE,QAAQ,OAAO,MAAM;AAAA,EACzD;AAEA,QAAM,QAAQ,CAAC,MAAuB;AAAE,QAAI,YAAY,CAAC,IAAI,CAAC,EAAG;AAAQ,UAAM;AAAW,YAAQ,IAAI;AAAA,EAAG;AACzG,QAAM,QAAQ,MAAM;AAAE,UAAM,UAAU,KAAK,IAAI,GAAG,MAAM,UAAU,CAAC;AAAG,QAAI,CAAC,MAAM,QAAS,SAAQ,KAAK;AAAA,EAAG;AAC1G,QAAM,QAAQ,CAAC,MAAuB;AAAE,QAAI,YAAY,CAAC,IAAI,CAAC,EAAG;AAAQ,MAAE,eAAe;AAAG,MAAE,aAAa,aAAa;AAAA,EAAQ;AACjI,QAAM,OAAO,CAAC,MAAuB;AACnC,QAAI,YAAY,CAAC,IAAI,CAAC,EAAG;AACzB,MAAE,eAAe;AACjB,UAAM,UAAU;AAAG,YAAQ,KAAK;AAChC,UAAM,SAAS,WAAW,MAAM,KAAK,EAAE,aAAa,KAAK,IAAI,MAAM,KAAK,EAAE,aAAa,KAAK,EAAE,MAAM,GAAG,CAAC;AACxG,UAAM,EAAE,UAAU,SAAS,IAAI,YAAY,QAAQ,EAAE,QAAQ,YAAY,CAAC;AAC1E,QAAI,SAAS,UAAU,SAAU,UAAS,QAAQ;AAClD,QAAI,SAAS,UAAU,QAAS,SAAQ,QAAQ;AAAA,EAClD;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,CAAC,eAAe,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MACrF;AAAA,MACA,aAAa;AAAA,MAAO,aAAa;AAAA,MAAO,YAAY;AAAA,MAAO,QAAQ;AAAA,MAElE;AAAA;AAAA,QACA,OACC,8CAAC,SAAI,WAAU,oBAAmB,eAAY,QAC5C,yDAAC,SAAI,WAAU,oBACb;AAAA,wDAAC,OAAE,WAAU,yBAAwB;AAAA,UACrC,8CAAC,UAAK,WAAU,qBAAqB,iBAAM;AAAA,UAC1C,OAAO,8CAAC,UAAK,WAAU,oBAAoB,gBAAK,IAAU;AAAA,WAC7D,GACF,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AAKO,SAAS,eAAe;AAAA,EAC7B;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAa,WAAW;AAAA,EAAM;AAAA,EACzD,QAAQ;AAAA,EAAgB,OAAO;AAAA,EAAa,YAAY;AAAA,EAAI;AAC9D,GAAwB;AACtB,QAAM,MAAY,eAAyB,IAAI;AAC/C,SACE,+CAAO,kBAAN,EACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QAAS,WAAW,CAAC,gBAAgB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAAG;AAAA,QAChF,cAAY;AAAA,QAAO,OAAO;AAAA,QAAO,SAAS,MAAM,IAAI,WAAW,IAAI,QAAQ,MAAM;AAAA,QAEhF,sBAAY,OAAO,WAAW,8CAAC,OAAE,WAAW,WAAW,MAAM,eAAY,QAAO;AAAA;AAAA,IACnF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QAAU,MAAK;AAAA,QAAO;AAAA,QAAgB;AAAA,QAAoB,WAAU;AAAA,QACpE,UAAU,CAAC,MAAM;AACf,gBAAM,EAAE,UAAU,SAAS,IAAI,YAAY,EAAE,OAAO,OAAmB,EAAE,QAAQ,YAAY,CAAC;AAC9F,cAAI,SAAS,UAAU,SAAU,UAAS,QAAQ;AAClD,cAAI,SAAS,UAAU,QAAS,SAAQ,QAAQ;AAChD,YAAE,OAAO,QAAQ;AAAA,QACnB;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AAWO,SAAS,eACd,QACA,MASA;AACA,QAAM,IAAI,QAAQ,CAAC;AACnB,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAuB,CAAC,CAAC;AACzD,QAAM,cAAoB,eAA+C,CAAC,CAAC;AAE3E,QAAM,QAAQ,CAAC,IAAY,SAA8B,SAAS,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,KAAK,OAAO,OAAO,CAAC,GAAG,GAAG,IAAI,IAAI,CAAE,CAAC;AAE3I,QAAM,MAAY,oBAAY,CAAC,QAAoB;AACjD,QAAI,CAAC,OAAQ;AACb,UAAM,KAAK,OAAO,oBAAoB,cAAc,IAAI,gBAAgB,IAAI;AAC5E,gBAAY,QAAQ,IAAI,EAAE,IAAI;AAC9B,UAAM,IAAI,IAAI,EAAE,UAAU,GAAG,OAAO,OAAU,CAAC;AAC/C,YAAQ,QAAQ,EACb,KAAK,MAAM,OAAQ,IAAI,MAAc,CAAC,MAAM,MAAM,IAAI,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,SAAS,MAAS,CAAC,EAClI,KAAK,CAAC,QAAQ;AACb,YAAM,IAAI,OAAO,CAAC;AAClB,YAAM,IAAI,IAAI,EAAE,UAAU,KAAK,KAAM,EAAU,OAAO,IAAI,KAAK,OAAQ,EAAU,SAAS,IAAI,OAAO,OAAO,QAAW,QAAQ,KAAK,CAAQ;AAC5I,QAAE,cAAc,EAAE,WAAW,GAAG;AAAA,IAClC,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,MAAM,GAAG,OAAO,QAAS;AAC7B,YAAM,IAAI,IAAI,EAAE,UAAU,MAAM,OAAQ,OAAO,IAAI,WAAY,gBAAgB,CAAQ;AACvF,QAAE,WAAW,EAAE,QAAQ,KAAK,GAAG;AAAA,IACjC,CAAC,EACA,QAAQ,MAAM;AAAE,aAAO,YAAY,QAAQ,IAAI,EAAE;AAAA,IAAG,CAAC;AAAA,EAC1D,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,MAAY,oBAAY,CAAC,UAA6B;AAC1D,QAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,UAAM,OAAO,MAAM,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,aAAa,CAAC,CAAC;AACzD,aAAS,CAAC,SAAS,KAAK,OAAO,IAAI,CAAC;AACpC,SAAK,QAAQ,GAAG;AAChB,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,GAAG,CAAC;AAEhB,QAAM,SAAe,oBAAY,CAAC,QAAoB;AACpD,UAAM,KAAK,YAAY,QAAQ,IAAI,EAAE;AACrC,QAAI,IAAI;AAAE,UAAI;AAAE,WAAG,MAAM;AAAA,MAAG,SAAS,IAAI;AAAA,MAAa;AAAE,aAAO,YAAY,QAAQ,IAAI,EAAE;AAAA,IAAG;AAC5F,aAAS,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;AAAA,EACxD,GAAG,CAAC,CAAC;AAEL,QAAM,QAAc,oBAAY,CAAC,QAAoB;AAAE,QAAI,GAAG;AAAA,EAAG,GAAG,CAAC,GAAG,CAAC;AACzE,QAAM,QAAc,oBAAY,MAAM;AACpC,WAAO,OAAO,YAAY,OAAO,EAAE,QAAQ,CAAC,OAAO;AAAE,UAAI;AAAE,cAAM,GAAG,MAAM;AAAA,MAAG,SAAS,IAAI;AAAA,MAAa;AAAA,IAAE,CAAC;AAC1G,gBAAY,UAAU,CAAC;AACvB,aAAS,CAAC,CAAC;AAAA,EACb,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,YAAY,QAAQ,EAAE,WAAW,OAAO,CAAC,EAAE,KAAK;AACjF,SAAO,EAAE,OAAO,KAAK,QAAQ,OAAO,OAAO,MAAM,SAAS;AAC5D;AAGO,IAAM,cAAc,EAAE,eAAe;;;AC3JtC,IAAAC,uBAAA;AAXN,IAAM,iBAAiB,CAAC,MAAc,MAAM,OAAO;AACjD,MAAI,CAAC,QAAQ,KAAK,UAAU,IAAK,QAAO;AACxC,QAAM,MAAM,kBAAkB,KAAK,IAAI;AACvC,QAAM,OAAO,MAAM,IAAI,CAAC,IAAI;AAC5B,QAAM,OAAO,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC;AAC7D,SAAO,OAAO,WAAM;AACtB;AAEA,SAAS,SAAS,EAAE,MAAM,GAAsB;AAC9C,SACE,8CAAC,UAAK,WAAU,gBAAe,MAAK,eAAc,iBAAe,KAAK,MAAM,KAAK,GAAG,iBAAe,GAAG,iBAAe,KACnH,wDAAC,UAAK,WAAU,qBAAoB,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,GAAG,GACjG;AAEJ;AASO,SAAS,SAAS,EAAE,MAAM,QAAQ,UAAU,SAAS,SAAAC,WAAU,OAAO,YAAY,GAAG,GAAkB;AAC5G,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,YAAY,KAAK,YAAY,QAAQ,KAAK,WAAW,OAAO,CAAC,KAAK;AACxE,QAAM,QAAQ,QAAQ,KAAK,MAAM,KAAK,IAAI;AAC1C,QAAM,QAAS,KAAK,SAAS,KAAK,MAAM,QAAS,QAAQ,KAAK,WAAW,KAAK,MAAM;AACpF,QAAM,OAAO,KAAK,SAAS,KAAK,OAAO,YAAY,KAAK,IAAI,IAAI;AAChE,QAAM,YAAY,CAAC,CAAC,UAAU,CAAC;AAE/B,SACE,+CAAC,SAAI,WAAW,CAAC,WAAWA,WAAU,eAAe,IAAI,KAAK,QAAQ,aAAa,IAAI,YAAY,iBAAiB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACzJ;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QAAS,WAAU;AAAA,QAAe,UAAU,CAAC;AAAA,QAClD,SAAS,YAAY,MAAM,OAAQ,IAAI,IAAI;AAAA,QAC3C,OAAO,KAAK,QAAQ,OAAO,WAAQ,OAAO;AAAA,QAE1C;AAAA,yDAAC,UAAK,WAAU,gBACb;AAAA,oBAAQ,8CAAC,SAAI,KAAK,OAAO,KAAI,IAAG,IAAK,8CAAC,OAAE,WAAW,WAAW,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,eAAY,QAAO;AAAA,aACnH,KAAK,QAAQ,IAAI,WAAW,QAAQ,IAAI,8CAAC,OAAE,WAAU,2BAA0B,eAAY,QAAO,IAAK;AAAA,aAC3G;AAAA,UACA,+CAAC,UAAK,WAAU,gBACd;AAAA,0DAAC,UAAK,WAAU,gBAAgB,yBAAe,KAAK,MAAMA,WAAU,KAAK,EAAE,GAAE;AAAA,YAC7E,8CAAC,UAAK,WAAU,gBACb,eAAK,QACF,+CAAC,UAAK,WAAU,eAAc;AAAA,4DAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,cAAG,KAAK;AAAA,eAAM,IACnG,YAAY,+CAAC,UAAK,WAAU,cAAc;AAAA,mBAAK,MAAM,KAAK,QAAkB;AAAA,cAAE;AAAA,eAAU,IACxF,MACN;AAAA,aACF;AAAA;AAAA;AAAA,IACF;AAAA,IACC,YAAY,8CAAC,YAAS,OAAO,KAAK,UAAoB,IAAK;AAAA,IAC3D,KAAK,SAAS,UACb,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAAS,MAAM,QAAS,IAAI,GAAG,cAAY,qBAAqB,KAAK,MACjH,wDAAC,OAAE,WAAU,yBAAwB,eAAY,QAAO,GAC1D,IACE;AAAA,IACH,WACC,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAAS,MAAM,SAAU,IAAI,GAAG,cAAY,YAAY,KAAK,MACzG,wDAAC,OAAE,WAAU,WAAU,eAAY,QAAO,GAC5C,IACE;AAAA,KACN;AAEJ;AAQO,SAAS,SAAS,EAAE,MAAM,QAAQ,UAAU,YAAY,KAAK,YAAY,GAAG,GAAkB;AACnG,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,MAAO,KAAK,SAAS,KAAK,MAAM,OAAQ,KAAK,WAAW,KAAK;AACnE,QAAM,YAAY,KAAK,YAAY,QAAQ,KAAK,WAAW,OAAO,CAAC,KAAK;AACxE,SACE,+CAAC,YAAO,WAAW,CAAC,WAAW,YAAY,iBAAiB,IAAI,KAAK,QAAQ,aAAa,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC/H;AAAA,kDAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAAS,SAAS,MAAM,OAAQ,IAAI,IAAI,QAAW,UAAU,CAAC,QACzG,gBAAM,8CAAC,SAAI,KAAU,KAAK,KAAK,QAAQ,IAAI,OAAO,EAAE,UAAU,GAAG,SAAQ,QAAO,IAC7E,8CAAC,UAAK,WAAU,oBAAmB,wDAAC,OAAE,WAAW,WAAW,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,eAAY,QAAO,GAAE,GAC1H;AAAA,IACC,YAAY,8CAAC,YAAS,OAAO,KAAK,UAAoB,IAAK;AAAA,IAC3D,KAAK,QAAQ,+CAAC,gBAAW,WAAU,eAAc;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG,KAAK;AAAA,OAAM,IAAgB;AAAA,IACtI,WACC,8CAAC,YAAO,MAAK,UAAS,WAAU,aAAY,SAAS,MAAM,SAAU,IAAI,GAAG,cAAY,YAAY,KAAK,MACvG,wDAAC,OAAE,WAAU,WAAU,eAAY,QAAO,GAC5C,IACE;AAAA,KACN;AAEJ;AASO,SAAS,UAAU,EAAE,QAAQ,CAAC,GAAG,OAAO,IAAI,QAAQ,UAAU,SAAS,YAAY,GAAG,GAAmB;AAC9G,QAAM,OAAO,MAAM,OAAO,OAAO;AACjC,MAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,SACE,8CAAC,SAAI,WAAW,CAAC,gBAAgB,gBAAgB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,aAAa,OAAO,KAAK,GACtH,eAAK,IAAI,CAAC,MAAM,8CAAC,YAA8B,MAAM,GAAG,QAAgB,UAAoB,WAA7D,EAAE,MAAM,EAAE,IAAqE,CAAE,GACnH;AAEJ;AAEA,IAAM,YAAY,CAAC,MAAc,OAAO,MAAM;AAC5C,QAAM,IAAI,OAAO,QAAQ,MAAM;AAC/B,QAAM,MAAM,wBAAwB,KAAK,CAAC;AAC1C,QAAM,OAAO,MAAM,MAAM,IAAI,CAAC,IAAI;AAClC,QAAM,OAAO,OAAO,EAAE,MAAM,GAAG,CAAC,KAAK,MAAM,IAAI;AAC/C,SAAO,KAAK,SAAS,OAAO,KAAK,MAAM,GAAG,IAAI,IAAI,WAAM,OAAO,OAAO;AACxE;AAIA,SAAS,SAAS,EAAE,MAAM,QAAQ,UAAU,QAAQ,GAAkB;AACpE,QAAM,YAAY,KAAK,YAAY,QAAQ,KAAK,WAAW,OAAO,CAAC,KAAK;AACxE,QAAM,QAAQ,QAAQ,KAAK,MAAM,KAAK,IAAI;AAC1C,QAAM,QAAS,KAAK,SAAS,KAAK,MAAM,QAAS,QAAQ,KAAK,WAAW,KAAK,MAAM;AACpF,QAAM,QAAQ,KAAK,QAAQ,KAAK,OAAO,WAAQ,YAAY,KAAK,IAAI,IAAI;AACxE,SACE,+CAAC,SAAI,WAAW,CAAC,WAAW,KAAK,QAAQ,aAAa,IAAI,YAAY,iBAAiB,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,KAAK,QAAQ,KAAK,OAAO,aAAQ,KAAK,QAAQ,OACzK;AAAA,mDAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,SAAS,MAAM,OAAQ,IAAI,IAAI,QAAW,UAAU,CAAC,UAAU,WAAW,cAAY,UAAU,KAAK,MAC1J;AAAA,cAAQ,8CAAC,SAAI,KAAK,OAAO,KAAI,IAAG,IAC/B,+CAAC,UAAK,WAAU,eACd;AAAA,sDAAC,OAAE,WAAW,WAAW,YAAY,KAAK,MAAM,KAAK,IAAI,GAAG,eAAY,QAAO;AAAA,QAC/E,8CAAC,UAAK,WAAU,gBAAgB,oBAAU,KAAK,IAAI,GAAE;AAAA,QACrD,8CAAC,UAAK,WAAU,gBAAgB,eAAK,QAAQ,YAAY,KAAK,IAAI,GAAE;AAAA,SACtE;AAAA,OAEA,KAAK,QAAQ,IAAI,WAAW,QAAQ,IAAI,8CAAC,OAAE,WAAU,2BAA0B,eAAY,QAAO,IAAK;AAAA,OAC3G;AAAA,IACC,YAAY,8CAAC,YAAS,OAAO,KAAK,UAAoB,IAAK;AAAA,IAC3D,KAAK,QACJ,8CAAC,UAAK,WAAU,eAAc,eAAY,QAAO,wDAAC,OAAE,WAAU,wBAAuB,GAAE,IACrF;AAAA,IACH,KAAK,SAAS,UACb,8CAAC,YAAO,MAAK,UAAS,WAAU,sBAAqB,SAAS,MAAM,QAAS,IAAI,GAAG,cAAY,qBAAqB,KAAK,MACxH,wDAAC,OAAE,WAAU,yBAAwB,eAAY,QAAO,GAC1D,IACE;AAAA,IACH,WACC,8CAAC,YAAO,MAAK,UAAS,WAAU,aAAY,SAAS,MAAM,SAAU,IAAI,GAAG,cAAY,YAAY,KAAK,MACvG,wDAAC,OAAE,WAAU,WAAU,eAAY,QAAO,GAC5C,IACE;AAAA,KACN;AAEJ;AASO,SAAS,SAAS,EAAE,QAAQ,CAAC,GAAG,QAAQ,UAAU,SAAS,QAAQ,MAAM,YAAY,KAAK,SAAAA,WAAU,OAAO,YAAY,GAAG,GAAkB;AACjJ,QAAM,OAAO,MAAM,OAAO,OAAO;AACjC,MAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,QAAM,OAAO,QAAQ,KAAK,OAAO,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;AACpE,QAAM,OAAO,KAAK,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE;AACtD,SACE,+CAAC,SAAI,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAChE;AAAA,SAAK,SACJ,8CAAC,SAAI,WAAU,qBACZ,eAAK,IAAI,CAAC,MAAM,8CAAC,YAA8B,MAAM,GAAG,QAAgB,UAAoB,aAA7D,EAAE,MAAM,EAAE,IAAyE,CAAE,GACvH,IACE;AAAA,IACH,KAAK,SACJ,8CAAC,SAAI,WAAU,qBACZ,eAAK,IAAI,CAAC,MAAM,8CAAC,YAA8B,MAAM,GAAG,QAAgB,UAAoB,SAAkB,SAASA,YAAxF,EAAE,MAAM,EAAE,IAAuF,CAAE,GACrI,IACE;AAAA,KACN;AAEJ;;;AC1LA,IAAAC,UAAuB;AA+cnB,IAAAC,uBAAA;AAlcJ,IAAM,QAAQ,OAAO,cAAc,eAAe,kBAAkB,KAAK,UAAU,YAAY,UAAU,aAAa,EAAE;AAExH,IAAM,YAAY;AAGlB,SAAS,YAAY,MAAuC;AAC1D,QAAM,MAA+B,CAAC;AACtC,MAAI,OAAO,GAAG;AACd,YAAU,YAAY;AACtB,SAAQ,IAAI,UAAU,KAAK,IAAI,GAAI;AACjC,QAAI,EAAE,QAAQ,KAAM,KAAI,KAAK,CAAC,KAAK,MAAM,MAAM,EAAE,KAAK,GAAG,EAAE,CAAC;AAC5D,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,OAAO,CAAC,GAAW,QAAgB;AAAE,UAAI,KAAK,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,QAAQ,CAAC;AAAA,IAAG;AACzJ,QAAI,UAAU,KAAK,EAAE,EAAG,MAAK,GAAG,aAAa;AAAA,aACpC,QAAQ,KAAK,EAAE,KAAK,MAAM,KAAK,EAAE,EAAG,MAAK,GAAG,OAAO;AAAA,aACnD,MAAM,KAAK,EAAE,EAAG,MAAK,GAAG,OAAO;AAAA,aAC/B,KAAK,KAAK,EAAE,EAAG,MAAK,GAAG,OAAO;AAAA,aAC9B,MAAM,KAAK,EAAE,GAAG;AACvB,YAAM,MAAM,GAAG,QAAQ,IAAI;AAC3B,UAAI,KAAK,CAAC,KAAK,QAAQ,GAAG,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG,QAAQ,GAAG,CAAC,GAAG,MAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAAA,IAC9F,WAAW,WAAW,KAAK,EAAE,EAAG,KAAI,KAAK,CAAC,IAAI,QAAQ,CAAC;AAAA,QAClD,MAAK,GAAG,OAAO;AACpB,WAAO,EAAE,QAAQ,GAAG;AAAA,EACtB;AACA,MAAI,OAAO,KAAK,OAAQ,KAAI,KAAK,CAAC,KAAK,MAAM,IAAI,GAAG,EAAE,CAAC;AACvD,SAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE;AACtC;AAEA,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,OAAO;AACb,IAAM,WAAW;AAGjB,SAAS,UAAU,KAAe,MAAc,SAA+B;AAC7E,QAAM,KAAK,IAAI,cAAc,KAAK;AAClC,KAAG,YAAY;AACf,KAAG,aAAa,YAAY,IAAI;AAChC,QAAM,MAAM,CAAC,MAAc,QAAgB;AACzC,QAAI,CAAC,KAAM;AACX,QAAI,CAAC,KAAK;AAAE,SAAG,YAAY,IAAI,eAAe,IAAI,CAAC;AAAG;AAAA,IAAQ;AAC9D,UAAM,IAAI,IAAI,cAAc,MAAM;AAClC,MAAE,YAAY;AACd,MAAE,cAAc;AAChB,OAAG,YAAY,CAAC;AAAA,EAClB;AAEA,QAAM,QAAQ,SAAS,KAAK,IAAI;AAChC,MAAI,SAAS,SAAS;AACpB,OAAG,UAAU,IAAI,SAAS;AAC1B,QAAI,OAAO;AAAE,UAAI,MAAM,CAAC,GAAG,QAAQ;AAAG,UAAI,MAAM,CAAC,GAAG,UAAU;AAAA,IAAG,MAC5D,KAAI,MAAM,EAAE;AACjB,QAAI,CAAC,KAAM,IAAG,YAAY,IAAI,cAAc,IAAI,CAAC;AACjD,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,KAAK,KAAK,IAAI;AACxB,MAAI,GAAG;AACL,OAAG,UAAU,IAAI,SAAS,EAAE,CAAC,EAAE,MAAM;AACrC,QAAI,EAAE,CAAC,GAAG,QAAQ;AAAG,QAAI,EAAE,CAAC,GAAG,QAAQ;AACvC,gBAAY,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;AAC/C,WAAO;AAAA,EACT;AACA,QAAM,IAAI,KAAK,KAAK,IAAI;AACxB,MAAI,KAAK,EAAE,CAAC,GAAG;AACb,OAAG,UAAU,IAAI,UAAU;AAC3B,QAAI,EAAE,CAAC,GAAG,EAAE;AAAG,QAAI,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,QAAQ;AACxC,gBAAY,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;AAC/C,WAAO;AAAA,EACT;AACA,QAAM,KAAK,MAAM,KAAK,IAAI;AAC1B,MAAI,IAAI;AACN,OAAG,UAAU,IAAI,OAAO;AACxB,QAAI,GAAG,CAAC,EAAG,IAAG,MAAM,cAAe,GAAG,CAAC,EAAE,SAAS,IAAK;AACvD,QAAI,GAAG,CAAC,GAAG,EAAE;AAAG,QAAI,GAAG,CAAC,GAAG,YAAY;AAAG,QAAI,GAAG,CAAC,GAAG,QAAQ;AAC7D,QAAI,GAAG,CAAC,EAAG,KAAI,GAAG,CAAC,GAAG,KAAK,KAAK,GAAG,CAAC,CAAC,IAAI,qBAAqB,UAAU;AACxE,gBAAY,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;AAChD,WAAO;AAAA,EACT;AACA,MAAI,SAAS,KAAK,IAAI,GAAG;AACvB,OAAG,UAAU,IAAI,UAAU;AAC3B,QAAI,MAAM,EAAE;AACZ,WAAO;AAAA,EACT;AACA,MAAI,wBAAwB,KAAK,IAAI,GAAG;AACtC,OAAG,UAAU,IAAI,SAAS;AAC1B,QAAI,MAAM,QAAQ;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,YAAY,IAAI;AAC9B,MAAI,CAAC,MAAM,OAAQ,IAAG,YAAY,IAAI,cAAc,IAAI,CAAC;AAAA,MACpD,OAAM,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;AACxC,SAAO;AACT;AAQA,IAAM,WAAW,CAAC,MAAqB,EAAE,aAAa,KAAK,6CAA6C,KAAM,EAAc,OAAO;AAEnI,IAAM,aAAa,CAAC,OAAwB;AAC1C,MAAI,IAAI;AACR,KAAG,WAAW,QAAQ,CAAC,MAAM;AAAE,SAAM,EAAE,aAAa,KAAM,EAAc,YAAY,OAAQ,KAAM,EAAE,eAAe;AAAA,EAAK,CAAC;AACzH,SAAO;AACT;AAIA,SAAS,QAAQ,MAAe,QAAmF;AACjH,QAAM,MAAM,UAAU,CAAC;AACvB,QAAM,MAA4B,IAAI,IAAI,MAAM,IAAI;AACpD,MAAI,OAAO;AAEX,QAAM,MAAM,CAAC,MAAY,YAAwC;AAC/D,QAAI,QAAQ,CAAC,GAAG,MAAM;AAAE,UAAI,IAAI,CAAC,KAAK,QAAQ,KAAK,EAAE,SAAS,KAAM,KAAI,CAAC,IAAI,QAAQ,EAAE,MAAM;AAAA,IAAG,CAAC;AAAA,EACnG;AACA,QAAM,cAAc,CAAC,IAAa,SAAiB;AACjD,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,QAAQ,IAAI,GAAG,WAAW,QAAQ,KAAK;AACzD,YAAM,IAAI,GAAG,WAAW,CAAC;AACzB,WAAM,EAAE,aAAa,KAAM,EAAc,YAAY,OAAQ,KAAK,EAAE,eAAe,IAAI;AAAA,IACzF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,CAAC,OAAgB;AAClC,OAAG,WAAW,QAAQ,CAAC,MAAM;AAC3B,UAAI,EAAE,aAAa,GAAG;AACpB,YAAI,GAAG,CAAC,MAAM,KAAK,SAAS,KAAK,IAAI,GAAI,EAAW,UAAW,MAAM,CAAC;AACtE,gBAAS,EAAW;AAAA,MACtB,WAAW,EAAE,aAAa,KAAM,EAAc,YAAY,MAAM;AAC9D,YAAI,GAAG,CAAC,MAAM,KAAK,SAAS,YAAY,GAAc,CAAC,CAAC;AACxD,mBAAW,CAAY;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,MAAM,KAAK,KAAK,UAAU;AAC3C,MAAI,QAAQ;AACZ,WAAS,QAAQ,CAAC,MAAM;AACtB,QAAI,SAAS,CAAC,GAAG;AACf,UAAI,CAAC,MAAO,SAAQ;AACpB,cAAQ;AACR,UAAI,GAAG,CAAC,MAAM,KAAK,SAAS,YAAY,GAAc,CAAC,CAAC;AACxD,iBAAW,CAAY;AAAA,IACzB,WAAW,EAAE,aAAa,KAAM,EAAc,YAAY,MAAM;AAC9D,cAAQ;AACR,cAAQ;AAAA,IACV,OAAO;AACL,cAAQ;AACR,UAAI,GAAG,CAAC,MAAM,KAAK,SAAS,KAAK,IAAI,KAAK,IAAK,EAAW,aAAa,IAAI,MAAM,CAAC;AAClF,cAAQ,EAAE,eAAe;AAAA,IAC3B;AAAA,EACF,CAAC;AAGD,MAAI,QAAQ,CAAC,GAAG,MAAM;AACpB,QAAI,IAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,SAAS,KAAM;AAC7C,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,EAAE,UAAU,IAAI,SAAS,QAAQ,KAAK;AACxD,YAAM,IAAI,SAAS,CAAC;AACpB,WAAK,SAAS,CAAC,KAAK,IAAI,IAAI,KAAK,WAAW,CAAY,EAAE,UAAU,EAAE,eAAe,IAAI;AAAA,IAC3F;AACA,QAAI,CAAC,IAAI;AAAA,EACX,CAAC;AAED,SAAO,EAAE,MAAM,QAAQ,IAAI,IAAI,CAAC,MAAO,KAAK,OAAO,KAAK,SAAS,CAAE,EAAE;AACvE;AAEA,SAAS,WAAW,MAAe,QAAsB;AACvD,QAAM,QAAQ,MAAM,KAAK,KAAK,QAAQ;AACtC,MAAI,YAAY,KAAK,IAAI,GAAG,MAAM;AAClC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,OAAO,KAAK,eAAe,IAAI;AACrC,QAAI,aAAa,OAAO,MAAM,MAAM,SAAS,GAAG;AAC9C,YAAM,SAAS,SAAS,iBAAiB,MAAM,WAAW,SAAS;AACnE,UAAI,GAAgB,OAAO,GAAG,SAAsB,MAAM,eAAe;AACzE,aAAQ,IAAI,OAAO,SAAS,GAAI;AAC9B,cAAM,IAAK,EAAW,UAAW;AACjC,YAAI,OAAO,KAAK,WAAW;AAAE,mBAAS;AAAW,yBAAe,KAAK,IAAI,GAAG,YAAY,IAAI;AAAG;AAAA,QAAO;AACtG,gBAAQ;AAAG,iBAAS;AAAW,uBAAe;AAAA,MAChD;AACA,YAAM,MAAM,OAAO,aAAa;AAChC,YAAM,QAAQ,SAAS,YAAY;AACnC,UAAI,OAAQ,OAAM,SAAS,QAAQ,YAAY;AAAA,UAC1C,OAAM,SAAS,MAAM,CAAC;AAC3B,YAAM,SAAS,IAAI;AACnB,UAAK,gBAAgB;AACrB,UAAK,SAAS,KAAK;AACnB;AAAA,IACF;AACA,iBAAa,MAAM;AAAA,EACrB;AACF;AAIA,SAAS,QAAQ,MAAe,OAAkB;AAChD,QAAM,QAAQ,OAAO,SAAS,OAAO,KAAK,KAAK,EAAE,MAAM,IAAI;AAC3D,QAAM,MAAM,KAAK;AACjB,MAAI,UAAU;AACd,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,WAAW;AACjB,QAAI,SAAS,KAAK,IAAI,EAAG,WAAU,CAAC;AACpC,UAAM,WAAW,KAAK,SAAS,CAAC;AAChC,UAAM,OAAO,WAAW,OAAO,QAAQ;AACvC,QAAI,YAAY,SAAS,aAAa,UAAU,MAAM,IAAK;AAC3D,UAAM,OAAO,UAAU,KAAK,MAAM,QAAQ;AAC1C,SAAK,aAAa,YAAY,GAAG;AACjC,QAAI,SAAU,MAAK,aAAa,MAAM,QAAQ;AAAA,QACzC,MAAK,YAAY,IAAI;AAAA,EAC5B;AACA,SAAO,KAAK,SAAS,SAAS,MAAM,OAAQ,MAAK,YAAY,KAAK,SAAiB;AACrF;AAEA,IAAM,YAAY;AAqDX,IAAM,iBAAuB,mBAAsD,SAASC,gBAAe;AAAA,EAChH,QAAQ;AAAA,EAAI;AAAA,EAAU;AAAA,EAAU;AAAA,EAAW;AAAA,EAAS;AAAA,EACpD,cAAc;AAAA,EAAI,WAAW;AAAA,EAAO,WAAW;AAAA,EAAO;AAAA,EACtD,UAAU;AAAA,EAAG,UAAU;AAAA,EAAI,YAAY;AAAA,EACvC,gBAAgB;AAAA,EAAM,YAAY;AAAA,EAAW,YAAY;AAAA,EAAI;AAC/D,GAAG,KAAK;AACN,QAAM,SAAe,eAAuB,IAAI;AAChD,QAAM,YAAkB,eAAO,KAAK;AACpC,QAAM,eAAqB,eAAsB,IAAI;AAGrD,EAAM,wBAAgB,MAAM;AAC1B,UAAM,OAAO,OAAO;AACpB,QAAI,CAAC,QAAQ,UAAU,QAAS;AAChC,UAAM,SAAS,SAAS,kBAAkB,QAAQ,KAAK,SAAS,SAAS,aAAa;AACtF,YAAQ,MAAM,KAAK;AACnB,UAAM,QAAQ,aAAa;AAC3B,iBAAa,UAAU;AACvB,QAAI,UAAU,SAAS,KAAM,YAAW,MAAM,KAAK;AAAA,EACrD,GAAG,CAAC,KAAK,CAAC;AAEV,EAAM,kBAAU,MAAM;AAAE,QAAI,aAAa,OAAO,QAAS,QAAO,QAAQ,MAAM;AAAA,EAAG,GAAG,CAAC,SAAS,CAAC;AAE/F,QAAM,WAAW,MAAc;AAC7B,UAAM,OAAO,OAAO;AACpB,UAAM,MAAM,OAAO,aAAa;AAChC,QAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,WAAY,QAAO;AAC7C,UAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,WAAO,QAAQ,MAAM,CAAC,EAAE,MAAM,EAAE,gBAAgB,QAAQ,EAAE,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC;AAAA,EACpF;AAEA,QAAM,eAAe,MAAsC;AACzD,UAAM,OAAO,OAAO;AACpB,UAAM,MAAM,OAAO,aAAa;AAChC,QAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,WAAY,QAAO,EAAE,OAAO,MAAM,QAAQ,KAAK,MAAM,OAAO;AACtF,UAAM,IAAI,IAAI,WAAW,CAAC;AAC1B,UAAMC,QAAO,QAAQ,MAAM,CAAC,EAAE,MAAM,EAAE,gBAAgB,QAAQ,EAAE,YAAY,GAAG,EAAE,MAAM,EAAE,cAAc,QAAQ,EAAE,UAAU,CAAC,CAAC;AAC7H,UAAM,CAAC,GAAG,CAAC,IAAIA,MAAK;AACpB,WAAO,EAAE,OAAO,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,EAAE;AAAA,EACtD;AAEA,QAAM,SAAS,CAAC,MAAc,UAA0B;AACtD,QAAI,aAAa,KAAK,SAAS,UAAW;AAC1C,iBAAa,UAAU,SAAS,OAAO,OAAO;AAC9C,gBAAY,SAAS,IAAI;AACzB,QAAI,UAAW,QAAO,MAAM,SAAS,OAAO,KAAK,SAAS,KAAK;AAAA,EACjE;AAEA,QAAM,MAA4B;AAAA,IAChC,OAAO,CAAC,MAAM,OAAO,WAAW,OAAO,QAAQ,MAAM,CAAC;AAAA,IACtD,MAAM,MAAM;AAAE,aAAO,WAAW,OAAO,QAAQ,KAAK;AAAA,IAAG;AAAA,IACvD,IAAI,UAAU;AAAE,aAAO,OAAO;AAAA,IAAS;AAAA,IACvC,cAAc;AAAA,IACd,cAAc,CAAC,OAAO,KAAK,MAAM,YAAY;AAC3C,YAAM,OAAO,MAAM,MAAM,GAAG,KAAK,IAAI,OAAO,MAAM,MAAM,GAAG;AAC3D,aAAO,MAAM,WAAW,OAAO,QAAQ,KAAK,SAAS,OAAO;AAAA,IAC9D;AAAA,IACA,QAAQ,CAAC,SAAS;AAAE,YAAM,IAAI,aAAa;AAAG,UAAI,aAAa,EAAE,OAAO,EAAE,KAAK,IAAI;AAAA,IAAG;AAAA,IACtF,eAAe,CAAC,QAAQ,OAAO,oBAAoB;AACjD,YAAM,IAAI,aAAa;AACvB,YAAM,MAAM,MAAM,MAAM,EAAE,OAAO,EAAE,GAAG;AACtC,YAAM,QAAQ,SAAS,OAAO,SAAS;AACvC,YAAM,UAAU,MAAM,MAAM,EAAE,QAAQ,OAAO,QAAQ,EAAE,KAAK,MAAM,UAAU,MAAM,MAAM,EAAE,KAAK,EAAE,MAAM,MAAM,MAAM,MAAM;AACzH,UAAI,SAAS;AACX,cAAMC,QAAO,MAAM,MAAM,GAAG,EAAE,QAAQ,OAAO,MAAM,IAAI,MAAM,MAAM,MAAM,EAAE,MAAM,MAAM,MAAM;AAC7F,eAAOA,OAAM,EAAE,QAAQ,OAAO,SAAS,IAAI,MAAM;AACjD;AAAA,MACF;AACA,YAAM,QAAQ,OAAO,mBAAmB;AACxC,YAAM,OAAO,MAAM,MAAM,GAAG,EAAE,KAAK,IAAI,SAAS,QAAQ,QAAQ,MAAM,MAAM,EAAE,GAAG;AACjF,aAAO,MAAM,MAAM,EAAE,QAAQ,OAAO,SAAS,MAAM,SAAS,MAAM,SAAS,EAAE,QAAQ,OAAO,SAAS,MAAM,MAAM;AAAA,IACnH;AAAA,IACA,aAAa,CAAC,WAAW;AACvB,YAAM,IAAI,aAAa;AACvB,YAAM,OAAO,MAAM,YAAY,MAAM,KAAK,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI;AACjE,YAAM,QAAQ,MAAM,QAAQ,MAAM,EAAE,GAAG;AACvC,YAAM,KAAK,UAAU,KAAK,MAAM,SAAS;AACzC,YAAM,QAAQ,MAAM,MAAM,MAAM,EAAE;AAClC,YAAM,KAAK,MAAM,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,KAAK,EAAE,WAAW,MAAM,CAAC;AAC3E,YAAM,OAAO,MAAM,MAAM,IAAI,EAAE,IAAI,CAAC,MAAO,KAAK,EAAE,QAAQ,QAAQ,EAAE,IAAI,SAAS,CAAE,EAAE,KAAK,IAAI;AAC9F,UAAI,aAAa,MAAM,IAAI,MAAM,OAAO,KAAK,MAAM;AAAA,IACrD;AAAA,EACF;AACA,EAAM,4BAAoB,KAAK,MAAM,GAAG;AAGxC,WAAS,OAAO,MAAc,OAAe;AAC3C,QAAI,CAAC,UAAW;AAChB,UAAM,OAAO,KAAK,MAAM,GAAG,KAAK;AAChC,UAAM,OAAO,KAAK,MAAM,KAAK,YAAY,IAAI,IAAI,CAAC;AAClD,UAAM,QAAQ,eAAe,KAAK,IAAI;AACtC,QAAI,OAAO;AAAE,gBAAU,EAAE,MAAM,SAAS,OAAO,MAAM,CAAC,GAAG,MAAM,QAAQ,MAAM,CAAC,EAAE,QAAQ,IAAI,MAAM,CAAC;AAAG;AAAA,IAAQ;AAC9G,UAAM,KAAK,uBAAuB,KAAK,IAAI;AAC3C,QAAI,IAAI;AAAE,YAAM,MAAM,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AAAG,gBAAU,EAAE,MAAM,WAAW,OAAO,GAAG,CAAC,GAAG,MAAM,QAAQ,IAAI,QAAQ,IAAI,MAAM,CAAC;AAAG;AAAA,IAAQ;AAC3I,cAAU,IAAI;AAAA,EAChB;AAEA,QAAM,iBAAiB,MAAM;AAC3B,UAAM,IAAI,aAAa;AACvB,UAAM,YAAY,MAAM,YAAY,MAAM,KAAK,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI;AACtE,UAAM,OAAO,MAAM,MAAM,WAAW,EAAE,KAAK;AAC3C,UAAM,KAAK,UAAU,KAAK,IAAI;AAC9B,UAAM,IAAI,KAAK,KAAK,IAAI;AACxB,QAAI,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AACtB,YAAM,SAAS,KAAK,KAAK,GAAG,CAAC,CAAC,IAAK,SAAS,GAAG,CAAC,GAAG,EAAE,IAAI,IAAK,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE,IAAI,GAAG,CAAC;AAC7F,YAAM,MAAM,OAAO,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,SAAS;AAC9D,UAAI,aAAa,EAAE,OAAO,EAAE,KAAK,GAAG;AACpC;AAAA,IACF;AACA,QAAI,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG;AAAE,UAAI,aAAa,WAAW,EAAE,KAAK,IAAI,SAAS;AAAG;AAAA,IAAQ;AACtF,QAAI,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG;AAAE,UAAI,aAAa,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAAG;AAAA,IAAQ;AACrG,QAAI,aAAa,EAAE,OAAO,EAAE,KAAK,IAAI;AAAA,EACvC;AAEA,QAAM,UAAU,CAAC,MAA2B;AAC1C,iBAAa,UAAU,CAAC;AACxB,QAAI,EAAE,iBAAkB;AACxB,QAAK,EAA2C,eAAe,EAAE,YAAY,KAAK;AAAE,gBAAU,UAAU;AAAM;AAAA,IAAQ;AAEtH,UAAM,MAAM,QAAQ,EAAE,UAAU,EAAE;AAClC,QAAI,OAAO,CAAC,EAAE,QAAQ;AACpB,YAAM,IAAI,EAAE,IAAI,YAAY;AAC5B,UAAI,MAAM,KAAK;AAAE,UAAE,eAAe;AAAG,YAAI,cAAc,MAAM,MAAM,MAAM;AAAG;AAAA,MAAQ;AACpF,UAAI,MAAM,KAAK;AAAE,UAAE,eAAe;AAAG,YAAI,cAAc,KAAK,KAAK,QAAQ;AAAG;AAAA,MAAQ;AACpF,UAAI,MAAM,KAAK;AAAE,UAAE,eAAe;AAAG,YAAI,cAAc,KAAK,KAAK,MAAM;AAAG;AAAA,MAAQ;AAClF,UAAI,MAAM,KAAK;AACb,UAAE,eAAe;AACjB,cAAM,IAAI,aAAa;AACvB,cAAM,MAAM,MAAM,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK;AAC3C,YAAI,aAAa,EAAE,OAAO,EAAE,KAAK,MAAM,MAAM,UAAU,EAAE,QAAQ,IAAI,SAAS,CAAC;AAC/E;AAAA,MACF;AAAA,IACF;AAEA,QAAI,EAAE,QAAQ,SAAS;AACrB,QAAE,eAAe;AACjB,UAAI,EAAE,YAAY,CAAC,cAAe,gBAAe;AAAA,UAC5C,aAAY,SAAS,KAAK;AAC/B;AAAA,IACF;AACA,QAAI,EAAE,QAAQ,OAAO;AACnB,YAAM,IAAI,aAAa;AACvB,YAAM,UAAU,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,UAAU,KAAK,CAAC,GAAG;AACjE,YAAM,OAAO,MAAM,MAAM,MAAM,YAAY,MAAM,KAAK,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,GAAG,EAAE,KAAK;AACvF,UAAI,SAAS,MAAM,KAAK,MAAM,KAAK,IAAI,GAAG;AAAE,UAAE,eAAe;AAAG,YAAI,OAAO,IAAI;AAAA,MAAG;AAAA,IACpF;AAAA,EACF;AAEA,QAAM,cAAc,CAAC,MAAgE;AACnF,QAAI,EAAE,cAAc,qBAAqB,EAAE,cAAc,mBAAmB;AAC1E,QAAE,eAAe;AACjB,qBAAe;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM;AAClB,UAAM,OAAO,OAAO;AACpB,QAAI,CAAC,QAAQ,UAAU,QAAS;AAChC,UAAM,MAAM,OAAO,aAAa;AAChC,UAAM,IAAI,OAAO,IAAI,aAAa,IAAI,WAAW,CAAC,IAAI;AACtD,UAAMD,QAAO,QAAQ,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,gBAAgB,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;AACvF,WAAOA,MAAK,MAAM,IAAIA,MAAK,OAAO,CAAC,IAAIA,MAAK,KAAK,MAAM;AAAA,EACzD;AAEA,QAAM,QAAQ,CAAC,MAA4B;AACzC,eAAW,QAAQ,CAAC;AACpB,QAAI,EAAE,iBAAkB;AACxB,UAAM,OAAO,EAAE,iBAAiB,EAAE,cAAc,QAAQ,YAAY;AACpE,QAAI,QAAQ,KAAM;AAClB,MAAE,eAAe;AACjB,UAAM,IAAI,aAAa;AACvB,QAAI,aAAa,EAAE,OAAO,EAAE,KAAK,KAAK,QAAQ,UAAU,IAAI,CAAC;AAAA,EAC/D;AAEA,QAAM,KAAK;AACX,SACE,+CAAC,SAAI,WAAW,CAAC,eAAe,WAAW,gBAAgB,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAChG;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QAAQ;AAAA,QAAQ,WAAU;AAAA,QAC/B,iBAAiB,CAAC,YAAY,CAAC;AAAA,QAC/B,gCAA8B;AAAA,QAC9B,MAAK;AAAA,QAAU,kBAAe;AAAA,QAAO,cAAY;AAAA,QACjD,YAAY;AAAA,QAAM,gBAAe;AAAA,QACjC,OAAO,EAAE,WAAY,UAAU,KAAM,MAAM,WAAY,UAAU,KAAM,KAAK;AAAA,QAC5E,WAAW;AAAA,QACX,eAAe;AAAA,QACf,SAAS;AAAA,QACT,SAAS;AAAA,QACT,oBAAoB,MAAM;AAAE,oBAAU,UAAU;AAAA,QAAM;AAAA,QACtD,kBAAkB,MAAM;AAAE,oBAAU,UAAU;AAAO,gBAAM;AAAA,QAAG;AAAA,QAC9D,SAAS,MAAM;AAAE,cAAI,UAAW,QAAO,OAAO,SAAS,CAAC;AAAA,QAAG;AAAA,QAC3D,SAAS,MAAM;AAAE,cAAI,UAAW,QAAO,OAAO,SAAS,CAAC;AAAA,QAAG;AAAA;AAAA,IAC7D;AAAA,IACC,CAAC,QAAQ,8CAAC,UAAK,WAAU,aAAY,eAAY,QAAQ,uBAAY,IAAU;AAAA,KAClF;AAEJ,CAAC;;;ACneD,IAAAE,UAAuB;;;ACAvB,IAAAC,UAAuB;AAuFvB,IAAM,qBAAwC;AAAA,EAC5C,EAAE,OAAO,SAAS,OAAO;AAAA,IACvB,EAAE,KAAK,aAAa,OAAO,cAAc,QAAQ,kCAAkC;AAAA,IACnF,EAAE,KAAK,aAAa,OAAO,cAAc,QAAQ,8DAA8D;AAAA,IAC/G,EAAE,KAAK,cAAc,OAAO,kBAAkB,QAAQ,6CAA6C;AAAA,IACnG,EAAE,KAAK,eAAe,OAAO,gBAAgB,QAAQ,iDAAiD;AAAA,EACxG,EAAE;AAAA,EACF,EAAE,OAAO,YAAY,OAAO;AAAA,IAC1B,EAAE,KAAK,cAAc,OAAO,oBAAoB,QAAQ,mCAAmC;AAAA,IAC3F,EAAE,KAAK,gBAAgB,OAAO,sBAAsB,QAAQ,0CAA0C;AAAA,IACtG,EAAE,KAAK,eAAe,OAAO,oBAAoB,QAAQ,gDAAgD;AAAA,EAC3G,EAAE;AAAA,EACF,EAAE,OAAO,SAAS,OAAO;AAAA,IACvB,EAAE,KAAK,cAAc,OAAO,kBAAkB,QAAQ,yCAAyC;AAAA,IAC/F,EAAE,KAAK,cAAc,OAAO,uBAAuB,QAAQ,+CAA+C;AAAA,EAC5G,EAAE;AAAA,EACF,EAAE,OAAO,kBAAkB,OAAO;AAAA,IAChC,EAAE,KAAK,cAAc,OAAO,cAAc,QAAQ,4BAA4B;AAAA,IAC9E,EAAE,KAAK,gBAAgB,OAAO,gBAAgB,QAAQ,0CAA0C;AAAA,IAChG,EAAE,KAAK,gBAAgB,OAAO,gBAAgB,QAAQ,2CAA2C;AAAA,IACjG,EAAE,KAAK,gBAAgB,OAAO,wBAAwB,QAAQ,iDAAiD;AAAA,IAC/G,EAAE,KAAK,cAAc,OAAO,sBAAsB,QAAQ,+BAA+B;AAAA,IACzF,EAAE,KAAK,gBAAgB,OAAO,oBAAoB,QAAQ,gEAAgE;AAAA,EAC5H,EAAE;AACJ;AAEA,IAAM,kBAA4B,mBAAmB,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAG7F,IAAM,QAAgB;AAAA,EACpB;AAAA,IAAE,IAAI;AAAA,IAAS,MAAM;AAAA,IAAS,QAAQ;AAAA,IAAM,aAAa;AAAA,IACvD,aAAa;AAAA,EAAgB;AAAA,EAC/B;AAAA,IAAE,IAAI;AAAA,IAAS,MAAM;AAAA,IAAiB,QAAQ;AAAA,IAAM,aAAa;AAAA,IAC/D,aAAa,CAAC,aAAa,aAAa,cAAc,cAAc,gBAAgB,eAAe,cAAc,cAAc,gBAAgB,gBAAgB,gBAAgB,cAAc,cAAc;AAAA,EAAE;AAAA,EAC/M;AAAA,IAAE,IAAI;AAAA,IAAW,MAAM;AAAA,IAAW,QAAQ;AAAA,IAAO,aAAa;AAAA,IAC5D,aAAa,CAAC,aAAa,aAAa,cAAc,cAAc,gBAAgB,eAAe,cAAc,cAAc;AAAA,EAAE;AAAA,EACnI;AAAA,IAAE,IAAI;AAAA,IAAW,MAAM;AAAA,IAAW,QAAQ;AAAA,IAAO,aAAa;AAAA,IAC5D,aAAa,CAAC,aAAa,cAAc,cAAc,eAAe,cAAc;AAAA,EAAE;AAAA,EACxF;AAAA,IAAE,IAAI;AAAA,IAAe,MAAM;AAAA,IAAuB,QAAQ;AAAA,IAAO,aAAa;AAAA,IAC5E,aAAa,CAAC,aAAa,cAAc,cAAc,cAAc;AAAA,EAAE;AAAA,EACzE;AAAA,IAAE,IAAI;AAAA,IAAS,MAAM;AAAA,IAAgB,QAAQ;AAAA,IAAO,aAAa;AAAA,IAC/D,aAAa,CAAC,aAAa,eAAe,gBAAgB,YAAY;AAAA,EAAE;AAC5E;AAqBA,IAAM,SAAkB;AAAA,EACtB;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AACF;AAEA,IAAM,QAAgB;AAAA;AAAA,EAEpB;AAAA,IAAE,KAAK;AAAA,IAAiB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,QAAQ;AAAA,IAAS,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC1I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,aAAa;AAAA,IAAwE,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAC9H;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA6B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACzI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,eAAe;AAAA,IAAG,aAAa;AAAA,IAA4E,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAChK;AAAA,IAAE,KAAK;AAAA,IAAiB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAgC,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACvI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAA8D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EACvJ;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAmB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAC1J,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,iBAAiB,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAAwF,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EAC/L;AAAA,IAAE,KAAK;AAAA,IAAkB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAoB,QAAQ;AAAA,IAAU,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC9I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,aAAa;AAAA,IAA2D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EAClH;AAAA,IAAE,KAAK;AAAA,IAAiB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAU,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACjH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAW,SAAS;AAAA,IACzD,WAAW,CAAC,kBAAkB,eAAe;AAAA,IAAG,aAAa;AAAA,IAA0D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA;AAAA,EAGjK;AAAA,IAAE,KAAK;AAAA,IAAoB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAiB,QAAQ;AAAA,IAAY,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC/I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,eAAe;AAAA,IAAG,aAAa;AAAA,IAA0E,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAC9J;AAAA,IAAE,KAAK;AAAA,IAA0B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAmB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACnI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAA4F,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EAClL;AAAA,IAAE,KAAK;AAAA,IAAkC,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA2B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACnJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAA+E,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EACrK;AAAA,IAAE,KAAK;AAAA,IAAkB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAiB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACzH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAA+D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EACrJ;AAAA,IAAE,KAAK;AAAA,IAAyB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACjI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAW,SAAS;AAAA,IAC1D,WAAW,CAAC,eAAe;AAAA,IAAG,aAAa;AAAA,IAA+D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACnJ;AAAA,IAAE,KAAK;AAAA,IAAmB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAc,QAAQ;AAAA,IAAW,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC1I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAA2D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAClJ;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAuB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAC9J,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,mBAAmB,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAAwE,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAClL;AAAA,IAAE,KAAK;AAAA,IAAwB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAiB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC/H,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,iBAAiB;AAAA,IAAG,aAAa;AAAA,IAAyC,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAC/H;AAAA,IAAE,KAAK;AAAA,IAA+B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAwB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC7I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,sBAAsB;AAAA,IAAG,aAAa;AAAA,IAAsE,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EAChK;AAAA,IAAE,KAAK;AAAA,IAAyB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACjI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,sBAAsB;AAAA,IAAG,aAAa;AAAA,IAAwE,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EAClK;AAAA,IAAE,KAAK;AAAA,IAAwB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA0B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,SAAQ,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IACjK,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,wBAAuB,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAA8D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EAC7K;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,QAAQ;AAAA,IAAc,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACpJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,eAAe;AAAA,IAAG,aAAa;AAAA,IAA4D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EACjJ;AAAA,IAAE,KAAK;AAAA,IAAyB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAC5J,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAA0D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACnJ;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAqB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACjI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAuD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAChJ;AAAA,IAAE,KAAK;AAAA,IAAoB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA0B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAC/J,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAoE,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC7J;AAAA,IAAE,KAAK;AAAA,IAAwB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAiB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC/H,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAS,SAAS;AAAA,IACvD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAA6D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACtJ;AAAA,IAAE,KAAK;AAAA,IAAmB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAc,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACvH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAgE,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACzJ;AAAA,IAAE,KAAK;AAAA,IAAqB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAc,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACzH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAS,SAAS;AAAA,IACvD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAkD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC3I;AAAA,IAAE,KAAK;AAAA,IAAoB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAoB,QAAQ;AAAA,IAAY,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAClJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,eAAe;AAAA,IAAG,aAAa;AAAA,IAA0D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAC9I;AAAA,IAAE,KAAK;AAAA,IAAqB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA0B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAChK,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAA6D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EACzK;AAAA,IAAE,KAAK;AAAA,IAAe,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,QAAQ;AAAA,IAAO,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACtI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,iBAAiB;AAAA,IAAG,aAAa;AAAA,IAA8C,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EACpI;AAAA,IAAE,KAAK;AAAA,IAAmB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAmB,QAAQ;AAAA,IAAW,SAAS;AAAA,IAAM,SAAS;AAAA,IACvH,OAAO,CAAC,WAAW,OAAO;AAAA,IAAG,OAAO,EAAE,UAAU,MAAM;AAAA,IACtD,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAsD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA;AAAA,EAGhJ;AAAA,IAAE,KAAK;AAAA,IAAqB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAoB,QAAQ;AAAA,IAAa,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACpJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,iBAAiB,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAAuD,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAC/J;AAAA,IAAE,KAAK;AAAA,IAAoB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAmB,QAAQ;AAAA,IAAY,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACjJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,eAAe;AAAA,IAAG,aAAa;AAAA,IAA8D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAClJ;AAAA,IAAE,KAAK;AAAA,IAAuB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAmB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAChI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAAmD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC1I;AAAA,IAAE,KAAK;AAAA,IAA0B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAqB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,SAAQ,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAC9J,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAA4D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACnJ;AAAA,IAAE,KAAK;AAAA,IAA2B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAsB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,SAAQ,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAChK,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,qBAAoB,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAAkD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC7J;AAAA,IAAE,KAAK;AAAA,IAA6B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAwB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,SAAQ,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IACpK,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,mBAAmB;AAAA,IAAG,aAAa;AAAA,IAA8D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACtJ;AAAA,IAAE,KAAK;AAAA,IAAuB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,SAAQ,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IACxJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,iBAAiB;AAAA,IAAG,aAAa;AAAA,IAAsD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC5I;AAAA,IAAE,KAAK;AAAA,IAAqB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA2B,QAAQ;AAAA,IAAa,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC3J,KAAK;AAAA,IAAM,WAAW;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzE,aAAa;AAAA,IAAkE,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EACzH;AAAA,IAAE,KAAK;AAAA,IAA2B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA4B,SAAS;AAAA,IAAO,SAAS;AAAA,IACtH,OAAO,CAAC,aAAa;AAAA,IAAG,OAAO,CAAC;AAAA,IAChC,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,qBAAqB,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAA2E,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EACxL;AAAA,IAAE,KAAK;AAAA,IAA6B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA0B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IAC5J,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,yBAAyB;AAAA,IAAG,aAAa;AAAA,IAA2D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACzJ;AAAA,IAAE,KAAK;AAAA,IAAmB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAqB,QAAQ;AAAA,IAAO,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC7I,KAAK;AAAA,IAAM,WAAW;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzE,aAAa;AAAA,IAAqE,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EAC5H;AAAA,IAAE,KAAK;AAAA,IAAmB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAW,QAAQ;AAAA,IAAW,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACvI,KAAK;AAAA,IAAM,WAAW;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzE,aAAa;AAAA,IAAmD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA;AAAA,EAGzG;AAAA,IAAE,KAAK;AAAA,IAAkB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAoB,QAAQ;AAAA,IAAU,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC9I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAA0D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EACjJ;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAe,QAAQ;AAAA,IAAU,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC7I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,gBAAgB;AAAA,IAAG,aAAa;AAAA,IAA6D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAClJ;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAe,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,SAAS,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IACpJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,sBAAsB,kBAAkB;AAAA,IAAG,aAAa;AAAA,IAAkE,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EAC9K;AAAA,IAAE,KAAK;AAAA,IAAsB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAmB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC/H,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,gBAAgB;AAAA,IAAG,aAAa;AAAA,IAA4C,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACjI;AAAA,IAAE,KAAK;AAAA,IAAqB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAc,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACzH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAyD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAClJ;AAAA,IAAE,KAAK;AAAA,IAAyB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAuB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACtI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAyD,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EACjJ;AAAA,IAAE,KAAK;AAAA,IAA8B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAyB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,SAAQ,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IACtK,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAA4E,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EACpK;AAAA,IAAE,KAAK;AAAA,IAAiC,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA0B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACjJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAAoD,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EAC5I;AAAA,IAAE,KAAK;AAAA,IAAqB,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAkB,SAAS;AAAA,IAAM,SAAS;AAAA,IACrG,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,EAAE,SAAS,KAAK;AAAA,IAC7D,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAW,SAAS;AAAA,IAC1D,WAAW,CAAC,oBAAoB,iBAAiB;AAAA,IAAG,aAAa;AAAA,IAAwD,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EACjK;AAAA,IAAE,KAAK;AAAA,IAA0B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAAmB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAI,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAC7J,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,qBAAqB,oBAAoB;AAAA,IAAG,aAAa;AAAA,IAA4D,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA;AAAA,EAGzK;AAAA,IAAE,KAAK;AAAA,IAA4B,SAAS;AAAA,IAAiB,OAAO;AAAA,IAA4B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC9I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,mBAAmB;AAAA,IAAG,aAAa;AAAA,IAAgD,OAAO;AAAA,IAAc,SAAS;AAAA,EAAQ;AAAA,EACvI;AAAA,IAAE,KAAK;AAAA,IAA2B,SAAS;AAAA,IAAY,OAAO;AAAA,IAAmB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC/H,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,aAAa;AAAA,IAAwC,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA,EAC9F;AAAA,IAAE,KAAK;AAAA,IAAyB,SAAS;AAAA,IAAY,OAAO;AAAA,IAAuB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAI,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAChI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,yBAAyB;AAAA,IAAG,aAAa;AAAA,IAAkD,OAAO;AAAA,IAAc,SAAS;AAAA,EAAS;AAAA;AAAA,EAGhJ;AAAA,IAAE,KAAK;AAAA,IAAe,SAAS;AAAA,IAAS,OAAO;AAAA,IAAkB,QAAQ;AAAA,IAAS,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IAChJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,aAAa;AAAA,IAA+C,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EACtG;AAAA,IAAE,KAAK;AAAA,IAAe,SAAS;AAAA,IAAS,OAAO;AAAA,IAAyB,QAAQ;AAAA,IAAS,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IACvJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,WAAW,CAAC,aAAa;AAAA,IAAG,aAAa;AAAA,IAAuD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EAC1I;AAAA,IAAE,KAAK;AAAA,IAAe,SAAS;AAAA,IAAS,OAAO;AAAA,IAAiB,QAAQ;AAAA,IAAS,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IAC/I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,SAAS;AAAA,IACxD,aAAa;AAAA,IAAsD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC5G;AAAA,IAAE,KAAK;AAAA,IAAe,SAAS;AAAA,IAAS,OAAO;AAAA,IAAa,QAAQ;AAAA,IAAS,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAS,SAAS,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IACtJ,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,aAAa;AAAA,IAAG,aAAa;AAAA,IAA6C,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EAChI;AAAA,IAAE,KAAK;AAAA,IAAoB,SAAS;AAAA,IAAS,OAAO;AAAA,IAAe,SAAS;AAAA,IAAO,SAAS;AAAA,IAAG,OAAO,CAAC,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IACvH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,aAAa;AAAA,IAAG,aAAa;AAAA,IAA8C,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA,EACjI;AAAA,IAAE,KAAK;AAAA,IAAwB,SAAS;AAAA,IAAS,OAAO;AAAA,IAAe,SAAS;AAAA,IAAO,SAAS;AAAA,IAAG,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACpH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,aAAa;AAAA,IAAG,aAAa;AAAA,IAA8D,OAAO;AAAA,IAAe,SAAS;AAAA,EAAS;AAAA;AAAA,EAGjJ;AAAA,IAAE,KAAK;AAAA,IAAoB,SAAS;AAAA,IAAS,OAAO;AAAA,IAA0B,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IAC3I,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,aAAa;AAAA,IAAG,aAAa;AAAA,IAAwD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC1I;AAAA,IAAE,KAAK;AAAA,IAAuB,SAAS;AAAA,IAAS,OAAO;AAAA,IAAkB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IACtI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,aAAa;AAAA,IAAG,aAAa;AAAA,IAAsD,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EACxI;AAAA,IAAE,KAAK;AAAA,IAAqB,SAAS;AAAA,IAAS,OAAO;AAAA,IAAgB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC,SAAQ,OAAO;AAAA,IAAG,OAAO,CAAC;AAAA,IAClI,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAS,SAAS;AAAA,IACxD,WAAW,CAAC,aAAa;AAAA,IAAG,aAAa;AAAA,IAA4C,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAC9H;AAAA,IAAE,KAAK;AAAA,IAAmB,SAAS;AAAA,IAAc,OAAO;AAAA,IAAe,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IACrH,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,aAAa;AAAA,IAA4C,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AAAA,EAClG;AAAA,IAAE,KAAK;AAAA,IAAoB,SAAS;AAAA,IAAc,OAAO;AAAA,IAAoB,SAAS;AAAA,IAAM,SAAS;AAAA,IAAK,OAAO,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAC3H,KAAK;AAAA,IAAc,OAAO;AAAA,IAAI,QAAQ;AAAA,IAAU,SAAS;AAAA,IACzD,WAAW,CAAC,iBAAiB;AAAA,IAAG,aAAa;AAAA,IAA+B,OAAO;AAAA,IAAe,SAAS;AAAA,EAAQ;AACvH;AAEA,IAAM,QAAgB;AAAA,EACpB;AAAA,IAAE,IAAI;AAAA,IAAU,MAAM;AAAA,IAAc,OAAO;AAAA,IAAsB,OAAO;AAAA,IAAwB,MAAM;AAAA,IACpG,OAAO,CAAC,WAAW,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,YAAY;AAAA,IAAiB,QAAQ;AAAA,IAAY,KAAK;AAAA,IACrG,UAAU;AAAA,IAAkB,OAAO;AAAA,EAAkB;AAAA,EACvD;AAAA,IAAE,IAAI;AAAA,IAAY,MAAM;AAAA,IAAe,OAAO;AAAA,IAAwB,OAAO;AAAA,IAAiB,MAAM;AAAA,IAClG,OAAO,CAAC,SAAS;AAAA,IAAG,QAAQ;AAAA,IAAU,YAAY;AAAA,IAAa,QAAQ;AAAA,IAAY,KAAK;AAAA,IAAM,UAAU;AAAA,EAAmB;AAAA,EAC7H;AAAA,IAAE,IAAI;AAAA,IAAW,MAAM;AAAA,IAAe,OAAO;AAAA,IAAuB,OAAO;AAAA,IAAkB,MAAM;AAAA,IACjG,OAAO,CAAC,eAAe,SAAS;AAAA,IAAG,QAAQ;AAAA,IAAU,YAAY;AAAA,IAAe,QAAQ;AAAA,IAAY,KAAK;AAAA,IAAM,UAAU;AAAA,EAAsB;AAAA,EACjJ;AAAA,IAAE,IAAI;AAAA,IAAS,MAAM;AAAA,IAAc,OAAO;AAAA,IAAqB,OAAO;AAAA,IAAgB,MAAM;AAAA,IAC1F,OAAO,CAAC,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,YAAY;AAAA,IAAc,QAAQ;AAAA,IAAY,KAAK;AAAA,IAAM,UAAU;AAAA,EAAkB;AAAA,EAC3H;AAAA,IAAE,IAAI;AAAA,IAAW,MAAM;AAAA,IAAiB,OAAO;AAAA,IAAuB,OAAO;AAAA,IAAc,MAAM;AAAA,IAC/F,OAAO,CAAC,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAU,YAAY;AAAA,IAAc,QAAQ;AAAA,IAAY,KAAK;AAAA,IAAM,UAAU;AAAA,EAAmB;AAAA,EAC5H;AAAA,IAAE,IAAI;AAAA,IAAS,MAAM;AAAA,IAAiB,OAAO;AAAA,IAAqB,OAAO;AAAA,IAAmB,MAAM;AAAA,IAChG,OAAO,CAAC,SAAS;AAAA,IAAG,QAAQ;AAAA,IAAU,YAAY;AAAA,IAAU,QAAQ;AAAA,IAAY,KAAK;AAAA,IAAO,UAAU;AAAA,EAAiB;AAAA,EACzH;AAAA,IAAE,IAAI;AAAA,IAAU,MAAM;AAAA,IAAiB,OAAO;AAAA,IAAsB,OAAO;AAAA,IAAiB,MAAM;AAAA,IAChG,OAAO,CAAC,SAAS;AAAA,IAAG,QAAQ;AAAA,IAAW,YAAY;AAAA,IAAK,QAAQ;AAAA,IAAkB,KAAK;AAAA,IAAO,UAAU;AAAA,EAAiB;AAAA,EAC3H;AAAA,IAAE,IAAI;AAAA,IAAS,MAAM;AAAA,IAAe,OAAO;AAAA,IAAqB,OAAO;AAAA,IAAgB,MAAM;AAAA,IAC3F,OAAO,CAAC,OAAO;AAAA,IAAG,QAAQ;AAAA,IAAa,YAAY;AAAA,IAAU,QAAQ;AAAA,IAAY,KAAK;AAAA,IAAM,UAAU;AAAA,EAAkB;AAC5H;AAGA,SAAS,OAAO,MAAsB;AACpC,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAAE,SAAK,KAAK,WAAW,CAAC;AAAG,QAAI,KAAK,KAAK,GAAG,QAAQ;AAAA,EAAG;AAC7F,SAAO,KAAK,IAAI,CAAC,IAAI;AACvB;AAEA,IAAM,QAAQ;AAId,SAAS,aAAmC;AAC1C,MAAI;AAAE,WAAO,KAAK,MAAM,aAAa,QAAQ,KAAK,KAAK,MAAM;AAAA,EAAG,QAAQ;AAAE,WAAO;AAAA,EAAM;AACzF;AACA,SAAS,YAAY,OAAqD;AACxE,MAAI;AACF,UAAM,OAAO,OAAO,OAAO,CAAC,GAAG,WAAW,GAAG,KAAK;AAClD,iBAAa,QAAQ,OAAO,KAAK,UAAU,IAAI,CAAC;AAChD,WAAO;AAAA,EACT,QAAQ;AAAE,WAAO;AAAA,EAAM;AACzB;AAGA,SAAS,aAAa,QAAgB,WAAyE;AAC7G,QAAM,QAAS,aAAa,UAAU,SAAU;AAChD,QAAM,QAAS,aAAa,UAAU,SAAU;AAChD,QAAM,QAAS,aAAa,UAAU,SAAU;AAChD,QAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,KAAK,MAAM,CAAC;AAC1D,QAAM,OAAO,MAAM,OAAO,CAAC,MAAM,KAAK,MAAM,QAAQ,EAAE,EAAE,KAAK,CAAC;AAC9D,QAAM,cAAc,CAAC,GAAG,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACnE,QAAM,WAAoC,CAAC;AAC3C,QAAM,QAAQ,CAAC,MAAM;AAAE,aAAS,EAAE,GAAG,IAAI,aAAa,GAAG,IAAI;AAAA,EAAG,CAAC;AACjE,SAAO,EAAE,MAAM,OAAO,MAAM,aAAa,OAAO,UAAU,UAAU,OAAO,UAAU,OAAO,UAAU,MAAM;AAC9G;AAGA,SAAS,aAAa,MAAY,MAAqB;AACrD,MAAI,CAAC,KAAK,QAAS,QAAO;AAC1B,MAAI,QAAQ,KAAK,SAAS,KAAK,MAAM,KAAK,EAAE,KAAK,KAAM,QAAO,CAAC,CAAC,KAAK,MAAM,KAAK,EAAE;AAClF,MAAI,KAAK,SAAS,KAAK,MAAM,QAAQ;AACnC,QAAI,QAAQ,KAAK,MAAM,KAAK,CAAC,MAAM,KAAK,MAAM,QAAQ,CAAC,KAAK,CAAC,EAAG,QAAO;AACvE,QAAI,KAAK,WAAW,IAAK,QAAO;AAChC,WAAO;AAAA,EACT;AACA,MAAI,KAAK,WAAW,IAAK,QAAO;AAChC,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,SAAO,OAAO,OAAO,KAAK,MAAM,MAAM,KAAK,EAAE,IAAI,KAAK,UAAU;AAClE;AAGA,SAAS,YAAY,MAAY,MAA6B;AAC5D,MAAI,CAAC,KAAK,QAAS,QAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB,QAAQ,2CAA2C;AAClH,MAAI,QAAQ,KAAK,SAAS,KAAK,MAAM,KAAK,EAAE,KAAK,MAAM;AACrD,UAAM,KAAK,CAAC,CAAC,KAAK,MAAM,KAAK,EAAE;AAC/B,WAAO,EAAE,IAAI,QAAQ,KAAK,4BAAuB,4BAAuB,QAAQ,wBAAwB,KAAK,OAAO,IAAI;AAAA,EAC1H;AACA,MAAI,KAAK,SAAS,KAAK,MAAM,UAAU,QAAQ,KAAK,MAAM,KAAK,CAAC,MAAM,KAAK,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG;AACjG,WAAO,EAAE,IAAI,MAAM,QAAQ,iBAAiB,QAAQ,uBAAuB,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAAA,EACzG;AACA,MAAI,KAAK,WAAW,IAAK,QAAO,EAAE,IAAI,MAAM,QAAQ,oBAAoB,QAAQ,iBAAiB;AACjG,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO,KAAK,SAAS,KAAK,MAAM,SAC5B,EAAE,IAAI,OAAO,QAAQ,gBAAgB,QAAQ,gBAAgB,KAAK,MAAM,KAAK,IAAI,IAAI,mBAAmB,IACxG,EAAE,IAAI,OAAO,QAAQ,cAAc,QAAQ,sCAAsC;AAAA,EACvF;AACA,QAAM,IAAI,OAAO,OAAO,KAAK,MAAM,MAAM,KAAK,EAAE,IAAI;AACpD,SAAO,KAAK,QAAQ,IAAI,KAAK,UACzB,EAAE,IAAI,MAAM,QAAQ,cAAc,QAAQ,YAAY,IAAI,mBAAmB,KAAK,UAAU,eAAe,IAC3G,EAAE,IAAI,OAAO,QAAQ,mBAAmB,QAAQ,YAAY,IAAI,yBAAyB,KAAK,UAAU,eAAe;AAC7H;AAEA,IAAM,YAAY,oBAAI,IAA0B;AAChD,IAAI,UAA0B;AAU9B,SAAS,YAAY,QAA0B;AAC7C,QAAM,SAAS,WAAW;AAC1B,QAAM,KAAK,UAAW,UAAU,OAAO,UAAW,MAAM,CAAC,EAAE;AAC3D,YAAU,aAAa,IAAI,OAAO,oBAAoB;AACtD,MAAI,UAAU,OAAO,QAAS,QAAO,OAAO,QAAQ,MAAM,OAAO,OAAO;AACxE,SAAO;AACT;AAEA,SAAS,aAAsB;AAAE,SAAO,WAAW,YAAY;AAAG;AAElE,SAAS,cAAc,QAAyB;AAC9C,cAAY,EAAE,OAAO,CAAC;AACtB,YAAU;AACV,QAAM,IAAI,YAAY,MAAM;AAC5B,YAAU,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;AAC/B,SAAO;AACT;AAGA,SAAS,YAAY,OAA4B;AAC/C,QAAM,IAAI,WAAW;AACrB,SAAO,OAAO,EAAE,MAAM,KAAK;AAC3B,QAAM,SAAwB,WAAW,KAAK,CAAC;AAC/C,cAAY,EAAE,SAAS,OAAO,OAAO,CAAC,GAAG,OAAO,SAAS,KAAK,EAAE,CAAC;AACjE,YAAU,QAAQ,CAAC,OAAO,GAAG,WAAW,CAAC,CAAC;AAC1C,SAAO,EAAE;AACX;AAGA,SAAS,UAAmB;AAC1B,QAAM,KAAK,WAAW,EAAE,KAAK;AAC7B,YAAU;AACV,QAAM,IAAI,YAAY,EAAE;AACxB,YAAU,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;AAC/B,SAAO;AACT;AAEA,SAAS,UAAU,IAAsC;AAAE,YAAU,IAAI,EAAE;AAAG,SAAO,MAAM,UAAU,OAAO,EAAE;AAAG;AAEjH,SAAS,IAAI,YAAwC;AACnD,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,IAAI,WAAW;AACrB,QAAM,OAAO,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AACjE,SAAO,KAAK,MAAM,CAAC,MAAM,EAAE,YAAY,QAAQ,CAAC,KAAK,CAAC;AACxD;AACA,SAAS,OAAO,aAAgC;AAC9C,QAAM,IAAI,WAAW;AACrB,UAAQ,eAAe,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,YAAY,QAAQ,CAAC,KAAK,CAAC;AACtE;AACA,SAAS,QAAQ,QAAyB;AAAE,SAAO,WAAW,EAAE,KAAK,MAAM,QAAQ,MAAM,KAAK;AAAG;AACjG,SAAS,OAAO,KAAsB;AAAE,SAAO,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG;AAAG;AAI1E,SAAS,SAAS,KAA0B;AAAE,UAAQ,WAAW,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,KAAK;AAAM;AAOvH,SAAS,UAAU,KAA2B;AAC5C,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,IAAI,SAAS,GAAG;AACtB,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,OAAO,GAAG,IAAI,OAAO;AAC9B;AACA,SAAS,UAAU,KAAsB;AAAE,SAAO,UAAU,GAAG,MAAM;AAAO;AAC5E,SAAS,YAAY,KAAsB;AAAE,SAAO,UAAU,GAAG;AAAG;AAGpE,SAAS,SAAS,KAAsB;AAAE,SAAO,UAAU,GAAG;AAAG;AAKjE,SAAS,QAAQ,WAAsF;AACrG,QAAM,QAAS,aAAa,UAAU,UAAW,WAAW,EAAE,YAAY,CAAC;AAK3E,QAAM,aAAc,aAAa,UAAU,eAAgB,MAAM;AACjE,QAAM,QAAuB,MAAM,IAAI,CAAC,MAAmB;AACzD,UAAM,OAAO,CAAC,CAAC,WAAW,EAAE,GAAG;AAM/B,UAAM,OAAO,OAAQ,EAAE,aAAa,EAAE,MAAQ,EAAE,OAAO,EAAE;AACzD,UAAM,aAA6B,EAAE,SAAS,OAAO,OAAO,EAAE,KAAK,IAAI,WAAc,CAAC;AACtF,WAAO;AAAA,MACL,KAAK,EAAE;AAAA,MAAK,OAAO,EAAE;AAAA,MAAO,SAAS,EAAE;AAAA,MAAS,aAAa,EAAE;AAAA,MAC/D,SAAS,EAAE;AAAA,MAAS,QAAQ,EAAE;AAAA,MAAQ,OAAO,EAAE;AAAA,MAAO,WAAW,EAAE,aAAa,CAAC;AAAA,MACjF,QAAQ,EAAE,UAAU;AAAA,MAAM,SAAS,EAAE;AAAA;AAAA,MAErC,OAAO,EAAE;AAAA,MAAO,WAAW,UAAU,QAAQ;AAAA,MAC7C,UAAU,UAAU,OAAO;AAAA,MAC3B,YAAY,UAAU,SAAS;AAAA;AAAA,MAE/B,aAAa;AAAA,MACb,MAAM,QAAQ;AAAA;AAAA,MAEd,cAAc,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE;AAAA,MACrC,QAAQ,OAAO,YAAa,EAAE,UAAU,SAAS;AAAA,IACnD;AAAA,EACF,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI;AAGvB,QAAM,KAAK,CAAC,GAAG,OAAQ,EAAE,SAAS,MAAM,EAAE,SAAS,MAAO,OAAO,EAAE,IAAI,EAAE,cAAc,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC;AAExI,QAAM,YAAY,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW;AACvD,SAAO;AAAA,IACL;AAAA,IAAO,WAAW,YAAY,IAAI,MAAM,SAAS;AAAA,IACjD,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE;AAAA,IAC5C,WAAW,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE;AAAA,EACjD;AACF;AAGA,SAAS,aAAsB;AAC7B,QAAM,CAAC,GAAG,IAAI,IAAU,iBAAkB,UAAU;AACpD,EAAM,kBAAU,MAAM,UAAU,IAAI,GAAG,CAAC,CAAC;AACzC,SAAO;AACT;AAUO,IAAM,aAAa;AAAA,EACxB;AAAA,EAAoB;AAAA,EAAiB;AAAA,EAAO;AAAA,EAAO;AAAA,EACnD;AAAA,EAAa;AAAA,EAAY;AAAA,EAAe;AAAA,EAAa;AAAA,EAAS;AAAA,EAC9D;AAAA,EAAK;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAQ;AAAA,EAC9B;AAAA,EAAU;AAAA,EAAW;AAAA,EAAW;AAAA,EAAa;AAAA,EAAU;AAAA,EACvD;AAAA,EAAc;AAAA,EAAa;AAAA,EAAQ;AACrC;;;AD3oBI,IAAAC,uBAAA;AAlBJ,IAAM,gBAAmC;AAAA,EACvC,EAAE,IAAI,WAAW,OAAO,gBAAgB,MAAM,eAAe,MAAM,8BAA8B;AAAA,EACjG,EAAE,IAAI,eAAe,OAAO,eAAe,MAAM,sBAAsB,MAAM,kCAAkC;AACjH;AAEA,IAAM,sBAAyC;AAAA,EAC7C,EAAE,IAAI,SAAS,OAAO,SAAS,MAAM,eAAe,MAAM,6BAA6B,MAAM,aAAa;AAAA,EAC1G,EAAE,IAAI,SAAS,OAAO,uBAAuB,MAAM,gBAAgB,MAAM,6BAA6B,MAAM,eAAe;AAAA,EAC3H,EAAE,IAAI,SAAS,OAAO,iBAAiB,MAAM,gBAAgB,MAAM,6BAA6B,MAAM,eAAe;AACvH;AAOA,SAAS,KAAK,EAAE,MAAM,OAAO,GAAc;AACzC,SACE;AAAA,IAAC;AAAA;AAAA,MAAO,MAAK;AAAA,MAAS,MAAK;AAAA,MAAW,WAAU;AAAA,MAC9C,SAAS,MAAM,OAAO,IAAI;AAAA,MAC1B;AAAA,sDAAC,OAAE,WAAW,WAAW,KAAK,MAAM,eAAY,QAAO;AAAA,QACvD,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAI,eAAK,OAAM;AAAA,QACrC,KAAK,QAAQ,8CAAC,SAAM,MAAK,WAAW,eAAK,OAAM,IAAW;AAAA;AAAA;AAAA,EAC7D;AAEJ;AAMO,SAAS,YAAY;AAAA,EAC1B,QAAQ;AAAA,EACR,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,GAAG;AACL,GAAqB;AACnB,QAAM,UAAU,WAAW,WAAW;AACtC,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,CAAC,WAAW,YAAY,IAAU,iBAAS,KAAK;AACtD,QAAM,MAAY,eAA0B,IAAI;AAChD,QAAM,OAAO,QAAQ;AAErB,QAAM,eAAe,WAAW,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,WAAW,IAAI,EAAE,IAAI,CAAC;AAC/E,QAAM,OAAO,CAAC,SAA0B;AACtC,YAAQ,KAAK;AACb,QAAI,KAAK,SAAU,QAAO,KAAK,SAAS;AACxC,QAAI,WAAY,QAAO,WAAW,KAAK,MAAM,IAAI;AACjD,QAAI,KAAK,KAAM,QAAO,SAAS,OAAO,KAAK;AAAA,EAC7C;AACA,QAAM,UAAU,MAAM;AACpB,YAAQ,KAAK;AACb,QAAI,UAAW,QAAO,UAAU;AAChC,WAAO,MAAM,8DAAyD;AAAA,EACxE;AAEA,SACE,gFACE;AAAA;AAAA,MAAC;AAAA;AAAA,QAAO,MAAK;AAAA,QAAS;AAAA,QAAU,WAAW,CAAC,mBAAmB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAChG,iBAAc;AAAA,QAAO,iBAAe;AAAA,QAAM,cAAY,oBAAe,KAAK;AAAA,QAC1E,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,QAAI,GAAG;AAAA,QACvC;AAAA,wDAAC,UAAO,MAAM,KAAK,MAAM,MAAK,MAAK;AAAA,UACnC,8CAAC,OAAE,WAAU,oBAAmB,eAAY,QAAO,OAAO,EAAE,UAAU,IAAI,OAAO,oBAAoB,GAAG;AAAA;AAAA;AAAA,IAC1G;AAAA,IACA,8CAAC,WAAQ,MAAY,WAAW,KAAK,SAAS,MAAM,QAAQ,KAAK,GAAG,WAAU,cAAa,OAAO,KAChG,yDAAC,SAAI,MAAK,QAAO,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACpD;AAAA,qDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,SAAS,aAAa,cAAc,0BAA0B,GACtG;AAAA,sDAAC,UAAO,MAAM,KAAK,MAAM;AAAA,QACzB,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,UAAU,GAAG,MAAM,EAAE,GAC/D;AAAA,wDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,YAAY,IAAI,GAAI,eAAK,MAAK;AAAA,UACpE,8CAAC,UAAK,WAAU,sCAAsC,eAAK,OAAM;AAAA,WACnE;AAAA,SACF;AAAA,MAEC,aAAa,QAAQ,MAAM,SAC1B,8CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,SAAS,aAAa,UAAU,QAAQ,cAAc,0BAA0B,GACtH,kBAAQ,MAAM,IAAI,CAAC,MAAM,8CAAC,SAAiB,MAAM,EAAE,OAAO,UAAU,YAAY,WAAY,YAAE,QAAzD,EAAE,EAA4D,CAAQ,GAC9G,IACE;AAAA,MAEJ,8CAAC,SAAI,WAAU,iBACZ,gBAAM,IAAI,CAAC,MAAM,8CAAC,QAAgB,MAAM,GAAG,QAAQ,QAAvB,EAAE,EAA2B,CAAE,GAC9D;AAAA,MAEC,aAAa,SACZ,+CAAC,SAAI,WAAU,iBAAgB,OAAO,EAAE,WAAW,0BAA0B,GAC3E;AAAA,sDAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,SAAS,gBAAgB,SAAS,QAAQ,GAAG,4BAAc;AAAA,QAC1G,aAAa,IAAI,CAAC,MAAM,8CAAC,QAAgB,MAAM,GAAG,QAAQ,QAAvB,EAAE,EAA2B,CAAE;AAAA,SACrE,IACE;AAAA,MAIH,kBACC,+CAAC,SAAI,WAAU,iBAAgB,OAAO,EAAE,WAAW,0BAA0B,GAC3E;AAAA,uDAAC,YAAO,MAAK,UAAS,MAAK,YAAW,WAAU,gBAAe,SAAS,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC,GAClG;AAAA,wDAAC,OAAE,WAAU,qBAAoB,eAAY,QAAO;AAAA,UACpD,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG,oCAAsB;AAAA,UAChD,8CAAC,OAAE,WAAW,kBAAkB,YAAY,OAAO,SAAS,eAAY,QAAO,OAAO,EAAE,UAAU,GAAG,GAAG;AAAA,WAC1G;AAAA,QACC,YACC,8CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,WAAW,KAAK,WAAW,OAAO,GAC1E,kBAAQ,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE,IAAI,CAAC,MAC1D;AAAA,UAAC;AAAA;AAAA,YAAkB,MAAK;AAAA,YAAS,WAAU;AAAA,YAAe,gBAAc,EAAE,OAAO,KAAK,KAAK,SAAS;AAAA,YAClG,SAAS,MAAM;AAAE,yBAAW,cAAc,EAAE,EAAE;AAAG,sBAAQ,KAAK;AAAG,2BAAa,KAAK;AAAA,YAAG;AAAA,YACtF;AAAA,4DAAC,UAAO,MAAM,EAAE,MAAM,MAAK,MAAK;AAAA,cAChC,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,aAAa,GACzF;AAAA,8DAAC,UAAK,OAAO,EAAE,YAAY,EAAE,OAAO,KAAK,KAAK,MAAM,IAAI,GAAI,YAAE,MAAK;AAAA,gBACnE,8CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,UAAU,KAAK,GAAI,YAAE,MAAM,KAAK,IAAI,GAAE;AAAA,iBAC5E;AAAA,cACC,EAAE,OAAO,KAAK,KAAK,8CAAC,OAAE,WAAU,eAAc,eAAY,QAAO,OAAO,EAAE,OAAO,iBAAiB,GAAG,IAAK;AAAA;AAAA;AAAA,UAPhG,EAAE;AAAA,QAQf,CACD,GACH,IACE;AAAA,SACN,IACE;AAAA,MAEJ,8CAAC,SAAI,WAAU,iBAAgB,OAAO,EAAE,WAAW,0BAA0B,GAC3E,yDAAC,YAAO,MAAK,UAAS,MAAK,YAAW,WAAU,gBAAe,eAAY,QAAO,SAAS,SACzF;AAAA,sDAAC,OAAE,WAAU,kBAAiB,eAAY,QAAO;AAAA,QACjD,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG,sBAAQ;AAAA,SACpC,GACF;AAAA,OACF,GACF;AAAA,KACF;AAEJ;;;AExKA,IAAAC,UAAuB;AAmEd,IAAAC,uBAAA;AAHT,IAAM,cAAyE,EAAE,KAAK,WAAW,MAAM,QAAQ,OAAO,WAAW,KAAK,WAAW,QAAQ,SAAS;AAE3J,SAAS,KAAK,EAAE,IAAI,GAAqB;AAC9C,SAAO,8CAAC,SAAI,WAAU,WAAW,eAAK,UAAU,KAAK,MAAM,CAAC,GAAE;AAChE;AASA,SAAS,SAAS,EAAE,GAAG,UAAU,GAAkB;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAqB,IAAI;AACzD,QAAM,MAAM,YAAY;AACtB,aAAS,MAAM;AACf,UAAM,MAAM,OAAO,eAAe,MAAM,IAAI;AAC5C,QAAI;AACF,YAAM,OAAO,MAAM,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,IAAI,CAAC,EAAE;AAC1F,eAAS,EAAE,IAAI,KAAK,OAAO,OAAO,eAAe,MAAM,IAAI,IAAI,EAAE,GAAG,KAAK,CAAC;AAAA,IAC5E,SAAS,GAAG;AACV,eAAS,EAAE,IAAI,KAAK,OAAO,OAAO,eAAe,MAAM,IAAI,IAAI,EAAE,GAAG,OAAO,OAAQ,KAAc,EAAU,WAAW,CAAC,EAAE,CAAC;AAAA,IAC5H;AAAA,EACF;AACA,SACE,8CAAC,QAAK,WAAU,QAAO,QAAQ,OAC7B,yDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACxC;AAAA,mDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,SAAS,aAAa,UAAU,OAAO,GAC/E;AAAA,oDAAC,SAAM,MAAM,YAAY,EAAE,MAAM,KAAK,WAAY,YAAE,QAAO;AAAA,MAC3D,8CAAC,UAAK,WAAU,WAAU,OAAO,EAAE,UAAU,MAAM,YAAY,KAAK,OAAO,eAAe,WAAW,YAAY,GAAI,YAAE,MAAK;AAAA,MAC3H,EAAE,SAAS,8CAAC,SAAM,MAAK,WAAU,MAAK,QAAO,wBAAU,IAAW;AAAA,MACnE,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,MAC1B,+CAAC,UAAK,WAAU,+BAA+B;AAAA,UAAE,QAAQ,CAAC;AAAA,QAAE;AAAA,QAAE,EAAE,QAAQ,CAAC;AAAA,QAAE;AAAA,SAAE;AAAA,MAC7E,8CAAC,UAAO,MAAK,MAAK,SAAQ,aAAY,MAAK,QAAO,SAAS,UAAU,QAAQ,SAAS,KAAK,oBAAM;AAAA,OACnG;AAAA,IACA,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,IAAI,SAAS,cAAc,GACjE;AAAA,qDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACxC;AAAA,sDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,YAAY,IAAI,GAAI,YAAE,OAAM;AAAA,QAClE,8CAAC,OAAE,WAAU,2BAA0B,OAAO,EAAE,QAAQ,GAAG,UAAU,SAAS,GAAI,YAAE,SAAQ;AAAA,QAC3F,EAAE,UAAU,EAAE,OAAO,SACpB,8CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,OAAO,GAAI,YAAE,OAAO,IAAI,CAAC,MAAM,8CAAC,OAAa,eAAJ,CAAM,CAAM,GAAE,IACzG;AAAA,SACN;AAAA,MACA,+CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,sCAAsC,KAAK,IAAI,YAAY,QAAQ,GACpH;AAAA,UAAE,UAAU,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GAAG;AAAA,wDAAC,UAAK,WAAU,wBAAuB,0BAAY;AAAA,UAAO,8CAAC,QAAK,KAAK,EAAE,SAAS;AAAA,WAAE,IAAS;AAAA,QACpJ,EAAE,QAAQ,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GAAG;AAAA,wDAAC,UAAK,WAAU,wBAAuB,mBAAK;AAAA,UAAO,8CAAC,QAAK,KAAK,EAAE,OAAO;AAAA,WAAE,IAAS;AAAA,QAC1I,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GAAG;AAAA,wDAAC,UAAK,WAAU,wBAAuB,0BAAY;AAAA,UAAO,8CAAC,QAAK,KAAK,EAAE,UAAU;AAAA,WAAE;AAAA,SAClI;AAAA,MACC,EAAE,QAAQ,8CAAC,QAAK,MAAK,QAAO,WAAU,uBAAsB,MAAM,EAAE,OAAO,SAAS,MAAM,IAAK;AAAA,MAC/F,SAAS,UAAU,SAClB,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACxC;AAAA,uDAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,EAAE,GACvC;AAAA,wDAAC,UAAK,WAAU,wBAAuB,gCAAkB;AAAA,UACzD,+CAAC,SAAM,MAAM,MAAM,QAAQ,WAAW,WAAW,MAAK,SAAS;AAAA,kBAAM;AAAA,YAAG;AAAA,aAAE;AAAA,WAC5E;AAAA,QACA,8CAAC,QAAK,KAAK,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,MAAM,MAAM;AAAA,SAChE,IACE;AAAA,OACN;AAAA,KACF,GACF;AAEJ;AAGO,SAAS,eAAe;AAAA,EAC7B,OAAO,CAAC;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,GAAwB;AACtB,QAAM,CAAC,GAAG,IAAI,IAAU,iBAAS,EAAE;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAU,iBAAwB,IAAI;AAC9D,QAAM,CAAC,KAAK,MAAM,IAAU,iBAAwB,IAAI;AACxD,QAAM,CAAC,UAAU,WAAW,IAAU,iBAAS,KAAK;AAEpD,QAAM,eAAe,WAAW,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG;AAChE,QAAM,OAAO,KAAK,OAAO,CAAC,OACvB,CAAC,UAAU,EAAE,WAAW,YACxB,CAAC,YAAY,EAAE,YACf,CAAC,gBAAgB,aAAa,UAAU,QAAQ,EAAE,EAAE,KAAK,OACzD,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,QAAQ,MAAM,EAAE,UAAU,OAAO,EAAE,UAAU,CAAC,GAAG,KAAK,GAAG,GAAG,YAAY,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE;AAE/H,QAAM,YAAuC,UAAU,OAAO,SAC1D,SACA,CAAC,CAAC,iBAAiB,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC7C,QAAM,UAAU,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtD,QAAM,YAAY,KAAK,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AAE/C,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,IAAI,UAAU,KAAK,GAAI,GAAG,MACzG;AAAA,mDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACxC;AAAA,eAAS,8CAAC,UAAK,WAAU,wBAAwB,kBAAO,IAAU;AAAA,MACnE,8CAAC,QAAG,WAAU,SAAQ,OAAO,EAAE,QAAQ,EAAE,GAAI,iBAAM;AAAA,MAClD,OAAO,8CAAC,OAAE,WAAU,iCAAgC,OAAO,EAAE,QAAQ,EAAE,GAAI,gBAAK,IAAO;AAAA,OAC1F;AAAA,IAEC,WAAW,QAAQ,SAClB,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACxC;AAAA,oDAAC,UAAK,WAAU,wBAAuB,2EAAwD;AAAA,MAC/F,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,OAAO,GACxD;AAAA,uDAAC,OAAI,MAAK,SAAQ,UAAU,CAAC,KAAK,SAAS,MAAM,OAAO,IAAI,GAAG;AAAA;AAAA,UAAY,8CAAC,UAAK,WAAU,WAAW,eAAK,QAAO;AAAA,WAAO;AAAA,QACxH,QAAQ,IAAI,CAAC,MACZ,+CAAC,OAAe,MAAM,EAAE,MAAM,UAAU,QAAQ,EAAE,IAAI,SAAS,MAAM,OAAO,QAAQ,EAAE,KAAK,OAAO,EAAE,EAAE,GACnG;AAAA,YAAE;AAAA,UAAM;AAAA,UAAC,8CAAC,UAAK,WAAU,WAAW,YAAE,UAAU,QAAO;AAAA,aADhD,EAAE,EAEZ,CACD;AAAA,SACH;AAAA,MAGC,eACC;AAAA,QAAC;AAAA;AAAA,UAAK,MAAK;AAAA,UAAO,WAAW,aAAa,QAAQ,YAAY,aAAa,UAAU,SAAS;AAAA,UAC5F,MAAM,4CAA4C,aAAa,UAAU,KAAK,IAAI,IAAI;AAAA,UACtF,SAAS,8CAAC,UAAO,MAAK,MAAK,SAAQ,SAAQ,MAAK,KAAI,SAAS,MAAM,OAAO,IAAI,GAAG,8BAAgB;AAAA;AAAA,MAAW,IAC5G;AAAA,OACN,IACE;AAAA,IAEH,aAAa,8CAAC,QAAK,MAAK,QAAO,WAAU,wCAAuC,MAAM,YAAY,SAAS,MAAM,IAAK;AAAA,IAEvH,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,UAAU,OAAO,GACzD;AAAA,oDAAC,SAAM,MAAK,oBAAmB,aAAY,yCAAwC,OAAO,GAAG,UAAU,CAAC,MAAM,KAAK,EAAE,OAAO,KAAK,GAAG,OAAO,EAAE,OAAO,IAAI,GAAG;AAAA,MAC1J,QAAQ,IAAI,CAAC,MACZ,+CAAC,OAAY,UAAU,WAAW,GAAG,SAAS,MAAM,UAAU,WAAW,IAAI,OAAO,CAAC,GAClF;AAAA;AAAA,QAAE;AAAA,QAAC,8CAAC,UAAK,WAAU,WAAW,eAAK,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,QAAO;AAAA,WADjE,CAEV,CACD;AAAA,MACA,YACC,+CAAC,OAAI,MAAK,QAAO,UAAU,UAAU,SAAS,MAAM,YAAY,CAAC,QAAQ,GAAG;AAAA;AAAA,QAC9D,8CAAC,UAAK,WAAU,WAAW,qBAAU;AAAA,SACnD,IACE;AAAA,MACJ,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,MAC1B,+CAAC,UAAK,WAAU,uBAAuB;AAAA,aAAK;AAAA,QAAO;AAAA,QAAK,KAAK;AAAA,QAAO;AAAA,QAAW,YAAY,WAAQ,YAAY,WAAW;AAAA,SAAG;AAAA,OAC/H;AAAA,IAEC,KAAK,WAAW,IACf,8CAAC,QAAK,WAAU,QAAO,wDAAC,OAAE,WAAU,uBAAsB,OAAO,EAAE,QAAQ,EAAE,GAAG,gDAAkC,GAAI,IACpH,UAAU,IAAI,CAAC,CAAC,GAAG,GAAG,MAAM;AAC9B,YAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,IAAI,QAAQ,EAAE,EAAE,KAAK,CAAC;AACvD,UAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,aACE,+CAAC,SAAY,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACjD;AAAA,sDAAC,UAAK,WAAU,eAAe,aAAE;AAAA,QAChC,MAAM,IAAI,CAAC,MAAM,8CAAC,YAAoB,GAAM,aAAZ,EAAE,EAAgC,CAAE;AAAA,WAF7D,CAGV;AAAA,IAEJ,CAAC;AAAA,IAEA,eAAe,YAAY,SAC1B,8CAAC,QAAK,OAAM,6BAA4B,WAAU,QAChD,wDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACxC,sBAAY,IAAI,CAAC,CAAC,GAAG,CAAC,MACrB,+CAAC,SAAY,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,YAAY,aAAa,GACzE;AAAA,oDAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,OAAO,KAAK,MAAM,QAAQ,YAAY,EAAE,GAAI,aAAE;AAAA,MAC9F,8CAAC,UAAK,WAAU,2BAA0B,OAAO,EAAE,UAAU,SAAS,GAAI,aAAE;AAAA,SAFpE,CAGV,CACD,GACH,GACF,IACE;AAAA,IAEH,iBAAiB,cAAc,SAC9B,8CAAC,eAAY,MAAK,eAAc,OAAM,wCAAuC,UAAU,cAAc,SAAS,eAC5G,wDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACvC,wBAAc,IAAI,CAAC,CAAC,IAAI,UAAU,GAAG,MACpC,+CAAC,SAAa,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,YAAY,cAAc,SAAS,SAAS,WAAW,0BAA0B,GAClI;AAAA,oDAAC,SAAM,MAAK,UAAU,cAAG;AAAA,MACzB,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,MAAM,EAAE,GAClD;AAAA,sDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,YAAY,IAAI,GAAI,oBAAS;AAAA,QACnE,8CAAC,UAAK,WAAU,uBAAuB,eAAI;AAAA,SAC7C;AAAA,SALQ,EAMV,CACD,GACH,GACF,IACE;AAAA,KACN;AAEJ;;;AC5PA,IAAAC,UAAuB;AAoFjB,IAAAC,uBAAA;AAjDN,IAAM,YAAY,CAAC,oBAAoB,mBAAmB,kBAAkB,uBAAuB,qBAAqB,oBAAoB,iBAAiB,eAAe;AAC5K,IAAM,SAAS;AAAA,EACb,EAAE,KAAK,cAAc,OAAO,4BAA4B,QAAQ,6CAA6C;AAAA,EAC7G,EAAE,KAAK,eAAe,OAAO,wBAAwB,QAAQ,2CAA2C;AAAA,EACxG,EAAE,KAAK,cAAc,OAAO,yCAAyC,QAAQ,8CAA8C;AAAA,EAC3H,EAAE,KAAK,eAAe,OAAO,uCAAuC,QAAQ,yCAAyC;AAAA,EACrH,EAAE,KAAK,UAAU,OAAO,iBAAiB,QAAQ,mCAAmC;AACtF;AAWO,SAAS,YAAY,EAAE,MAAM,UAAU,QAAQ,YAAY,UAAU,eAAe,MAAM,YAAY,IAAI,GAAG,KAAK,GAAqB;AAC5I,QAAM,UAAU,WAAW,WAAW;AACtC,QAAM,OAAO,YAAY,QAAQ;AACjC,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAuB,OAAO;AAAA,IAC5D,MAAM,KAAK,QAAQ;AAAA,IAAI,OAAO,KAAK,SAAS;AAAA,IAAI,OAAO,KAAK,SAAS;AAAA,IACrE,OAAO,KAAK,SAAS;AAAA,IAAI,UAAU,KAAK,YAAY,UAAU,CAAC;AAAA,IAC/D,KAAK,KAAK,OAAO;AAAA,IAAI,QAAQ,KAAK,UAAU,EAAE,YAAY,MAAM,aAAa,MAAM,YAAY,MAAM,aAAa,OAAO,QAAQ,KAAK;AAAA,EACxI,EAAE;AACF,QAAM,CAAC,QAAQ,SAAS,IAAU,iBAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAS,KAAK;AAC9C,QAAM,MAAM,CAA+B,GAAM,MAAuB;AAAE,aAAS,CAAC,MAAM,OAAO,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;AAAG,aAAS,KAAK;AAAA,EAAG;AAC9I,QAAM,YAAY,CAAC,MAAc;AAAE,aAAS,CAAC,MAAM,OAAO,OAAO,CAAC,GAAG,GAAG,EAAE,QAAQ,OAAO,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAAG,aAAS,KAAK;AAAA,EAAG;AAE3J,QAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,OAAO,MAAM,WAAW,KAAK,SAAS,OAC/E,MAAM,WAAW,KAAK,SAAS,OAAO,MAAM,cAAc,KAAK,YAAY,UAAU,CAAC,MACtF,MAAM,SAAS,KAAK,OAAO,OAAO,KAAK,UAAU,MAAM,MAAM,MAAM,KAAK,UAAU,KAAK,UAAU,EAAE,YAAY,MAAM,aAAa,MAAM,YAAY,MAAM,aAAa,OAAO,QAAQ,KAAK,CAAC;AAE9L,QAAM,OAAO,YAAY;AACvB,cAAU,IAAI;AACd,QAAI,OAAQ,OAAM,OAAO,KAAK;AAAA,QAAQ,YAAW,YAAY,KAAK;AAClE,cAAU,KAAK;AAAG,aAAS,IAAI;AAAA,EACjC;AAEA,QAAM,eAAgC,YAAY;AAAA,IAChD,EAAE,IAAI,MAAM,QAAQ,2BAAwB,OAAO,cAAc,MAAM,cAAc,SAAS,KAAK;AAAA,IACnG,EAAE,IAAI,MAAM,QAAQ,yBAAsB,OAAO,cAAc,MAAM,cAAc;AAAA,IACnF,EAAE,IAAI,MAAM,QAAQ,qBAAkB,OAAO,eAAe,MAAM,SAAS;AAAA,EAC7E;AAEA,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,IAAI,UAAU,IAAI,GAAI,GAAG,MACxG;AAAA,mDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACzC;AAAA,oDAAC,UAAK,WAAU,wBAAuB,qBAAO;AAAA,MAC9C,8CAAC,QAAG,WAAU,SAAQ,OAAO,EAAE,QAAQ,EAAE,GAAG,0BAAY;AAAA,MACxD,8CAAC,OAAE,WAAU,iCAAgC,OAAO,EAAE,QAAQ,EAAE,GAAG,wGAEnE;AAAA,OACF;AAAA,IAEA,8CAAC,QAAK,WAAU,QACd,yDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,UAAU,QAAQ,YAAY,aAAa,GACnF;AAAA,oDAAC,UAAO,MAAM,MAAM,QAAQ,KAAK,MAAM,MAAK,MAAK;AAAA,MACjD,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,IAAI,GAChE;AAAA,sDAAC,UAAK,WAAU,SAAQ,OAAO,EAAE,QAAQ,EAAE,GAAI,gBAAM,QAAQ,KAAK,MAAK;AAAA,QACvE,+CAAC,UAAK,WAAU,uBAAuB;AAAA,gBAAM,SAAS;AAAA,UAAe;AAAA,UAAI,KAAK,QAAQ;AAAA,WAAU;AAAA,QAChG,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,QAAQ,YAAY,EAAE,GACvE;AAAA,kBAAQ,MAAM,IAAI,CAAC,MAAM,8CAAC,SAAiB,MAAM,EAAE,OAAO,UAAU,YAAY,WAAY,YAAE,QAAzD,EAAE,EAA4D,CAAQ;AAAA,UAC3G,KAAK,MAAM,8CAAC,SAAM,MAAK,QAAO,MAAK,gBAAe,iBAAG,IAAW;AAAA,WACnE;AAAA,SACF;AAAA,MACA,8CAAC,UAAO,SAAQ,aAAY,MAAK,MAAK,MAAK,SAAQ,0BAAY;AAAA,OACjE,GACF;AAAA,IAIA;AAAA,MAAC;AAAA;AAAA,QACC,OACE,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACzC;AAAA,wDAAC,UAAK,sBAAQ;AAAA,UACd,8CAAC,UAAK,WAAU,uBAAsB,OAAO,EAAE,YAAY,IAAI,GAAG,sDAAwC;AAAA,WAC5G;AAAA,QAEF,WAAU;AAAA,QACV,yDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACzC;AAAA,yDAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,sCAAsC,KAAK,GAAG,GAChG;AAAA,0DAAC,SAAM,OAAM,aAAY,OAAO,MAAM,MAAM,UAAU,CAAC,MAAM,IAAI,QAAQ,EAAE,OAAO,KAAK,GAAG;AAAA,YAC1F,8CAAC,SAAM,OAAM,aAAY,OAAO,MAAM,OAAO,UAAU,CAAC,MAAM,IAAI,SAAS,EAAE,OAAO,KAAK,GAAG,aAAY,6BAA4B;AAAA,aACtI;AAAA,UACA,+CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,sCAAsC,KAAK,GAAG,GAChG;AAAA;AAAA,cAAC;AAAA;AAAA,gBAAM,OAAM;AAAA,gBAAa,OAAO,MAAM;AAAA,gBAAO,UAAQ;AAAA,gBAAC,UAAQ;AAAA,gBAC7D,MAAM,KAAK,MAAM,8DAAyD;AAAA;AAAA,YAA4C;AAAA,YACxH,8CAAC,SAAM,OAAM,SAAQ,OAAO,MAAM,OAAO,UAAU,CAAC,MAAM,IAAI,SAAS,EAAE,OAAO,KAAK,GAAG,aAAY,YAAW;AAAA,aACjH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cAAS,OAAM;AAAA,cAAY,OAAO,MAAM;AAAA,cAAK,UAAU,CAAC,MAAM,IAAI,OAAO,EAAE,OAAO,KAAK;AAAA,cAAG,MAAM;AAAA,cAC/F,aAAY;AAAA,cACZ,MAAK;AAAA;AAAA,UAA0B;AAAA,WACnC;AAAA;AAAA,IACF;AAAA,IAEA,8CAAC,QAAK,OAAM,uBAAsB,WAAU,QAC1C,yDAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,sCAAsC,KAAK,GAAG,GAChG;AAAA;AAAA,QAAC;AAAA;AAAA,UAAO,OAAM;AAAA,UAAY,OAAO,MAAM;AAAA,UAAU,UAAU,CAAC,MAAM,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,UAAG,SAAS;AAAA,UAC1G,MAAK;AAAA;AAAA,MAAkD;AAAA,MACzD,8CAAC,UAAO,OAAM,iBAAgB,SAAS,CAAC,UAAU,QAAQ,GAAG,aAAY,UAAS;AAAA,OACpF,GACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OACE,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACzC;AAAA,wDAAC,UAAK,2BAAa;AAAA,UACnB,8CAAC,UAAK,WAAU,uBAAsB,OAAO,EAAE,YAAY,IAAI,GAAG,+EAA4D;AAAA,WAChI;AAAA,QAEF,WAAU;AAAA,QACV,wDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACxC,iBAAO,IAAI,CAAC,MACX,8CAAC,UAAmB,SAAS,CAAC,CAAC,MAAM,OAAO,EAAE,GAAG,GAAG,UAAU,MAAM,UAAU,EAAE,GAAG,GAAG,OAAO,EAAE,OAAO,aAAa,EAAE,UAAxG,EAAE,GAA8G,CAC9H,GACH;AAAA;AAAA,IACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OACE,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACzC;AAAA,wDAAC,UAAK,oBAAM;AAAA,UACZ,8CAAC,UAAK,WAAU,uBAAsB,OAAO,EAAE,YAAY,IAAI,GAAG,uCAAyB;AAAA,WAC7F;AAAA,QAEF,WAAU;AAAA,QACV,QAAQ;AAAA,UAAC;AAAA;AAAA,YAAO,MAAK;AAAA,YAAK,SAAQ;AAAA,YAAQ,MAAK;AAAA,YAC7C,SAAS,MAAM,cAAc,WAAW,QAAQ;AAAA,YAAG;AAAA;AAAA,QAAoB;AAAA,QACzE;AAAA,yDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACxC;AAAA,0DAAC,WAAQ,OAAM,SAAS,kBAAQ,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,QAAO;AAAA,YAC9E,+CAAC,WAAQ,OAAM,eAAe;AAAA,sBAAQ,YAAY;AAAA,cAAO;AAAA,eAAQ;AAAA,YACjE,8CAAC,WAAQ,OAAM,gBAAgB,eAAK,UAAU,UAAI;AAAA,aACpD;AAAA,UACA,8CAAC,OAAE,WAAU,uBAAsB,OAAO,EAAE,QAAQ,WAAW,GAAG,wIAElE;AAAA;AAAA;AAAA,IACF;AAAA,IAEC,eACC;AAAA,MAAC;AAAA;AAAA,QAAK,OAAM;AAAA,QAAoB,WAAU;AAAA,QACxC,QAAQ,8CAAC,UAAO,MAAK,MAAK,SAAQ,SAAQ,MAAK,YAAW,iCAAmB;AAAA,QAC7E,wDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACvC,uBAAa,IAAI,CAAC,MACjB,+CAAC,SAAe,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,SAAS,UAAU,WAAW,2BAA2B,UAAU,OAAO,GAC7H;AAAA,wDAAC,OAAE,WAAU,uBAAsB,OAAO,EAAE,UAAU,IAAI,OAAO,oBAAoB,GAAG,eAAY,QAAO;AAAA,UAC3G,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,IAAI,GACjE;AAAA,0DAAC,UAAK,WAAU,cAAa,OAAO,EAAE,YAAY,IAAI,GAAI,YAAE,QAAO;AAAA,YACnE,+CAAC,UAAK,WAAU,uBAAuB;AAAA,gBAAE;AAAA,cAAM;AAAA,cAAI,EAAE;AAAA,eAAK;AAAA,aAC5D;AAAA,UACC,EAAE,UAAU,8CAAC,SAAM,MAAK,WAAU,KAAG,MAAC,yBAAW,IAAW,8CAAC,UAAO,MAAK,MAAK,SAAQ,SAAQ,oBAAM;AAAA,aAN7F,EAAE,EAOZ,CACD,GACH;AAAA;AAAA,IACF,IACE;AAAA,IAEJ,+CAAC,SAAI,WAAU,UAAS,OAAO;AAAA,MAAE,KAAK;AAAA,MAAI,UAAU;AAAA,MAAQ,UAAU;AAAA,MAAU,QAAQ;AAAA,MAAG,SAAS;AAAA,MAClG,cAAc;AAAA,MAAI,YAAY;AAAA,MAAkB,QAAQ;AAAA,MAA2B,WAAW;AAAA,IAAiC,GAC/H;AAAA,oDAAC,UAAK,WAAU,cAAa,OAAO,EAAE,YAAY,KAAK,MAAM,EAAE,GAC5D,kBAAQ,WAAW,QAAQ,oBAAoB,sBAClD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAK,SAAQ;AAAA,UAAQ,UAAU,CAAC,SAAS;AAAA,UACpD,SAAS,MAAM;AAAE,qBAAS,EAAE,MAAM,KAAK,QAAQ,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,IAAI,UAAU,KAAK,YAAY,UAAU,CAAC,GAAG,KAAK,KAAK,OAAO,IAAI,QAAQ,KAAK,UAAU,EAAE,YAAY,MAAM,aAAa,MAAM,YAAY,MAAM,aAAa,OAAO,QAAQ,KAAK,EAAE,CAAC;AAAG,qBAAS,KAAK;AAAA,UAAG;AAAA,UAAG;AAAA;AAAA,MAEzU;AAAA,MACA,8CAAC,UAAO,MAAK,MAAK,MAAK,SAAQ,UAAU,CAAC,OAAO,SAAS,QAAQ,SAAS,MAAM,0BAAY;AAAA,OAC/F;AAAA,KACF;AAEJ;;;AC/MA,IAAAC,UAAuB;;;ACAvB,IAAAC,UAAuB;AAmDvB,IAAM,kBAA4B;AAAA;AAAA;AAGlC;AAEA,IAAM,cAAwB;AAAA;AAAA,EAE5B;AAAA,EAAmB;AAAA,EAAqB;AAC1C;AAKA,IAAM,gBAA0C;AAAA;AAAA,EAE9C,iBAAiB,CAAC,cAAc;AAAA,EAChC,sBAAsB,CAAC,aAAa;AAAA,EACpC,iBAAiB,CAAC,gBAAgB,gBAAgB,gBAAgB,cAAc;AAAA,EAChF,sBAAsB,CAAC,eAAe,oBAAoB,iBAAiB,iBAAiB,oBAAoB;AAAA,EAChH,kBAAkB,CAAC,oBAAoB,0BAA0B,wBAAwB,mBAAmB;AAAA,EAC5G,iBAAiB,CAAC,YAAY;AAAA;AAAA,EAG9B,oBAAoB,CAAC,UAAU;AAAA,EAC/B,0BAA0B,CAAC,UAAU;AAAA,EACrC,kCAAkC,CAAC,UAAU;AAAA,EAC7C,kBAAkB,CAAC,UAAU;AAAA,EAC7B,yBAAyB,CAAC,YAAY;AAAA,EACtC,mBAAmB,CAAC,cAAc;AAAA,EAClC,sBAAsB,CAAC,sBAAsB,mBAAmB;AAAA,EAChE,wBAAwB,CAAC,gBAAgB,iBAAiB;AAAA,EAC1D,+BAA+B,CAAC,iBAAiB;AAAA,EACjD,yBAAyB,CAAC,iBAAiB;AAAA,EAC3C,wBAAwB,CAAC,4BAA4B;AAAA,EACrD,sBAAsB,CAAC,iBAAiB;AAAA,EACxC,yBAAyB,CAAC,2BAA2B,iBAAiB;AAAA,EACtE,sBAAsB,CAAC,YAAY;AAAA,EACnC,oBAAoB,CAAC,mBAAmB;AAAA,EACxC,wBAAwB,CAAC,cAAc;AAAA,EACvC,mBAAmB,CAAC,iBAAiB;AAAA,EACrC,qBAAqB,CAAC,iBAAiB;AAAA,EACvC,oBAAoB,CAAC,eAAe;AAAA,EACpC,qBAAqB,CAAC,kBAAkB;AAAA,EACxC,eAAe,CAAC,gBAAgB,YAAY;AAAA,EAC5C,mBAAmB,CAAC,cAAc;AAAA,EAClC,uBAAuB,CAAC,eAAe;AAAA,EACvC,qBAAqB,CAAC,kBAAkB,kBAAkB;AAAA,EAC1D,2BAA2B,CAAC,mBAAmB;AAAA,EAC/C,6BAA6B,CAAC,oBAAoB,kBAAkB;AAAA,EACpE,oBAAoB,CAAC,eAAe;AAAA,EACpC,uBAAuB,CAAC,eAAe;AAAA,EACvC,0BAA0B,CAAC,kBAAkB;AAAA,EAC7C,2BAA2B,CAAC,cAAc,iBAAiB,cAAc;AAAA,EACzE,6BAA6B,CAAC,iBAAiB;AAAA;AAAA,EAG/C,kBAAkB,CAAC,UAAU;AAAA,EAC7B,sBAAsB,CAAC,aAAa;AAAA,EACpC,qBAAqB,CAAC,YAAY;AAAA,EAClC,sBAAsB,CAAC,aAAa;AAAA,EACpC,yBAAyB,CAAC,aAAa;AAAA,EACvC,8BAA8B,CAAC,qBAAqB;AAAA,EACpD,iCAAiC,CAAC,aAAa;AAAA,EAC/C,sBAAsB,CAAC,cAAc,gBAAgB,gBAAgB,cAAc;AAAA;AAAA,EAGnF,qBAAqB,CAAC,sBAAsB,oBAAoB,eAAe,gBAAgB;AAAA,EAC/F,0BAA0B,CAAC,oBAAoB,WAAW;AAAA,EAC1D,4BAA4B,CAAC,oBAAoB,qBAAqB,mBAAmB;AAAA,EACzF,mBAAmB,CAAC,sBAAsB,kBAAkB;AAAA,EAC5D,oBAAoB,CAAC,uBAAuB;AAAA;AAAA,EAG5C,eAAe,CAAC,YAAY;AAAA,EAC5B,eAAe,CAAC,cAAc,kBAAkB;AAAA,EAChD,eAAe,CAAC,YAAY;AAAA,EAC5B,eAAe,CAAC,YAAY;AAAA,EAC5B,oBAAoB,CAAC,cAAc;AAAA,EACnC,wBAAwB,CAAC,cAAc;AAAA,EACvC,oBAAoB,CAAC,gBAAgB,gBAAgB,cAAc;AAAA,EACnE,uBAAuB,CAAC,gBAAgB,gBAAgB;AAAA,EACxD,qBAAqB,CAAC,cAAc;AAAA;AAAA,EAGpC,2BAA2B,CAAC,UAAU;AAAA,EACtC,yBAAyB,CAAC,UAAU;AACtC;AAEA,IAAM,aAAa;AACnB,IAAMC,aAAY,oBAAI,IAAqC;AAC3D,IAAI,QAAkC,CAAC;AAEvC,SAAS,OAAwB;AAC/B,MAAI;AACF,UAAM,IAAI,aAAa,QAAQ,UAAU;AACzC,WAAO,MAAM,UAAU,MAAM,SAAS,IAAI;AAAA,EAC5C,QAAQ;AAAE,WAAO;AAAA,EAAQ;AAC3B;AACA,SAAS,OAAa;AAAE,EAAAA,WAAU,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;AAAG;AAE7D,IAAI,OAAwB,KAAK;AAE1B,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA,QAAQ,KAAqC;AAAE,YAAQ,OAAO,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC;AAAA,EAAG;AAAA,EAC5F,QAAQ,KAAuB;AAAE,WAAO,MAAM,GAAG,KAAK,CAAC;AAAA,EAAG;AAAA;AAAA,EAE1D,WAAqB;AAAE,WAAO,OAAO,KAAK,KAAK;AAAA,EAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlD,cAAc,KAAqB;AACjC,KAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO;AAAE,UAAI,gBAAgB,QAAQ,EAAE,IAAI,EAAG,iBAAgB,KAAK,EAAE;AAAA,IAAG,CAAC;AAAA,EAChG;AAAA,EAEA,gBAAgB,IAAqB;AAAE,WAAO,gBAAgB,QAAQ,EAAE,KAAK;AAAA,EAAG;AAAA;AAAA,EAGhF,OAAO,KAA4B;AACjC,QAAI,YAAY,QAAQ,GAAG,KAAK,EAAG,QAAO,EAAE,UAAU,MAAM,YAAY,MAAM,SAAS,CAAC,EAAE;AAC1F,UAAM,MAAM,MAAM,GAAG;AAGrB,QAAI,CAAC,OAAO,CAAC,IAAI,OAAQ,QAAO,EAAE,UAAU,OAAO,YAAY,MAAM,SAAS,CAAC,EAAE;AACjF,UAAM,UAAU,IAAI,OAAO,CAAC,OAAO,gBAAgB,QAAQ,EAAE,IAAI,CAAC;AAClE,WAAO,EAAE,UAAU,QAAQ,WAAW,GAAG,QAAiB;AAAA,EAC5D;AAAA,EACA,WAAW,KAAsB;AAAE,WAAO,WAAW,OAAO,GAAG,EAAE;AAAA,EAAU;AAAA,EAE3E,UAA2B;AAAE,WAAO;AAAA,EAAM;AAAA,EAC1C,SAAkB;AAAE,WAAO,SAAS;AAAA,EAAQ;AAAA,EAC5C,QAAQ,MAA6B;AACnC,UAAM,IAAqB,SAAS,SAAS,SAAS;AACtD,QAAI,MAAM,KAAM;AAChB,WAAO;AACP,QAAI;AAAE,mBAAa,QAAQ,YAAY,CAAC;AAAA,IAAG,QAAQ;AAAA,IAAqB;AACxE,SAAK;AAAA,EACP;AAAA,EACA,UAAU,IAAiD;AAAE,IAAAA,WAAU,IAAI,EAAE;AAAG,WAAO,MAAMA,WAAU,OAAO,EAAE;AAAA,EAAG;AAAA;AAAA,EAGnH,UAA0B;AACxB,UAAM,OAAO,OAAO,KAAK,KAAK,EAAE,OAAO,YAAY,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3E,QAAI,WAAW;AACf,SAAK,QAAQ,CAAC,MAAM;AAAE,UAAI,WAAW,WAAW,CAAC,EAAG;AAAA,IAAY,CAAC;AACjE,WAAO;AAAA,MAAE,OAAO,KAAK;AAAA,MAAQ;AAAA,MAAoB,YAAY,KAAK,SAAS;AAAA,MAClE,gBAAgB,gBAAgB;AAAA,IAAO;AAAA,EAClD;AACF;AAEA,WAAW,QAAQ,aAAa;AAEzB,SAAS,iBAAkC;AAChD,QAAM,CAAC,GAAG,IAAI,IAAU,iBAA0B,WAAW,QAAQ,CAAC;AACtE,EAAM,kBAAU,MAAM,WAAW,UAAU,IAAI,GAAG,CAAC,CAAC;AACpD,SAAO;AACT;AAEO,SAAS,iBAAiB,KAA2E;AAC1G,QAAM,IAAI,eAAe;AACzB,QAAM,KAAK,WAAW,OAAO,GAAG;AAChC,SAAO;AAAA,IAAE,MAAM;AAAA,IAAG,UAAU,GAAG;AAAA,IAAU,SAAS,GAAG;AAAA,IAAS,YAAY,CAAC,CAAC,GAAG;AAAA,IACtE,YAAY,CAAC,CAAC,GAAG;AAAA,IAAY,UAAU,MAAM,UAAU,CAAC,GAAG;AAAA,EAAS;AAC/E;AAKO,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;;;AD3KxB,IAAAC,uBAAA;AAzBR,IAAM,SAAmG;AAAA,EACvG,SAAS,EAAE,MAAM,WAAW,MAAM,gBAAgB,OAAO,QAAQ;AAAA,EACjE,MAAM,EAAE,MAAM,WAAW,MAAM,gBAAgB,OAAO,YAAY;AAAA,EAClE,SAAS,EAAE,MAAM,WAAW,MAAM,iBAAiB,OAAO,eAAe;AAC3E;AACA,IAAM,eAAuC,EAAE,iBAAiB,iBAAiB,UAAU,aAAa,OAAO,gBAAgB,cAAc,mBAAmB;AAEhK,IAAM,UAAU,CAACC,SAAuB;AACtC,QAAM,IAAI,oBAAI,KAAK,OAAOA,IAAG,IAAI,WAAW;AAC5C,SAAO,MAAM,CAAsB,IAAIA,OAAM,EAAE,mBAAmB,QAAW,EAAE,OAAO,SAAS,KAAK,WAAW,MAAM,UAAU,CAAC;AAClI;AAQA,SAAS,YAAY,EAAE,MAAM,OAAO,WAAW,GAAqB;AAClE,QAAM,IAAI,OAAO,KAAK,MAAM,KAAK,OAAO;AACxC,QAAM,QAAQ,KAAK,aAAa,CAAC,GAAG,IAAI,CAAC,MAAM,MAAM,CAAC,CAAC,EAAE,OAAO,OAAO;AACvE,QAAM,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW;AAClD,SACE,8CAAC,QAAK,WAAU,QACd,yDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACzC;AAAA,mDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,OAAO,GACxD;AAAA,oDAAC,UAAK,WAAU,WAAU,OAAO,EAAE,YAAY,KAAK,MAAM,GAAG,UAAU,IAAI,GAAI,eAAK,OAAM;AAAA,MAC1F,8CAAC,SAAM,MAAK,WAAU,MAAM,aAAa,KAAK,OAAO,KAAK,gBAAiB,eAAK,SAAQ;AAAA,MACxF,8CAAC,SAAM,MAAM,EAAE,MAAM,MAAM,EAAE,MAAO,YAAE,OAAM;AAAA,OAC9C;AAAA,IACA,8CAAC,OAAE,WAAU,2BAA0B,OAAO,EAAE,QAAQ,GAAG,UAAU,SAAS,GAAI,eAAK,aAAY;AAAA,IAClG,KAAK,UACJ,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,YAAY,aAAa,GACjE;AAAA,oDAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,OAAO,IAAI,MAAM,QAAQ,YAAY,EAAE,GAAG,qBAAO;AAAA,MACjG,8CAAC,UAAK,WAAU,cAAa,OAAO,EAAE,MAAM,GAAG,UAAU,SAAS,GAAI,eAAK,SAAQ;AAAA,OACrF,IACE;AAAA,IACJ,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,UAAU,OAAO,GACxD;AAAA,WAAK,SAAS,+CAAC,UAAK,WAAU,uBAAsB;AAAA,sDAAC,OAAE,WAAU,0BAAyB;AAAA,QAAE;AAAA,QAAE,KAAK;AAAA,SAAO,IAAU;AAAA,MACrH,+CAAC,UAAK,WAAU,uBAAsB;AAAA,sDAAC,OAAE,WAAU,cAAa;AAAA,QAAE;AAAA,QAAE,KAAK;AAAA,SAAM;AAAA,MAC9E,KAAK,SAAS,8CAAC,SAAM,MAAK,WAAU,MAAK,WAAU,oBAAM,IAAW;AAAA,MACrE,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,MAC1B;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAS,SAAS,MAAM,cAAc,WAAW,KAAK,GAAG;AAAA,UACpE,OAAO,EAAE,KAAK,SAAS,QAAQ,WAAW,SAAS,eAAe,YAAY,UAAU,KAAK,EAAE;AAAA,UAC/F,wDAAC,UAAK,WAAU,WAAU,OAAO,EAAE,UAAU,IAAI,OAAO,eAAe,GAAI,eAAK,KAAI;AAAA;AAAA,MACtF;AAAA,OACF;AAAA,IACC,KAAK,SACJ,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,QAAQ,YAAY,GAAG,WAAW,0BAA0B,GAC7G;AAAA,oDAAC,UAAK,WAAU,wBAAuB,OAAO,EAAE,YAAY,EAAE,GAAG,mBAAK;AAAA,MACrE,KAAK,IAAI,CAAC,MACT,8CAAC,OAAgB,MAAM,EAAE,cAAc,UAAU,SAAU,YAAE,SAAnD,EAAE,GAAuD,CACpE;AAAA,OACH,IACE;AAAA,IACH,SAAS,UAAU,CAAC,KAAK,cACxB,+CAAC,UAAK,WAAU,cAAa,OAAO,EAAE,OAAO,mBAAmB,GAAG;AAAA;AAAA,MAClD,SAAS,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,OAAO;AAAA,MAAE;AAAA,MAAE,SAAS,WAAW,IAAI,OAAO;AAAA,MAAM;AAAA,OACnG,IACE;AAAA,KACN,GACF;AAEJ;AAaO,SAAS,gBAAgB,EAAE,YAAY,QAAQ,WAAW,KAAK,GAAyB;AAC7F,QAAM,UAAU,WAAW,WAAW;AACtC,QAAM,CAAC,SAAS,UAAU,IAAU,iBAAS,EAAE;AAC/C,QAAM,CAAC,GAAG,IAAI,IAAU,iBAAS,EAAE;AACnC,QAAM,YAAkB,eAAuB,IAAI;AACnD,QAAM,SAAe,eAAuB,IAAI;AAEhD,QAAM,KAAW,gBAAQ,MAAM,WAAW,QAAQ,EAAE,YAAY,WAAW,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC;AACnG,QAAM,QAAc,gBAAQ,MAAM;AAChC,UAAM,IAAiC,CAAC;AACxC,OAAG,MAAM,QAAQ,CAAC,MAAmB;AAAE,QAAE,EAAE,GAAG,IAAI;AAAA,IAAG,CAAC;AACtD,WAAO;AAAA,EACT,GAAG,CAAC,EAAE,CAAC;AAEP,QAAM,QAAuB,GAAG,MAAM,OAAO,CAAC,OAC3C,CAAC,WAAW,EAAE,YAAY,aAC1B,CAAC,MAAM,EAAE,QAAQ,MAAM,EAAE,cAAc,OAAO,EAAE,WAAW,MAAM,MAAM,EAAE,KAAK,YAAY,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE;AACzH,QAAM,WAAW,CAAC,GAAG,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,MAAmB,EAAE,OAAO,CAAC,CAAC;AAKzE,EAAM,kBAAU,MAAM;AACpB,QAAI,OAAO,GAAG,OAAO;AACrB,UAAM,QAAQ,MAAM;AAClB,YAAM,MAAM,UAAU,SAAS,OAAO,OAAO;AAC7C,UAAI,CAAC,IAAK;AAEV,UAAI,CAAC,MAAM;AAAE,YAAI,YAAY,IAAI;AAAc;AAAA,MAAQ;AAGvD,UAAI,YAAY,KAAK,IAAI,GAAG,KAAK,YAAY,EAAE;AAAA,IACjD;AACA,WAAO,sBAAsB,MAAM;AAAE,YAAM;AAAG,aAAO,sBAAsB,KAAK;AAAA,IAAG,CAAC;AACpF,WAAO,MAAM;AAAE,2BAAqB,IAAI;AAAG,2BAAqB,IAAI;AAAA,IAAG;AAAA,EACzE,GAAG,CAAC,SAAS,GAAG,GAAG,SAAS,CAAC;AAE7B,QAAM,eAAe,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW;AAC1D,QAAM,eAAe,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE;AAGxD,QAAM,OAAO,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,MAAM;AAChE,UAAM,IAAI,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB;AACrD,WAAO,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,SAAS,IAAI,KAAK;AAAA,EAC7D,GAAG,CAAC;AACJ,QAAM,YAAY,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW;AAElD,MAAI,YAAuC;AAC3C,SACE,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,IAAI,UAAU,IAAK,GACzD;AAAA,mDAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,GACzC;AAAA,oDAAC,UAAK,WAAU,wBAAuB,0BAAY;AAAA,MACnD,8CAAC,QAAG,WAAU,SAAQ,OAAO,EAAE,QAAQ,EAAE,GAAI,iBAAM;AAAA,MACnD,8CAAC,OAAE,WAAU,iCAAgC,OAAO,EAAE,QAAQ,EAAE,GAC7D,kBAAQ,oNACX;AAAA,OACF;AAAA,IAEA,+CAAC,SAAI,WAAU,yBACb;AAAA,oDAAC,YAAS,SAAO,MAAC,OAAM,SAAQ,OAAO,OAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,GAAG,MAAM,SAAS,aAAa;AAAA,MACvG,8CAAC,YAAS,SAAO,MAAC,OAAM,aAAY,OAAO,OAAO,GAAG,SAAS,GAAG,KAAI,gBAAe;AAAA,MACpF,8CAAC,YAAS,SAAO,MAAC,OAAM,eAAc,OAAO,OAAO,OAAO,UAAU,UAAK,KAAI,kCAAiC;AAAA,MAC/G,8CAAC,YAAS,SAAO,MAAC,OAAM,WAAU,OAAO,YAAY,WAAW,UAAU,QAAQ,UAAK,KAAK,YAAY,UAAU,YAAY,aAAa;AAAA,OAC7I;AAAA,IAEA,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,UAAU,OAAO,GACzD;AAAA,oDAAC,SAAM,MAAK,oBAAmB,aAAY,6CAA4C,OAAO,GAAG,UAAU,CAAC,MAAM,KAAK,EAAE,OAAO,KAAK,GAAG,OAAO,EAAE,OAAO,IAAI,GAAG;AAAA,MAC/J,8CAAC,UAAO,aAAY,gBAAe,OAAO,SAAS,UAAU,CAAC,MAAM,WAAW,EAAE,OAAO,KAAK,GAAG,SAAS,UAAU,OAAO,EAAE,OAAO,IAAI,GAAG;AAAA,MAC1I,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,MAC1B;AAAA,QAAC;AAAA;AAAA,UAAO,MAAK;AAAA,UAAK,SAAQ;AAAA,UAAY,MAAK;AAAA,UACzC,SAAS,MAAM;AAAE,kBAAM,IAAI,UAAU,SAAS,IAAI,OAAO;AAAS,gBAAI,EAAG,GAAE,YAAY,IAAI,KAAK,IAAI,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE;AAAA,UAAc;AAAA,UAAG;AAAA;AAAA,MAEhJ;AAAA,OACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QAAK,MAAK;AAAA,QAAO,WAAU;AAAA,QAC1B,MAAK;AAAA,QACL,SAAS;AAAA;AAAA,IAAM;AAAA,IAEjB,8CAAC,SAAI,WAAU,SACb,wDAAC,SAAI,WAAU,gBAAe,KAAK,WACjC,yDAAC,SAAI,WAAU,eACb;AAAA,oDAAC,UAAK,WAAU,eACd,wDAAC,UAAK,WAAU,oBAAmB,OAAO,EAAE,QAAQ,MAAM,SAAU,MAAM,eAAe,MAAM,SAAU,MAAM,KAAK,GAAG,GACzH;AAAA,MACC,MAAM,IAAI,CAAC,MAAM,MAAM;AAGtB,cAAM,YAAY,KAAK,UAAU;AACjC,oBAAY,KAAK;AACjB,cAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,KAAK,EAAE;AAC5D,cAAM,aAAa,MAAM;AACzB,eACE,+CAAO,kBAAN,EACE;AAAA,sBACC,+CAAC,SAAI,WAAU,aACb;AAAA,2DAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,QAAQ,YAAY,WAAW,GACjF;AAAA,4DAAC,UAAK,OAAO,EAAE,YAAY,IAAI,GAAI,eAAK,UAAU,IAAI,YAAY,WAAW,KAAK,QAAQ,aAAQ,KAAK,WAAU;AAAA,cAChH,KAAK,UAAU,IAAI,OAClB,+CAAC,UAAK,WAAU,WAAU,OAAO,EAAE,SAAS,KAAK,YAAY,IAAI,GAC9D;AAAA,wBAAQ,KAAK,UAAU;AAAA,gBAAE;AAAA,gBAAI,QAAQ,KAAK,IAAI;AAAA,iBACjD;AAAA,cACF,+CAAC,UAAK,OAAO,EAAE,SAAS,KAAK,YAAY,IAAI,GAAG;AAAA;AAAA,gBAAG;AAAA,gBAAQ;AAAA,gBAAS,YAAY,IAAI,KAAK;AAAA,iBAAI;AAAA,eAC/F;AAAA,YACC,KAAK,WAAW,8CAAC,OAAE,WAAU,iBAAiB,eAAK,UAAS,IAAO;AAAA,aACtE,IACE;AAAA,UACH,aACC,8CAAC,SAAI,WAAU,aAAY,KAAK,QAC9B,yDAAC,UAAK,WAAU,kBAAiB;AAAA,0DAAC,OAAE,WAAU,iBAAgB;AAAA,YAAE;AAAA,aAAyC,GAC3G,IACE;AAAA,UACJ,+CAAC,SAAI,WAAU,aACb;AAAA,0DAAC,UAAK,WAAW,gBAAgB,KAAK,cAAc,eAAe,KAAK,WAAW,SAAS,YAAY,KAAK;AAAA,YAC7G,+CAAC,SAAI,WAAU,cACZ;AAAA,sBAAQ,KAAK,IAAI;AAAA,cAClB,8CAAC,QAAG;AAAA,cACJ,8CAAC,UAAK,OAAO,EAAE,SAAS,KAAK,GAAI,eAAK,cAAc,YAAY,WAAW,KAAK,OAAM;AAAA,eACxF;AAAA,YACA,8CAAC,eAAY,MAAY,OAAc,YAAwB;AAAA,aACjE;AAAA,aA3BmB,KAAK,GA4B1B;AAAA,MAEJ,CAAC;AAAA,MACA,CAAC,MAAM,SAAS,8CAAC,OAAE,WAAU,uBAAsB,0CAA4B,IAAO;AAAA,OACzF,GACF,GACF;AAAA,IAEA,+CAAC,OAAE,WAAU,uBAAsB,OAAO,EAAE,QAAQ,EAAE,GAAG;AAAA;AAAA,MACoB,8CAAC,UAAK,WAAU,WAAU,yBAAW;AAAA,MAAO;AAAA,OAEzH;AAAA,KACF;AAEJ;;;AElPA,IAAAC,UAAuB;AACvB,IAAAC,oBAA6B;AAsDzB,IAAAC,uBAAA;AAnCJ,IAAM,eAAe;AAErB,SAAS,eAAyB;AAChC,MAAI;AAAE,WAAO,KAAK,MAAM,eAAe,QAAQ,YAAY,KAAK,IAAI;AAAA,EAAG,SAAS,GAAG;AAAE,WAAO,CAAC;AAAA,EAAG;AAClG;AACA,SAAS,cAAc,MAAsB;AAC3C,MAAI;AAAE,mBAAe,QAAQ,cAAc,KAAK,UAAU,IAAI,CAAC;AAAA,EAAG,SAAS,GAAG;AAAA,EAAqB;AACrG;AAGA,SAAS,UAAU,KAAkD;AACnE,QAAM,CAAC,IAAI,KAAK,IAAU,iBAAS,MAAM,CAAC,CAAC,OAAO,aAAa,EAAE,QAAQ,GAAG,KAAK,CAAC;AAClF,EAAM,kBAAU,MAAM;AAAE,UAAM,CAAC,CAAC,OAAO,aAAa,EAAE,QAAQ,GAAG,KAAK,CAAC;AAAA,EAAG,GAAG,CAAC,GAAG,CAAC;AAClF,QAAM,MAAM,CAAC,SAAkB;AAC7B,QAAI,CAAC,IAAK;AACV,UAAM,OAAO,aAAa,EAAE,OAAO,CAAC,MAAM,MAAM,GAAG;AACnD,QAAI,KAAM,MAAK,KAAK,GAAG;AACvB,kBAAc,IAAI;AAClB,UAAM,IAAI;AAAA,EACZ;AACA,SAAO,CAAC,IAAI,GAAG;AACjB;AAYA,SAAS,SAAS,EAAE,OAAO,QAAQ,SAAS,KAAK,QAAQ,WAAW,SAAS,SAAS,GAAkB;AACtG,SACE,gFACE;AAAA,mDAAC,UAAK,WAAU,iBACd;AAAA,oDAAC,OAAE,WAAU,sBAAqB,eAAY,QAAO;AAAA,MACpD;AAAA,OACH;AAAA,IACC,SAAS,8CAAC,UAAK,WAAU,kBAAkB,kBAAO,IAAU;AAAA,IAC5D,UAAU,+CAAC,UAAK,WAAU,mBAAkB;AAAA,oDAAC,UAAK,WAAU,eAAc,mBAAK;AAAA,MAAO;AAAA,MAAE;AAAA,OAAQ,IAAU;AAAA,IAC1G,OAAO,UAAU,YAChB,+CAAC,UAAK,WAAU,gBACb;AAAA,YAAM,+CAAC,UAAK;AAAA,sDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,QAAE;AAAA,QAAE;AAAA,SAAI,IAAU;AAAA,MACrF,SAAS,+CAAC,UAAK;AAAA,sDAAC,OAAE,WAAU,0BAAyB,eAAY,QAAO;AAAA,QAAE;AAAA,QAAE;AAAA,SAAO,IAAU;AAAA,MAC7F,YACC,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,WAAW;AAAA;AAAA,QACjD,8CAAC,OAAE,WAAU,qBAAoB,eAAY,QAAO;AAAA,SACtE,IACE;AAAA,OACN,IACE;AAAA,IACH,UACC,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,UACtD;AAAA,oDAAC,OAAE,WAAU,aAAY,eAAY,QAAO;AAAA,MAAE;AAAA,OAChD,IACE;AAAA,KACN;AAEJ;AAWA,SAAS,aAAa,MAAwE;AAC5F,QAAM,SAAe,eAAwB,IAAI;AACjD,QAAM,CAAC,KAAK,MAAM,IAAU,iBAA8B,IAAI;AAC9D,EAAM,wBAAgB,MAAM;AAC1B,QAAI,CAAC,QAAQ,CAAC,OAAO,SAAS;AAAE,aAAO,IAAI;AAAG;AAAA,IAAQ;AACtD,UAAM,QAAQ,MAAM;AAClB,UAAI,CAAC,OAAO,QAAS;AACrB,YAAM,IAAI,OAAO,QAAQ,sBAAsB;AAC/C,YAAMC,KAAI,KAAK,MAAM,IAAI,MAAM;AAC/B,YAAM,QAAQ,OAAO,cAAc,EAAE;AACrC,YAAM,KAAK,QAAQ,OAAO,EAAE,MAAM;AAClC,aAAO;AAAA,QACL,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,OAAO,EAAE,QAAQ,IAAIA,KAAI,GAAG,OAAO,aAAaA,KAAI,GAAG,CAAC;AAAA,QACvF,KAAK,KAAK,SAAY,EAAE,SAAS;AAAA,QACjC,QAAQ,KAAK,OAAO,cAAc,EAAE,MAAM,MAAM;AAAA,QAChD,OAAOA;AAAA,MACT,CAAC;AAAA,IACH;AACA,UAAM;AACN,WAAO,iBAAiB,UAAU,OAAO,IAAI;AAC7C,WAAO,iBAAiB,UAAU,KAAK;AACvC,WAAO,MAAM;AAAE,aAAO,oBAAoB,UAAU,OAAO,IAAI;AAAG,aAAO,oBAAoB,UAAU,KAAK;AAAA,IAAG;AAAA,EACjH,GAAG,CAAC,IAAI,CAAC;AACT,SAAO,CAAC,QAAQ,GAAG;AACrB;AA4CO,SAAS,WAAW;AAAA,EACzB,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA;AAAA,EAEA,UAAU;AAAA,EACV;AAAA;AAAA,EAEA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,GAAiC;AAC/B,QAAM,CAAC,UAAU,WAAW,IAAI,UAAU,SAAS;AACnD,QAAM,UAAU,aAAa,CAAC,CAAC;AAC/B,QAAM,SAAS,YAAY;AAC3B,QAAM,MAAM,CAAC,OAAO,QAAQ,UAAU,WAAW,UAAU,MAAM,MAAM,SAAS,MAAM,MAAM,MAAM,EAC/F,OAAO,OAAO,EAAE,KAAK,QAAK;AAE7B,MAAI,QAAQ;AACV,QAAI,WAAW,UAAU;AACvB,aACE,+CAAC,UAAK,WAAW,CAAC,qBAAqB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MAC9E;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YAAO,MAAK;AAAA,YAAS,WAAU;AAAA,YAAe,OAAO,wDAAmD,MAAM;AAAA,YAC7G,SAAS,MAAM,YAAY,KAAK;AAAA,YAAG,cAAW;AAAA,YAC9C,wDAAC,OAAE,WAAU,sBAAqB,eAAY,QAAO;AAAA;AAAA,QACvD;AAAA,SACF;AAAA,IAEJ;AACA,WACE;AAAA,MAAC;AAAA;AAAA,QAAW;AAAA,QAAc;AAAA,QAAgB;AAAA,QAAkB;AAAA,QAAU;AAAA,QACpE;AAAA,QAAsB;AAAA,QAAkB,UAAU,MAAM,YAAY,IAAI;AAAA,QACxE;AAAA,QAAY;AAAA,QAAU;AAAA,QAAsB;AAAA,QAC3C;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,MAAI,WAAW,UAAU;AACvB,WACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACzF;AAAA,qDAAC,SAAI,WAAU,eAAc,MAAK,UAChC;AAAA,uDAAC,UAAK,WAAU,iBACd;AAAA,wDAAC,OAAE,WAAU,sBAAqB,eAAY,QAAO;AAAA,UAAE;AAAA,WAEzD;AAAA,QACA,8CAAC,UAAK,WAAU,sBAAqB,gHAErC;AAAA,QACA,+CAAC,UAAK,WAAU,uBACb;AAAA,sBACC,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,WAAW;AAAA;AAAA,YACzD,8CAAC,OAAE,WAAU,qBAAoB,eAAY,QAAO;AAAA,aAC9D,IACE;AAAA,UACJ,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,MAAM,YAAY,KAAK,GAC7E;AAAA,0DAAC,OAAE,WAAU,mBAAkB,eAAY,QAAO;AAAA,YAAE;AAAA,aACtD;AAAA,WACF;AAAA,SACF;AAAA,MACC;AAAA,OACH;AAAA,EAEJ;AAEA,SACE,+CAAC,SAAI,WAAW,CAAC,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,YAAY,EAAE,UAAU,IAAI,QAAY,GAAG,MAClH;AAAA,kDAAC,SAAI,WAAU,iBAAgB,OAAO,EAAE,QAAQ,UAAU,OAAO,oBAAoB,GAAI,GAAG,EAAE,OAAO,GAAG,GAAU,eAAY,QAC3H,UACH;AAAA,IACA,8CAAC,SAAI,WAAU,gBAAe;AAAA,IAC9B,8CAAC,SAAI,WAAU,gBAAe,MAAK,QACjC;AAAA,MAAC;AAAA;AAAA,QAAS;AAAA,QAAc;AAAA,QAAgB;AAAA,QAAkB;AAAA,QAAU;AAAA,QAClE;AAAA,QAAsB;AAAA,QAAkB,UAAU,MAAM,YAAY,IAAI;AAAA;AAAA,IAAG,GAC/E;AAAA,KACF;AAEJ;AAkBA,SAAS,WAAW,EAAE,OAAO,QAAQ,SAAS,KAAK,QAAQ,WAAW,SAAS,UAAU,MAAM,KAAK,WAAW,MAAM,SAAS,GAAoB;AAChJ,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,CAAC,QAAQ,GAAG,IAAI,aAAa,IAAI;AACvC,QAAM,QAAc,eAA6C,IAAI;AACrE,QAAM,OAAO,MAAM;AACjB,QAAI,MAAM,SAAS;AAAE,mBAAa,MAAM,OAAO;AAAG,YAAM,UAAU;AAAA,IAAM;AACxE,YAAQ,IAAI;AAAA,EACd;AAGA,QAAM,OAAO,MAAM;AACjB,QAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAC7C,UAAM,UAAU,WAAW,MAAM;AAC/B,YAAM,IAAI,SAAS;AAGnB,UAAI,MAAM,EAAE,QAAQ,iBAAiB,KAAK,EAAE,QAAQ,oBAAoB,GAAI;AAC5E,cAAQ,KAAK;AAAA,IACf,GAAG,GAAG;AAAA,EACR;AACA,EAAM,kBAAU,MAAM,MAAM;AAAE,QAAI,MAAM,QAAS,cAAa,MAAM,OAAO;AAAA,EAAG,GAAG,CAAC,CAAC;AAEnF,SACE;AAAA,IAAC;AAAA;AAAA,MAAK,KAAK;AAAA,MAAQ,WAAW,CAAC,WAAW,kBAAkB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC7F,cAAc;AAAA,MAAM,cAAc;AAAA,MAAM,SAAS;AAAA,MAAM,QAAQ;AAAA,MAAO,GAAG;AAAA,MACzE;AAAA,sDAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,QAAQ,UAAU,KAAK,IAAI,MAAM,GAAG,IAAI,oBAAoB,GAAI,GAAG,EAAE,OAAO,GAAG,GAAU,eAAY,QAC3I,UACH;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YAAO,MAAK;AAAA,YAAS,WAAU;AAAA,YAAoB,cAAY;AAAA,YAAK,OAAO;AAAA,YAC1E,iBAAe;AAAA,YAAM,SAAS;AAAA,YAAM,QAAQ;AAAA,YAC5C,SAAS,MAAO,OAAO,QAAQ,KAAK,IAAI,KAAK;AAAA,YAC7C,wDAAC,OAAE,WAAU,sBAAqB,eAAY,QAAO;AAAA;AAAA,QACvD;AAAA,QACC,QAAQ,UAAM;AAAA,UACb;AAAA,YAAC;AAAA;AAAA,cAAI,WAAU;AAAA,cAAiC,MAAK;AAAA,cACnD,OAAO,EAAE,UAAU,SAAS,MAAM,IAAI,MAAM,KAAK,IAAI,KAAK,QAAQ,IAAI,QAAQ,OAAO,IAAI,MAAM;AAAA,cAC/F,cAAc;AAAA,cAAM,cAAc;AAAA,cAClC;AAAA,gBAAC;AAAA;AAAA,kBAAS;AAAA,kBAAc;AAAA,kBAAgB;AAAA,kBAAkB;AAAA,kBAAU;AAAA,kBAClE;AAAA,kBAAsB;AAAA,kBAAkB;AAAA;AAAA,cAAoB;AAAA;AAAA,UAChE;AAAA,UAAQ,SAAS;AAAA,QAAI,IAAI;AAAA;AAAA;AAAA,EAC7B;AAEJ;AAEO,SAAS,UAAUC,MAAoC;AAC5D,MAAI,CAACA,KAAK,QAAO;AACjB,QAAM,IAAI,oBAAI,KAAKA,OAAM,WAAW;AACpC,MAAI,MAAM,EAAE,QAAQ,CAAC,EAAG,QAAOA;AAC/B,SAAO,EAAE,mBAAmB,QAAW,EAAE,OAAO,SAAS,MAAM,UAAU,CAAC;AAC5E;AAIO,IAAM,YAAY;;;AC5RnB,IAAAC,uBAAA;AAPC,SAAS,iBAAiB,EAAE,YAAY,OAAO,QAAQ,SAAAC,WAAU,OAAO,YAAY,IAAI,GAAG,KAAK,GAA0B;AAC/H,QAAM,OAAO,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU,EAAE,OAAO,OAAO;AACjF,SACE;AAAA,IAAC;AAAA;AAAA,MAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC9D,OAAO;AAAA,QAAE,KAAK;AAAA,QAAI,YAAY;AAAA,QAAc,SAASA,WAAU,cAAc;AAAA,QAC3E,cAAc;AAAA,QAAI,QAAQ;AAAA,QAAmC,YAAY;AAAA,QACzE,UAAU;AAAA,QAAK,WAAW;AAAA,MAAO;AAAA,MAAI,GAAG;AAAA,MAC1C;AAAA,uDAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,EAAE,GACvC;AAAA,wDAAC,OAAE,WAAU,qBAAoB,OAAO,EAAE,UAAU,IAAI,OAAO,oBAAoB,GAAG,eAAY,QAAO;AAAA,UACzG,8CAAC,UAAK,WAAWA,WAAU,gBAAgB,SAAU,mBAAS,kCAAiC;AAAA,WACjG;AAAA,QACA,8CAAC,OAAE,WAAU,2BAA0B,OAAO,EAAE,QAAQ,GAAG,UAAU,SAAS,GAC3E,oBAAU,2FACb;AAAA,QACC,KAAK,SACJ,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,OAAO,GACzD;AAAA,wDAAC,UAAK,WAAU,wBAAuB,sBAAQ;AAAA,UAC9C,KAAK,IAAI,CAAC,MACT,8CAAC,UAAa,WAAU,WAAU,OAAO;AAAA,YAAE,UAAU;AAAA,YAAM,SAAS;AAAA,YAAW,cAAc;AAAA,YAC3F,QAAQ;AAAA,YAA2B,YAAY;AAAA,UAAiB,GAAI,eAD3D,CAC6D,CACzE;AAAA,WACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AAeO,SAAS,KAAK,EAAE,MAAM,OAAO,MAAM,SAAS,OAAO,UAAU,SAAAA,WAAU,OAAO,SAAS,GAA+B;AAC3H,aAAW,WAAW;AACtB,MAAI,KAAK;AACT,MAAI,KAAM,MAAK,MAAM,WAAW,IAAI,IAAI;AACxC,MAAI,MAAO,MAAK,MAAM,WAAW,OAAO,KAAK;AAC7C,MAAI,KAAM,MAAK,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,WAAW,OAAO,IAAI,WAAW,QAAQ,IAAI;AACnG,MAAI,GAAI,QAAO;AACf,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,OAAQ,QAAO;AACnB,SAAO,8CAAC,oBAAiB,YAAY,QAAQ,OAAO,SAASA,UAAS;AACxE;AAqBO,SAAS,YAAY;AAAA,EAAE;AAAA,EAAM,WAAW;AAAA,EAAM;AAAA,EAAU;AAAA,EAAW;AAAA,EAAM;AAAA,EAAW;AAAA,EAC7D,UAAU;AAAA,EAAS,UAAU;AAAA,EAAM,aAAa;AAAe,GAAsC;AACjI,aAAW,WAAW;AACtB,QAAM,KAAK,iBAAiB,IAAI;AAEhC,MAAI,CAAC,WAAW,UAAU,IAAI,EAAG,QAAO;AAExC,MAAI,GAAG,YAAY,GAAG,SAAS,OAAQ,QAAO;AAG9C,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,IAAmB,WAAW,SAAS,IAAI,KAAK,CAAC;AACvD,QAAM,UAAU,GAAG,WAAW,CAAC;AAC/B,SACE;AAAA,IAAC;AAAA;AAAA,MAAW,OAAO,UAAU,YAAY,WAAW,EAAE,SAAS,kBAAkB;AAAA,MAC/E,QAAQ,EAAE;AAAA,MACV,SAAS,EAAE,YAAY,QAAQ,SAC3B,QAAQ,SAAS,eAAe,QAAQ,WAAW,IAAI,KAAK,OAAO,sBAAsB,QAAQ,KAAK,IAAI,IAC1G;AAAA,MACJ;AAAA,MACA,KAAK,UAAU,EAAE,GAAG;AAAA,MAAG,QAAQ,EAAE;AAAA,MAAQ;AAAA,MAAY;AAAA,MAAsB;AAAA,MAC3E,WAAW;AAAA,MAAM,WAAW,CAAC,cAAc,WAAW,IAAI,UAAU;AAAA,MACnE;AAAA;AAAA,EACH;AAEJ;AAGO,SAAS,eAAe,EAAE,MAAM,SAAS,GAA6E;AAC3H,aAAW,WAAW;AACtB,MAAI,WAAW,IAAI,IAAI,EAAG,QAAO;AACjC,SACE;AAAA,IAAC;AAAA;AAAA,MAAK,OAAO,eAAe,MAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI;AAAA,MAClE,OAAO,EAAE,SAAS,eAAe,SAAS,MAAM,QAAQ,cAAc;AAAA,MAAG,iBAAc;AAAA,MACvF,wDAAC,UAAK,OAAO,EAAE,eAAe,OAAO,GAAI,UAAS;AAAA;AAAA,EACpD;AAEJ;;;ACnIA,IAAAC,UAAuB;AAgDjB,IAAAC,uBAAA;AApBC,SAAS,WAAW,EAAE,YAAY,OAAO,eAAe,GAAG,YAAY,WAAW,YAAY,QAAQ,GAAqC;AAChJ,QAAMC,QAAO,eAAe;AAC5B,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,MAAY,eAAwB,IAAI;AAC9C,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,CAAC,MAAoB;AAAE,UAAI,IAAI,WAAW,CAAC,IAAI,QAAQ,SAAS,EAAE,MAAc,EAAG,SAAQ,KAAK;AAAA,IAAG;AAChH,UAAM,MAAM,CAAC,MAAqB;AAAE,UAAI,EAAE,QAAQ,SAAU,SAAQ,KAAK;AAAA,IAAG;AAC5E,aAAS,iBAAiB,eAAe,IAAI;AAC7C,aAAS,iBAAiB,WAAW,GAAG;AACxC,WAAO,MAAM;AAAE,eAAS,oBAAoB,eAAe,IAAI;AAAG,eAAS,oBAAoB,WAAW,GAAG;AAAA,IAAG;AAAA,EAClH,GAAG,CAAC,IAAI,CAAC;AACT,MAAI,CAAC,UAAW,QAAO;AAEvB,QAAM,OAAOA,UAAS;AACtB,QAAM,IAAI,WAAW,WAAW,QAAQ;AACxC,QAAM,KAAK,CAAC,SAA0B;AAAE,eAAW,QAAQ,IAAI;AAAG,YAAQ,KAAK;AAAA,EAAG;AAElF,SACE,+CAAC,UAAK,OAAO,EAAE,UAAU,YAAY,SAAS,cAAc,GAAG,KAC7D;AAAA;AAAA,MAAC;AAAA;AAAA,QAAO,MAAK;AAAA,QAAS,SAAS,MAAM,QAAQ,CAAC,IAAI;AAAA,QAChD,cAAY,OAAO,sBAAiB,eAAe,wBAAwB;AAAA,QAC3E,iBAAe;AAAA,QACf,OAAO,OAAO,oGACA;AAAA,QACd,WAAW,iBAAiB,OAAO,aAAa,OAAO,OAAO,aAAa;AAAA,QAC3E;AAAA,wDAAC,OAAE,WAAW,SAAS,OAAO,aAAa,iBAAiB,OAAO,EAAE,UAAU,GAAG,GAAG;AAAA,UACpF,QAAQ,eACP,8CAAC,UAAwB,WAAU,yBAAyB,yBAAe,KAAK,QAAQ,gBAA7E,YAA0F,IACnG;AAAA;AAAA;AAAA,IACN;AAAA,IAEC,OACC,+CAAC,UAAK,WAAU,6BACd;AAAA,qDAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,SAAS,aAAa,cAAc,0BAA0B,GACvG;AAAA,uDAAC,UAAK,WAAW,eAAe,OAAO,qBAAqB,qBAC1D;AAAA,wDAAC,OAAE,WAAW,SAAS,OAAO,aAAa,iBAAiB,eAAY,QAAO;AAAA,UAC9E,OAAO,cAAc;AAAA,WACxB;AAAA,QACC,OAAO,+CAAC,UAAK,WAAU,+BAA+B;AAAA;AAAA,UAAa;AAAA,UAAmB,iBAAiB,IAAI,KAAK;AAAA,WAAI,IAAU;AAAA,QAC/H,8CAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,QACzB,QAAQ,aACP,8CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,YAAY,mBAAK,IACvE;AAAA,SACN;AAAA,MAEA,+CAAC,UAAK,OAAO,EAAE,SAAS,SAAS,SAAS,aAAa,cAAc,0BAA0B,GAC7F;AAAA,sDAAC,UAAK,WAAU,2BAA0B,OAAO,EAAE,SAAS,SAAS,UAAU,SAAS,GACrF,iBACG,8KACA,0CAA0C,EAAE,aAAa,SAAS,EAAE,QAAQ,8FAClF;AAAA,QACA,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,WAAW,IAAI,UAAU,OAAO,GACxE;AAAA,yDAAC,UAAK,WAAU,+BACb;AAAA,cAAE;AAAA,YAAe;AAAA,YAAU,EAAE,mBAAmB,IAAI,KAAK;AAAA,YAAI;AAAA,YAAS,EAAE;AAAA,YAAS;AAAA,YAAE,EAAE;AAAA,YAAM;AAAA,aAC9F;AAAA,UACC,aACC,gFACE;AAAA,0DAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,YAC1B,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,MAAM;AAAE,sBAAQ,KAAK;AAAG,yBAAW;AAAA,YAAG,GAAG;AAAA;AAAA,cACtF,8CAAC,OAAE,WAAU,qBAAoB,eAAY,QAAO;AAAA,eAC/D;AAAA,aACF,IACE;AAAA,WACN;AAAA,SACF;AAAA,MAEA,+CAAC,UAAK,WAAU,kBACd;AAAA,uDAAC,YAAO,MAAK,UAAS,WAAW,iBAAiB,CAAC,OAAO,WAAW,KAAK,SAAS,MAAM,GAAG,MAAM,GAChG;AAAA,wDAAC,OAAE,WAAU,mBAAkB,eAAY,QAAO;AAAA,UAClD,+CAAC,UAAK,WAAU,oBACd;AAAA,0DAAC,UAAK,WAAU,qBAAoB,uBAAS;AAAA,YAC7C,8CAAC,UAAK,WAAU,oBAAmB,oDAAsC;AAAA,aAC3E;AAAA,UACC,CAAC,OAAO,8CAAC,OAAE,WAAU,eAAc,eAAY,QAAO,IAAK;AAAA,WAC9D;AAAA,QACA,+CAAC,YAAO,MAAK,UAAS,WAAW,iBAAiB,OAAO,WAAW,KAAK,SAAS,MAAM,GAAG,MAAM,GAC/F;AAAA,wDAAC,OAAE,WAAU,eAAc,eAAY,QAAO;AAAA,UAC9C,+CAAC,UAAK,WAAU,oBACd;AAAA,0DAAC,UAAK,WAAU,qBAAoB,uBAAS;AAAA,YAC7C,8CAAC,UAAK,WAAU,oBAAmB,mDAAqC;AAAA,aAC1E;AAAA,UACC,OAAO,8CAAC,OAAE,WAAU,eAAc,eAAY,QAAO,IAAK;AAAA,WAC7D;AAAA,SACF;AAAA,MAEC,QAAQ,YACP,8CAAC,UAAK,OAAO,EAAE,SAAS,SAAS,WAAW,KAAK,WAAW,QAAQ,WAAW,0BAA0B,GACtG,oBAAU,GACb,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;AAMO,SAAS,YAAY,EAAE,OAAO,GAAsC;AACzE,QAAMA,QAAO,eAAe;AAC5B,MAAIA,UAAS,OAAQ,QAAO;AAC5B,SACE,+CAAC,SAAI,WAAU,cAAa,MAAK,UAC/B;AAAA,mDAAC,UAAK,WAAU,6BACd;AAAA,oDAAC,OAAE,WAAU,eAAc,eAAY,QAAO;AAAA,MAAE;AAAA,OAElD;AAAA,IACA,8CAAC,UAAK,WAAU,qBAAoB,qGAEpC;AAAA,IACA,+CAAC,YAAO,MAAK,UAAS,WAAU,gBAAe,SAAS,MAAO,SAAS,OAAO,IAAI,WAAW,QAAQ,MAAM,GAC1G;AAAA,oDAAC,OAAE,WAAU,mBAAkB,eAAY,QAAO;AAAA,MAAE;AAAA,OACtD;AAAA,KACF;AAEJ;;;ACzCM,IAAAC,uBAAA;AAvFC,IAAM,kBAA0C;AAAA,EACrD,OAAO;AAAA,EAAI,QAAQ;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,qBAAqB;AAAA,EAC1E,UAAU;AAAA,EAAI,OAAO;AAAA,EAAI,SAAS;AAAA,EAAM,SAAS;AAAA,EACjD,sBAAsB;AAAA,EAAM,iBAAiB;AAAA,EAC7C,eAAe;AAAA,EAAI,gBAAgB;AAAA;AACrC;AACA,IAAM,IAAI;AAGH,SAAS,gBAAgB,SAAyB;AACvD,QAAM,IAAI,OAAO,WAAW,EAAE,EAAE,KAAK;AACrC,SAAO,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,IAAI;AAC/B;AAGO,IAAM,kBAAkB;AAmBxB,IAAM,WAA8C;AAAA,EACzD,OAAsB,EAAE,OAAO,OAAa,MAAM,eAAsB,OAAO,iBAAqB,QAAQ,gBAAgB,UAAU,KAAK;AAAA,EAC3I,QAAsB,EAAE,OAAO,QAAa,MAAM,qBAAsB,OAAO,kBAAqB,QAAQ,gBAAgB,UAAU,KAAK;AAAA,EAC3I,WAAsB,EAAE,OAAO,WAAa,MAAM,OAAsB,OAAO,qBAAqB,QAAQ,UAAgB,UAAU,KAAK;AAAA,EAC3I,qBAAsB,EAAE,OAAO,UAAa,MAAM,SAAsB,OAAO,oBAAqB,QAAQ,UAAgB,UAAU,KAAK;AAAA,EAC3I,SAAsB,EAAE,OAAO,SAAa,MAAM,aAAsB,OAAO,mBAAqB,QAAQ,SAAgB,UAAU,KAAK;AAAA,EAC3I,WAAsB,EAAE,OAAO,WAAa,MAAM,YAAsB,OAAO,qBAAqB,QAAQ,SAAgB,UAAU,KAAK;AAAA,EAC3I,UAAsB,EAAE,OAAO,UAAa,MAAM,QAAsB,OAAO,oBAAqB,QAAQ,SAAgB,UAAU,KAAK;AAAA,EAC3I,SAAsB,EAAE,OAAO,SAAa,MAAM,mBAAsB,OAAO,mBAAqB,QAAQ,UAAgB,UAAU,MAAM;AAAA,EAC5I,OAAsB,EAAE,OAAO,OAAa,MAAM,sBAAsB,OAAO,iBAAqB,QAAQ,UAAgB,UAAU,MAAM;AAAA,EAC5I,iBAAsB,EAAE,OAAO,gBAAa,MAAM,WAAsB,OAAO,iBAAqB,QAAQ,WAAgB,UAAU,MAAM;AAAA,EAC5I,sBAAsB,EAAE,OAAO,qBAAkB,MAAM,YAAiB,OAAO,iBAAqB,QAAQ,WAAgB,UAAU,MAAM;AAAA,EAC5I,OAAsB,EAAE,OAAO,OAAa,MAAM,WAAsB,OAAO,iBAAqB,QAAQ,WAAgB,UAAU,MAAM;AAC9I;AAEA,IAAM,WAA8B,EAAE,OAAO,SAAS,MAAM,OAAO,OAAO,mBAAmB,QAAQ,SAAS,UAAU,MAAM;AAGvH,SAAS,YAAY,MAAyC;AACnE,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,SAAS,IAAI,EAAG,QAAO,EAAE,GAAG,SAAS,IAAI,GAAG,KAAK;AACrD,QAAM,IAAI,OAAO,IAAI,EAAE,YAAY,EAAE,KAAK;AAC1C,QAAM,MAAM,OAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,YAAY,MAAM,CAAC;AACvE,MAAI,IAAK,QAAO,EAAE,GAAG,SAAS,GAAG,GAAG,MAAM,IAAI;AAE9C,QAAM,QAAQ,OAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,YAAY,EAAE,WAAW,CAAC,KAAK,EAAE,WAAW,IAAI,YAAY,CAAC,CAAC;AACpH,MAAI,MAAO,QAAO,EAAE,GAAG,SAAS,KAAK,GAAG,MAAM,MAAM;AACpD,MAAI,0BAA0B,KAAK,CAAC,EAAG,QAAO,EAAE,GAAG,SAAS,KAAK,GAAG,KAAK;AACzE,SAAO,EAAE,GAAG,UAAU,OAAO,OAAO,IAAI,GAAG,KAAK;AAClD;AAmBO,SAAS,WAAW,EAAE,SAAS,OAAO,MAAM,YAAY,MAAM,MAAM,OAAO,SAAS,OAAO,YAAY,IAAI,GAAG,KAAK,GAAoB;AAC5I,QAAM,IAAI,YAAY,OAAO;AAC7B,QAAM,KAAK,gBAAgB,WAAW,EAAE;AACxC,MAAI,KAAK;AACP,WACE,8CAAC,UAAK,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,MAAM,OAAO,EAAE,YAAY,EAAE,MAAM,GAAI,GAAG,MAAM;AAAA,EAEpI;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MAAK,WAAW,CAAC,WAAW,SAAS,OAAO,eAAe,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MACjG,OAAO,EAAE,OAAO,WAAQ,EAAE,UAAU,KAAK,kBAAe,KAAK;AAAA,MAC7D,OAAO,EAAE,UAAU,EAAE,MAAM;AAAA,MAA2B,GAAG;AAAA,MACzD;AAAA,sDAAC,OAAE,WAAW,WAAW,EAAE,MAAM,eAAY,QAAO;AAAA,QACnD,YAAY,8CAAC,UAAK,WAAU,iBAAiB,YAAE,OAAM,IAAU;AAAA,QAC/D,SAAS,8CAAC,UAAK,WAAU,kBAAkB,gBAAM,GAAE,IAAU;AAAA;AAAA;AAAA,EAChE;AAEJ;;;AC9D4D,IAAAC,uBAAA;AA/C5D,IAAMC,SAAgB;AAAA,EACpB,EAAE,KAAK,QAAQ,OAAO,QAAQ,GAAG,GAAG,OAAO,OAAO;AAAA,EAClD,EAAE,KAAK,YAAY,OAAO,YAAY,GAAG,GAAG,OAAO,cAAS;AAAA,EAC5D,EAAE,KAAK,UAAU,OAAO,UAAU,GAAG,GAAG,OAAO,eAAU;AAAA,EACzD,EAAE,KAAK,YAAY,OAAO,YAAY,GAAG,GAAG,OAAO,OAAO;AAC5D;AA2BO,SAAS,uBAAuB,EAAE,WAAW,CAAC,GAAG,WAAW,YAAY,cAAc,cAAc,UAAU,OAAO,YAAY,GAAG,GAAgC;AACzK,QAAM,UAAUA,OAAM,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE;AAC5F,QAAM,UAAU,KAAK,IAAI,GAAG,GAAG,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;AACjE,QAAM,QAAQA,OAAM,KAAK,CAAC,MAAM,EAAE,QAAQ,SAAS,KAAKA,OAAM,CAAC;AAC/D,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,GAAG,GAClF;AAAA,kDAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,iBAAiB,KAAK,IAAI,YAAY,MAAM,GAC7F,kBAAQ,IAAI,CAAC,MAAM;AAClB,YAAM,OAAO,eAAe,EAAE,IAAI;AAClC,YAAM,SAAS,iBAAiB,EAAE;AAClC,aACE;AAAA,QAAC;AAAA;AAAA,UAAmB,MAAK;AAAA,UAAS,SAAS,eAAe,MAAM,aAAa,SAAS,OAAO,EAAE,GAAG,IAAI;AAAA,UACpG,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,gBAAgB,YAAY,KAAK,IAAI,SAAS,IAAI,QAAQ,gBAAgB,SAAS,yBAAyB,kBAAkB,cAAc,eAAe,YAAY,SAAS,qBAAqB,kBAAkB,QAAQ,eAAe,YAAY,WAAW,WAAW,QAAQ,WAAW,KAAK,YAAY,kFAAkF;AAAA,UACzb;AAAA,0DAAC,UAAK,OAAO,EAAE,SAAS,QAAQ,eAAe,kBAAkB,KAAK,GAAG,WAAW,UAAU,GAAG,GAC9F,oBACG,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,8CAAC,UAAa,WAAU,WAAU,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,KAA5D,CAA+D,CAAE,IACpH,EAAE,MAAM,IAAI,CAAC,MACb;AAAA,cAAC;AAAA;AAAA,gBAAkB,OAAO,EAAE,OAAO,WAAQ,EAAE;AAAA,gBAC3C,OAAO,EAAE,QAAQ,IAAI,cAAc,GAAG,YAAY,eAAe,EAAE,IAAI,UAAU,QAAQ,yBAAyB,EAAE,IAAI,UAAU,OAAO,eAAe,EAAE,IAAI,UAAU,SAAS,QAAQ,YAAY,UAAU,SAAS,SAAS,UAAU,IAAI,YAAY,KAAK,UAAU,UAAU,YAAY,SAAS;AAAA,gBACxS,YAAE,SAAS,EAAE;AAAA;AAAA,cAFL,EAAE;AAAA,YAGb,CACD,GACL;AAAA,YACA,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,YAAY,WAAW,GAC/D;AAAA,4DAAC,UAAK,WAAU,eAAc,OAAO,EAAE,UAAU,IAAI,OAAO,EAAE,MAAM,SAAS,gBAAgB,uBAAuB,GACjH,oBAAU,WAAM,EAAE,MAAM,QAC3B;AAAA,cACA,8CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,OAAO,KAAK,GAAG,eAAY,QACpE,WAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,8CAAC,UAAa,WAAW,kBAAkB,KAAK,EAAE,IAAI,WAAW,KAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,EAAE,KAAxF,CAA2F,CAAE,GACnI;AAAA,eACF;AAAA,YACA,+CAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACzC;AAAA,4DAAC,UAAK,WAAU,eAAe,YAAE,OAAM;AAAA,cACvC,+CAAC,UAAK,WAAU,uBAAsB,OAAO,EAAE,UAAU,KAAK,GAAG;AAAA;AAAA,gBAAK,EAAE;AAAA,iBAAM;AAAA,eAChF;AAAA;AAAA;AAAA,QAvBW,EAAE;AAAA,MAwBf;AAAA,IAEJ,CAAC,GACH;AAAA,IACC,YACC,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,SAAS,aAAa,cAAc,eAAe,YAAY,oBAAoB,QAAQ,2BAA2B,UAAU,OAAO,GAC/K;AAAA,oDAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,OAAO,eAAe,MAAM,IAAI,SAAS,GAAG,eAAY,QACjG,WAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,8CAAC,UAAa,WAAW,kBAAkB,KAAK,MAAM,IAAI,WAAW,KAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,KAA7F,CAAgG,CAAE,GACxI;AAAA,MACA,+CAAC,UAAK,WAAU,2BAA0B,OAAO,EAAE,MAAM,GAAG,UAAU,IAAI,GACxE;AAAA,uDAAC,YAAO,OAAO,EAAE,OAAO,cAAc,GAAG;AAAA;AAAA,UAAY;AAAA,WAAW;AAAA,QAAS;AAAA,SAC3E;AAAA,OACF,IACE;AAAA,KACN;AAEJ;;;AC3FA,IAAAC,UAAuB;AAiCb,IAAAC,uBAAA;AATH,SAAS,OAAO,EAAE,OAAO,CAAC,GAAG,UAAU,OAAO,YAAY,GAAG,GAAgB;AAClF,QAAM,MAAM,KAAK,IAAI,GAAG,GAAG,KAAK,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACtE,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAwB,IAAI;AAC5D,QAAM,SAAS,CAAC,QAAgB,OAAO,KAAK,OAAO,OAAO,KAAK,SAAS;AACxE,QAAM,OAA+B,EAAE,IAAI,mBAAmB,MAAM,qBAAqB,QAAQ,sBAAsB;AACvH,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,EAAE,GACjF;AAAA,mDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,gBAAgB,YAAY,eAAe,GAAG,UAAU,OAAO,GACtG;AAAA,OAAC,CAAC,aAAa,KAAK,EAAE,GAAG,CAAC,SAAS,KAAK,IAAI,GAAG,CAAC,SAAS,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAChF,+CAAC,UAAa,WAAU,8BAA6B,OAAO,EAAE,KAAK,EAAE,GACnE;AAAA,sDAAC,UAAK,OAAO,EAAE,OAAO,IAAI,QAAQ,GAAG,cAAc,GAAG,YAAY,EAAE,GAAG;AAAA,QAAG;AAAA,WADjE,CAEX,CACD;AAAA,MACD,+CAAC,UAAK,WAAU,8BAA6B,OAAO,EAAE,KAAK,EAAE,GAC3D;AAAA,sDAAC,UAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,IAAI,YAAY,eAAe,GAAG;AAAA,QAAE;AAAA,SACvE;AAAA,OACF;AAAA,IACC,KAAK,IAAI,CAAC,MAAM;AACf,YAAM,MAAM,EAAE,WAAW,EAAE;AAC3B,YAAM,OAAO,OAAO,GAAG;AACvB,YAAM,MAAM,cAAc,EAAE,WAAW,UAAU,EAAE,SAAS,cACzD,MAAM,KAAK,WAAQ,KAAK,IAAI,GAAG,EAAE,QAAQ,CAAC,IAAI,eAAe,MAAM,IAAI,WAAQ,IAAI,QAAQ,CAAC,IAAI,cAAc,sBAC9G,EAAE,OAAO,aAAQ,EAAE,OAAO;AAC7B,aACE;AAAA,QAAC;AAAA;AAAA,UAAoB,WAAU;AAAA,UAAS,OAAO,EAAE,KAAK,IAAI,SAAS,SAAS,cAAc,0BAA0B;AAAA,UAClH,cAAc,MAAM,SAAS,EAAE,OAAO;AAAA,UAAG,cAAc,MAAM,SAAS,IAAI;AAAA,UAC1E;AAAA,0DAAC,UAAK,OAAO,EAAE,OAAO,KAAK,MAAM,OAAO,GAAG,wDAAC,cAAW,SAAS,EAAE,SAAS,MAAK,MAAK,GAAE;AAAA,YACvF,8CAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,QAAQ,IAAI,UAAU,IAAI,GACrE,oBAAU,8CAAC,UAAK,WAAU,WAAU,OAAO,EAAE,UAAU,YAAY,OAAO,SAAS,cAAc,EAAE,GAAG,IAAK,gFAC1G;AAAA,4DAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,OAAQ,EAAE,WAAW,MAAM,MAAO,KAAK,YAAY,KAAK,IAAI,GAAG,cAAc,mBAAmB,YAAY,4EAA4E,GAAG;AAAA,cAC7P,8CAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAO,EAAE,SAAS,MAAM,MAAO,KAAK,KAAK,GAAG,OAAO,GAAG,QAAQ,IAAI,YAAY,gBAAgB,cAAc,EAAE,GAAG;AAAA,cACtJ,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,UAAU,YAAY,OAAO,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,MAAM,OAAO,IAAI,QAAQ,MAAM,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,MAAM,OAAO,SAAS,UAAW,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,MAAM,MAAO,aAAa,KAAK,GAAG,UAAU,IAAI,OAAO,qBAAqB,YAAY,UAAU,YAAY,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,MAAM,OAAO,mBAAmB,QAAQ,aAAa,EAAE,GAAI;AAAA,kBAAE;AAAA,gBAAS;AAAA,iBAAC;AAAA,cACvb,UAAU,EAAE,UACX,8CAAC,UAAK,WAAU,cAAa,MAAK,WAAU,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,OAAO,QAAQ,QAAQ,IAAI,UAAU,oBAAoB,YAAY,UAAU,WAAW,QAAQ,OAAO,cAAc,GAAI,eAAI,IACjN;AAAA,eACN,GACF;AAAA;AAAA;AAAA,QAZQ,EAAE;AAAA,MAaZ;AAAA,IAEJ,CAAC;AAAA,KACH;AAEJ;;;ACvBiB,IAAAC,uBAAA;AAzCjB,IAAM,QAAQ,CAAC,MAAc,MAAM,KAAK,MAAM,CAAC,EAAE,eAAe;AA+BzD,SAAS,oBAAoB;AAAA,EAClC,WAAW,CAAC;AAAA,EAAG,WAAW;AAAA,EAAG,WAAW;AAAA,EAAI;AAAA,EAAO,UAAU;AAAA,EAAO,YAAY;AAAA,EAAM,YAAY;AACpG,GAA6B;AAC3B,QAAM,OAAO,SAAS,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,KAAK,CAAC;AACnD,QAAM,QAAQ,QAAQ,WAAW;AACjC,QAAM,QAAQ,UAAU,SAAY,QAAQ,OAAO;AACnD,QAAM,MAAM,CAAC,MAAe,QAAS,IAAI,QAAS,MAAM;AACxD,QAAM,aAAa,SAAS,OAAO,CAAC,GAAG,MAAM,IAAI,OAAO,OAAO,EAAE,SAAS,CAAC,EAAE,QAAQ,YAAY,EAAE,CAAC,GAAG,CAAC;AACxG,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,GAAG,GACjF;AAAA,cAAU,8CAAC,UAAK,WAAU,WAAU,OAAO,EAAE,QAAQ,IAAI,cAAc,cAAc,GAAG,IACvF,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,QAAQ,IAAI,cAAc,eAAe,UAAU,UAAU,KAAK,GAAG,YAAY,mBAAmB,GAClI;AAAA,eAAS,IAAI,CAAC,MACb;AAAA,QAAC;AAAA;AAAA,UAAkB,OAAO,EAAE,OAAO,WAAQ,EAAE,IAAI,QAAQ,CAAC,IAAI;AAAA,UAC5D,OAAO,EAAE,OAAO,IAAI,EAAE,GAAG,IAAI,KAAK,YAAY,EAAE,SAAS,YAAY,EAAE,IAAI,EAAE,OAAO,SAAS,QAAQ,YAAY,UAAU,UAAU,MAAM,YAAY,KAAK,OAAO,QAAQ,UAAU,UAAU,YAAY,oCAAoC;AAAA,UAC9O,cAAI,EAAE,GAAG,IAAI,IAAI,EAAE,IAAI,QAAQ,CAAC,IAAI;AAAA;AAAA,QAF5B,EAAE;AAAA,MAGb,CACD;AAAA,MACA,QAAQ,IACP;AAAA,QAAC;AAAA;AAAA,UAAK,OAAO,2BAA2B,WAAW;AAAA,UACjD,OAAO,EAAE,OAAO,IAAI,KAAK,IAAI,KAAK,YAAY,wFAAwF,SAAS,QAAQ,YAAY,UAAU,UAAU,MAAM,YAAY,KAAK,OAAO,OAAO;AAAA,UAC3N,cAAI,KAAK,IAAI,IAAI,MAAM,MAAM,QAAQ,CAAC,IAAI;AAAA;AAAA,MAC7C,IACE;AAAA,OACN;AAAA,IAGD,YACC,+CAAC,WAAM,WAAU,YAAW,OAAO,EAAE,UAAU,sBAAsB,GACnE;AAAA,oDAAC,WAAM,yDAAC,QACN;AAAA,sDAAC,QAAG,OAAO,EAAE,OAAO,MAAM,GAAG,qBAAO;AAAA,QACpC,8CAAC,QAAG,OAAO,EAAE,OAAO,MAAM,GAAG,oBAAM;AAAA,QACnC,8CAAC,QAAG,WAAU,UAAS,OAAO,EAAE,OAAO,MAAM,GAAG,mBAAK;AAAA,QACrD,8CAAC,QAAG,WAAU,UAAS,OAAO,EAAE,OAAO,MAAM,GAAG,iBAAG;AAAA,QACnD,8CAAC,QAAG,WAAU,UAAS,OAAO,EAAE,OAAO,MAAM,GAAG,mBAAK;AAAA,SACvD,GAAK;AAAA,MACL,+CAAC,WACE;AAAA,iBAAS,IAAI,CAAC,MACb,+CAAC,QACC;AAAA,wDAAC,QAAG,wDAAC,cAAW,SAAS,EAAE,MAAM,MAAK,MAAK,GAAE;AAAA,UAC7C,8CAAC,QAAG;AAAA,YAAC;AAAA;AAAA,cAAK,WAAU;AAAA,cAA4B,OAAO,EAAE,QAAQ,IAAI,UAAU,GAAG;AAAA,cACtF,OAAO,+BAA4B,EAAE,WAAW,0BAAuB;AAAA,cAAM,uBAAa,gBAAgB,EAAE,IAAI,KAAK;AAAA;AAAA,UAAG,GAAO;AAAA,UAC3H,8CAAC,QAAG,WAAU,UAAU,YAAE,OAAM;AAAA,UAChC,8CAAC,QAAG,WAAU,UAAU,YAAE,IAAI,QAAQ,CAAC,GAAE;AAAA,UACzC,+CAAC,QAAG,WAAU,UAAU;AAAA,gBAAI,EAAE,GAAG,EAAE,QAAQ,CAAC;AAAA,YAAE;AAAA,aAAC;AAAA,aANxC,EAAE,IAOX,CACD;AAAA,QACA,QAAQ,IACP,+CAAC,QACC;AAAA,wDAAC,QAAG,yDAAC,UAAK,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,YAAY,IAAI,GAC5D;AAAA,0DAAC,UAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,GAAG,YAAY,uFAAuF,MAAM,OAAO,GAAG;AAAA,YAAE;AAAA,aAE5K,GAAO;AAAA,UACP,8CAAC,QAAG,yDAAC,UAAK,WAAU,6BAA4B,OAAO,EAAE,QAAQ,IAAI,UAAU,GAAG,GAAG;AAAA;AAAA,YAAE;AAAA,YAAS;AAAA,YAAO;AAAA,YAAS;AAAA,aAAC,GAAO;AAAA,UACxH,8CAAC,QAAG,WAAU,mBAAkB,oBAAC;AAAA,UACjC,8CAAC,QAAG,WAAU,UAAU,gBAAM,QAAQ,CAAC,GAAE;AAAA,UACzC,+CAAC,QAAG,WAAU,UAAU;AAAA,gBAAI,KAAK,EAAE,QAAQ,CAAC;AAAA,YAAE;AAAA,aAAC;AAAA,WACjD,IACE;AAAA,QACJ,+CAAC,QAAG,OAAO,EAAE,YAAY,mBAAmB,GAC1C;AAAA,wDAAC,QAAG,OAAO,EAAE,YAAY,IAAI,GAAG,0BAAY;AAAA,UAC5C,8CAAC,QAAG;AAAA,UACJ,8CAAC,QAAG,WAAU,UAAS,OAAO,EAAE,YAAY,IAAI,GAAI,gBAAM,UAAU,GAAE;AAAA,UACtE,8CAAC,QAAG,WAAU,UAAS,OAAO,EAAE,YAAY,IAAI,GAAI,gBAAM,QAAQ,CAAC,GAAE;AAAA,UACrE,8CAAC,QAAG,WAAU,UAAS,OAAO,EAAE,YAAY,IAAI,GAAG,kBAAI;AAAA,WACzD;AAAA,SACF;AAAA,OACF,IACE;AAAA,KACN;AAEJ;;;ACxGA,IAAAC,UAAuB;AA+Cf,IAAAC,uBAAA;AA5CR,IAAM,UAAU,CAAC,QAAgB,OAAO,MAAM,aAAa,OAAO,MAAM,WAAW,OAAO,KAAK,aAAa;AAyBrG,SAAS,kBAAkB;AAAA,EAChC;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAK,MAAM;AAAA,EAAG;AAAA,EAAK,OAAO;AAAA,EAAK;AAAA,EAC9C;AAAA,EAAW;AAAA,EAAU;AAAA,EAAU,YAAY;AAC7C,GAA2B;AACzB,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAS,KAAK;AAC9C,EAAM,kBAAU,MAAM,SAAS,KAAK,GAAG,CAAC,KAAK,CAAC;AAC9C,QAAM,QAAQ,UAAU;AACxB,QAAM,UAAU,WAAW,SAAS,KAAK,IAAI;AAC7C,QAAM,WAAW,QAAQ,OAAO;AAChC,QAAM,UAAU,QAAQ,GAAG;AAC3B,QAAM,QAAQ,QAAQ;AACtB,QAAM,MAAM,CAAC,MAAc;AAAE,aAAS,CAAC;AAAG,QAAI,UAAW,WAAU,GAAG,WAAW,SAAS,CAAC,IAAI,GAAG;AAAA,EAAG;AACrG,QAAM,MAAM,QAAQ,MAAM,KAAM,QAAQ,QAAQ,MAAM,OAAQ;AAC9D,QAAM,SAAS,MAAM;AAAE,aAAS,KAAK;AAAG,QAAI,SAAU,UAAS;AAAA,EAAG;AAElE,SACE;AAAA,IAAC;AAAA;AAAA,MAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC9D,OAAO,EAAE,KAAK,IAAI,SAAS,IAAI,QAAQ,gBAAgB,QAAQ,wBAAwB,kBAAkB,cAAc,eAAe,YAAY,QAAQ,yBAAyB,kBAAkB,OAAO,eAAe,YAAY,kFAAkF;AAAA,MACzT;AAAA,uDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,UAAU,OAAO,GACzD;AAAA,wDAAC,UAAK,WAAU,SAAQ,OAAO,EAAE,MAAM,GAAG,UAAU,IAAI,GAAI,kBAAO;AAAA,UACnE,8CAAC,YAAS,MAAM,SAAS,KAAU,MAAK,UAAS;AAAA,UAChD,QAAQ,gFACP;AAAA,0DAAC,OAAE,WAAU,8BAA6B,eAAY,QAAO;AAAA,YAC7D,8CAAC,YAAS,MAAM,UAAU,KAAK,SAAS,MAAK,UAAS,SAAO,MAAC;AAAA,aAChE,IAAM;AAAA,WACR;AAAA,QAEA,+CAAC,SAAI,WAAU,aACb;AAAA,wDAAC,UAAK,WAAU,kBAAiB,OAAO,EAAE,OAAO,MAAM,IAAI,GAAG;AAAA,UAC7D,QACC,8CAAC,UAAK,WAAU,kBAAiB,OAAO,EAAE,MAAM,MAAM,KAAK,YAAY,QAAQ,IAAI,wBAAwB,kBAAkB,GACzH,mBAAQ,IAAI,YAAO,QAAQ,KAAK,IAAI,KAAK,EAAE,eAAe,GAC9D,IACE;AAAA,UACJ;AAAA,YAAC;AAAA;AAAA,cAAM,MAAK;AAAA,cAAQ;AAAA,cAAU;AAAA,cAAU;AAAA,cAAY,OAAO;AAAA,cACzD,UAAU,CAAC,MAAM,IAAI,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,cAC3C,WAAW,CAAC,MAAM;AAAE,oBAAI,EAAE,QAAQ,SAAU,QAAO;AAAA,cAAG;AAAA,cACtD,cAAY,eAAe;AAAA;AAAA,UAAQ;AAAA,WACvC;AAAA,QAEA,+CAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,IAAI,UAAU,OAAO,GACzD;AAAA,yDAAC,UAAK,WAAU,YAAW,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,IAAI,GACjE;AAAA,0DAAC,UAAK,WAAU,UAAS,OAAO,EAAE,UAAU,IAAI,YAAY,IAAI,GAAI,gBAAM,MAAM,eAAe,GAAE;AAAA,YACjG,8CAAC,UAAK,WAAU,uBAAsB,uEAAyD;AAAA,aACjG;AAAA,UACA,8CAAC,YAAO,MAAK,UAAS,WAAU,uBAAsB,UAAU,CAAC,OAAO,SAAS,QAAQ,oBAAM;AAAA,UAC/F;AAAA,YAAC;AAAA;AAAA,cAAO,MAAK;AAAA,cAAS,WAAU;AAAA,cAAwB,UAAU,CAAC;AAAA,cACjE,SAAS,MAAM;AAAE,oBAAI,SAAU,UAAS,OAAO,OAAO;AAAA,cAAG;AAAA,cAAG;AAAA;AAAA,UAAmB;AAAA,WACnF;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACzCY,IAAAC,uBAAA;AAnCZ,IAAM,aAAa;AAAA,EACjB,EAAE,KAAK,OAAO,OAAO,OAAO,MAAM,eAAe,OAAO,gBAAgB;AAAA,EACxE,EAAE,KAAK,WAAW,OAAO,WAAW,MAAM,OAAO,OAAO,oBAAoB;AAAA,EAC5E,EAAE,KAAK,WAAW,OAAO,WAAW,MAAM,YAAY,OAAO,oBAAoB;AAAA,EACjF,EAAE,KAAK,SAAS,OAAO,SAAS,MAAM,aAAa,OAAO,kBAAkB;AAAA,EAC5E,EAAE,KAAK,SAAS,OAAO,SAAS,MAAM,mBAAmB,OAAO,kBAAkB;AAAA,EAClF,EAAE,KAAK,OAAO,OAAO,OAAO,MAAM,WAAW,OAAO,gBAAgB;AACtE;AAmBO,SAAS,cAAc,EAAE,UAAU,CAAC,GAAG,WAAW,GAAG,WAAW,IAAI,YAAY,YAAY,GAAG,GAAuB;AAC3H,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,WAAW,QAAQ,CAAC;AAC3D,QAAM,SAAS,QAAQ,UAAU;AACjC,SACE,+CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO,EAAE,KAAK,GAAG,GAClF;AAAA,kDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,KAAK,GAAG,UAAU,OAAO,GACvD,qBAAW,IAAI,CAAC,MAAM;AACrB,YAAM,KAAK,QAAQ,SAAS,EAAE,GAAG;AACjC,aACE;AAAA,QAAC;AAAA;AAAA,UAAiB,OAAO,EAAE,SAAS,KAAK,oBAAe;AAAA,UACtD,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,UAAU,KAAK,GAAG,OAAO,IAAI,SAAS,UAAU,cAAc,eAAe,QAAQ,gBAAgB,KAAK,sBAAsB,kBAAkB,YAAY,KAAK,sBAAsB,oBAAoB,OAAO,KAAK,sBAAsB,uBAAuB;AAAA,UACrU;AAAA,0DAAC,OAAE,WAAW,WAAW,EAAE,MAAM,OAAO,EAAE,UAAU,IAAI,OAAO,KAAK,EAAE,QAAQ,oBAAoB,GAAG,eAAY,QAAO;AAAA,YACxH,8CAAC,UAAK,OAAO,EAAE,UAAU,MAAM,YAAY,IAAI,GAAI,YAAE,OAAM;AAAA;AAAA;AAAA,QAHlD,EAAE;AAAA,MAIb;AAAA,IAEJ,CAAC,GACH;AAAA,IACA,+CAAC,SAAI,WAAU,YAAW,OAAO,EAAE,KAAK,EAAE,GACxC;AAAA,qDAAC,SAAI,WAAU,UAAS,OAAO,EAAE,gBAAgB,iBAAiB,KAAK,GAAG,GACxE;AAAA,sDAAC,UAAK,WAAU,eAAc,yCAA2B;AAAA,QACzD,+CAAC,UAAK,WAAU,UAAS,OAAO,EAAE,OAAO,SAAS,qBAAqB,qBAAqB,YAAY,IAAI,GAAG;AAAA;AAAA,UAC3G;AAAA,UAAS;AAAA,UAAO;AAAA,UAAS;AAAA,WAC7B;AAAA,SACF;AAAA,MACA,8CAAC,SAAI,OAAO,EAAE,QAAQ,GAAG,cAAc,eAAe,YAAY,oBAAoB,UAAU,SAAS,GACvG,wDAAC,SAAI,OAAO,EAAE,QAAQ,QAAQ,OAAQ,SAAS,MAAO,KAAK,YAAY,qBAAqB,cAAc,WAAW,YAAY,oCAAoC,GAAG,GAC1K;AAAA,MACA,+CAAC,UAAK,WAAU,2BAA0B,OAAO,EAAE,UAAU,SAAS,GACnE;AAAA,gBAAQ;AAAA,QAAO;AAAA,QAAkC;AAAA,QACjD,SACG,gHACA;AAAA,QACH,aAAa,MAAM,aAAa;AAAA,SACnC;AAAA,OACF;AAAA,KACF;AAEJ;;;AClEA,IAAAC,UAAuB;;;ACAvB,IAAAC,UAAuB;AAwIhB,IAAM,mBAAmB;AAChC,IAAM,cAAc,CAAC,UAAU,SAAS;AACxC,IAAM,cAAc,CAAC,aAAa,WAAW;AAC7C,IAAM,iBAAiB;AAEvB,IAAI,MAAM;AACV,IAAM,MAAM,CAAC,MAAc,IAAI,MAAO,EAAE,MAAO,MAAM,KAAK,IAAI,EAAE,SAAS,EAAE;AAC3E,IAAM,QAAQ,CAAC,OAAe,IAAI,QAAc,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAKxE,IAAM,YAAmB;AAAA,EACvB,IAAI,GAAG;AAAE,QAAI;AAAE,aAAO,OAAO,eAAe,QAAQ,CAAC;AAAA,IAAG,SAAS,GAAG;AAAE,aAAO;AAAA,IAAM;AAAA,EAAE;AAAA,EACrF,IAAI,GAAG,GAAG;AAAE,QAAI;AAAE,aAAO,eAAe,QAAQ,GAAG,CAAC;AAAA,IAAG,SAAS,GAAG;AAAA,IAAa;AAAA,EAAE;AAAA,EAClF,IAAI,GAAG;AAAE,QAAI;AAAE,aAAO,eAAe,WAAW,CAAC;AAAA,IAAG,SAAS,GAAG;AAAA,IAAa;AAAA,EAAE;AACjF;AAEO,IAAM,kBAAkB,CAAC,MAC9B,CAAC,CAAC,MAAM,EAAE,SAAS,YAAa,EAAE,YAAY,QAAQ,EAAE,SAAS,SAAS;AACrE,IAAM,kBAAkB,CAAC,UAC7B,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEzC,SAAS,UAAU,QAAoD;AAC5E,QAAM,IAAI,OAAO,UAAU,EAAE,EAAE,YAAY;AAC3C,MAAI,YAAY,QAAQ,CAAC,MAAM,GAAI,QAAO;AAC1C,MAAI,YAAY,QAAQ,CAAC,MAAM,GAAI,QAAO;AAC1C,SAAO;AACT;AAMO,SAAS,cAAc,MAAqC;AACjE,QAAM;AAAA,IACJ;AAAA,IAAa;AAAA,IAAW;AAAA,IAAY;AAAA,IAAgB,UAAU;AAAA,IAC9D,iBAAiB;AAAA,IAAM,kBAAkB;AAAA,IAAK,QAAQ;AAAA,IACtD;AAAA,IAAU;AAAA,IAAe;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAS;AAAA,EACrD,IAAI,QAAS,CAAC;AAEd,QAAM,CAAC,QAAQ,SAAS,IAAU,iBAA+B,MAAM;AACvE,QAAM,CAAC,UAAU,WAAW,IAAU,iBAAwB,IAAI;AAClE,QAAM,CAAC,UAAU,WAAW,IAAU,iBAAwB,CAAC,CAAC;AAChE,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAuB,CAAC,CAAC;AACzD,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAwB,IAAI;AAC5D,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,CAAC,eAAe,gBAAgB,IAAU,iBAAwB,IAAI;AAE5E,QAAM,UAAgB,eAAsB,CAAC,CAAC;AAC9C,QAAM,WAAiB,eAAqB,CAAC,CAAC;AAC9C,QAAM,UAAgB,eAAO,KAAK;AAClC,QAAM,aAAmB,eAAO,KAAK;AACrC,QAAM,WAAiB,eAAyB,IAAI;AACpD,QAAM,cAAoB,eAAO,CAAC;AAClC,QAAM,YAAkB,eAAsB,IAAI;AAClD,QAAM,UAAgB,eAAO,IAAI;AAMjC,EAAM,kBAAU,MAAM;AACpB,YAAQ,UAAU;AAClB,WAAO,MAAM;AAAE,cAAQ,UAAU;AAAA,IAAO;AAAA,EAC1C,GAAG,CAAC,CAAC;AAEL,QAAM,SAAS,CAAC,SAAwB;AAAE,YAAQ,UAAU;AAAM,QAAI,QAAQ,QAAS,aAAY,IAAI;AAAA,EAAG;AAC1G,QAAM,QAAQ,CAAC,IAAY,MACzB,OAAO,QAAQ,QAAQ,IAAI,CAAC,MAAO,EAAE,OAAO,KAAK,OAAO,OAAO,CAAC,GAAG,GAAG,OAAO,MAAM,aAAa,EAAE,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC;AACjH,QAAM,OAAO,IAAI,SAAwB,OAAO,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAE5E,QAAM,OAAO,CAAC,QAA0B;AACtC,UAAM,OAAS,KAA8B,WAAY,OAAO,OAAO,OAAO;AAC9E,eAAW,QAAQ,GAAG;AACtB,QAAI,SAAS,kBAAkB;AAAE,gBAAU,cAAc;AAAG,eAAS,IAAI;AAAG,aAAO;AAAA,IAAM;AACzF,WAAO;AAAA,EACT;AAIA,QAAM,aAAmB,oBAAY,OAAO,OAAuC;AACjF,UAAM,OAAO,MAAM,WAAY,UAAU,EAAE;AAG3C,UAAM,OAAO,CAAC,GAAK,QAAQ,KAAK,YAAa,CAAC,CAAE;AAChD,gBAAY,UAAU,KAAK;AAC3B,WAAO,IAAI;AACX,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AAEf,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,YAAY;AAEf,gBAAU,MAAM;AAAG,eAAS,IAAI;AAChC,aAAO,CAAC,CAAC;AAAG,eAAS,UAAU,CAAC;AAAG,eAAS,CAAC,CAAC;AAAG,kBAAY,UAAU;AACvE;AAAA,IACF;AACA,QAAI,OAAO;AAEX,QAAI,SAAS,SAAS;AAAE,UAAI;AAAE,iBAAS,QAAQ,MAAM;AAAA,MAAG,SAAS,GAAG;AAAA,MAAwB;AAAE,eAAS,UAAU;AAAA,IAAM;AACvH,YAAQ,UAAU;AAAO,YAAQ,KAAK;AAAG,qBAAiB,IAAI;AAC9D,aAAS,UAAU,CAAC;AAAG,aAAS,CAAC,CAAC;AAClC,eAAW,UAAU;AACrB,cAAU,WAAW;AAAG,aAAS,IAAI;AACrC,KAAC,YAAY;AACX,UAAI;AAEF,cAAM,KAAK,gBAAgB,OAAO,YAAY;AAC5C,gBAAM,MAAM,MAAM,WAAW,cAAc,EAAE,aAAa,UAAU,CAAC;AACrE,iBAAO,OAAO,IAAI;AAAA,QACpB,GAAG;AACH,YAAI,KAAM;AACV,YAAI,CAAC,IAAI;AAAE,oBAAU,cAAc;AAAG,mBAAS,gBAAgB;AAAG;AAAA,QAAQ;AAC1E,kBAAU,UAAU;AAAI,oBAAY,EAAE;AACtC,kBAAU,SAAS;AACnB,cAAM,WAAW,EAAE;AACnB,YAAI,KAAM;AACV,kBAAU,OAAO;AACjB,yBAAiB,cAAc,EAAE;AACjC,cAAM,SAAS,MAAM,IAAI,iBAAiB,EAAE;AAC5C,YAAI,OAAQ,WAAU,MAAM;AAAA,iBACnB,eAAgB,MAAK,cAAc;AAAA,MAC9C,SAAS,KAAK;AACZ,YAAI,KAAM;AACV,YAAI,CAAC,KAAK,GAAG,GAAG;AAAE,oBAAU,cAAc;AAAG,mBAAW,KAA8B,WAAY,aAAa;AAAA,QAAG;AAAA,MACpH;AAAA,IACF,GAAG;AACH,WAAO,MAAM;AAAE,aAAO;AAAA,IAAM;AAAA,EAE9B,GAAG,CAAC,YAAY,aAAa,WAAW,YAAY,CAAC;AAIrD,iBAAe,QAAQ,OAAe,eAAsC;AAC1E,UAAM,IAAI,iBAAiB,UAAU,SAAS,KAAK;AACnD,QAAI,WAAW;AACf,WAAO,aAAa,iBAAiB;AACnC,UAAI,WAAW,QAAS;AACxB,YAAM,MAAM,cAAc;AAC1B,UAAI,CAAC,QAAQ,QAAS;AACtB,UAAI;AACJ,UAAI;AACF,cAAM,MAAM,WAAY,OAAO,KAAK;AAAA,MACtC,SAAS,KAAK;AAGZ,cAAM,SAAS,MAAM,cAAc;AACnC,YAAI,QAAQ;AAAE,oBAAU,KAAK;AAAG;AAAA,QAAQ;AACxC,sBAAc,eAAiB,KAA8B,WAAY,mBAAmB,IAAI;AAChG;AAAA,MACF;AACA,YAAM,eAAe,EAAE,IAAI,CAAC;AAC5B,YAAMC,UAAS,UAAU,OAAO,IAAI,MAAM;AAC1C,UAAIA,YAAW,UAAW;AAC1B,UAAIA,YAAW,WAAW;AACxB,kBAAU,OAAO,GAAG;AACpB;AAAA,MACF;AACA,oBAAc,eAAgB,QAAQ,IAAI,SAAS,IAAI,WAAY,cAAc,MAAM,GAAG;AAC1F;AAAA,IACF;AACA,QAAI,CAAC,WAAW,QAAS,eAAc,eAAe,WAAW,IAAI;AAAA,EACvE;AAEA,iBAAe,gBAAkC;AAC/C,UAAM,SAAS,YAAY;AAC3B,QAAI;AACF,YAAM,OAAO,MAAM,WAAW,UAAU,OAAQ;AAChD,aAAO,KAAK,SAAS;AAAA,IACvB,SAAS,GAAG;AAAE,aAAO;AAAA,IAAO;AAAA,EAC9B;AAGA,iBAAe,UAAU,QAAgB,MAAiC;AACxE,UAAM,IAAI,iBAAiB,UAAU,OAAO;AAC5C,QAAI;AACF,YAAM,OAAO,MAAM,WAAW,UAAU,OAAQ;AAChD,YAAM,aAAa,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,EAAE,MAAM;AAChE,UAAI,cAAc,YAAY,WAAW,OAAQ,UAAS,WAAW,MAAM;AAAA,IAC7E,SAAS,KAAK;AAAE,WAAK,GAAG;AAAA,IAAG;AAAA,EAC7B;AAEA,WAAS,cAAc,eAAuB,MAAc,WAAoB,KAAuB;AACrG,UAAM,IAAI,iBAAiB,UAAU,OAAO;AAG5C,QAAI,CAAC,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,aAAa,GAAG;AACxD,WAAK,EAAE,IAAI,eAAe,MAAM,aAAa,MAAM,KAAK,CAAC;AAAA,IAC3D;AACA,UAAM,eAAe,EAAE,SAAS,OAAO,WAAW,OAAO,OAAO,MAAM,WAAW,CAAC,CAAC,WAAW,KAAK,OAAO,OAAU,CAAC;AACrH,eAAW,QAAQ,IAAI,MAAM,IAAI,CAAC;AAAA,EACpC;AAEA,WAAS,UAAU,OAAqB;AACtC,UAAM,KAAK,IAAI,GAAG;AAClB,SAAK,EAAE,IAAI,MAAM,aAAa,SAAS,MAAM,OAAO,SAAS,KAAK,CAAC;AACnE,YAAQ,IAAI;AAAG,YAAQ,UAAU;AAAM,qBAAiB,KAAK,IAAI,CAAC;AAClE,YAAQ,OAAO,EAAE,EAAE,QAAQ,MAAM;AAAE,cAAQ,UAAU;AAAO,cAAQ,KAAK;AAAG,uBAAiB,IAAI;AAAA,IAAG,CAAC;AAAA,EACvG;AAIA,iBAAe,aAAa,MAAiC;AAC3D,UAAM,KAAK,UAAU;AACrB,QAAI,CAAC,GAAI;AACT,YAAQ,UAAU;AAAM,YAAQ,IAAI;AAAG,qBAAiB,KAAK,IAAI,CAAC;AAClE,UAAM,SAAS,IAAI,GAAG;AACtB,UAAM,WAAW,IAAI,GAAG;AACxB;AAAA,MACE,EAAE,IAAI,QAAQ,MAAM,QAAQ,MAAM,KAAK,QAAQ,MAAM,aAAa,KAAK,aAAa,SAAS,MAAM,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AAAA,MACvI,EAAE,IAAI,UAAU,MAAM,aAAa,MAAM,IAAI,WAAW,CAAC,CAAC,WAAY,eAAe,SAAS,CAAC,WAAY,eAAe,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AAAA,IAChK;AACA,UAAM,KAAgB,OAAO,oBAAoB,cAAc,IAAI,gBAAgB,IAAI,EAAE,QAAQ;AAAA,IAAC,GAAG,QAAQ,OAAU;AACvH,aAAS,UAAU;AACnB,cAAU,OAAO,KAAK,IAAI;AAE1B,QAAI;AACF,UAAI;AACJ,UAAI,WAAY,eAAe;AAC7B,cAAM,MAAM,WAAY,cAAc,IAAI,KAAK,MAAM;AAAA,UACnD,SAAS,CAAC,UAAkB,MAAM,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,MAAM,OAAO,WAAW,KAAK,EAAE;AAAA;AAAA,UACtG,QAAQ,CAAC,SAAS,MAAM,UAAU,CAAC,MAAM;AACvC,kBAAM,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM;AACpC,kBAAM,KAAK,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE;AAClD,gBAAI,OAAO,GAAI,OAAM,KAAK,IAAI;AAAA,gBAAQ,OAAM,EAAE,IAAI,OAAO,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI;AACnF,mBAAO,EAAE,MAAM;AAAA,UACjB,CAAC;AAAA,UACD,YAAY,CAAC,UAAkB,MAAM,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,MAAM,MAAM,EAAE;AAAA,QAClG,GAAG,GAAG,QAAuB,KAAK,eAAe,KAAK,YAAY,SAAS,KAAK,cAAc,MAAS;AAAA,MACzG,WAAW,KAAK,eAAe,KAAK,YAAY,QAAQ;AACtD,cAAM,MAAM,WAAY,YAAY,IAAI,KAAK,MAAM,GAAG,QAAQ,KAAK,WAAW;AAAA,MAChF,OAAO;AACL,cAAM,MAAM,WAAY,YAAY,IAAI,KAAK,MAAM,GAAG,MAAM;AAAA,MAC9D;AAEA,YAAM,QAAQ,EAAE,SAAS,MAAM,CAAC;AAChC,YAAM,IAAuB,OAAO,CAAC;AACrC,UAAI,EAAE,cAAc,EAAE,QAAQ;AAC5B,cAAM,UAAU,EAAE,WAAW,OAAO,SAAS,MAAM,OAAO,EAAE,QAAQ,MAAM,EAAE,SAAS,GAAG,CAAC;AACzF,cAAM,QAAQ,EAAE,QAAQ,QAAQ;AAAA,MAClC,OAAO;AACL,cAAM,UAAU;AAAA,UACd,WAAW;AAAA,UAAO,SAAS;AAAA,UAC3B,MAAM,EAAE,SAAS,OAAO,EAAE,QAAQ,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,GAAG,QAAQ;AAAA,UAC1F,QAAQ,EAAE;AAAA,UAAQ,OAAO,EAAE,SAAS,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,GAAG;AAAA,UACpF,WAAW,EAAE;AAAA,UAAW,OAAO,EAAE;AAAA,UAAO,OAAO,EAAE;AAAA,UACjD,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AACD,oBAAY,WAAW;AACvB,YAAI,EAAE,UAAU,SAAU,UAAS,EAAE,MAAM;AAAA,MAC7C;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,UAAW,QAAS,IAA0B,SAAS,gBAAiB,IAA6B,YAAY,cAAe,WAAW;AACjJ,YAAM,QAAQ,EAAE,SAAS,MAAM,CAAC;AAChC,UAAI,SAAS;AACX,cAAM,UAAU,CAAC,OAAO,EAAE,WAAW,OAAO,SAAS,OAAO,SAAS,MAAM,WAAW,MAAM,MAAM,EAAE,QAAQ,KAAK,EAAE;AAAA,MACrH,WAAW,CAAC,KAAK,GAAG,GAAG;AACrB,cAAM,UAAU,EAAE,WAAW,OAAO,SAAS,OAAO,OAAS,KAA8B,WAAY,eAAe,WAAW,KAAK,CAAC;AAAA,MACzI,OAAO;AACL,eAAO,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,QAAQ,CAAC;AAAA,MACzD;AAAA,IACF,UAAE;AACA,eAAS,UAAU;AACnB,cAAQ,UAAU;AAAO,cAAQ,KAAK;AAAG,uBAAiB,IAAI;AAAA,IAChE;AAAA,EACF;AAEA,iBAAe,QAAuB;AACpC,QAAI,QAAQ,QAAS;AACrB,WAAO,SAAS,QAAQ,QAAQ;AAC9B,UAAI,WAAW,QAAS;AACxB,YAAM,OAAO,SAAS,QAAQ,CAAC;AAC/B,eAAS,UAAU,SAAS,QAAQ,MAAM,CAAC;AAC3C,eAAS,SAAS,QAAQ,MAAM,CAAC;AACjC,YAAM,aAAa,IAAI;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,OAAa,oBAAY,CAAC,MAAc,gBAA+B;AAC3E,UAAM,QAAQ,QAAQ,IAAI,KAAK;AAC/B,QAAI,CAAC,QAAQ,EAAE,eAAe,YAAY,QAAS;AACnD,QAAI,WAAW,eAAgB;AAC/B,UAAM,OAAmB,EAAE,IAAI,IAAI,GAAG,GAAG,MAAM,MAAM,aAAa,eAAe,YAAY,SAAS,YAAY,MAAM,IAAI,OAAU;AACtI,aAAS,UAAU,SAAS,QAAQ,OAAO,IAAI;AAC/C,aAAS,SAAS,QAAQ,MAAM,CAAC;AACjC,eAAW,UAAU;AACrB,UAAM;AAAA,EAER,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,OAAa,oBAAY,MAAM;AACnC,eAAW,UAAU;AACrB,UAAM,KAAK,SAAS;AACpB,QAAI,IAAI;AAAE,UAAI;AAAE,WAAG,MAAM;AAAA,MAAG,SAAS,GAAG;AAAA,MAAa;AAAA,IAAE;AACvD,UAAM,SAAS,CAAC,GAAG,QAAQ,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS;AAClF,QAAI,QAAQ;AACV,YAAM,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,OAAO,WAAW,OAAO,SAAS,MAAM,WAAW,MAAM,MAAM,EAAE,QAAQ,KAAK,EAAE;AACpH,UAAI,OAAO,SAAS,cAAc,WAAW,WAAW;AAEtD,gBAAQ,QAAQ,WAAW,UAAU,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACpE;AACA,YAAM,IAAI,iBAAiB,UAAU,OAAO;AAAA,IAC9C;AAAA,EAGF,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,eAAqB,oBAAY,CAAC,OAAe;AACrD,aAAS,UAAU,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAC7D,aAAS,SAAS,QAAQ,MAAM,CAAC;AAAA,EACnC,GAAG,CAAC,CAAC;AAEL,QAAM,QAAc,oBAAY,MAAM;AACpC,UAAM,OAAO,QAAQ;AACrB,QAAI,KAAK;AACT,aAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,IAAK,KAAI,KAAK,CAAC,EAAE,SAAS,QAAQ;AAAE,WAAK;AAAG;AAAA,IAAO;AACzF,QAAI,OAAO,GAAI;AACf,UAAM,OAAO,KAAK,EAAE;AACpB,WAAO,KAAK,MAAM,GAAG,EAAE,CAAC;AACxB,gBAAY,UAAU,KAAK,IAAI,GAAG,YAAY,UAAU,CAAC;AACzD,eAAW,UAAU;AACrB,aAAS,UAAW,CAAC,EAAE,IAAI,IAAI,GAAG,GAAG,MAAM,KAAK,QAAQ,IAAI,aAAa,KAAK,YAAY,CAAC,EAAmB,OAAO,SAAS,OAAO;AACrI,aAAS,SAAS,QAAQ,MAAM,CAAC;AACjC,UAAM;AAAA,EACR,GAAG,CAAC,CAAC;AAEL,QAAM,QAAc,oBAAY,MAAM;AACpC,WAAO,CAAC,CAAC;AAAG,gBAAY,UAAU;AAClC,aAAS,UAAU,CAAC;AAAG,aAAS,CAAC,CAAC;AAClC,eAAW,QAAQ;AAAA,EACrB,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,cAAoB,oBAAY,CAAC,IAAY,UAAyB;AAC1E,UAAM,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,QAAQ,OAAO,MAAM,EAAE;AACpE,UAAM,MAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACnD,kBAAc,WAAW,EAAE,SAAS,KAAK,UAAU,MAAM,IAAI,WAAW,MAAM,CAAC;AAAA,EAEjF,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,SAAe,oBAAY,YAAY;AAC3C,QAAI,CAAC,UAAU,QAAS;AACxB,cAAU,SAAS;AACnB,QAAI;AAAE,YAAM,WAAW,UAAU,OAAQ;AAAG,gBAAU,OAAO;AAAA,IAAG,SACzD,KAAK;AAAE,UAAI,CAAC,KAAK,GAAG,EAAG,WAAU,OAAO;AAAA,IAAG;AAAA,EACpD,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACL;AAAA,IAAQ;AAAA,IAAU;AAAA,IAAU,SAAS,gBAAgB,QAAQ;AAAA,IAAG;AAAA,IAChE;AAAA,IAAM;AAAA,IAAO;AAAA,IACb;AAAA,IAAM;AAAA,IAAM;AAAA,IAAO;AAAA,IAAO;AAAA,IAAc;AAAA,IAAa;AAAA,IACrD,SAAS,WAAW;AAAA,EACtB;AACF;AASO,IAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACxfA,IAAAC,UAAuB;;;ACAvB,IAAAC,UAAuB;AAiEd,IAAAC,uBAAA;AAHT,SAAS,SAAS,EAAE,MAAM,GAAuB;AAC/C,MAAI;AACJ,MAAI;AAAE,WAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,EAAG,SAAS,GAAG;AAAE,WAAO,OAAO,KAAK;AAAA,EAAG;AACjF,SAAO,8CAAC,aAAU,MAAM,MAAgB,UAAS,QAAO,eAAe,IAAI;AAC7E;AASO,SAAS,WAAW,EAAE,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,GAAoB;AACxF,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,IAAI,UAAU,CAAC;AACrB,QAAM,UAAU,OAAO,UAAU;AACjC,QAAM,QAAQ,EAAE,WAAW,OAAO;AAClC,SACE,+CAAC,aAAQ,WAAW,gBAAgB,UAAU,gBAAgB,KAAK,cAAY,OAC7E;AAAA,mDAAC,YAAO,WAAU,mBAChB;AAAA,oDAAC,OAAE,WAAW,YAAY,EAAE,QAAQ,YAAY,eAAY,QAAO;AAAA,MACnE,8CAAC,UAAK,WAAU,oBAAoB,iBAAM;AAAA,MACzC,OAAO,WAAW,8CAAC,UAAK,WAAU,oBAAmB,sBAAQ,IAAU;AAAA,MACvE,UAAU,8CAAC,UAAK,WAAU,8BAA6B,qBAAO,IAAU;AAAA,OAC3E;AAAA,IACC,UACC,+CAAC,SAAI,WAAU,oBAAmB,MAAK,SACrC;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MACvD,8CAAC,UAAM,iBAAO,SAAS,4DAAsD;AAAA,OAC/E,IAEA,8CAAC,SAAI,WAAU,mBACZ,mBAAS,OAAO,MAAM,IAAI,8CAAC,YAAS,OAAO,OAAO,SAAS,GAC9D;AAAA,IAED,CAAC,WAAW,UACX,+CAAC,YAAO,WAAU,mBACf;AAAA,aAAO,WAAW,8CAAC,UAAK,WAAU,mBAAkB,6DAA+C,IAAU,8CAAC,UAAK;AAAA,MACpH,+CAAC,YAAO,MAAK,UAAS,WAAU,mCAAkC,UAAU,SAAS,SAAS,MAAM,QAAQ,MAAM,GAChH;AAAA,sDAAC,OAAE,WAAW,YAAY,UAAU,UAAU,oBAAoB,eAAY,QAAO;AAAA,QACpF,UAAU,YAAa,EAAE,cAAc;AAAA,SAC1C;AAAA,OACF,IACE;AAAA,KACN;AAEJ;AAMO,SAAS,cAAc,EAAE,MAAM,YAAY,WAAW,cAAc,MAAM,GAAuB;AACtG,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,WAAW;AAClD,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,+CAAC,SAAI,WAAW,eAAe,OAAO,aAAa,KACjD;AAAA,mDAAC,YAAO,MAAK,UAAS,WAAU,kBAAiB,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,iBAAe,MACjG;AAAA,oDAAC,OAAE,WAAU,eAAc,eAAY,QAAO;AAAA,MAC9C,8CAAC,UAAM,sBAAY,aAAa,aAAa,iBAAiB,eAAe,UAAU,IAAI,mBAAkB;AAAA,MAC5G,YAAY,+CAAC,UAAK,WAAU,YAAW,eAAY,QAAO;AAAA,sDAAC,UAAK;AAAA,QAAE,8CAAC,UAAK;AAAA,QAAE,8CAAC,UAAK;AAAA,SAAE,IAAU;AAAA,MAC7F,8CAAC,OAAE,WAAW,kBAAkB,OAAO,OAAO,SAAS,eAAY,QAAO;AAAA,OAC5E;AAAA,IACC,OAAO,8CAAC,SAAI,WAAU,kBAAkB,gBAAK,IAAS;AAAA,KACzD;AAEJ;AAMO,SAAS,UAAU,EAAE,QAAQ,CAAC,GAAG,OAAO,GAAmB;AAChE,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,SACE,+CAAC,SAAI,WAAU,aACb;AAAA,mDAAC,YAAO,MAAK,UAAS,WAAU,kBAAiB,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,iBAAe,MACjG;AAAA,oDAAC,OAAE,WAAU,gBAAe,eAAY,QAAO;AAAA,MAC/C,+CAAC,UAAM;AAAA,cAAM;AAAA,QAAO;AAAA,QAAQ,MAAM,WAAW,IAAI,KAAK;AAAA,SAAI;AAAA,MAC1D,8CAAC,OAAE,WAAW,kBAAkB,OAAO,OAAO,SAAS,eAAY,QAAO;AAAA,OAC5E;AAAA,IACC,OACC,8CAAC,QAAG,WAAU,kBACX,gBAAM,IAAI,CAAC,GAAG,MACb,+CAAC,QACC;AAAA,oDAAC,UAAK,WAAU,yBAAyB,YAAE,UAAU,IAAI,GAAE;AAAA,MAC1D,EAAE,MACD,8CAAC,OAAE,MAAM,EAAE,KAAK,QAAO,UAAS,KAAI,uBAAsB,SAAS,SAAS,CAAC,MAAM,OAAO,GAAG,CAAC,IAAI,QAAY,YAAE,SAAS,EAAE,KAAI,IAC7H,8CAAC,UAAM,YAAE,SAAS,UAAS;AAAA,MAC9B,EAAE,SAAS,8CAAC,UAAK,WAAU,mBAAmB,YAAE,QAAO,IAAU;AAAA,SAL3D,EAAE,MAAM,CAMjB,CACD,GACH,IACE;AAAA,KACN;AAEJ;AAIA,SAAS,UAAU,MAAc,KAA6B;AAC5D,MAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,UAAU,IAAK,QAAO;AAChD,QAAM,MAAM,KAAK,MAAM,GAAG,GAAG;AAC7B,QAAM,KAAK,IAAI,YAAY,GAAG;AAC9B,UAAQ,KAAK,MAAM,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK,QAAQ,IAAI;AAC/D;AAKO,SAAS,YAAY,EAAE,SAAS,GAAG,IAAI,GAAqB;AACjE,QAAM,CAAC,UAAU,WAAW,IAAU,iBAAS,KAAK;AACpD,QAAM,SAAS,EAAE,SAAS;AAC1B,QAAM,MAAM,EAAE,QAAQ;AACtB,QAAM,UAAU,CAAC,YAAY,CAAC,EAAE,YAAY,UAAU,KAAK,IAAI,eAAe,IAAI;AAClF,QAAM,OAAO,WAAW,OAAO,UAAU;AACzC,QAAM,SAAS,IAAI,YAAY,CAAC;AAEhC,SACE,+CAAC,SAAI,WAAU,YACZ;AAAA,MAAE,YAAY,IAAI,eACjB,8CAAC,iBAAc,MAAM,EAAE,UAAU,YAAY,EAAE,YAAY,WAAW,EAAE,aAAa,CAAC,EAAE,MAAM,IAC5F;AAAA,IAEH,EAAE,SAAS,EAAE,MAAM,UAAU,IAAI,YAChC,8CAAC,YAAS,OAAO,EAAE,OAAO,aAAa,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,GAAG,OAAK,MAAC,IACxF;AAAA,IAEH,OACC,+CAAC,SAAI,WAAW,cAAc,SAAS,aAAa,KACjD;AAAA,eACG,8CAAC,YAAS,QAAQ,MAAM,eAAe,GAAG,WAAW,EAAE,eAAe,GAAG,GAAG,gBAAgB,IAAI,gBAAgB,IAChH,8CAAC,SAAI,WAAU,aAAa,gBAAK;AAAA,MACpC,EAAE,YAAY,8CAAC,UAAK,WAAU,aAAY,eAAY,QAAO,IAAK;AAAA,OACrE,IACE;AAAA,IAEH,WAAW,OACV,+CAAC,YAAO,MAAK,UAAS,WAAU,YAAW,SAAS,MAAM,YAAY,IAAI,GACxE;AAAA,oDAAC,OAAE,WAAU,oBAAmB,eAAY,QAAO;AAAA,MAAE;AAAA,MACrD,8CAAC,UAAK,WAAU,2BAA2B,cAAI,SAAS,MAAO,IAAI,OAAO,eAAe,IAAI,gBAAiB,KAAK,MAAM,IAAI,SAAS,GAAG,IAAI,KAAM,gBAAe;AAAA,OACpK,IACE,YAAY,IAAI,mBAAmB,IAAI,SAAS,IAAI,kBACtD,+CAAC,YAAO,MAAK,UAAS,WAAU,YAAW,SAAS,MAAM,YAAY,KAAK,GACzE;AAAA,oDAAC,OAAE,WAAU,kBAAiB,eAAY,QAAO;AAAA,MAAE;AAAA,OACrD,IACE;AAAA,IAEH,EAAE,eAAe,EAAE,YAAY,SAC9B,8CAAC,YAAS,OAAO,EAAE,aAAa,QAAQ,IAAI,kBAAkB,OAAK,MAAC,WAAW,IAAI,oBAAoB,KAAK,SAAS,IAAI,QAAQ,IAC/H;AAAA,IAEH,EAAE,SACD;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ,EAAE;AAAA,QACV,SAAS,IAAI,iBAAiB,CAAC,GAAG,EAAE,OAAO,IAAI;AAAA,QAC/C,SAAS,IAAI,mBAAmB,CAAC,GAAG,EAAE,OAAO,IAAI;AAAA,QACjD,SAAS,IAAI;AAAA,QACb,SAAS,IAAI,kBAAkB,IAAI,eAAe,EAAE,EAAE;AAAA;AAAA,IACxD,IACE;AAAA,IAEH,EAAE,aAAa,EAAE,UAAU,SAAS,8CAAC,aAAU,OAAO,EAAE,WAAW,QAAQ,IAAI,gBAAgB,IAAK;AAAA,IAEpG,EAAE,UACD,+CAAC,SAAI,WAAU,eAAc,MAAK,UAChC;AAAA,qDAAC,UAAK,WAAU,YAAW,eAAY,QAAO;AAAA,sDAAC,UAAK;AAAA,QAAE,8CAAC,UAAK;AAAA,QAAE,8CAAC,UAAK;AAAA,SAAE;AAAA,MACtE,+CAAC,UAAK,WAAU,qBACb;AAAA,UAAE,UAAU,aAAa;AAAA,QACzB,EAAE,OAAO,EAAE,IAAI,SAAS,+CAAC,UAAK,WAAU,mBAAkB;AAAA;AAAA,UAAI,EAAE,IAAI;AAAA,WAAO,IAAU;AAAA,QACrF,EAAE,OAAO,EAAE,IAAI,SAAS,+CAAC,UAAK,WAAU,mBAAkB;AAAA;AAAA,UAAI,EAAE,IAAI;AAAA,WAAO,IAAU;AAAA,SACxF;AAAA,MACC,EAAE,QAAQ,8CAAC,UAAK,WAAU,0BAA0B,iBAAO,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE,GAAE,IAAU;AAAA,OAC9F,IACE;AAAA,IAEH,EAAE,UAAU,+CAAC,SAAI,WAAU,eAAc;AAAA,oDAAC,OAAE,WAAU,qBAAoB,eAAY,QAAO;AAAA,MAAE;AAAA,OAAO,IAAS;AAAA,IAE/G,EAAE,QACD,+CAAC,SAAI,WAAU,aAAY,MAAK,SAC9B;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MACvD,8CAAC,UAAK,WAAU,kBAAkB,cAAI,YAAY,IAAI,UAAU,EAAE,KAAK,IAAI,EAAE,OAAM;AAAA,MAClF,EAAE,aAAa,IAAI,UAClB,+CAAC,YAAO,MAAK,UAAS,WAAU,mBAAkB,SAAS,IAAI,SAC7D;AAAA,sDAAC,OAAE,WAAU,yBAAwB,eAAY,QAAO;AAAA,QAAE;AAAA,SAC5D,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;AAIA,SAAS,aAAgD;AACvD,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,IAAU,eAA6C,IAAI;AACjE,EAAM,kBAAU,MAAM,MAAM;AAAE,QAAI,EAAE,QAAS,cAAa,EAAE,OAAO;AAAA,EAAG,GAAG,CAAC,CAAC;AAC3E,SAAO,CAAC,MAAM,CAAC,SAAiB;AAC9B,UAAM,IAAI,UAAU,aAAa,UAAU,UAAU,YAAY,UAAU,UAAU,UAAU,IAAI,IAAI,QAAQ,OAAO;AACtH,MAAE,MAAM,MAAM;AAAA,IAAC,CAAC,EAAE,QAAQ,MAAM;AAC9B,cAAQ,IAAI;AACZ,UAAI,EAAE,QAAS,cAAa,EAAE,OAAO;AACrC,QAAE,UAAU,WAAW,MAAM,QAAQ,KAAK,GAAG,IAAI;AAAA,IACnD,CAAC;AAAA,EACH,CAAC;AACH;AAUO,SAAS,WAAW,EAAE,OAAO,IAAI,GAAoB;AAC1D,QAAM,CAAC,QAAQ,IAAI,IAAI,WAAW;AAClC,QAAM,OAAO,MAAM,SAAS,MAAM,SAAS,SAAS,CAAC;AACrD,QAAM,OAAO,MAAM,SAAS,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,MAAM;AAChF,QAAM,cAAc,MAAM,SAAS;AACnC,QAAM,KAAK,KAAK;AAChB,MAAI,CAAC,IAAI,eAAgB,QAAO;AAChC,SACE,+CAAC,SAAI,WAAU,eAAc,MAAK,SAAQ,cAAW,mBACnD;AAAA,mDAAC,YAAO,MAAK,UAAS,WAAW,aAAa,SAAS,aAAa,KAAK,SAAS,MAAM,KAAK,eAAe,IAAI,CAAC,GAAG,cAAW,gBAC7H;AAAA,oDAAC,OAAE,WAAW,YAAY,SAAS,UAAU,SAAS,eAAY,QAAO;AAAA,MACzE,8CAAC,UAAK,WAAU,iBAAiB,mBAAS,WAAW,QAAO;AAAA,OAC9D;AAAA,IACC,eAAe,IAAI,UAClB,8CAAC,YAAO,MAAK,UAAS,WAAU,WAAU,SAAS,IAAI,SAAS,cAAW,mBACzE,wDAAC,OAAE,WAAU,yBAAwB,eAAY,QAAO,GAC1D,IACE;AAAA,IACH,MAAM,SAAS,UAAU,IAAI,SAC5B,8CAAC,YAAO,MAAK,UAAS,WAAU,WAAU,SAAS,MAAM,IAAI,OAAQ,IAAI,GAAG,cAAW,mBACrF,wDAAC,OAAE,WAAU,uBAAsB,eAAY,QAAO,GACxD,IACE;AAAA,IACH,eAAe,IAAI,aAClB,+CAAO,kBAAN,EACC;AAAA,oDAAC,YAAO,MAAK,UAAS,WAAW,aAAa,OAAO,OAAO,WAAW,KAAK,SAAS,MAAM,IAAI,WAAY,KAAK,IAAI,IAAI,GAAG,gBAAc,OAAO,MAAM,cAAW,iBAC/J,wDAAC,OAAE,WAAU,mBAAkB,eAAY,QAAO,GACpD;AAAA,MACA,8CAAC,YAAO,MAAK,UAAS,WAAW,aAAa,OAAO,SAAS,WAAW,KAAK,SAAS,MAAM,IAAI,WAAY,KAAK,IAAI,MAAM,GAAG,gBAAc,OAAO,QAAQ,cAAW,gBACrK,wDAAC,OAAE,WAAU,qBAAoB,eAAY,QAAO,GACtD;AAAA,OACF,IACE;AAAA,IACH,IAAI,eAAe,IAAI,aAAa,KAAK,IAAI;AAAA,KAChD;AAEJ;AAOO,SAAS,SAAS,EAAE,OAAO,IAAI,GAAkB;AACtD,QAAM,SAAS,MAAM,SAAS;AAC9B,QAAM,OAAO,SAAS,IAAI,WAAY,MAAM,UAAU,IAAI;AAC1D,QAAM,SAAS,SAAS,IAAI,aAAa,IAAI;AAC7C,QAAM,QAAQ,MAAM,SAAS,CAAC,EAAE;AAEhC,SACE,+CAAC,aAAQ,WAAW,iBAAiB,MAAM,MAAM,cAAY,OAAO,IAAI,KAAK,QAAQ,SAAS,YAAY,KAAK,IAAI,KACjH;AAAA,mDAAC,SAAI,WAAU,iBACZ;AAAA,UAAI,cACH,8CAAC,UAAK,WAAW,mBAAmB,MAAM,MAAM,eAAY,QACzD,mBAAS,8CAAC,SAAI,KAAK,QAAQ,KAAI,IAAG,IAAK,SACpC,8CAAC,UAAK,WAAU,kBAAmB,mBAAQ,OAAO,MAAM,GAAG,CAAC,EAAE,YAAY,GAAE,IAC5E,8CAAC,OAAE,WAAW,YAAY,IAAI,iBAAiB,YAAY,GACjE,IACE;AAAA,MACJ,8CAAC,UAAK,WAAU,WAAW,gBAAK;AAAA,MAC/B,QAAQ,8CAAC,gBAAa,WAAU,YAAW,OAAO,OAAO,IAAK;AAAA,MAC9D,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,8CAAC,UAAK,WAAU,kBAAkB,gBAAM,SAAS,KAAK,CAAC,MAAM,EAAE,KAAK,EAAG,OAAM,IAAU;AAAA,OAChI;AAAA,IACA,+CAAC,SAAI,WAAU,iBACZ;AAAA,YAAM,SAAS,IAAI,CAAC,MACnB,8CAAC,SAAe,WAAW,aAAa,EAAE,UAAU,gBAAgB,KAClE,wDAAC,eAAY,SAAS,GAAG,KAAU,KAD3B,EAAE,EAEZ,CACD;AAAA,MACD,8CAAC,cAAW,OAAc,KAAU;AAAA,OACtC;AAAA,KACF;AAEJ;;;ADhTuB,IAAAC,uBAAA;AA5CvB,IAAM,eAAe;AACrB,IAAM,WAAW;AAIV,SAAS,cAAc,MAAqC;AACjE,QAAM,SAAqD,CAAC;AAC5D,GAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM;AAC1B,UAAM,OAAO,CAAC,EAAE,EAAE,UAAW,EAAE,SAAS,EAAE,MAAM,UAAW,EAAE,SAAS,EAAE,WAAW,EAAE;AACrF,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,UAAM,IAAI,EAAE,YAAY,KAAK,MAAM,EAAE,SAAS,IAAI;AAClD,UAAM,QAAQ,QAAQ,KAAK,KAAK,QAAQ,KAAK,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,eAAe,CAAC,CAAC;AAC5F,QAAI,QAAQ,CAAC,KAAK,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,SAAS,KAAK,UAAU,SAAS,EAAE,UAAU,OAAO,OAAO;AAC5G,WAAK,SAAS,KAAK,CAAC;AACpB,WAAK,IAAI,KAAK,OAAO,KAAK,IAAI;AAC9B;AAAA,IACF;AACA,WAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,UAAU,CAAC,CAAC,GAAG,GAAG,MAAM,KAAK,EAAE,GAAG,CAAC;AAAA,EACnF,CAAC;AACD,SAAO;AACT;AAEA,IAAM,SAAS,CAACC,SAA2C;AACzD,QAAM,IAAIA,OAAM,IAAI,KAAKA,IAAG,IAAI;AAChC,SAAO,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,IAAI;AACvD;AAEA,SAAS,SAAS,KAAqB;AACrC,QAAM,IAAI,IAAI,KAAK,GAAG;AACtB,QAAM,SAAQ,oBAAI,KAAK,GAAE,aAAa;AACtC,QAAM,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,EAAE,aAAa;AACvD,MAAI,QAAQ,MAAO,QAAO;AAC1B,MAAI,QAAQ,KAAM,QAAO;AACzB,SAAO,EAAE,mBAAmB,CAAC,GAAG,EAAE,SAAS,QAAQ,KAAK,WAAW,OAAO,OAAO,CAAC;AACpF;AAEA,SAAS,YAAY,EAAE,QAAQ,CAAC,GAAG,OAAO,GAAsF;AAC9H,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,SACE,8CAAC,SAAI,WAAU,eACZ,gBAAM,IAAI,CAAC,GAAG,MAAM;AACnB,UAAM,KAAiB,OAAO,MAAM,WAAW,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI;AACvE,WACE,+CAAC,YAAO,MAAK,UAA0B,WAAU,oBAAmB,SAAS,MAAM,UAAU,OAAO,GAAG,QAAQ,GAAG,KAAK,GACpH;AAAA,SAAG,OAAO,8CAAC,OAAE,WAAW,WAAW,GAAG,MAAM,eAAY,QAAO,IAAK;AAAA,MACrE,+CAAC,UAAK,WAAU,oBACd;AAAA,sDAAC,UAAK,WAAU,qBAAqB,aAAG,OAAM;AAAA,QAC7C,GAAG,cAAc,8CAAC,UAAK,WAAU,oBAAoB,aAAG,aAAY,IAAU;AAAA,SACjF;AAAA,MACA,8CAAC,OAAE,WAAU,uCAAsC,eAAY,QAAO;AAAA,SAN7C,GAAG,MAAM,CAOpC;AAAA,EAEJ,CAAC,GACH;AAEJ;AAEA,SAAS,eAAe;AACtB,SACE,8CAAC,SAAI,WAAU,YAAW,eAAY,QACnC,WAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MACX,+CAAC,SAAY,WAAU,iBACrB;AAAA,kDAAC,SAAI,WAAU,0BAAyB,OAAO,EAAE,OAAO,IAAI,QAAQ,GAAG,GAAG;AAAA,IAC1E,+CAAC,SAAI,WAAU,kBACb;AAAA,oDAAC,SAAI,WAAU,WAAU,OAAO,EAAE,OAAO,IAAI,QAAQ,OAAO,QAAQ,GAAG,GAAG;AAAA,MAC1E,8CAAC,SAAI,WAAU,WAAU,OAAO,EAAE,OAAO,IAAI,QAAQ,OAAO,QAAQ,GAAG,GAAG;AAAA,MAC1E,8CAAC,SAAI,WAAU,WAAU,OAAO,EAAE,OAAO,IAAI,QAAQ,OAAO,QAAQ,GAAG,GAAG;AAAA,OAC5E;AAAA,OANQ,CAOV,CACD,GACH;AAEJ;AA2BO,SAAS,eAAe;AAAA,EAC7B,WAAW,CAAC;AAAA,EAAG;AAAA,EAAK;AAAA,EAAQ;AAAA,EAAO,cAAc,CAAC;AAAA,EAAG;AAAA,EACrD,aAAa;AAAA,EAAmB;AAAA,EAAkB,YAAY;AAAA,EAC9D;AAAA,EAAa,YAAY;AAC3B,GAAwB;AACtB,QAAM,WAAiB,eAA8B,IAAI;AACzD,QAAM,QAAc,eAAO,IAAI;AAC/B,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,CAAC;AACxC,QAAM,OAAa,eAAO,CAAC;AAE3B,QAAM,WAAW,CAAC,WAAqB;AACrC,UAAM,KAAK,SAAS;AACpB,QAAI,CAAC,GAAI;AAET,OAAG,SAAS,EAAE,KAAK,GAAG,cAAc,UAAU,SAAS,WAAW,OAAO,CAAC;AAC1E,UAAM,UAAU;AAChB,YAAQ,CAAC;AACT,SAAK,UAAU,SAAS;AAAA,EAC1B;AAEA,QAAM,WAAW,MAAM;AACrB,UAAM,KAAK,SAAS;AACpB,QAAI,CAAC,GAAI;AACT,UAAM,MAAM,GAAG,eAAe,GAAG,YAAY,GAAG;AAChD,UAAM,UAAU,OAAO;AACvB,QAAI,MAAM,WAAW,MAAM;AAAE,cAAQ,CAAC;AAAG,WAAK,UAAU,SAAS;AAAA,IAAQ;AAAA,EAC3E;AAEA,EAAM,wBAAgB,MAAM;AAC1B,UAAM,KAAK,SAAS;AACpB,QAAI,CAAC,GAAI;AACT,QAAI,MAAM,SAAS;AAAE,SAAG,YAAY,GAAG;AAAc,WAAK,UAAU,SAAS;AAAA,IAAQ,MAChF,SAAQ,KAAK,IAAI,GAAG,SAAS,SAAS,KAAK,OAAO,CAAC;AAAA,EAE1D,GAAG,CAAC,QAAQ,CAAC;AAIb,EAAM,kBAAU,MAAM;AACpB,UAAM,KAAK,SAAS;AACpB,UAAM,QAAQ,MAAO,GAAG;AACxB,QAAI,CAAC,MAAM,CAAC,SAAS,OAAO,mBAAmB,YAAa;AAC5D,UAAM,KAAK,IAAI,eAAe,MAAM;AAAE,UAAI,MAAM,QAAS,IAAG,YAAY,GAAG;AAAA,IAAc,CAAC;AAC1F,OAAG,QAAQ,KAAK;AAChB,WAAO,MAAM,GAAG,WAAW;AAAA,EAC7B,GAAG,CAAC,CAAC;AAEL,QAAM,SAAe,gBAAQ,MAAM,cAAc,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACtE,QAAM,QAAQ,CAAC,SAAS,UAAU,WAAW;AAE7C,SACE,+CAAC,SAAI,WAAW,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,KAAK,UAAU,UAClF;AAAA,mDAAC,SAAI,WAAU,WAAU,MAAK,OAAM,cAAW,gBAC5C;AAAA,iBAAW,aAAa,WAAW,cAAc,8CAAC,gBAAa,IAAK;AAAA,MAEpE,WAAW,iBACV,+CAAC,SAAI,WAAU,YACb;AAAA,sDAAC,UAAK,WAAU,iBAAgB,wDAAC,OAAE,WAAU,eAAc,eAAY,QAAO,GAAE;AAAA,QAChF,8CAAC,QAAG,WAAU,kBAAkB,cAAI,aAAa,sCAAgC;AAAA,QACjF,8CAAC,OAAE,WAAU,iBACV,oBAAU,qBACP,sHACA,0CAAqC,QAAQ,OAAO,QAAQ,MAAM,MAAM,oDAC9E;AAAA,QACC,IAAI,cACH,+CAAC,YAAO,MAAK,UAAS,WAAU,qCAAoC,SAAS,IAAI,aAC/E;AAAA,wDAAC,OAAE,WAAU,yBAAwB,eAAY,QAAO;AAAA,UAAE;AAAA,WAC5D,IACE;AAAA,SACN,IACE;AAAA,MAEH,QACC,cAAc,YAAY,IACxB,+CAAC,SAAI,WAAU,aACb;AAAA,sDAAC,UAAK,WAAU,kBAAiB,wDAAC,OAAE,WAAW,WAAW,WAAW,eAAY,QAAO,GAAE;AAAA,QAC1F,8CAAC,QAAG,WAAU,mBAAmB,sBAAW;AAAA,QAC3C,mBAAmB,8CAAC,OAAE,WAAU,kBAAkB,4BAAiB,IAAO;AAAA,QAC3E,8CAAC,eAAY,OAAO,aAAa,QAAgB;AAAA,SACnD,IAEA;AAAA,MAEH,OAAO,IAAI,CAAC,GAAG,MAAM;AACpB,cAAM,OAAO,OAAO,IAAI,CAAC;AACzB,cAAM,IAAI,OAAO,EAAE,SAAS,CAAC,EAAE,SAAS;AACxC,cAAM,UAAU,CAAC,CAAC,MAAM,CAAC,QAAQ,OAAO,KAAK,SAAS,CAAC,EAAE,SAAS,MAAM;AACxE,eACE,+CAAO,kBAAN,EACE;AAAA,oBAAU,8CAAC,SAAI,WAAU,WAAU,wDAAC,UAAM,mBAAS,CAAE,GAAE,GAAO,IAAS;AAAA,UACxE,8CAAC,YAAS,OAAO,GAAG,KAAU;AAAA,aAFX,EAAE,OAAO,CAG9B;AAAA,MAEJ,CAAC;AAAA,OACH;AAAA,IAEC,OACC,+CAAC,YAAO,MAAK,UAAS,WAAU,YAAW,SAAS,MAAM,SAAS,IAAI,GACrE;AAAA,oDAAC,OAAE,WAAU,oBAAmB,eAAY,QAAO;AAAA,MAClD;AAAA,MAAK;AAAA,MAAa,SAAS,IAAI,KAAK;AAAA,OACvC,IACE;AAAA,KACN;AAEJ;AAGO,IAAM,gBAAgB,EAAE,cAAc;;;AEpN7C,IAAAC,UAAuB;AAiIY,IAAAC,uBAAA;AAxE5B,SAAS,aAAa;AAAA,EAC3B;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAM;AAAA,EAAU,cAAc;AAAA,EAAmB;AAAA,EACnE;AAAA,EAAmB;AAAA,EAAa;AAAA,EAAa,sBAAsB;AAAA,EACnE;AAAA,EAAe;AAAA,EAAgB;AAAA,EAC/B,QAAQ,CAAC;AAAA,EAAG;AAAA,EAAgB;AAAA,EAAY;AAAA,EACxC;AAAA,EAAO;AAAA,EAAe;AAAA,EAAM;AAAA,EAAQ;AAAA,EACpC;AAAA,EAAU;AACZ,GAAsB;AACpB,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,SAAS,EAAE;AAClD,QAAM,CAAC,SAAS,UAAU,IAAU,iBAA+B,IAAI;AACvE,QAAM,CAAC,cAAc,eAAe,IAAU,iBAA0B,CAAC,CAAC;AAC1E,QAAM,CAAC,WAAW,YAAY,IAAU,iBAAS,KAAK;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAU,iBAAwB,IAAI;AAC9D,QAAM,SAAe,eAA6B,IAAI;AACtD,QAAM,OAAa,eAAuB,IAAI;AAC9C,QAAM,YAAkB,eAA4B,IAAI;AACxD,QAAM,SAAS,eAAe,mBAAmB,EAAE,SAAS,MAAM;AAAA,EAAC,EAAE,CAAC;AAEtE,EAAM,kBAAU,MAAM;AAAE,QAAI,SAAS,QAAQ,UAAU,KAAM,SAAQ,KAAK;AAAA,EAAG,GAAG,CAAC,KAAK,CAAC;AACvF,QAAM,SAAS,CAAC,MAAc;AAAE,YAAQ,CAAC;AAAG,qBAAiB,cAAc,CAAC;AAAA,EAAG;AAE/E,QAAM,YAAY,OAAO;AACzB,QAAM,UAAU,CAAC,YAAY,CAAC,cAAc,KAAK,KAAK,EAAE,SAAS,KAAK,OAAO,MAAM,SAAS;AAE5F,QAAM,QAAQ,CAAC,QAAgB;AAAE,cAAU,GAAG;AAAG,eAAW,MAAM,UAAU,IAAI,GAAG,GAAI;AAAA,EAAG;AAE1F,QAAM,SAAS,MAAM;AACnB,QAAI,CAAC,QAAS;AACd,aAAS,KAAK,KAAK,GAAG,OAAO,MAAM,IAAI,CAAC,MAAM;AAC5C,YAAM,EAAE,MAAM,OAAO,GAAG,KAAK,IAAI;AACjC,aAAO;AAAA,IACT,CAAC,CAAC;AACF,WAAO,EAAE;AACT,WAAO,MAAM;AACb,eAAW,IAAI;AAAA,EACjB;AAGA,QAAM,UAAU,CAAC,MAA4B;AAC3C,QAAI,CAAC,kBAAmB;AACxB,UAAM,QAAQ,sBAAsB,EAAE,aAAa,EAAE,qBAAqB,QAAQ,aAAa,YAAY,CAAC;AAC5G,QAAI,MAAM,YAAY,MAAM,SAAS,QAAQ;AAAE,YAAM,MAAM,SAAS,CAAC,EAAE,OAAO;AAAG,kBAAY,SAAS,MAAM,QAAQ;AAAA,IAAG;AACvH,QAAI,CAAC,MAAM,UAAU,CAAC,MAAM,MAAM,OAAQ;AAC1C,MAAE,eAAe;AACjB,WAAO,IAAI,MAAM,KAAK;AAAA,EACxB;AAGA,EAAM,kBAAU,MAAM;AACpB,QAAI,CAAC,WAAW,QAAQ,SAAS,aAAa,CAAC,gBAAgB;AAAE,sBAAgB,CAAC,CAAC;AAAG;AAAA,IAAQ;AAC9F,QAAI,OAAO,mBAAmB,YAAY;AACxC,UAAI,OAAO;AACX,cAAQ,QAAQ,eAAe,QAAQ,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM;AAAE,YAAI,CAAC,KAAM,iBAAgB,KAAK,CAAC,CAAC;AAAA,MAAG,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACnH,aAAO,MAAM;AAAE,eAAO;AAAA,MAAM;AAAA,IAC9B;AACA,UAAM,KAAK,QAAQ,SAAS,IAAI,YAAY;AAC5C,oBAAgB,eAAe,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,OAAO,EAAE,eAAe,KAAK,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,EACvH,GAAG,CAAC,SAAS,cAAc,CAAC;AAE5B,QAAM,aAAmB,gBAAQ,MAAM;AACrC,QAAI,CAAC,WAAW,QAAQ,SAAS,WAAW,CAAC,cAAe,QAAO,CAAC;AACpE,UAAM,KAAK,QAAQ,SAAS,IAAI,YAAY;AAC5C,WAAO,cAAc,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,QAAQ,OAAO,EAAE,eAAe,KAAK,YAAY,EAAE,SAAS,CAAC,CAAC;AAAA,EACzH,GAAG,CAAC,SAAS,aAAa,CAAC;AAE3B,QAAM,YAAwB,WACzB,QAAQ,SAAS,UAAU,aAAa,cAAc,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,OAAO;AAChF,UAAM,QAAQ;AACd,UAAM,UAAU;AAChB,WAAO;AAAA,MACL,IAAI,GAAG;AAAA,MAAI,OAAO,QAAQ,SAAS,UAAU,MAAM,MAAM,KAAK,QAAQ;AAAA,MACtE,aAAa,GAAG;AAAA,MAAa,MAAM,GAAG;AAAA,MAAM,MAAM,QAAQ;AAAA,MAC1D,UAAU,MAAM,WAAW,8CAAC,WAAQ,MAAM,MAAM,UAAU,MAAK,MAAK,IAAK;AAAA,MACzE,UAAU,MAAM;AACd,cAAM,SAAS,QAAQ,SAAS,UAC3B,MAAM,YAAY,MAAM,MAAM,KAAK,MAAM,MAAM,KAAK,MACrD,OAAO,QAAQ,SAAS,QAAQ,SAAS;AAC7C,eAAO,WAAW,OAAO,QAAQ,aAAa,QAAQ,MAAM,QAAQ,IAAI,MAAM;AAC9E,mBAAW,IAAI;AACf,YAAI,MAAM,UAAW,YAAW,MAAM;AAAE,mBAAS,MAAM,MAAM,IAAI,CAAC,CAAC;AAAG,iBAAO,EAAE;AAAA,QAAG,GAAG,CAAC;AACtF,YAAI,MAAM,IAAK,OAAM,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,CAAC,IACC,CAAC;AACL,QAAM,WAAW,CAAC,CAAC,WAAW,UAAU,SAAS;AAEjD,QAAM,UAAU,CAAC,MAA2B;AAC1C,QAAI,UAAU;AACZ,UAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,OAAO;AACxC,UAAE,eAAe;AACjB,cAAM,SAAS,SAAS,cAA2B,sCAAsC,KAAK,SAAS,cAA2B,4BAA4B;AAC9J,YAAI,OAAQ,QAAO,MAAM;AAAA,YAAQ,YAAW,IAAI;AAChD;AAAA,MACF;AACA,UAAI,EAAE,QAAQ,aAAa,EAAE,QAAQ,aAAa;AAEhD,UAAE,eAAe;AACjB,cAAM,OAAO,SAAS,cAAc,uBAAuB;AAC3D,YAAI,KAAM,MAAK,cAAc,IAAI,cAAc,WAAW,EAAE,KAAK,EAAE,KAAK,SAAS,KAAK,CAAC,CAAC;AACxF;AAAA,MACF;AACA,UAAI,EAAE,QAAQ,UAAU;AAAE,UAAE,eAAe;AAAG,mBAAW,IAAI;AAAG;AAAA,MAAQ;AAAA,IAC1E;AACA,UAAM,MAAM,EAAE,WAAW,EAAE;AAC3B,QAAI,OAAO,EAAE,QAAQ,SAAS;AAAE,QAAE,eAAe;AAAG,aAAO;AAAG;AAAA,IAAQ;AACtE,QAAI,EAAE,QAAQ,YAAY,QAAQ,QAAQ;AAAE,QAAE,eAAe;AAAG,aAAO;AAAA,IAAG;AAAA,EAC5E;AAEA,QAAM,QAAQ,MAAM;AAClB,QAAI,CAAC,aAAc;AACnB,QAAI,WAAW;AAAE,UAAI,UAAU,QAAS,WAAU,QAAQ;AAAG,mBAAa,KAAK;AAAG;AAAA,IAAQ;AAC1F,iBAAa,IAAI;AACjB,UAAM,MAAM,aAAa;AAAA,MACvB,QAAQ,CAAC,GAAW,SAAiC;AAAE,gBAAS,QAAQ,KAAK,UAAW,KAAK,OAAO,OAAO,MAAM,MAAM,CAAC;AAAA,MAAG;AAAA,MAC3H,OAAO,MAAM,aAAa,KAAK;AAAA,IACjC,CAAC;AACD,cAAU,UAAU,OAAO,QAAQ,aAAa,MAAM,MAAM;AAAA,IAAC;AAAA,EAC/D;AAEA,SACE,+CAAC,SAAI,WAAW,kBAAkB,WAAW,iBAAiB,OAAO,SAAS,eAAe,KAC1F;AAAA,UAAM,SACL,8CAAC,SAAI,WAAU,aAAY,cAAW,mBACnC,gBAAM,IAAI,CAAC,MACV,+CAAC,SAAI,WAAU,iBACb;AAAA,oDAAC,OAAE,WAAU,yBAAwB,eAAY,QAAO;AAAA,MACxD,8CAAC,UAAK,WAAU,kBAAkB,YAAE,SAAS,EAAE,cAAc,EAAE,YAAY,SAAS,aAAa,KAAI;AAAA,MACpG,iBACC,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAAS,MAAM,eAAe,EAAE,EAAE,GAAG,cAAW,yBAC5F,wDAAC,OAAE,WAAU,WAAU,eAAY,QAAO,GAC5C,IACE;AAAA,SAP8B,EAAE,EAQtC,CACD,GACH,IACE;AAAA,IAEH;AAAA,IAED;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS,oBAAoB,CAAC,UAAU,OAAO,IAAI,KAAK,IAAI;AAAA,QAC5D,UAAU,CAAC,MAAM;AAAE,gBAAM,EAAE,CAAC,EAAE,OAAO;AAAG,sBAAY,SAAS,CAAC;AAAA,QAAG;AAAA,QACjE,QAAQ;AAAA,QAAa;AAAA,QACrB,UAAU,CAAC,qBAAqB;AAAA,QAChC,OAAM;AAAA,QACN,MAAM,cAAc,YAAY,QAAQ,MAAM,QAAK,IAAI;AAAA,QAEvD,yDAAC,SAAI,KAAK,MAAM,WAAU,mBACvB;AAAA,iBAAO,MAAM,SACZ,8CAAC,SAAI,WAAU,cACb,wDAAC,aAAU,OAAO,OAAO,OAAO,MAAM,SAAS,KAAK,IAAI,UAAU,OAAO,QAAQ,SAAS,OAAO,OAAO,QAAQ,kBAAkB,GACpI,IACE;AAAA,UAEJ;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cAAQ,OAAO;AAAA,cAAM,UAAU;AAAA,cAAQ,UAAU;AAAA,cACtD,WAAW;AAAA,cAAS;AAAA,cAAkB,WAAW;AAAA,cACjD,aAAa,WAAW,iCAAiC;AAAA,cACzD;AAAA,cAAoB;AAAA,cAAsB;AAAA,cAC1C,SAAS,SAAS,IAAI;AAAA,cAAG,SAAS;AAAA,cAAI,WAAU;AAAA;AAAA,UAClD;AAAA,UAEA,+CAAC,SAAI,WAAU,aACZ;AAAA,gCACC,8CAAC,kBAAe,SAAS,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,aAAa,aAA0B,OAAM,gBAAe,MAAK,QAAO,IACzJ;AAAA,YACH,eACC,8CAAC,YAAO,MAAK,UAAS,WAAW,kBAAkB,YAAY,aAAa,KAAK,SAAS,OAAO,gBAAc,WAAW,cAAY,YAAY,mBAAmB,WACnK,wDAAC,OAAE,WAAW,YAAY,YAAY,aAAa,eAAe,eAAY,QAAO,GACvF,IACE;AAAA,YACH;AAAA,YACD,8CAAC,UAAK,WAAU,iBAAgB;AAAA,YAC/B,aAAa,KAAK,SAAS,YAAY,MACtC,+CAAC,UAAK,WAAW,0BAA0B,KAAK,SAAS,YAAY,OAAO,YAAY,KAAM;AAAA,mBAAK;AAAA,cAAO;AAAA,cAAE;AAAA,eAAU,IACpH;AAAA,YACH,OACC,+CAAC,YAAO,MAAK,UAAS,WAAU,YAAW,SAAS,QAAQ,cAAW,mBACrE;AAAA,4DAAC,OAAE,WAAU,qBAAoB,eAAY,QAAO;AAAA,cACpD,8CAAC,UAAK,kBAAI;AAAA,eACZ,IAEA,+CAAC,YAAO,MAAK,UAAS,WAAU,YAAW,SAAS,QAAQ,UAAU,CAAC,SAAS,cAAW,gBACzF;AAAA,4DAAC,OAAE,WAAU,2BAA0B,eAAY,QAAO;AAAA,cAC1D,8CAAC,UAAK,WAAU,kBAAiB,kBAAI;AAAA,eACvC;AAAA,aAEJ;AAAA,WACF;AAAA;AAAA,IACF;AAAA,IAEC,SAAS,+CAAC,SAAI,WAAU,cAAa,MAAK,UAAS;AAAA,oDAAC,OAAE,WAAU,wBAAuB,eAAY,QAAO;AAAA,MAAG;AAAA,OAAO,IAAS;AAAA,IAC7H,QAAQ,CAAC,SAAS,8CAAC,SAAI,WAAU,YAAY,gBAAK,IAAS;AAAA,IAE5D;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QAAU,WAAW;AAAA,QAAM,WAAU;AAAA,QAAY,QAAQ;AAAA,QAC/D,UAAU,SAAS,MAAM;AAAA,QAAK,WAAW;AAAA,QAAK,WAAU;AAAA,QACxD,SAAS,MAAM,WAAW,IAAI;AAAA,QAAG,aAAa;AAAA,QAAO,gBAAc;AAAA,QACnE,OAAO,WAAW,QAAQ,SAAS,UAAU,aAAa;AAAA,QAE1D;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YAAW,WAAW;AAAA,YAC7B,QAAQ,8CAAC,SAAI,WAAU,gBAAgB,qBAAW,QAAQ,SAAS,UAAU,aAAa,kBAAiB;AAAA,YAC3G,SAAS,MAAM,WAAW,IAAI;AAAA;AAAA,QAChC;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;;;AC3QA,IAAAC,UAAuB;AAkDf,IAAAC,uBAAA;AA1CR,IAAMC,WAAU,aAAa;AAkBtB,SAAS,eAAe,EAAE,cAAc,cAAc,aAAa,SAAS,OAAO,GAAwB;AAChH,QAAM,CAAC,MAAM,OAAO,IAAU,iBAAS,KAAK;AAC5C,QAAM,SAAe,eAA0B,IAAI;AACnD,QAAM,QAAQ,gBAAgB;AAC9B,QAAM,KAAK,gBAAgB;AAC3B,QAAM,SAAS,eAAe;AAC9B,MAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,OAAQ,QAAO;AAEhD,QAAM,QAAQ,MAAM,OAAO,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,IAAI;AAC9D,QAAM,OAAO,MAAM,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,KAAK,KAAK,IAAI,CAAC,IAAI;AACxF,QAAM,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,MAAO,OAAO,QAAS,GAAG,CAAC,IAAI;AAEtE,QAAM,OAAiB,CAAC;AACxB,MAAI,SAAS,MAAM,UAAW,MAAK,KAAK,eAAe,MAAM,SAAS,CAAC;AACvE,MAAI,SAAS,MAAM,OAAQ,MAAK,KAAKA,SAAQ,MAAM,MAAM,IAAI,SAAS;AACtE,MAAI,SAAS,MAAM,WAAW,KAAM,MAAK,KAAK,MAAM,OAAO,MAAM,OAAO,EAAE,QAAQ,MAAM,UAAU,IAAI,IAAI,CAAC,CAAC;AAC5G,MAAI,SAAS,MAAM,aAAc,MAAK,KAAK,MAAM,eAAe,mBAAmB,MAAM,iBAAiB,IAAI,KAAK,IAAI;AACvH,MAAI,GAAI,MAAK,KAAK,MAAM,WAAW;AAEnC,QAAM,aAAa,CAAC,EAAE,MAAM;AAE5B,SACE,+CAAO,kBAAN,EACC;AAAA,mDAAC,SAAI,WAAU,WACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UAAS,KAAK;AAAA,UAAQ,WAAU;AAAA,UAAc,UAAU,CAAC;AAAA,UAC9D,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,UAAG,iBAAe,aAAa,OAAO;AAAA,UACtE,cAAY,aAAa,kBAAkB;AAAA,UAE1C;AAAA,iBACC,8CAAC,UAAK,WAAU,gBAAe,eAAY,QACzC,wDAAC,kBAAe,OAAc,UAAU,GAAG,UAAU,QAAQ,GAAG,WAAW,OAAO,GACpF,IACE;AAAA,YACJ,8CAAC,UAAK,WAAU,gBAAgB,eAAK,KAAK,QAAK,GAAE;AAAA,YAChD,aAAa,8CAAC,OAAE,WAAU,mCAAkC,eAAY,QAAO,IAAK;AAAA;AAAA;AAAA,MACvF;AAAA,MACC;AAAA,OACH;AAAA,IAEA,8CAAC,WAAQ,MAAY,WAAW,QAAQ,WAAU,aAAY,SAAS,MAAM,QAAQ,KAAK,GAAG,UAAU,KAAK,WAAW,KAAK,QAAM,MAAC,OAAM,SACvI,yDAAC,SAAI,WAAU,aACZ;AAAA,WACC,8CAAC,aAAQ,WAAU,iBACjB;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UAAc,UAAU,GAAG;AAAA,UAAU,OAAO,GAAG,SAAS;AAAA,UACxD,QAAQ,GAAG,WAAW,UAAU,aAAa,QAAQA;AAAA,UAAS,QAAQ;AAAA,UAAG,QAAM;AAAA,UAC/E,gBAAe;AAAA;AAAA,MACjB,GACF,IACE;AAAA,MACH,UAAU,OAAO,SAChB,+CAAC,aAAQ,WAAU,iBACjB;AAAA,sDAAC,QAAG,WAAU,eAAe,0BAAe;AAAA,QAC5C,8CAAC,SAAI,WAAU,kBACZ,iBAAO,IAAI,CAAC,MACX;AAAA,UAAC;AAAA;AAAA,YAAoB,OAAO,EAAE;AAAA,YAAO,SAAS,EAAE;AAAA,YAC9C,MAAM,EAAE,WAAW,YAAY,eAAe,EAAE,QAAQ,IAAI,EAAE;AAAA;AAAA,UADjD,EAAE;AAAA,QACqD,CACvE,GACH;AAAA,SACF,IACE;AAAA,MACH,QACC,+CAAC,aAAQ,WAAU,iCAChB;AAAA,cAAM,YAAY,+CAAC,SAAI;AAAA,wDAAC,UAAK,qBAAO;AAAA,UAAO,8CAAC,OAAE,WAAU,cAAc,yBAAe,MAAM,SAAS,GAAE;AAAA,WAAI,IAAS;AAAA,QACnH,MAAM,SAAS,+CAAC,SAAI;AAAA,wDAAC,UAAK,oBAAM;AAAA,UAAO,8CAAC,OAAE,WAAU,cAAc,gBAAM,OAAO,eAAe,GAAE;AAAA,WAAI,IAAS;AAAA,QAC7G,MAAM,WAAW,OAAO,+CAAC,SAAI;AAAA,wDAAC,UAAK,kBAAI;AAAA,UAAO,+CAAC,OAAE,WAAU,cAAa;AAAA;AAAA,YAAE,OAAO,MAAM,OAAO,EAAE,QAAQ,CAAC;AAAA,aAAE;AAAA,WAAI,IAAS;AAAA,QACxH,MAAM,QAAQ,+CAAC,SAAI;AAAA,wDAAC,UAAK,mBAAK;AAAA,UAAO,8CAAC,OAAE,WAAU,cAAc,gBAAM,OAAM;AAAA,WAAI,IAAS;AAAA,SAC5F,IACE;AAAA,MACH,UACC,8CAAC,YAAO,WAAU,kBAChB,yDAAC,YAAO,MAAK,UAAS,WAAU,mBAAkB,SAAS,MAAM;AAAE,gBAAQ,KAAK;AAAG,gBAAQ;AAAA,MAAG,GAC5F;AAAA,sDAAC,OAAE,WAAU,eAAc,eAAY,QAAO;AAAA,QAAE;AAAA,SAClD,GACF,IACE;AAAA,OACN,GACF;AAAA,KACF;AAEJ;AAyBO,SAAS,cAAc;AAAA,EAC5B;AAAA,EAAQ;AAAA,EAAO;AAAA,EACf;AAAA,EAAc;AAAA,EAAQ;AAAA,EACtB;AAAA,EAAU;AAAA,EAAkB,gBAAgB;AAAA,EAC5C;AAAA,EAAY,QAAQ;AACtB,GAAuB;AACrB,MAAI,CAAC,UAAU,CAAC,OAAO,OAAQ,QAAO;AACtC,QAAMC,WAAU,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,KAAK,OAAO,CAAC;AAC9D,QAAM,UAAmC,CAAC;AAC1C,QAAM,OAAgB,CAAC;AACvB,SAAO,QAAQ,CAAC,MAAM;AACpB,QAAI,EAAE,OAAO;AAAE,OAAC,QAAQ,EAAE,KAAK,IAAI,QAAQ,EAAE,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC;AAAG;AAAA,IAAQ;AAC5E,SAAK,KAAK,CAAC;AAAA,EACb,CAAC;AAED,QAAM,OAAO,CAAC,OAAwB;AAAA,IACpC,IAAI,EAAE;AAAA,IAAI,OAAO,EAAE;AAAA,IAAO,aAAa,EAAE;AAAA,IAAa,UAAU,EAAE;AAAA,IAClE,SAAS,EAAE,QAAQA,YAAWA,SAAQ;AAAA,IACtC,MAAM,EAAE;AAAA,IACR,UAAU,EAAE,WAAW,8CAAC,WAAQ,MAAM,EAAE,UAAU,MAAK,MAAK,IAAK;AAAA,IACjE,UAAU,MAAM,iBAAiB,cAAc,EAAE,EAAE;AAAA,EACrD;AAEA,QAAM,QAAqB,CAAC,EAAE,MAAM,WAAW,OAAO,SAAS,CAAC,EAAiB,OAAO,KAAK,IAAI,IAAI,CAAC;AACtG,SAAO,KAAK,OAAO,EAAE,QAAQ,CAAC,MAAM;AAClC,UAAM,KAAK,EAAE,IAAI,SAAS,GAAG,OAAO,GAAG,MAAM,SAAS,SAAS,QAAQ,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;AAAA,EACvF,CAAC;AACD,MAAI,cAAc,WAAW,OAAQ,OAAM,KAAK,EAAE,IAAI,QAAQ,OAAO,eAAe,SAAS,WAAW,IAAI,IAAI,EAAE,CAAC;AACnH,MAAI,kBAAkB;AACpB,UAAM,KAAK,EAAE,MAAM,YAAY,CAAC;AAChC,UAAM,KAAK,EAAE,MAAM,WAAW,OAAO,YAAY,CAAC;AAClD,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,QAAQ,MACN,+CAAC,WAAM,WAAU,iBACf;AAAA,sDAAC,UAAM,yBAAc;AAAA,QACrB,8CAAC,WAAM,MAAK,YAAW,WAAU,SAAQ,SAAS,CAAC,CAAC,UAAU,UAAU,CAAC,MAAM,iBAAiB,EAAE,OAAO,OAAO,GAAG;AAAA,QACnH,8CAAC,UAAK,WAAW,qBAAqB,WAAW,WAAW,KAAK,eAAY,QAAO,wDAAC,UAAK,WAAU,mBAAkB,GAAE;AAAA,SAC1H;AAAA,IAEJ,CAAC;AAAA,EACH;AAEA,SACE,+CAAO,kBAAN,EACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QAAc,WAAU;AAAA,QAAU,UAAU;AAAA,QAAK,WAAU;AAAA,QAC3D,OAAOA,WAAUA,SAAQ,QAAQ;AAAA,QAAS,OAAM;AAAA;AAAA,IAClD;AAAA,IACC,gBAAgB,aAAa,SAC5B;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QAAU,UAAU;AAAA,QAAK,WAAU;AAAA,QAAmB,cAAc;AAAA,QAC9E,OAAO,UAAU,aAAa,CAAC;AAAA,QAAG,OAAM;AAAA,QACxC,OAAO,aAAa,IAAI,CAAC,QAAQ;AAAA,UAC/B,IAAI;AAAA,UAAI,OAAO;AAAA,UAAI,SAAS,OAAO;AAAA,UACnC,UAAU,MAAM,kBAAkB,eAAe,EAAE;AAAA,QACrD,EAAE;AAAA;AAAA,IACJ,IACE;AAAA,KACN;AAEJ;;;ALoBI,IAAAC,uBAAA;AAxMJ,IAAM,WAAmC,EAAE,SAAS,cAAc,QAAQ,aAAa,MAAM,WAAW,OAAO,YAAY,OAAO,WAAW;AAuHtI,SAAS,eAAe;AAAA;AAAA,EAE7B;AAAA,EAAa;AAAA,EAAW;AAAA,EACxB;AAAA;AAAA,EAEA,QAAQ;AAAA,EAAa;AAAA,EAAU,aAAa;AAAA,EAAM;AAAA,EAAe;AAAA,EACjE,gBAAgB;AAAA,EAAa,WAAW;AAAA,EAAO;AAAA,EAAiB;AAAA,EAChE,gBAAgB;AAAA,EAAW,cAAc;AAAA;AAAA,EAEzC,WAAW;AAAA,EAAM,kBAAkB;AAAA,EAAK,iBAAiB;AAAA,EACzD,YAAY;AAAA,EAAM,eAAe;AAAA,EACjC;AAAA,EAAY;AAAA,EAAkB;AAAA,EAAW,cAAc,CAAC;AAAA,EAAG;AAAA,EAC3D;AAAA,EAAe;AAAA,EAAiB;AAAA,EAAe;AAAA,EAAkB;AAAA;AAAA,EAEjE,cAAc;AAAA,EAAmB;AAAA,EAAW;AAAA,EAC5C;AAAA,EAAmB;AAAA,EAAa;AAAA,EAAa,sBAAsB;AAAA,EACnE;AAAA,EAAe;AAAA,EAAgB;AAAA,EAAc;AAAA;AAAA,EAE7C;AAAA,EAAc;AAAA,EAAc;AAAA,EAC5B;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAe;AAAA,EAAc;AAAA,EAAQ;AAAA,EACpD;AAAA,EAAU;AAAA,EAAkB;AAAA;AAAA,EAE5B;AAAA,EAAS;AAAA,EAAgB;AAAA,EAAa;AAAA;AAAA,EAEtC,UAAU;AAAA,EAAW,QAAQ;AAAA,EAAK,WAAW;AAAA,EAAK,WAAW;AAAA,EAAK,YAAY;AAAA,EAC9E;AAAA,EAAQ,YAAY;AAAA,EAAI;AAAA;AAAA,EAExB;AAAA,EAAU;AAAA,EAAe;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAY;AACjE,GAAwB;AACtB,QAAM,CAAC,YAAY,aAAa,IAAU,iBAAS,KAAK;AACxD,QAAM,CAAC,SAAS,UAAU,IAAU,iBAAkC,CAAC,CAAC;AACxE,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAS,EAAE;AAC3C,QAAM,WAAiB,eAAwC,IAAI;AACnE,EAAM,kBAAU,MAAM,cAAc,KAAK,GAAG,CAAC,KAAK,CAAC;AAEnD,QAAM,SAAS,cAAc;AAAA,IAC3B;AAAA,IAAa;AAAA,IAAW;AAAA,IAAY;AAAA,IAAgB;AAAA,IACpD;AAAA,IAAU;AAAA,IAAe;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAS;AAAA,EACrD,CAAC;AAGD,QAAM,YAAY,CAAC,MAA0B;AAC3C,QAAI,CAAC,UAAW;AAChB,MAAE,eAAe;AACjB,aAAS,UAAU,EAAE,GAAG,EAAE,SAAS,GAAG,WAAW;AACjD,UAAM,OAAO,CAAC,OAAqB;AACjC,UAAI,CAAC,SAAS,QAAS;AACvB,YAAM,KAAK,SAAS,QAAQ,IAAI,GAAG;AACnC,oBAAc,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,SAAS,QAAQ,IAAI,EAAE,CAAC,CAAC;AAAA,IAC/E;AACA,UAAM,KAAK,MAAM;AACf,eAAS,UAAU;AACnB,aAAO,oBAAoB,eAAe,IAAI;AAC9C,aAAO,oBAAoB,aAAa,EAAE;AAC1C,eAAS,KAAK,MAAM,aAAa;AAAA,IACnC;AACA,aAAS,KAAK,MAAM,aAAa;AACjC,WAAO,iBAAiB,eAAe,IAAI;AAC3C,WAAO,iBAAiB,aAAa,EAAE;AAAA,EACzC;AAEA,QAAM,SAAS,YAAY,YAAY,aAAa,MAAM,YAAY;AAEtE,QAAM,MAAM;AAAA,IACV;AAAA,IAAe;AAAA,IAAU;AAAA,IAAiB;AAAA,IAAY;AAAA,IAAe;AAAA,IACrE;AAAA,IAAU;AAAA,IAAiB;AAAA,IAAgB;AAAA,IAAW;AAAA,IACtD;AAAA,IAAe;AAAA,IAAiB,gBAAgB;AAAA,IAAS;AAAA,IACzD;AAAA,IAAkB;AAAA,IAClB,SAAS,OAAO;AAAA,IAChB,YAAY,CAAC,IAAY,MAAqB,OAAO,YAAY,IAAI,CAAC;AAAA,IACtE,QAAQ,CAAC,MAAmB;AAAE,eAAS,EAAE,QAAQ,EAAE;AAAG,uBAAiB,cAAc,CAAC;AAAA,IAAG;AAAA,IACzF,eAAe,gBAAgB,CAAC,MAAc;AAC5C,YAAM,UAAU,CAAC,GAAG,OAAO,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC;AACxE,UAAI,QAAS,YAAW,CAAC,MAAM,OAAO,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC;AAC3E,oBAAc,CAAC;AAAA,IACjB,IAAI;AAAA,IACJ,aAAa,OAAO;AAAA,IACpB,WAAW;AAAA,EACb;AAEA,QAAM,aACJ;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MAA4B;AAAA,MAA4B;AAAA,MACxD,SAAS,OAAO,QAAQ,SAAS,OAAO,QAAQ;AAAA;AAAA,EAClD;AAGF,QAAM,gBACJ;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MAAgB;AAAA,MAAc;AAAA,MAC9B;AAAA,MAA4B;AAAA,MAAgB;AAAA,MAC5C;AAAA,MAAoB;AAAA,MAAoC;AAAA,MACxD;AAAA;AAAA,EACF;AAGF,QAAM,aAAa,WAAW,QAAQ,SACpC;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MAAQ,MAAK;AAAA,MAA0B,cAAc;AAAA,MAAM,WAAU;AAAA,MAC7E,WAAU;AAAA,MAAuB,OAAM;AAAA,MAAU,UAAU;AAAA,MAC3D,OAAQ,CAAC,EAAE,MAAM,WAAW,OAAO,SAAS,CAAC,EAAiB,OAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,QACvF,IAAI,EAAE;AAAA,QAAI,OAAO,EAAE,SAAS;AAAA,QAC5B,aAAa,EAAE,YAAY,eAAe,EAAE,SAAS,IAAI,EAAE;AAAA,QAC3D,SAAS,EAAE,OAAO,OAAO;AAAA,QACzB,UAAU,MAAM,kBAAkB,eAAe,CAAC;AAAA;AAAA;AAAA,QAGlD,gBAAgB,iBAAiB;AAAA,UAC/B,MAAM;AAAA,UAAS,OAAO,mBAAc,EAAE,SAAS,cAAc;AAAA,UAAK,QAAQ;AAAA,UAC1E,UAAU,MAAM,eAAe,CAAC;AAAA,QAClC,IAAI;AAAA,MACN,EAAE,CAAC;AAAA;AAAA,EACL,IACE;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,CAAC,aAAa,SAAS,OAAO,KAAK,SAAS,SAAS,SAAS,cAAc,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC9H,OAAO;AAAA,QACL,GAAI,YAAY,YAAY,EAAE,OAAO,WAAW,IAAI,CAAC;AAAA,QACrD,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,QAC3B,GAAG;AAAA,MACL;AAAA,MACA,cAAY;AAAA,MAEX;AAAA,oBAAY,aAAa,YACxB;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YAAW,eAAe;AAAA,YAAW,MAAK;AAAA,YACpD,oBAAiB;AAAA,YAAW,cAAW;AAAA,YAAe,UAAU;AAAA,YAChE,WAAW,CAAC,MAAM;AAChB,kBAAI,EAAE,QAAQ,YAAa,eAAc,CAAC,MAAM,KAAK,IAAI,UAAU,IAAI,EAAE,CAAC;AAC1E,kBAAI,EAAE,QAAQ,aAAc,eAAc,CAAC,MAAM,KAAK,IAAI,UAAU,IAAI,EAAE,CAAC;AAAA,YAC7E;AAAA;AAAA,QACF,IACE;AAAA,QAEH,aACC,+CAAC,YAAO,WAAU,YAChB;AAAA,wDAAC,UAAK,WAAU,iBAAgB,eAAY,QAAO,wDAAC,OAAE,WAAW,WAAW,eAAe,GAAE;AAAA,UAC7F,+CAAC,UAAK,WAAU,mBACd;AAAA,0DAAC,UAAK,WAAU,kBAAkB,iBAAM;AAAA,YACvC,WAAW,8CAAC,UAAK,WAAU,gBAAgB,oBAAS,IAAU;AAAA,aACjE;AAAA,UACA,+CAAC,UAAK,WAAU,iBACb;AAAA;AAAA,YACA;AAAA,YACA,cACC,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAAS,aAAa,cAAW,oBAAmB,OAAM,oBACtG,wDAAC,OAAE,WAAU,cAAa,eAAY,QAAO,GAC/C,IACE;AAAA,YACH,UACC,8CAAC,YAAO,MAAK,UAAS,WAAU,eAAc,SAAS,SAAS,cAAW,eAAc,OAAM,SAC7F,wDAAC,OAAE,WAAU,WAAU,eAAY,QAAO,GAC5C,IACE;AAAA,aACN;AAAA,WACF,IACE;AAAA,QAEJ;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,OAAO;AAAA,YAAS;AAAA,YAAU,QAAQ,OAAO;AAAA,YAAQ,OAAO,OAAO;AAAA,YACzE;AAAA,YAA0B,QAAQ,CAAC,MAAM,OAAO,KAAK,CAAW;AAAA,YAChE;AAAA,YAAwB;AAAA,YAAoC;AAAA,YAC5D;AAAA;AAAA,QACF;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,CAAC,MAAM,SAAS,OAAO,KAAK,MAAM,IAAI;AAAA,YAChD,QAAQ,OAAO;AAAA,YACf,MAAM,OAAO;AAAA,YACb,UAAU,OAAO,WAAW,kBAAkB,OAAO,WAAW;AAAA,YAChE;AAAA,YAA0B;AAAA,YAAsB;AAAA,YAChD;AAAA,YAAsC;AAAA,YACtC;AAAA,YAA0B;AAAA,YAC1B;AAAA,YAA8B;AAAA,YAAgC;AAAA,YAC9D,OAAO,OAAO;AAAA,YAAO,gBAAgB,OAAO;AAAA,YAC5C;AAAA,YAAwB,eAAe;AAAA,YACvC;AAAA,YACA;AAAA,YAAc,eAAe;AAAA,YAAU;AAAA;AAAA,QACzC;AAAA;AAAA;AAAA,EACF;AAEJ;;;AM3TA,IAAAC,UAAuB;AAiHhB,SAAS,SAAcC,MAA4B;AACxD,SAAO,CAAC,KAAU,UAChB,MAAM,QAAQ,KAAK,IAAI,MAAM,SAASA,KAAI,GAAG,CAAC,IAAIA,KAAI,GAAG,MAAM;AACnE;AACO,SAAS,YAAiBA,MAA6B;AAC5D,SAAO,CAAC,KAAU,UAA4B;AAC5C,UAAM,KAAKA,KAAI,GAAG,KAAK,CAAC;AACxB,WAAO,MAAM,QAAQ,KAAK,IACtB,MAAM,KAAK,CAAC,MAAM,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,IACxC,GAAG,SAAS,OAAO,KAAK,CAAC;AAAA,EAC/B;AACF;AACO,SAAS,YAAiBA,MAA2B;AAC1D,SAAO,CAAC,KAAU,UAA4B;AAC5C,UAAM,IAAIA,KAAI,GAAG;AACjB,UAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,GAAG,OAAO,iBAAiB;AAC1E,UAAM,KAAK,OAAO,OAAO,CAAC,KAAK,CAAC;AAChC,UAAM,QAAQ,OAAO,CAAC;AACtB,UAAM,KAAK,SAAS,OAAO,OAAO,oBAAoB,OAAO,KAAK;AAClE,WAAO,KAAK,OAAO,OAAO,OAAO,qBAAqB,KAAK;AAAA,EAC7D;AACF;AAEA,IAAM,WAAuB,EAAE,MAAM,GAAG,UAAU,IAAI,MAAM,MAAM,KAAK,QAAQ,GAAG,IAAI,SAAS,CAAC,EAAE;AAElG,SAAS,QAAQ,GAAY,GAAY,KAA6B;AACpE,QAAM,QAAQ,CAAC,MAAe,KAAK,QAAQ,MAAM;AACjD,MAAI,MAAM,CAAC,KAAK,MAAM,CAAC,EAAG,QAAO;AACjC,MAAI,MAAM,CAAC,EAAG,QAAO;AACrB,MAAI,MAAM,CAAC,EAAG,QAAO;AACrB,QAAM,IAAI,OAAO,MAAM,YAAY,OAAO,MAAM,WAC5C,IAAI,IACJ,OAAO,CAAC,EAAE,cAAc,OAAO,CAAC,GAAG,QAAW,EAAE,SAAS,MAAM,aAAa,OAAO,CAAC;AACxF,SAAO,QAAQ,QAAQ,IAAI,CAAC;AAC9B;AAOA,IAAI,MAAkB;AACtB,IAAI,QAA2B;AAa/B,SAAS,eAA8B,EAAE,UAAU,QAAQ,UAAU,MAAM,SAAS,GAA4C;AAI9H,QAAM,CAAC,OAAO,QAAQ,IAAU,iBAAqB,MAAM;AACzD,UAAM,QAAQ,SAAS,OAAO;AAC9B,UAAM,QAAQ,YAAY,QAAQ,MAAM,SAAS,QAAQ,IAAI,CAAC;AAC9D,WAAO,EAAE,GAAG,UAAU,GAAI,YAAY,CAAC,GAAI,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC,GAAI,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,MAAM,KAAK,MAAM,OAAO,OAAO,IAAI,CAAC,EAAG;AAAA,EAC5K,CAAC;AACD,QAAM,WAAiB,oBAAY,CAACC,WAAsE;AACxG,UAAM,QAAQ,SAAS,OAAO;AAC9B,QAAI,YAAY,MAAO,OAAM,SAAS,UAAUA,MAAK;AAAA,EACvD,GAAG,CAAC,QAAQ,CAAC;AACb,QAAM,CAAC,KAAK,MAAM,IAAU,iBAAmC,IAAI;AACnE,QAAM,CAAC,SAAS,UAAU,IAAU,iBAAS,IAAI;AACjD,QAAMC,OAAY,eAAO,CAAC;AAC1B,QAAM,UAAU,QAAQ,CAAC,GAAG,KAAK,GAAG;AACpC,QAAM,WAAW,KAAK,UAAU,UAAU,CAAC,CAAC;AAC5C,QAAM,WAAW,KAAK,UAAU,KAAK;AAErC,EAAM,kBAAU,MAAM;AACpB,UAAM,KAAK,EAAEA,KAAI;AACjB,eAAW,IAAI;AAGf,UAAM,IAAI,WAAW,MAAM;AACzB,eAAS,OAAO,EAAE,QAAQ,UAAU,EAAE,GAAI,UAAU,CAAC,GAAI,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM;AAC/E,YAAI,OAAOA,KAAI,QAAS;AACxB,eAAO,CAAsB;AAC7B,mBAAW,KAAK;AAAA,MAClB,CAAC;AAAA,IACH,GAAG,MAAM,IAAI,MAAM,EAAE;AACrB,WAAO,MAAM,aAAa,CAAC;AAAA,EAE7B,GAAG,CAAC,UAAU,UAAU,UAAU,MAAM,CAAC;AAEzC,QAAM,QAAQ,CAAC,GAAwB,YAAY,SACjD,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,MAAM,YAAY,IAAK,EAAE,QAAQ,OAAO,EAAE,OAAO,EAAE,KAAM,EAAE;AAC5F,QAAM,eAAsB,EAAE,MAAM,MAAM,MAAM,UAAU,MAAM,UAAU,OAAO,GAAG,YAAY,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,OAAO,SAAS,MAAM;AAClJ,QAAM,QAAgB,OAAO,IAAI,SAAU;AAC3C,QAAM,MAAwB;AAAA,IAC5B,MAAM,MAAM,IAAI,OAAO,CAAC;AAAA;AAAA,IAExB;AAAA,IACA,OAAO,MAAM,SAAS;AAAA,IACtB,MAAM,MAAM,QAAQ,MAAM;AAAA,IAC1B,UAAU,MAAM;AAAA,IAChB,YAAY,MAAM,cAAc;AAAA,IAChC,MAAM,MAAM,QAAQ;AAAA,IACpB,IAAI,MAAM,MAAM;AAAA,IAChB,QAAS,OAAO,IAAI,UAAU,IAAI,OAAO,UAAW,CAAC;AAAA;AAAA,IAErD,WAAY,OAAO,IAAI,aAAc,CAAC;AAAA;AAAA,IAEtC;AAAA,IACA,MAAM,MAAM,OAAO,EAAE,KAAK,MAAM,MAAM,KAAK,MAAM,IAAI,IAAI;AAAA,IACzD,GAAG,MAAM;AAAA,IACT,SAAS,MAAM;AAAA,IACf;AAAA;AAAA,IAEA,gBAAgB,WAAW,CAAC;AAAA,IAC5B,mBAAmB,OAAO,OAAO,MAAM,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,QAAQ,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA,IACvG,SAAS,CAAC,SAAiB,MAAM,EAAE,KAAK,GAAG,KAAK;AAAA,IAChD,aAAa,CAAC,aAAqB;AAAE,eAAS,EAAE,SAAS,CAAC;AAAG,YAAM,EAAE,SAAS,CAAC;AAAA,IAAG;AAAA,IAClF,MAAM,CAAC,MAAc,MAAM,EAAE,EAAE,CAAC;AAAA,IAChC,YAAY,CAAC,QAAgB,SAAS,CAAC,MAAM;AAC3C,YAAM,MAAsB,EAAE,SAAS,OAAO,EAAE,QAAQ,SAAS,QAAQ;AACzE,eAAS,EAAE,MAAM,KAAK,IAAI,CAAC;AAC3B,aAAO,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,KAAK,IAAI;AAAA,IACzC,CAAC;AAAA,IACD,YAAY,CAAC,KAAa,QAAyB;AAAE,eAAS,EAAE,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC;AAAG,eAAS,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,KAAK,KAAK,OAAO,OAAO,EAAE;AAAA,IAAG;AAAA;AAAA,IAEvK,UAAU,MAAM,SAAS,OAAO,EAAE,QAAQ,UAAU,EAAE,GAAI,UAAU,CAAC,GAAI,GAAG,OAAO,MAAM,GAAG,UAAU,IAAO,CAAC,EAAE,KAAK,CAAC,MAAO,EAAwB,IAAI;AAAA;AAAA;AAAA,IAGzJ,WAAW,CAAC,IAAY,UAAkD,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,UAAU,aAAc,MAAqC,EAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,EAAE,EAAE;AAAA,IAC1O,aAAa,CAAC,OAAe,SAAS,CAAC,MAAM;AAAE,YAAM,IAAI,EAAE,GAAG,EAAE,QAAQ;AAAG,aAAO,EAAE,EAAE;AAAG,aAAO,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,EAAE;AAAA,IAAG,CAAC;AAAA,IAChI,YAAY,CAAC,YAAqC,MAAM,EAAE,QAAQ,CAAC;AAAA,IACnE,cAAc,MAAM,MAAM,EAAE,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,IAChD,SAAS,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAAA;AAAA;AAAA;AAAA,IAIzC,YAAY,WAAW,CAAC,CAAC;AAAA,IACzB,aAAa,SAAS,cAAc,KAAK;AAAA,EAC3C;AACA,SAAO;AACT;AAEA,IAAM,WAAW;AAAA,EACf;AAAA;AAAA,EAEA,OAAsB,KAAW;AAAE,UAAM;AAAK,WAAO;AAAA,EAAK;AAAA,EAC1D,SAAc;AACZ,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,wGAAmG;AAC7H,WAAO;AAAA,EACT;AAAA;AAAA,EAEA,SAAS,GAAqB;AAAE,YAAQ;AAAA,EAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS3C,IAAS,MAAa,OAA4B,KAAwC;AACxF,UAAM,IAAgB,EAAE,GAAG,UAAU,GAAI,SAAS,CAAC,EAAG;AACtD,UAAM,IAAI;AACV,UAAM,UAAU,EAAE,WAAW,CAAC;AAC9B,UAAM,SAAS,CAAC,MAAe,EAAE,KAAK,QAAQ,MAAM,MAAM,MAAM,SAAU,MAAM,QAAQ,CAAC,KAAK,CAAC,EAAE;AAGjG,QAAI,MAAa;AACjB,UAAM,QAAQ,EAAE,KAAK,IAAI,KAAK,EAAE,YAAY;AAC5C,QAAI,QAAQ,EAAE,YAAY;AACxB,YAAM,OAAO,EAAE;AACf,YAAM,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,OAAQ,EAA8B,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,SAAS,IAAI,CAAC,CAAC;AAAA,IACxH;AACA,UAAM,WAAW;AAGjB,WAAO,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,GAAG,MAAM;AAC7C,YAAM,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE;AACpC,UAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAI;AACzB,YAAM,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC;AAAA,IACpC,CAAC;AACD,UAAM,UAAU;AAIhB,UAAM,SAAiD,CAAC;AACxD,QAAI,EAAE,OAAQ,QAAO,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAIF,IAAG,MAAM;AAC5D,YAAM,SAAiC,CAAC;AACxC,eAAS,QAAQ,CAAC,MAAM;AAAE,cAAM,IAAIA,KAAI,CAAC;AAAG,YAAI,KAAK,KAAM,QAAO,CAAC,KAAK,OAAO,CAAC,KAAK,KAAK;AAAA,MAAG,CAAC;AAC9F,aAAO,EAAE,IAAI;AAAA,IACf,CAAC;AAGD,QAAI,EAAE,MAAM;AACV,YAAMA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,IAAI,MAAO,CAAC,MAAY,EAA8B,EAAE,IAAc;AAChH,YAAM,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,QAAQA,KAAI,CAAC,GAAGA,KAAI,CAAC,GAAG,EAAE,GAAG,CAAC;AAAA,IAC9D;AAGA,UAAM,QAAQ,QAAQ;AACtB,UAAM,WAAW,KAAK,IAAI,GAAG,EAAE,QAAQ;AACvC,UAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,QAAQ,CAAC;AAC1D,UAAM,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI,GAAG,UAAU;AACrD,UAAM,QAAQ,IAAI,OAAO,OAAO,KAAK,UAAU,OAAO,QAAQ;AAC9D,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,QACL;AAAA,QAAM;AAAA,QAAU;AAAA,QAAO;AAAA,QACvB,MAAM,UAAU,IAAI,KAAK,OAAO,KAAK,WAAW;AAAA,QAChD,IAAI,KAAK,IAAI,OAAO,OAAO,QAAQ;AAAA,QACnC,SAAS,OAAO;AAAA,QAChB,SAAS,OAAO;AAAA,MAClB;AAAA,MACA,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,EAAE,IAAI,IAAI;AAAA,MAC7C,QAAQ,EAAE,SAAS,SAAS,GAAG,EAAE,KAAK,IAAI,OAAO;AAAA,IACnD;AAAA,EACF;AAAA;AAAA,EAGA,cAAc,OAAoC;AAChD,UAAM,IAAgB,EAAE,GAAG,UAAU,GAAI,SAAS,CAAC,EAAG;AACtD,UAAM,QAAkB,CAAC;AACzB,QAAI,EAAE,SAAS,EAAG,OAAM,KAAK,UAAU,EAAE,IAAI;AAC7C,QAAI,EAAE,aAAa,SAAS,SAAU,OAAM,KAAK,cAAc,EAAE,QAAQ;AACzE,QAAI,EAAE,KAAM,OAAM,KAAK,UAAU,EAAE,OAAO,UAAU,EAAE,GAAG;AACzD,QAAI,EAAE,EAAG,OAAM,KAAK,OAAO,mBAAmB,EAAE,CAAC,CAAC;AAClD,WAAO,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM;AAClD,UAAI,KAAK,QAAQ,MAAM,MAAM,MAAM,SAAU,MAAM,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAS;AAG7E,UAAI,MAAM,QAAQ,CAAC,EAAG,GAAE,QAAQ,CAAC,MAAM,MAAM,KAAK,IAAI,MAAM,mBAAoB,MAAM,WAAW,MAAM,CAA+B,CAAC,CAAC;AAAA,UACnI,OAAM,KAAK,IAAI,MAAM,mBAAmB,CAA8B,CAAC;AAAA,IAC9E,CAAC;AACD,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AAAA,EAEA;AACF;;;ACtTA,IAAI,SAAS;AACb,IAAM,MAAM,CAAC,WACX,GAAG,MAAM,KAAK,EAAE,QAAQ,SAAS,EAAE,CAAC,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAC/E,IAAM,SAAS,CAAC,CAAC,IAAI,EAAE,MAAwB,KAAK,KAAK,OAAO,KAAK,KAAK;AAC1E,IAAMG,SAAQ,CAAC,OAAe,IAAI,QAAc,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAEpF,IAAM,OAAO,oBAAI,IAA2B;AAQ5C,SAAS,SACP,QACA,SACA,QACA,SACQ;AACR,QAAM,KAAK,IAAI,MAAM;AACrB,QAAM,OAAO,OAAO,SAAS,SAAS,CAAC,SAAS;AAChD,QAAM,QAAQ,OAAO,OAAO;AAC5B,OAAK,IAAI,IAAI,EAAE,IAAI,QAAQ,UAAU,UAAU,GAAG,OAAO,KAAK,CAAC,EAAE,CAAC;AAClE,OAAK,QAAQ,CAAC,OAAO,MAAM;AACzB,UAAM,KAAM,SAAS,IAAI,KAAM,KAAK;AACpC,eAAW,MAAM;AACf,UAAI,CAAC,KAAK,IAAI,EAAE,EAAG;AACnB,UAAI,MAAM,KAAK,SAAS,GAAG;AACzB,YAAI;AACF,eAAK,IAAI,IAAI,EAAE,IAAI,QAAQ,QAAQ,UAAU,GAAG,OAAO,QAAQ,QAAQ,EAAE,CAAC;AAAA,QAC5E,SAAS,KAAK;AACZ,eAAK,IAAI,IAAI;AAAA,YACX;AAAA,YAAI,QAAQ;AAAA,YAAU,UAAU;AAAA,YAAG;AAAA,YACnC,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACxD,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AACL,aAAK,IAAI,IAAI,EAAE,IAAI,QAAQ,WAAW,WAAW,IAAI,KAAK,KAAK,QAAQ,MAAM,CAAC;AAAA,MAChF;AAAA,IACF,GAAG,EAAE;AAAA,EACP,CAAC;AACD,SAAO;AACT;AAGA,SAAS,IAAuB,OAAuC;AACrE,QAAM,MAAM,KAAK,IAAI,KAAK;AAC1B,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,oBAAoB,KAAK,aAAa;AAGhE,SAAO,EAAE,GAAG,IAAI;AAClB;AAGA,eAAe,KAAwB,OAAe,MAA+C;AACnG,QAAM,aAAa,MAAM,cAAc;AACvC,aAAS;AACP,UAAM,SAAS,IAAa,KAAK;AACjC,UAAM,SAAS,MAAM;AACrB,QAAI,OAAO,WAAW,OAAQ,QAAO,OAAO;AAC5C,QAAI,OAAO,WAAW,SAAU,OAAM,IAAI,MAAM,OAAO,SAAS,eAAe,KAAK,EAAE;AACtF,UAAMA,OAAM,UAAU;AAAA,EACxB;AACF;AAEO,IAAM,aAAa,EAAE,UAAU,KAAK,KAAK;;;ACjCzC,SAAS,mBACd,cACA,SAC6B;AAC7B,QAAM,UAAU,SAAS,UAAU,CAAC,UAAkB,gBAAgB,KAAK;AAC3E,QAAM,SAAS,SAAS;AACxB,QAAM,MAAM,SAAS,QAAQ,OAAM,oBAAI,KAAK,GAAE,YAAY;AAE1D,MAAI,cAAc,SAAS,kBAAkB;AAC7C,MAAI,QAAQ,QAAQ,YAAY;AAEhC,MAAI,WAAmC;AAAA,IACrC;AAAA,MACE,GAAG;AAAA,MACH,SAAS;AAAA,MACT,KAAK,SAAS,OAAO;AAAA,MACrB,MAAM,IAAI;AAAA,MACV,QAAQ,SAAS,UAAU;AAAA,MAC3B,SAAS,CAAC;AAAA,IACZ;AAAA,EACF;AACA,QAAM,YAAY,oBAAI,IAAoB;AAC1C,YAAU,IAAI,aAAa,QAAQ,KAAK,CAAC;AAEzC,WAAS,OAAO,QAA2E;AACzF,mBAAe;AACf,aAAS,QAAQ,CAAC,MAAM;AAAE,QAAE,UAAU;AAAA,IAAO,CAAC;AAC9C,UAAM,UAAgC,EAAE,GAAG,QAAQ,GAAG,aAAa,SAAS,KAAK;AACjF,eAAW,CAAC,SAAS,GAAG,QAAQ;AAChC,cAAU,IAAI,aAAa,QAAQ,KAAK,CAAC;AACzC,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,WAAmB;AAAE,aAAO;AAAA,IAAO;AAAA,IACnC,cAAsC;AAAE,aAAO,CAAC,GAAG,QAAQ;AAAA,IAAG;AAAA,IAC9D,WAAW,GAA6C;AAAE,aAAO,SAAS,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;AAAA,IAAG;AAAA,IAElG,OAAO,KAAK,QAAQ,QAAQ,MAAM;AAChC,YAAM,SAAS,QAAQ,KAAK;AAC5B,YAAM,UAAU,OAAO,KAAK;AAC5B,aAAO,OAAO;AAAA,QACZ;AAAA,QAAK,MAAM,IAAI;AAAA,QAAG;AAAA,QAAQ;AAAA,QAAS;AAAA,QACnC,MAAM,SAAS,OAAO,QAAQ,KAAK,IAAI;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,IAEA,UAAU,GAAG,MAAM,UAAU;AAC3B,YAAM,WAAW,UAAU,IAAI,CAAC;AAChC,YAAM,WAAW,SAAS,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;AAC/C,UAAI,CAAC,YAAY,CAAC,SAAU,OAAM,IAAI,MAAM,+BAA+B,CAAC,YAAY;AACxF,YAAM,SAAS,QAAQ,KAAK;AAC5B,cAAQ,QAAQ,QAAQ;AACxB,aAAO,OAAO;AAAA,QACZ;AAAA,QAAK,MAAM,IAAI;AAAA,QACf,QAAQ,aAAa,CAAC;AAAA,QACtB,SAAS,CAAC,gBAAgB,CAAC,KAAK,SAAS,MAAM,GAAG;AAAA,QAClD,MAAM,SAAS,OAAO,QAAQ,KAAK,IAAI;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,IAEA,KAAK,MAAM,UAAU;AACnB,YAAM,OAAO,SAAS,CAAC;AACvB,YAAM,eAAe,OAAO,UAAU,IAAI,KAAK,IAAI,CAAC,IAAI;AACxD,UAAI,CAAC,QAAQ,CAAC,aAAc,OAAM,IAAI,MAAM,qCAAqC;AACjF,YAAM,SAAS,QAAQ,KAAK;AAC5B,cAAQ,QAAQ,YAAY;AAC5B,aAAO,OAAO;AAAA,QACZ;AAAA,QAAK,MAAM,IAAI;AAAA,QACf,QAAQ,UAAU,KAAK,MAAM;AAAA,QAC7B,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,UAAK,CAAC,EAAE;AAAA,QACzC,MAAM,SAAS,OAAO,QAAQ,KAAK,IAAI;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":["Tag","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","current","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","TONES","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","compact","React","import_jsx_runtime","import_jsx_runtime","compact","React","import_jsx_runtime","React","import_jsx_runtime","kind","m","buf","Tag","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","s","refresh","React","import_jsx_runtime","uid","React","import_jsx_runtime","React","import_jsx_runtime","current","React","import_jsx_runtime","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","usePopPos","popStyle","mode","React","import_react_dom","import_jsx_runtime","usePopPos","popStyle","mode","React","import_jsx_runtime","React","import_jsx_runtime","fmt","React","import_jsx_runtime","import_jsx_runtime","compact","React","import_jsx_runtime","MarkdownEditor","read","next","React","React","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","React","React","listeners","import_jsx_runtime","iso","React","import_react_dom","import_jsx_runtime","W","iso","import_jsx_runtime","compact","React","import_jsx_runtime","mode","import_jsx_runtime","import_jsx_runtime","BANDS","React","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","React","React","bucket","React","React","import_jsx_runtime","import_jsx_runtime","iso","React","import_jsx_runtime","React","import_jsx_runtime","compact","current","import_jsx_runtime","React","get","patch","seq","sleep"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/actions/Button.tsx","../src/components/actions/IconButton.tsx","../src/components/actions/Popover.tsx","../src/components/actions/SegmentedControl.tsx","../src/components/surfaces/Card.tsx","../src/components/surfaces/Collapsible.tsx","../src/components/surfaces/Drawer.tsx","../src/components/surfaces/Modal.tsx","../src/components/loading/LoadingRegion.tsx","../src/components/loading/ProgressBar.tsx","../src/components/loading/Skeleton.tsx","../src/components/loading/Spinner.tsx","../src/components/navigation/SidebarNav.tsx","../src/components/navigation/FlytedeskBrand.tsx","../src/components/navigation/Tabs.tsx","../src/components/navigation/Topbar.tsx","../src/components/feedback/Avatar.tsx","../src/components/feedback/Badge.tsx","../src/components/feedback/EmptyState.tsx","../src/components/feedback/Flag.tsx","../src/components/feedback/KeyHint.tsx","../src/components/feedback/Tag.tsx","../src/components/feedback/Toast.tsx","../src/components/feedback/Tooltip.tsx","../src/components/data/Clamp.tsx","../src/components/data/CsiBadge.tsx","../src/components/data/DataTable.tsx","../src/components/data/FilterBar.tsx","../src/components/data/StatTile.tsx","../src/components/data/CodeBlock.tsx","../src/components/data/Markdown.tsx","../src/components/data/Meter.tsx","../src/components/data/Pagination.tsx","../src/components/data/RelativeTime.tsx","../src/components/data/ScoreMeter.tsx","../src/components/data/SegmentedMeter.tsx","../src/kits/files.ts","../src/components/data/SortMenu.tsx","../src/components/data/StepList.tsx","../src/components/data/VirtualList.tsx","../src/components/data/EntityRow.tsx","../src/components/data/TransferList.tsx","../src/components/forms/Input.tsx","../src/components/forms/SearchField.tsx","../src/components/forms/Checkbox.tsx","../src/components/forms/Radio.tsx","../src/components/forms/Switch.tsx","../src/components/forms/Textarea.tsx","../src/components/forms/NumberInput.tsx","../src/components/forms/Select.tsx","../src/components/forms/DatePicker.tsx","../src/components/forms/TimePicker.tsx","../src/components/forms/Slider.tsx","../src/components/forms/RangeSlider.tsx","../src/components/forms/Dropzone.tsx","../src/components/forms/FileGrid.tsx","../src/components/forms/MarkdownEditor.tsx","../src/components/platform/AccountMenu.tsx","../src/kits/session.ts","../src/components/platform/ApiSpecBrowser.tsx","../src/components/platform/ProfilePage.tsx","../src/components/platform/RoadmapTimeline.tsx","../src/kits/runtime.ts","../src/components/platform/ComingSoon.tsx","../src/components/platform/Gate.tsx","../src/components/platform/ModeSwitch.tsx","../src/components/planner/ChannelMeta.tsx","../src/components/planner/SaturationDistribution.tsx","../src/components/planner/MixGap.tsx","../src/components/planner/ChannelContribution.tsx","../src/components/planner/BudgetReallocator.tsx","../src/components/planner/SurroundSound.tsx","../src/components/planner/Importance.tsx","../src/components/planner/PreferenceMeter.tsx","../src/components/chat/AgentChatPanel.tsx","../src/components/chat/chatEngine.ts","../src/components/chat/ChatTranscript.tsx","../src/components/chat/ChatTurn.tsx","../src/components/chat/ChatComposer.tsx","../src/components/chat/ChatSessionBar.tsx","../src/kits/query.ts","../src/kits/mockJobs.ts","../src/kits/versions.ts"],"sourcesContent":["export * from \"./components/actions\";\nexport * from \"./components/surfaces\";\nexport * from \"./components/loading\";\nexport * from \"./components/navigation\";\nexport * from \"./components/feedback\";\nexport * from \"./components/data\";\nexport * from \"./components/forms\";\nexport * from \"./components/platform\";\nexport * from \"./components/planner\";\nexport * from \"./components/chat\";\n\nexport * from \"./kits\";\n\n// \"Flag\" is exported by both components/feedback (the callout UI component) and\n// kits/session (the feature-flag record interface) — an explicit export of the\n// component here resolves the `export *` ambiguity in the component's favor, and\n// the kit's type is still reachable under a distinct name.\nexport { Flag } from \"./components/feedback\";\nexport type { Flag as SessionFlag } from \"./kits/session\";\n","import * as React from \"react\";\n\nconst VARIANTS: Record<string, string> = {\n primary: \"fd-btn-primary\",\n brandSoft: \"fd-btn-brandsoft\",\n secondary: \"fd-btn-secondary\",\n ghost: \"fd-btn-ghost\",\n danger: \"fd-btn-danger\",\n link: \"fd-btn-link\",\n};\n\n/**\n * The one action primitive. Primary is a gradient; everything else is flat.\n * Never more than one primary per view.\n */\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children?: React.ReactNode;\n /** primary = the one action. brandSoft = marketing CTA at >=19px/700 only (AA large-text). */\n variant?: \"primary\" | \"brandSoft\" | \"secondary\" | \"ghost\" | \"danger\" | \"link\";\n size?: \"sm\" | \"md\" | \"lg\";\n /** Phosphor icon name, leading, e.g. \"plus\" */\n icon?: string;\n /** Phosphor icon name, trailing */\n trailingIcon?: string;\n /** The site's signature inset-circle arrow. Use on hero CTAs only. */\n arrow?: boolean;\n /** Label stays put; a spinner replaces the leading icon. */\n loading?: boolean;\n block?: boolean;\n as?: \"button\" | \"a\";\n}\n\nexport function Button({\n children,\n variant = \"primary\",\n size = \"md\",\n icon,\n trailingIcon,\n arrow = false,\n loading = false,\n disabled = false,\n block = false,\n as = \"button\",\n className = \"\",\n ...rest\n}: ButtonProps) {\n const Tag = as as React.ElementType;\n const cls = [\n \"fd-btn\",\n VARIANTS[variant] || VARIANTS.primary,\n size === \"sm\" ? \"fd-btn-sm\" : size === \"lg\" ? \"fd-btn-lg\" : \"\",\n block ? \"fd-btn-block\" : \"\",\n loading ? \"fd-btn-loading\" : \"\",\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <Tag\n className={cls}\n disabled={Tag === \"button\" ? disabled || loading : undefined}\n aria-disabled={disabled || loading ? \"true\" : undefined}\n aria-busy={loading ? \"true\" : undefined}\n {...rest}\n >\n {icon && !loading ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {loading ? <span className=\"fd-spinner\" aria-hidden=\"true\" /> : null}\n <span>{children}</span>\n {trailingIcon && !arrow ? <i className={\"ph ph-\" + trailingIcon} aria-hidden=\"true\" /> : null}\n {arrow ? (\n <span className=\"fd-btn-arrow\" aria-hidden=\"true\">\n <i className=\"ph ph-arrow-right\" />\n </span>\n ) : null}\n </Tag>\n );\n}\n","import * as React from \"react\";\n\n/** A square action carrying only a Phosphor glyph. Always needs a label for a11y. */\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Phosphor icon name, e.g. \"dots-three-vertical\" */\n icon: string;\n /** Accessible name, also the title tooltip. Required. */\n label: string;\n size?: \"sm\" | \"md\" | \"lg\";\n variant?: \"ghost\" | \"outline\";\n round?: boolean;\n disabled?: boolean;\n className?: string;\n}\n\nexport function IconButton({\n icon,\n label,\n size = \"md\",\n variant = \"ghost\",\n round = false,\n disabled = false,\n className = \"\",\n ...rest\n}: IconButtonProps) {\n const cls = [\n \"fd-btn-icon\",\n variant === \"outline\" ? \"fd-btn-icon-outline\" : \"\",\n size === \"sm\" ? \"fd-btn-icon-sm\" : size === \"lg\" ? \"fd-btn-icon-lg\" : \"\",\n round ? \"fd-btn-icon-round\" : \"\",\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <button type=\"button\" className={cls} aria-label={label} title={label} disabled={disabled} {...rest}>\n <i className={\"ph ph-\" + icon} aria-hidden=\"true\" />\n </button>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport type Placement = \"bottom-start\" | \"bottom-end\" | \"bottom-center\" | \"top-start\" | \"top-end\" | \"top-center\";\n\nexport interface PopoverProps {\n open?: boolean;\n anchorRef: React.RefObject<HTMLElement>;\n onClose?: () => void;\n placement?: Placement;\n offset?: number;\n matchWidth?: boolean;\n width?: number;\n minWidth?: number;\n maxHeight?: number;\n padded?: boolean;\n role?: string;\n label?: string;\n closeOnOutside?: boolean;\n closeOnEscape?: boolean;\n returnFocus?: boolean;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n}\n\ninterface PopoverPosition {\n left: number;\n width: number | undefined;\n minWidth: number | undefined;\n top: number | null;\n bottom: number | null;\n maxH: number;\n side: \"top\" | \"bottom\";\n anchorWidth: number;\n}\n\nconst MARGIN = 8;\nconst parsePlacement = (p?: string): { side: \"top\" | \"bottom\"; align: string } => {\n const [side, align = \"start\"] = String(p || \"bottom-start\").split(\"-\");\n return { side: side === \"top\" ? \"top\" : \"bottom\", align };\n};\n\nconst samePosition = (a: PopoverPosition | null, b: PopoverPosition | null): boolean => {\n if (!a || !b) return a === b;\n return (\n a.left === b.left && a.top === b.top && a.bottom === b.bottom && a.width === b.width &&\n a.minWidth === b.minWidth && a.maxH === b.maxH && a.side === b.side && a.anchorWidth === b.anchorWidth\n );\n};\n\n/**\n * Fixed-position layer geometry for an anchored surface. Flips side when the\n * preferred one doesn't fit, clamps to the viewport, and re-measures continuously\n * while open.\n *\n * Continuously, on an animation frame, rather than on scroll and resize events: those\n * two cover an anchor that moves because the PAGE moved, and miss every other reason an\n * anchor moves. The one that broke this was a row inside a virtualized list — rows are\n * positioned by a CSS transform off their index, so re-sorting the list slides a row to\n * a new slot with no scroll, no resize and no layout event of any kind, and a popover\n * anchored to it simply stayed behind. Re-measuring per frame costs one\n * getBoundingClientRect on one element for as long as a popover is open, and state is\n * only set when the geometry actually changed (see samePosition), so a stationary anchor\n * causes no re-renders at all.\n *\n * The same loop is what notices the anchor being REMOVED — a virtualized row scrolled\n * out of the mounted band, a menu item deleted — and reports it through `onDetach`, so\n * an anchored layer can never end up pinned to an element that no longer exists.\n */\nexport function usePopoverPosition(\n open: boolean,\n anchorRef: React.RefObject<HTMLElement>,\n opts?: Partial<PopoverProps> & { estHeight?: number; estWidth?: number; onDetach?: () => void }\n): PopoverPosition | null {\n const o = opts || {};\n const { side: wantSide, align } = parsePlacement(o.placement);\n const [pos, setPos] = React.useState<PopoverPosition | null>(null);\n const posRef = React.useRef<PopoverPosition | null>(null);\n const detachRef = React.useRef<(() => void) | undefined>(o.onDetach);\n detachRef.current = o.onDetach;\n\n React.useLayoutEffect(() => {\n if (!open || !anchorRef || !anchorRef.current) { posRef.current = null; setPos(null); return; }\n const calc = () => {\n const el = anchorRef.current;\n if (!el) return;\n const r = el.getBoundingClientRect();\n const offset = o.offset == null ? 8 : o.offset;\n const estH = o.estHeight || 300;\n const below = window.innerHeight - r.bottom - offset - MARGIN;\n const above = r.top - offset - MARGIN;\n let side = wantSide;\n if (side === \"bottom\" && below < Math.min(estH, 180) && above > below) side = \"top\";\n else if (side === \"top\" && above < Math.min(estH, 180) && below > above) side = \"bottom\";\n const width = o.matchWidth ? r.width : Math.max(o.width || 0, o.minWidth || 0);\n const w = width || o.estWidth || 260;\n let left = align === \"end\" ? r.right - w : align === \"center\" ? r.left + r.width / 2 - w / 2 : r.left;\n left = Math.max(MARGIN, Math.min(left, window.innerWidth - w - MARGIN));\n const maxH = Math.max(140, (side === \"top\" ? above : below));\n const next: PopoverPosition = {\n left, width: o.matchWidth ? r.width : undefined, minWidth: o.minWidth,\n top: side === \"bottom\" ? r.bottom + offset : null,\n bottom: side === \"top\" ? window.innerHeight - r.top + offset : null,\n maxH, side, anchorWidth: r.width,\n };\n if (samePosition(posRef.current, next)) return;\n posRef.current = next;\n setPos(next);\n };\n calc();\n if (typeof requestAnimationFrame !== \"function\") return;\n let raf = 0;\n const tick = () => {\n const el = anchorRef.current;\n // A detached anchor still answers getBoundingClientRect — with all zeros, which\n // would silently teleport the layer to the top-left corner. Bail before measuring.\n if (!el || !el.isConnected) { detachRef.current && detachRef.current(); return; }\n calc();\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, o.placement, o.offset, o.matchWidth, o.width, o.minWidth, o.estHeight]);\n\n return pos;\n}\n\nconst portal = (node: React.ReactElement): React.ReactElement => {\n if (typeof document !== \"undefined\") return createPortal(node, document.body);\n return node;\n};\n\n/**\n * An anchored floating surface: menus, pickers, disclosure panels, meters.\n * Owns nothing but placement, dismissal and focus return — the content is yours.\n */\nexport function Popover({\n open, anchorRef, onClose, placement = \"bottom-start\", offset = 8,\n matchWidth = false, width, minWidth, maxHeight, padded = false,\n role = \"dialog\", label, closeOnOutside = true, closeOnEscape = true,\n returnFocus = true, className = \"\", style, children,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement>(null);\n // An anchor that leaves the DOM closes the layer rather than orphaning it — the case\n // this exists for is a popover opened from a row of a virtualized list, whose row is\n // unmounted the moment it scrolls out of the mounted band.\n const pos = usePopoverPosition(!!open, anchorRef, {\n placement, offset, matchWidth, width, minWidth, estHeight: maxHeight || 320,\n onDetach: onClose,\n });\n const restore = React.useRef<HTMLElement | null>(null);\n\n React.useEffect(() => {\n if (!open) return;\n restore.current = typeof document !== \"undefined\" ? (document.activeElement as HTMLElement | null) : null;\n return () => {\n if (returnFocus && restore.current && restore.current.focus) {\n try { restore.current.focus({ preventScroll: true }); } catch { /* noop */ }\n }\n };\n }, [open, returnFocus]);\n\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (!closeOnOutside) return;\n const target = e.target as Node;\n if (ref.current && ref.current.contains(target)) return;\n if (anchorRef && anchorRef.current && anchorRef.current.contains(target)) return;\n if ((e.target as Element).closest && (e.target as Element).closest(\".fd-pop\")) return; // nested layers\n onClose && onClose();\n };\n const key = (e: KeyboardEvent) => { if (closeOnEscape && e.key === \"Escape\") { e.stopPropagation(); onClose && onClose(); } };\n document.addEventListener(\"pointerdown\", away, true);\n document.addEventListener(\"keydown\", key);\n return () => { document.removeEventListener(\"pointerdown\", away, true); document.removeEventListener(\"keydown\", key); };\n }, [open, closeOnOutside, closeOnEscape, onClose, anchorRef]);\n\n if (!open || !pos) return null;\n return portal(\n <div\n ref={ref}\n role={role}\n aria-label={label}\n className={[\"fd-pop\", pos.side === \"top\" ? \"is-up\" : \"\", padded ? \"fd-pop-padded\" : \"\", className].filter(Boolean).join(\" \")}\n style={{\n position: \"fixed\", left: pos.left,\n top: pos.top == null ? \"auto\" : pos.top,\n bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n width: matchWidth ? pos.width : width,\n minWidth: minWidth || (matchWidth ? undefined : 200),\n // Size to content by default — cap only at real available room between the\n // anchor and the viewport edge (pos.maxH, computed by usePopoverPosition).\n // A caller-supplied `maxHeight` narrows that further (e.g. a long menu that\n // should scroll well before it reaches the viewport edge); it must never\n // widen past pos.maxH, which is why it's still Math.min'd against it. There\n // is intentionally no arbitrary default here — an unrequested cap would clip\n // ordinary content that simply happens to be taller than some fixed number.\n maxHeight: maxHeight != null ? Math.min(maxHeight, pos.maxH) : pos.maxH,\n transformOrigin: pos.side === \"top\" ? \"bottom center\" : \"top center\",\n zIndex: 140,\n ...style,\n } as React.CSSProperties}\n >\n {children}\n </div>\n );\n}\n\nexport interface MenuItem {\n id?: string;\n label?: React.ReactNode;\n icon?: string;\n description?: React.ReactNode;\n meta?: React.ReactNode;\n /** A key HINT. Renders a cap, binds nothing. */\n shortcut?: React.ReactNode;\n /** Present (true/false) makes the row a menuitemradio with a check column. */\n checked?: boolean;\n disabled?: boolean;\n submenu?: MenuItem[];\n /** A secondary action pinned to the row (e.g. delete). Rendered as a sibling button, so it is keyboard-reachable and does not nest inside the row button. */\n trailingAction?: { icon?: string; label: string; danger?: boolean; closeOnSelect?: boolean; onSelect?: (item: MenuItem) => void };\n onSelect?: (item: MenuItem) => void;\n kind?: \"separator\" | \"section\" | \"custom\";\n render?: () => React.ReactNode;\n}\n\nexport interface MenuProps {\n items: MenuItem[];\n onSelect?: (item: MenuItem) => void;\n onClose?: () => void;\n autoFocus?: boolean;\n header?: React.ReactNode;\n footer?: React.ReactNode;\n className?: string;\n}\n\nconst isItem = (it: MenuItem | null | undefined): boolean =>\n !!it && it.kind !== \"separator\" && it.kind !== \"section\" && it.kind !== \"custom\" && !it.disabled;\n\n/**\n * A keyboard-complete menu list. Items may be:\n * {id,label,icon,description,meta,shortcut,checked,disabled,submenu,onSelect}\n * {kind:\"separator\"} · {kind:\"section\",label} · {kind:\"custom\",render}\n * `shortcut` is a HINT — it renders a cap and binds nothing.\n */\nexport function Menu({ items = [], onSelect, onClose, autoFocus = true, className = \"\", footer, header }: MenuProps) {\n const listRef = React.useRef<HTMLDivElement>(null);\n const [active, setActive] = React.useState(() => items.findIndex(isItem));\n const [openSub, setOpenSub] = React.useState<number | null>(null);\n const subAnchor = React.useRef<HTMLElement | null>(null);\n const typed = React.useRef<{ s: string; t: number }>({ s: \"\", t: 0 });\n\n React.useEffect(() => { if (autoFocus && listRef.current) listRef.current.focus({ preventScroll: true }); }, [autoFocus]);\n\n const move = (dir: number) => {\n setActive((a) => {\n let i = a;\n for (let n = 0; n < items.length; n++) {\n i = (i + dir + items.length) % items.length;\n if (isItem(items[i])) return i;\n }\n return a;\n });\n };\n\n const choose = (it: MenuItem | null | undefined, i: number) => {\n if (!it || it.disabled) return;\n if (it.submenu && it.submenu.length) {\n subAnchor.current = (listRef.current && listRef.current.querySelector('[data-i=\"' + i + '\"]')) as HTMLElement | null;\n setOpenSub(i);\n return;\n }\n it.onSelect && it.onSelect(it);\n onSelect && onSelect(it);\n onClose && onClose();\n };\n\n const onKey = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"ArrowDown\") { e.preventDefault(); move(1); }\n else if (e.key === \"ArrowUp\") { e.preventDefault(); move(-1); }\n else if (e.key === \"Home\") { e.preventDefault(); setActive(items.findIndex(isItem)); }\n else if (e.key === \"End\") { e.preventDefault(); for (let i = items.length - 1; i >= 0; i--) if (isItem(items[i])) { setActive(i); break; } }\n else if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); choose(items[active], active); }\n else if (e.key === \"ArrowRight\") { const it = items[active]; if (it && it.submenu) { e.preventDefault(); choose(it, active); } }\n else if (e.key === \"ArrowLeft\") { if (openSub != null) { e.preventDefault(); setOpenSub(null); } }\n else if (e.key.length === 1 && /\\S/.test(e.key)) {\n const now = Date.now();\n typed.current = { s: (now - typed.current.t < 700 ? typed.current.s : \"\") + e.key.toLowerCase(), t: now };\n const hit = items.findIndex((it) => isItem(it) && String(it.label || \"\").toLowerCase().startsWith(typed.current.s));\n if (hit >= 0) setActive(hit);\n }\n };\n\n const sub = openSub != null ? items[openSub] : null;\n\n return (\n <React.Fragment>\n {header}\n <div\n ref={listRef} tabIndex={-1} role=\"menu\" onKeyDown={onKey}\n className={[\"fd-pop-list\", \"fd-menu\", className].filter(Boolean).join(\" \")}\n >\n {items.map((it, i) => {\n if (!it) return null;\n if (it.kind === \"separator\") return <div key={\"s\" + i} className=\"fd-menu-sep\" role=\"separator\" />;\n if (it.kind === \"section\") return <div key={\"h\" + i} className=\"fd-pop-group\" role=\"presentation\">{it.label}</div>;\n if (it.kind === \"custom\") return <div key={\"c\" + i} className=\"fd-menu-custom\">{it.render ? it.render() : null}</div>;\n const on = !!it.checked;\n const row = (\n <button\n type=\"button\" key={it.id || (it.label as React.Key) || i} data-i={i}\n role={it.checked != null ? \"menuitemradio\" : \"menuitem\"}\n aria-checked={it.checked != null ? on : undefined}\n aria-haspopup={it.submenu ? \"menu\" : undefined}\n aria-expanded={it.submenu ? openSub === i : undefined}\n aria-disabled={it.disabled || undefined}\n className={[\"fd-opt\", \"fd-menu-item\", i === active ? \"is-active\" : \"\", on ? \"is-selected\" : \"\"].filter(Boolean).join(\" \")}\n onMouseEnter={() => { setActive(i); if (openSub != null && openSub !== i) setOpenSub(null); }}\n onClick={() => choose(it, i)}\n >\n {it.icon ? <span className=\"fd-menu-icon\"><i className={\"ph ph-\" + it.icon} aria-hidden=\"true\" /></span> : null}\n <span className=\"fd-menu-text\">\n <span className=\"fd-opt-label\">{it.label}</span>\n {it.description ? <span className=\"fd-opt-desc\">{it.description}</span> : null}\n </span>\n {it.meta ? <span className=\"fd-opt-meta\">{it.meta}</span> : null}\n {it.shortcut ? <span className=\"fd-menu-shortcut\" aria-hidden=\"true\">{it.shortcut}</span> : null}\n {it.submenu ? <i className=\"ph ph-caret-right fd-menu-more\" aria-hidden=\"true\" /> : null}\n {it.checked != null ? <span className=\"fd-opt-check\">{on ? <i className=\"ph ph-check\" aria-hidden=\"true\" /> : null}</span> : null}\n </button>\n );\n const ta = it.trailingAction;\n if (!ta) return row;\n return (\n <div key={it.id || (it.label as React.Key) || i} className=\"fd-menu-row\" onMouseEnter={() => setActive(i)}>\n {row}\n <button\n type=\"button\" className={[\"fd-menu-row-act\", ta.danger ? \"is-danger\" : \"\"].filter(Boolean).join(\" \")}\n aria-label={ta.label} title={ta.label}\n onClick={(e) => { e.stopPropagation(); ta.onSelect && ta.onSelect(it); if (ta.closeOnSelect !== false) { onClose && onClose(); } }}\n >\n <i className={\"ph ph-\" + (ta.icon || \"trash\")} aria-hidden=\"true\" />\n </button>\n </div>\n );\n })}\n </div>\n {footer}\n {sub && sub.submenu ? (\n <Popover\n open anchorRef={{ current: subAnchor.current }} placement=\"bottom-start\" offset={-6}\n minWidth={200} maxHeight={320} label={sub.label as string | undefined} onClose={() => setOpenSub(null)}\n className=\"fd-menu-sub\"\n >\n <Menu items={sub.submenu} onSelect={(it) => { onSelect && onSelect(it); onClose && onClose(); }} onClose={() => setOpenSub(null)} />\n </Popover>\n ) : null}\n </React.Fragment>\n );\n}\n\nexport interface MenuButtonProps extends Omit<MenuProps, \"onClose\" | \"autoFocus\"> {\n label?: React.ReactNode;\n icon?: string;\n trailingIcon?: string | null;\n placement?: Placement;\n variant?: \"chip\" | \"ghost\";\n size?: \"sm\" | \"md\";\n disabled?: boolean;\n title?: string;\n ariaLabel?: string;\n width?: number;\n minWidth?: number;\n maxHeight?: number;\n children?: React.ReactNode;\n}\n\n/**\n * Trigger + menu in one: a compact chip that opens an anchored Menu.\n * Used for model pickers, row overflow actions, view switchers.\n */\nexport function MenuButton({\n label, icon, trailingIcon = \"caret-down\", items = [], onSelect, placement = \"top-end\",\n variant = \"chip\", size = \"sm\", disabled, title, ariaLabel, width, minWidth = 220, maxHeight = 380,\n className = \"\", children, header, footer,\n}: MenuButtonProps) {\n const [open, setOpen] = React.useState(false);\n const ref = React.useRef<HTMLButtonElement>(null);\n return (\n <React.Fragment>\n <button\n type=\"button\" ref={ref} disabled={disabled} title={title}\n aria-label={ariaLabel} aria-haspopup=\"menu\" aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n className={[\"fd-menubtn\", \"fd-menubtn-\" + variant, size === \"md\" ? \"is-md\" : \"\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")}\n >\n {icon ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {children != null ? children : <span className=\"fd-menubtn-label\">{label}</span>}\n {trailingIcon ? <i className={\"ph ph-\" + trailingIcon + \" fd-menubtn-caret\"} aria-hidden=\"true\" /> : null}\n </button>\n <Popover\n open={open} anchorRef={ref} placement={placement} onClose={() => setOpen(false)}\n width={width} minWidth={minWidth} maxHeight={maxHeight} role=\"menu\" label={(ariaLabel || label) as string | undefined}\n >\n <Menu items={items} header={header} footer={footer} onSelect={onSelect} onClose={() => setOpen(false)} />\n </Popover>\n </React.Fragment>\n );\n}\n","\n/** Two to four mutually exclusive views — density, date range, light/dark. */\nexport interface SegmentedControlProps {\n options: Array<string | { value: string; label: string }>;\n value?: string;\n onChange?: (value: string) => void;\n className?: string;\n}\n\nexport function SegmentedControl({ options = [], value, onChange, className = \"\", ...rest }: SegmentedControlProps) {\n return (\n <div className={[\"fd-seg\", className].filter(Boolean).join(\" \")} role=\"group\" {...rest}>\n {options.map((o) => {\n const v = typeof o === \"string\" ? o : o.value;\n const label = typeof o === \"string\" ? o : o.label;\n return (\n <button key={v} type=\"button\" aria-pressed={v === value}\n onClick={onChange ? () => onChange(v) : undefined}>\n {label}\n </button>\n );\n })}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The container. White, 12px radius, hairline border, low soft shadow, and a\n * divider under the header — that divider is the signature detail on flytedesk.com.\n */\nexport interface CardProps {\n title?: React.ReactNode;\n /** Right-aligned control in the header — usually an IconButton or a link Button. */\n action?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n elevation?: \"flat\" | \"rest\" | \"raised\";\n hoverable?: boolean;\n /** Set false to let children run edge to edge (tables, images). */\n padded?: boolean;\n className?: string;\n}\n\nexport function Card({\n title,\n action,\n footer,\n children,\n elevation = \"rest\",\n hoverable = false,\n padded = true,\n className = \"\",\n ...rest\n}: CardProps) {\n const cls = [\n \"fd-card\",\n elevation === \"flat\" ? \"fd-card-flat\" : elevation === \"raised\" ? \"fd-card-raised\" : \"\",\n hoverable ? \"fd-card-hoverable\" : \"\",\n className,\n ].filter(Boolean).join(\" \");\n return (\n <div className={cls} {...rest}>\n {title ? (\n <div className=\"fd-card-head\">\n <span className=\"fd-card-head-title\">{title}</span>\n {action}\n </div>\n ) : null}\n {padded ? <div className=\"fd-card-body\">{children}</div> : children}\n {footer ? <div className=\"fd-card-foot\">{footer}</div> : null}\n </div>\n );\n}\n\nexport interface CardRowProps {\n label: React.ReactNode;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function CardRow({ label, children, className = \"\" }: CardRowProps) {\n return (\n <div className={[\"fd-card-row\", className].filter(Boolean).join(\" \")}>\n <span className=\"fd-card-row-label\">{label}</span>\n <span className=\"fd-card-row-value\">{children}</span>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The system's main density valve: a large, calm trigger row that opens a panel.\n * Prefer this over tabs or a second page when a screen has more than it can show.\n */\nexport interface CollapsibleProps {\n title: React.ReactNode;\n subtitle?: React.ReactNode;\n /** Right-aligned status — a Badge or CsiBadge. */\n badge?: React.ReactNode;\n /** Phosphor icon name shown in a soft brand chip on the left. */\n icon?: string;\n defaultOpen?: boolean;\n /** Pass with onToggle for controlled use. */\n open?: boolean;\n onToggle?: (open: boolean) => void;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Collapsible({\n title,\n subtitle,\n badge,\n icon,\n defaultOpen = false,\n open,\n onToggle,\n children,\n className = \"\",\n ...rest\n}: CollapsibleProps) {\n const [internal, setInternal] = React.useState(defaultOpen);\n const isOpen = open === undefined ? internal : open;\n const toggle = () => {\n if (open === undefined) setInternal(!isOpen);\n if (onToggle) onToggle(!isOpen);\n };\n return (\n <div className={[\"fd-coll\", className].filter(Boolean).join(\" \")} data-open={isOpen ? \"true\" : \"false\"} {...rest}>\n <button type=\"button\" className=\"fd-coll-trigger\" aria-expanded={isOpen} onClick={toggle}>\n {icon ? (\n <span className=\"fd-coll-caret\" style={{ background: \"var(--brand-soft)\", color: \"var(--brand)\", transform: \"none\" }}>\n <i className={\"ph ph-\" + icon} aria-hidden=\"true\" />\n </span>\n ) : null}\n <span style={{ flex: 1, minWidth: 0 }}>\n <span className=\"fd-coll-title\" style={{ display: \"block\" }}>{title}</span>\n {subtitle ? <span className=\"fd-coll-sub\" style={{ display: \"block\" }}>{subtitle}</span> : null}\n </span>\n {badge}\n <span className=\"fd-coll-caret\"><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>\n </button>\n <div className=\"fd-coll-panel\"><div><div className=\"fd-coll-content\">{children}</div></div></div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/** A right-side panel for detail and editing without losing the list behind it. */\nexport interface DrawerProps {\n open?: boolean;\n title?: React.ReactNode;\n onClose?: () => void;\n /** Plain content, or a render function receiving `close` — call it to trigger the closing animation before onClose fires. */\n footer?: React.ReactNode | ((close: () => void) => React.ReactNode);\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Drawer({ open = true, title, onClose, footer, children, className = \"\", ...rest }: DrawerProps) {\n const [closing, setClosing] = React.useState(false);\n const close = React.useCallback(() => {\n if (!onClose) return;\n setClosing(true);\n setTimeout(onClose, 210);\n }, [onClose]);\n React.useEffect(() => {\n if (!open || !onClose) return;\n const h = (e: KeyboardEvent) => { if (e.key === \"Escape\") close(); };\n document.addEventListener(\"keydown\", h);\n return () => document.removeEventListener(\"keydown\", h);\n }, [open, onClose, close]);\n if (!open) return null;\n /* Portalled to <body> on purpose. Rendered inline, the drawer's position:fixed resolves\n against the nearest transformed ancestor — the animated screen wrapper — so it stretched\n to the full scroll height of the page (5000px+) instead of the viewport. */\n return createPortal(\n <>\n <div className={\"fd-scrim\" + (closing ? \" is-closing\" : \"\")} style={{ display: \"block\" }} onClick={close} />\n <aside className={[\"fd-drawer\", closing ? \"is-closing\" : \"\", className].filter(Boolean).join(\" \")} role=\"dialog\" aria-modal=\"true\" {...rest}>\n <div className=\"fd-card-head\" style={{ flex: \"none\" }}>\n <span className=\"fd-card-head-title\">{title}</span>\n {onClose ? <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Close\" onClick={close}><i className=\"ph ph-x\" /></button> : null}\n </div>\n <div style={{ flex: \"1 1 auto\", minHeight: 0, overflow: \"auto\", padding: 20 }}>{children}</div>\n {footer ? <div className=\"fd-card-foot\" style={{ flex: \"none\" }}>{typeof footer === \"function\" ? footer(close) : footer}</div> : null}\n </aside>\n </>,\n document.body\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/** A focused decision on a scrim. Max 560px, 760 with `wide` for data. Escape closes. */\nexport interface ModalProps {\n open?: boolean;\n title?: React.ReactNode;\n description?: React.ReactNode;\n onClose?: () => void;\n /** Plain content, or a render function receiving `close` — call it to trigger the closing animation before onClose fires. */\n footer?: React.ReactNode | ((close: () => void) => React.ReactNode);\n /** 760px — for tables and side-by-side comparisons. */\n wide?: boolean;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Modal({ open = true, title, description, onClose, footer, wide = false, children, className = \"\", ...rest }: ModalProps) {\n const [closing, setClosing] = React.useState(false);\n const close = React.useCallback(() => {\n if (!onClose) return;\n setClosing(true);\n setTimeout(onClose, 190);\n }, [onClose]);\n React.useEffect(() => {\n if (!open || !onClose) return;\n const h = (e: KeyboardEvent) => { if (e.key === \"Escape\") close(); };\n document.addEventListener(\"keydown\", h);\n return () => document.removeEventListener(\"keydown\", h);\n }, [open, onClose, close]);\n if (!open) return null;\n /* Portalled for the same reason as Drawer: inline, the fixed-position scrim resolves\n against the nearest transformed ancestor rather than the viewport. */\n return createPortal(\n <div\n className={\"fd-scrim\" + (closing ? \" is-closing\" : \"\")}\n onClick={onClose ? (e: React.MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) close(); } : undefined}\n >\n <div\n className={[\"fd-modal\", closing ? \"is-closing\" : \"\", wide ? \"fd-modal-wide\" : \"\", className].filter(Boolean).join(\" \")}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n {...rest}\n >\n {title ? (\n <div className=\"fd-modal-head\">\n <span style={{ flex: 1, minWidth: 0 }}>\n <span className=\"fd-modal-title\" style={{ display: \"block\" }}>{title}</span>\n {description ? <span className=\"fd-body-sm fd-secondary\" style={{ display: \"block\", marginTop: 6 }}>{description}</span> : null}\n </span>\n {onClose ? <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Close\" onClick={close}><i className=\"ph ph-x\" /></button> : null}\n </div>\n ) : null}\n <div className=\"fd-modal-body\">{children}</div>\n {footer ? <div className=\"fd-modal-foot\">{typeof footer === \"function\" ? footer(close) : footer}</div> : null}\n </div>\n </div>,\n document.body\n );\n}\n","import * as React from \"react\";\n\n/**\n * The async contract for one region of a screen. Four states, one component:\n * loading (skeleton), refreshing (previous data stays visible, dimmed and inert),\n * ready, empty/error.\n */\nexport interface LoadingRegionProps {\n state?: \"loading\" | \"refreshing\" | \"ready\" | \"empty\" | \"error\";\n /** What to show before first data. Mirror the ready layout. */\n skeleton?: React.ReactNode;\n children?: React.ReactNode;\n /** Announced to screen readers while busy. */\n label?: string;\n error?: string;\n onRetry?: () => void;\n className?: string;\n}\n\nexport function LoadingRegion({\n state = \"ready\",\n skeleton,\n children,\n label = \"Loading\",\n error,\n onRetry,\n className = \"\",\n ...rest\n}: LoadingRegionProps) {\n if (state === \"empty\" || state === \"error\") {\n return (\n <div className={[\"fd-empty\", className].filter(Boolean).join(\" \")} {...rest}>\n <span className=\"fd-empty-icon\">\n <i className={state === \"error\" ? \"ph ph-warning\" : \"ph ph-tray\"} aria-hidden=\"true\" />\n </span>\n <span className=\"fd-empty-title\">{state === \"error\" ? \"That didn't load\" : \"Nothing here yet\"}</span>\n <span className=\"fd-empty-body\">{error || \"Data will appear here once it exists.\"}</span>\n {onRetry ? <button type=\"button\" className=\"fd-btn fd-btn-secondary\" onClick={onRetry}>Try again</button> : null}\n </div>\n );\n }\n if (state === \"loading\") {\n return (\n <div className={className} role=\"status\" aria-busy=\"true\" aria-label={label} {...rest}>\n <span className=\"fd-sr\">{label}</span>\n {skeleton}\n </div>\n );\n }\n const stale = state === \"refreshing\";\n return (\n <div className={[stale ? \"fd-stale-region\" : \"\", className].filter(Boolean).join(\" \")}\n aria-busy={stale ? \"true\" : undefined} {...rest}>\n <div className={stale ? \"fd-stale\" : \"fd-arrived\"}>{children}</div>\n </div>\n );\n}\n","/** Determinate or indeterminate bar for a known long job — uploads, exports, plan builds. */\nexport interface ProgressBarProps {\n /** 0-100. Omit for indeterminate. */\n value?: number;\n label?: string;\n showValue?: boolean;\n className?: string;\n}\n\nexport function ProgressBar({ value, label, showValue = false, className = \"\", ...rest }: ProgressBarProps) {\n const indeterminate = value === undefined || value === null;\n const pct = indeterminate ? 0 : Math.max(0, Math.min(100, value));\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 8 }}>\n {label || showValue ? (\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n {label ? <span className=\"fd-label-lg\">{label}</span> : <span />}\n {showValue && !indeterminate ? <span className=\"fd-num fd-secondary\">{pct}%</span> : null}\n </div>\n ) : null}\n <div className={[\"fd-progress\", indeterminate ? \"fd-progress-indeterminate\" : \"\"].filter(Boolean).join(\" \")}\n role=\"progressbar\" aria-valuenow={indeterminate ? undefined : pct}\n aria-valuemin={0} aria-valuemax={100} aria-label={label} {...rest}>\n <div className=\"fd-progress-fill\" style={indeterminate ? undefined : { width: pct + \"%\" }} />\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The shape data will occupy, shown before the first payload lands.\n * Skeletons mirror the real layout so nothing shifts on arrival.\n */\nexport interface SkeletonProps {\n w?: number | string;\n h?: number | string;\n shape?: \"block\" | \"text\" | \"circle\" | \"card\";\n radius?: string;\n style?: React.CSSProperties;\n className?: string;\n}\n\nexport function Skeleton({ w = \"100%\", h = 16, shape = \"block\", radius, style, className = \"\", ...rest }: SkeletonProps) {\n const cls = [\n \"fd-skel\",\n shape === \"circle\" ? \"fd-skel-circle\" : shape === \"text\" ? \"fd-skel-text\" : shape === \"card\" ? \"fd-skel-card\" : \"fd-skel-block\",\n className\n ].filter(Boolean).join(\" \");\n return <span aria-hidden=\"true\" className={cls}\n style={{ display: \"block\", width: w, height: typeof h === \"number\" ? h + \"px\" : h, borderRadius: radius, ...style }} {...rest} />;\n}\n\nexport interface SkeletonTextProps {\n lines?: number;\n /** Per-line widths, cycled. Ragged widths read as text; equal widths read as a bug. */\n width?: string[];\n size?: number;\n gap?: number;\n className?: string;\n}\n\nexport function SkeletonText({ lines = 3, width = [\"100%\", \"92%\", \"64%\"], size = 15, gap = 8, className = \"\" }: SkeletonTextProps) {\n return (\n <span aria-hidden=\"true\" className={className} style={{ display: \"flex\", flexDirection: \"column\", gap: gap + \"px\" }}>\n {Array.from({ length: lines }).map((_, i) => (\n <span key={i} className=\"fd-skel fd-skel-text\"\n style={{ display: \"block\", height: size + \"px\", width: width[i % width.length] }} />\n ))}\n </span>\n );\n}\n","import * as React from \"react\";\n\n/** A small indeterminate indicator. For inline waits only — never over a whole page. */\nexport interface SpinnerProps {\n size?: \"sm\" | \"md\" | \"lg\";\n label?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport function Spinner({ size = \"md\", label = \"Loading\", className = \"\", style, ...rest }: SpinnerProps) {\n return (\n <span role=\"status\" aria-label={label}\n className={[\"fd-spinner\", size === \"lg\" ? \"fd-spinner-lg\" : \"\", className].filter(Boolean).join(\" \")}\n style={style} {...rest} />\n );\n}\n","import * as React from \"react\";\n\n/**\n * The app's 264px left rail. Grouped items under overline headers; the active item\n * takes a soft blue fill and deep blue label. Collapses off-canvas below 1024px.\n */\nexport interface SidebarNavItem {\n value: string;\n label: string;\n /** Phosphor icon name */\n icon: string;\n count?: number;\n /** Count still loading — shows a small skeleton instead of a number. */\n loading?: boolean;\n /** Member lacks the permission — shows a lock marker. Still navigable; the screen explains. */\n locked?: boolean;\n /** Designed but the backend is not wired — shows a construction marker. Still navigable;\n * the screen renders inert behind a coming-soon banner. */\n preview?: boolean;\n}\n\nexport interface SidebarNavProps {\n brand?: React.ReactNode;\n groups: Array<{ label?: string; items: SidebarNavItem[] }>;\n current?: string;\n onNavigate?: (value: string) => void;\n footer?: React.ReactNode;\n /** Mobile: slides the off-canvas rail in. */\n open?: boolean;\n className?: string;\n}\n\n/* Title-attribute tip rather than the Tooltip component: these sit inside a button, and a\n focusable tooltip trigger nested in a button is invalid and steals the click. */\nfunction Tip({ label, children }: { label: string; children?: React.ReactNode }) {\n return <span title={label} style={{ display: \"inline-flex\", flex: \"none\" }}>{children}</span>;\n}\n\nexport function SidebarNav({ brand, groups = [], current, onNavigate, footer, open = false, className = \"\", ...rest }: SidebarNavProps) {\n return (\n <nav className={[\"fd-side\", className].filter(Boolean).join(\" \")} data-open={open ? \"true\" : \"false\"} {...rest}>\n {brand ? <div style={{ height: \"var(--topbar-h)\", display: \"flex\", alignItems: \"center\", padding: \"0 18px\", borderBottom: \"1px solid var(--border)\", flex: \"none\", overflow: \"hidden\" }}>{brand}</div> : null}\n <div style={{ flex: 1, overflow: \"auto\", padding: \"4px 10px 18px\" }}>\n {groups.map((g, gi) => (\n <div key={gi}>\n {g.label ? <div className=\"fd-side-group\">{g.label}</div> : null}\n <div className=\"fd-stack\" style={{ gap: 2 }}>\n {g.items.map((it) => (\n <button key={it.value} type=\"button\" className=\"fd-side-item\"\n aria-current={current === it.value ? \"page\" : undefined}\n onClick={onNavigate ? () => onNavigate(it.value) : undefined}>\n <span className=\"fd-side-item-icon\"><i className={\"ph ph-\" + it.icon} aria-hidden=\"true\" /></span>\n <span style={{ flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{it.label}</span>\n {/* A preview item is navigable — the screen renders inert behind a banner — so it\n gets a marker rather than being hidden or disabled. */}\n {it.preview ? <Tip label=\"Designed, backend not wired yet\"><i className=\"ph ph-traffic-cone\" style={{ fontSize: 13, color: \"var(--warn-solid)\", flex: \"none\" }} /></Tip> : null}\n {it.locked ? <Tip label=\"You do not have permission for this\"><i className=\"ph ph-lock-simple\" style={{ fontSize: 13, color: \"var(--text-muted)\", flex: \"none\" }} /></Tip> : null}\n {it.count !== undefined ? <span className=\"fd-side-item-count\">{it.count}</span> : null}\n {it.loading ? <span className=\"fd-skel fd-skel-text\" style={{ width: 22, height: 11, marginLeft: \"auto\" }} /> : null}\n </button>\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div style={{ borderTop: \"1px solid var(--border)\", padding: 14, flex: \"none\" }}>{footer}</div> : null}\n </nav>\n );\n}\n","/** The real flytedesk wordmark. A genuinely transparent-background SVG (verified —\n * every non-ink pixel is alpha:0, not painted white; the old PNG's \"white-bg\"\n * filename was misleading, it was transparent too) drawn in a fixed dark navy\n * (#052E4A) — it has no light/white colorway of its own. SVG over the old PNG for\n * real infinite scalability, not a fixed-resolution raster stretched or downsampled\n * per size variant. Dark-theme visibility is handled in CSS (.fd-brand-mark),\n * not by shipping a second asset — see that rule's comment. */\nconst LOGO_SRC =\n \"https://cdn.prod.website-files.com/69a96def413819b7db64de8c/69ac8ec2ed84b986a5fb76dc_Logo%20(dark)%202.svg\";\n\nexport interface FlytedeskMarkProps {\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** Just the flytedesk logo, no label — for contexts too small for a stacked brand\n * (a collapsed rail, a favicon-sized corner mark). */\nexport function FlytedeskMark({ size = \"md\", className = \"\", ...rest }: FlytedeskMarkProps) {\n return (\n <span className={[\"fd-brand-mark\", size !== \"md\" ? \"fd-brand-mark-\" + size : \"\", className].filter(Boolean).join(\" \")} {...rest}>\n <img src={LOGO_SRC} alt=\"flytedesk\" />\n </span>\n );\n}\n\nexport interface FlytedeskBrandProps {\n /** The consuming app's name, shown under the logo — e.g. \"Media Planner\", \"Admin\". */\n appName: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\n/** The flytedesk logo stacked over the app's name — meant to drop straight into\n * SidebarNav's `brand` slot in every flytedesk app. */\nexport function FlytedeskBrand({ appName, size = \"md\", className = \"\", ...rest }: FlytedeskBrandProps) {\n return (\n <span className={[\"fd-brand\", size !== \"md\" ? \"fd-brand-\" + size : \"\", className].filter(Boolean).join(\" \")} {...rest}>\n <FlytedeskMark size={size} />\n <span className=\"fd-overline fd-muted\">{appName}</span>\n </span>\n );\n}\n","\n/**\n * Places within one screen. Underline only — no pill tabs in the product.\n */\nexport interface TabsProps {\n tabs: Array<string | { value: string; label: string; count?: number }>;\n value?: string;\n onChange?: (value: string) => void;\n className?: string;\n}\n\nexport function Tabs({ tabs = [], value, onChange, className = \"\", ...rest }: TabsProps) {\n return (\n <div className={[\"fd-tabs\", className].filter(Boolean).join(\" \")} role=\"tablist\" {...rest}>\n {tabs.map((t) => {\n const v = typeof t === \"string\" ? t : t.value;\n const label = typeof t === \"string\" ? t : t.label;\n const count = typeof t === \"string\" ? undefined : t.count;\n return (\n <button key={v} type=\"button\" role=\"tab\" className=\"fd-tab\" aria-selected={v === value}\n onClick={onChange ? () => onChange(v) : undefined}>\n {label}\n {count !== undefined ? <span className=\"fd-badge fd-badge-neutral\" style={{ height: 20, padding: \"0 7px\" }}>{count}</span> : null}\n </button>\n );\n })}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** 60px app header: breadcrumb left, actions right, and a 2px route loader along its top edge. */\nexport interface TopbarProps {\n /** A non-last crumb with `onClick` calls it (via `preventDefault`) instead of following\n * `href` — for a crumb that needs to run a side effect (e.g. clearing some selection)\n * before/instead of navigating. `href` still works on its own for a plain link crumb;\n * the two aren't mutually exclusive, but `onClick` wins when both are present. */\n crumbs?: Array<{ label: string; href?: string; onClick?: () => void }>;\n actions?: React.ReactNode;\n /** Shows the indeterminate route loader on the top edge. */\n loading?: boolean;\n /** Mobile menu handler — renders the hamburger. */\n onMenu?: () => void;\n className?: string;\n}\n\nexport function Topbar({ crumbs = [], actions, loading = false, onMenu, className = \"\", ...rest }: TopbarProps) {\n return (\n <header className={[\"fd-topbar\", className].filter(Boolean).join(\" \")} {...rest}>\n {onMenu ? <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Menu\" onClick={onMenu}><i className=\"ph ph-list\" /></button> : null}\n <nav className=\"fd-crumb\" aria-label=\"Breadcrumb\">\n {crumbs.map((c, i) => (\n <React.Fragment key={i}>\n {i > 0 ? <i className=\"ph ph-caret-right\" style={{ fontSize: 11, opacity: .6 }} aria-hidden=\"true\" /> : null}\n {i === crumbs.length - 1 ? (\n <span className=\"fd-crumb-current\">{c.label}</span>\n ) : (\n <a\n href={c.href || \"#\"}\n onClick={\n c.onClick\n ? (e) => {\n e.preventDefault();\n c.onClick!();\n }\n : undefined\n }\n >\n {c.label}\n </a>\n )}\n </React.Fragment>\n ))}\n </nav>\n <span style={{ flex: 1 }} />\n {actions}\n {loading ? <span className=\"fd-topload\" aria-hidden=\"true\" /> : null}\n </header>\n );\n}\n","\n/** A person or organisation mark. Initials on a soft brand tint when no image exists. */\nexport interface AvatarProps {\n name?: string;\n src?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nexport function Avatar({ name = \"\", src, size = \"md\", className = \"\", ...rest }: AvatarProps) {\n const initials = name.split(/\\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join(\"\").toUpperCase();\n return (\n <span className={[\"fd-avatar\", size === \"sm\" ? \"fd-avatar-sm\" : size === \"lg\" ? \"fd-avatar-lg\" : \"\", className].filter(Boolean).join(\" \")}\n title={name || undefined} {...rest}>\n {src ? <img src={src} alt={name} /> : initials || <i className=\"ph ph-user\" aria-hidden=\"true\" />}\n </span>\n );\n}\n\nexport interface AvatarStackProps {\n people: Array<string | { name: string; src?: string }>;\n size?: \"sm\" | \"md\" | \"lg\";\n max?: number;\n className?: string;\n}\n\nexport function AvatarStack({ people = [], size = \"sm\", max = 4, className = \"\" }: AvatarStackProps) {\n const shown = people.slice(0, max);\n const rest = people.length - shown.length;\n return (\n <span className={[\"fd-avatar-stack\", className].filter(Boolean).join(\" \")}>\n {shown.map((p, i) => <Avatar key={i} name={typeof p === \"string\" ? p : p.name} src={typeof p === \"string\" ? undefined : p.src} size={size} />)}\n {rest > 0 ? <Avatar name={\"+\" + rest} size={size} /> : null}\n </span>\n );\n}\n","import * as React from \"react\";\n\nconst TONES: Record<string, string> = { neutral: \"fd-badge-neutral\", info: \"fd-badge-info\", success: \"fd-badge-success\", warning: \"fd-badge-warning\", danger: \"fd-badge-danger\", live: \"fd-badge-live\", approved: \"fd-badge-approved\", count: \"fd-badge-count\" };\n\n/**\n * A pill of state. Badges never carry actions — if it is clickable it is a Tag.\n */\nexport interface BadgeProps {\n children?: React.ReactNode;\n /** live = the site's blue gradient \"Active\". approved = its mint pill. count = the blue number chip. */\n tone?: \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\" | \"live\" | \"approved\" | \"count\";\n dot?: boolean;\n /** Phosphor icon name */\n icon?: string;\n className?: string;\n}\n\nexport function Badge({ children, tone = \"neutral\", dot = false, icon, className = \"\", ...rest }: BadgeProps) {\n return (\n <span className={[\"fd-badge\", TONES[tone] || TONES.neutral, className].filter(Boolean).join(\" \")} {...rest}>\n {dot ? <span className=\"fd-badge-dot\" aria-hidden=\"true\" /> : null}\n {icon ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {children}\n </span>\n );\n}\n","import * as React from \"react\";\n\n/** Says what will appear here, and offers exactly one button. */\nexport interface EmptyStateProps {\n /** Phosphor icon name */\n icon?: string;\n title: React.ReactNode;\n children?: React.ReactNode;\n action?: React.ReactNode;\n className?: string;\n}\n\nexport function EmptyState({ icon = \"tray\", title, children, action, className = \"\", ...rest }: EmptyStateProps) {\n return (\n <div className={[\"fd-empty\", className].filter(Boolean).join(\" \")} {...rest}>\n <span className=\"fd-empty-icon\"><i className={\"ph ph-\" + icon} aria-hidden=\"true\" /></span>\n <span className=\"fd-empty-title\">{title}</span>\n {children ? <span className=\"fd-empty-body\">{children}</span> : null}\n {action}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * A callout with a fixed structure: statement, then cost, then two actions.\n * A flag without a number and a choice is not a flag — use plain body copy.\n */\nexport interface FlagProps {\n /** What is true. \"Ohio State is Weak.\" */\n statement: React.ReactNode;\n /** What it costs to fix. \"+$4,200 reaches Adequate.\" Rendered bold. */\n cost?: React.ReactNode;\n /** Two Buttons — the fix and the dismissal. */\n actions?: React.ReactNode;\n tone?: \"info\" | \"success\" | \"warning\" | \"danger\";\n className?: string;\n}\n\nexport function Flag({ statement, cost, actions, tone = \"warning\", className = \"\", ...rest }: FlagProps) {\n return (\n <div className={[\"fd-flag\", \"fd-flag-\" + tone, className].filter(Boolean).join(\" \")} role=\"status\" {...rest}>\n <span className=\"fd-flag-text\">\n {statement}\n {cost ? <> <span className=\"fd-flag-cost\">{cost}</span></> : null}\n </span>\n {actions ? <span className=\"fd-flag-actions\">{actions}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\nconst IS_MAC = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || \"\");\n\nconst GLYPH: Record<string, string> = {\n mod: IS_MAC ? \"⌘\" : \"Ctrl\", cmd: \"⌘\", meta: \"⌘\", ctrl: IS_MAC ? \"⌃\" : \"Ctrl\",\n alt: IS_MAC ? \"⌥\" : \"Alt\", opt: \"⌥\", option: \"⌥\", shift: \"⇧\",\n enter: \"↵\", return: \"↵\", esc: \"Esc\", escape: \"Esc\", tab: \"⇥\", space: \"Space\",\n backspace: \"⌫\", delete: \"⌦\", up: \"↑\", down: \"↓\", left: \"←\", right: \"→\", slash: \"/\",\n};\n\n/** A key hint that binds NOTHING — register the real shortcut separately. */\nexport interface KeyHintProps { keys: string; size?: \"sm\" | \"md\"; tone?: \"quiet\" | \"solid\"; className?: string }\n\n/**\n * A key hint. Renders a label and binds NOTHING — register the real shortcut\n * separately, or the cap and the binding drift apart.\n */\nexport function KeyHint({ keys, size = \"md\", tone = \"quiet\", className = \"\", ...rest }: KeyHintProps) {\n const parts = String(keys || \"\").split(\"+\").map((p) => p.trim()).filter(Boolean);\n const cls = [\"fd-keyhint\", size === \"sm\" ? \"fd-keyhint-sm\" : \"\", tone === \"solid\" ? \"fd-keyhint-solid\" : \"\", className].filter(Boolean).join(\" \");\n return (\n <span className={cls} aria-hidden=\"true\" {...rest}>\n {parts.map((p, i) => {\n const k = p.toLowerCase();\n const glyph = GLYPH[k] || (p.length === 1 ? p.toUpperCase() : p);\n return <kbd key={i}>{glyph}</kbd>;\n })}\n </span>\n );\n}\n\n/** The platform modifier as text, for prose: \"⌘\" or \"Ctrl\". */\nexport function modifierLabel(): string { return GLYPH.mod; }\n/** True when the event carries the platform's primary modifier. */\nexport function hasModifier(e: KeyboardEvent | React.KeyboardEvent): boolean { return IS_MAC ? e.metaKey : e.ctrlKey; }\n","import * as React from \"react\";\n\n// Badge's \"live\" / \"approved\" / \"count\" tones carry their own gradients and bespoke\n// height/padding, not just color — that's a pill treatment, not a toggle-chip one, so\n// Tag only takes the flat, token-only tones that drop in as background/border/color.\nconst TONES: Record<string, string> = { info: \"fd-tag-info\", success: \"fd-tag-success\", warning: \"fd-tag-warning\", danger: \"fd-tag-danger\" };\n\n/** A clickable chip — filters, selected campuses, applied channels. */\nexport interface TagProps {\n children?: React.ReactNode;\n icon?: string;\n selected?: boolean;\n /** Colors the chip once selected — e.g. a favoured (\"success\") or excluded (\"danger\") toggle. No effect while unselected. */\n tone?: \"neutral\" | \"info\" | \"success\" | \"warning\" | \"danger\";\n onRemove?: () => void;\n onClick?: () => void;\n className?: string;\n}\n\nexport function Tag({ children, icon, selected = false, tone = \"neutral\", onRemove, onClick, className = \"\", ...rest }: TagProps) {\n return (\n <button type=\"button\" className={[\"fd-tag\", selected ? TONES[tone] : null, className].filter(Boolean).join(\" \")}\n aria-pressed={selected} onClick={onClick} {...rest}>\n {icon ? <i className={\"ph ph-\" + icon} aria-hidden=\"true\" /> : null}\n {children}\n {onRemove ? (\n <span className=\"fd-tag-remove\" role=\"button\" aria-label=\"Remove\"\n onClick={(e) => { e.stopPropagation(); onRemove(); }}><i className=\"ph ph-x\" /></span>\n ) : null}\n </button>\n );\n}\n","import * as React from \"react\";\n\nconst ICON: Record<string, { i: string; bg: string }> = {\n success: { i: \"check\", bg: \"var(--ok-solid)\" },\n error: { i: \"x\", bg: \"var(--danger-solid)\" },\n info: { i: \"info\", bg: \"var(--info-solid)\" },\n loading: { i: \"\", bg: \"var(--n-500)\" },\n};\n\n/** Confirmation of something that already happened. Bottom-right, 5s, undo where reversible. */\nexport interface ToastProps {\n title: React.ReactNode;\n children?: React.ReactNode;\n tone?: \"success\" | \"error\" | \"info\" | \"loading\";\n onUndo?: () => void;\n onDismiss?: () => void;\n className?: string;\n}\n\nexport function Toast({ title, children, tone = \"success\", onUndo, onDismiss, className = \"\", ...rest }: ToastProps) {\n const ic = ICON[tone] || ICON.info;\n return (\n <div className={[\"fd-toast\", className].filter(Boolean).join(\" \")} role=\"status\" {...rest}>\n <span className=\"fd-toast-icon\" style={{ background: ic.bg }} aria-hidden=\"true\">\n {tone === \"loading\" ? <span className=\"fd-spinner\" style={{ width: 12, height: 12, borderWidth: 2, color: \"#fff\" }} /> : <i className={\"ph ph-\" + ic.i} />}\n </span>\n <span className=\"fd-toast-body\">\n <span className=\"fd-toast-title\" style={{ display: \"block\" }}>{title}</span>\n {children ? <span className=\"fd-secondary\" style={{ display: \"block\", marginTop: 2 }}>{children}</span> : null}\n {onUndo ? <button type=\"button\" className=\"fd-btn fd-btn-link\" style={{ marginTop: 8 }} onClick={onUndo}>Undo</button> : null}\n </span>\n {onDismiss ? <button type=\"button\" className=\"fd-btn-icon fd-btn-icon-sm\" aria-label=\"Dismiss\" onClick={onDismiss}><i className=\"ph ph-x\" /></button> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** A short clarification on hover or focus. Never the only place information lives. */\nexport interface TooltipProps {\n label: React.ReactNode;\n placement?: \"top\" | \"bottom\";\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function Tooltip({ label, placement = \"top\", children, className = \"\" }: TooltipProps) {\n const [show, setShow] = React.useState(false);\n const pos = placement === \"bottom\"\n ? { top: \"calc(100% + 8px)\", left: \"50%\", transform: \"translateX(-50%)\" }\n : { bottom: \"calc(100% + 8px)\", left: \"50%\", transform: \"translateX(-50%)\" };\n return (\n <span style={{ position: \"relative\", display: \"inline-flex\" }}\n onMouseEnter={() => setShow(true)} onMouseLeave={() => setShow(false)}\n onFocus={() => setShow(true)} onBlur={() => setShow(false)}>\n {children}\n {show ? <span className={[\"fd-tooltip\", className].filter(Boolean).join(\" \")} role=\"tooltip\" style={pos}>{label}</span> : null}\n </span>\n );\n}\n","import * as React from \"react\";\n\nexport interface ClampProps {\n children?: React.ReactNode;\n /** With maxChars, pass the raw string instead of children. */\n text?: string;\n maxChars?: number;\n maxHeight?: number;\n moreLabel?: string;\n lessLabel?: string;\n onToggle?: (open: boolean) => void;\n className?: string;\n}\n\n/**\n * Height- or character-clamped content with a Show more control.\n * The control is a real button, always in the DOM when the content overflows.\n */\nexport function Clamp({\n children, text, maxChars, maxHeight = 320,\n moreLabel = \"Show more\", lessLabel = \"Show less\",\n onToggle, className = \"\",\n}: ClampProps) {\n const [open, setOpen] = React.useState(false);\n const [overflows, setOverflows] = React.useState(false);\n const bodyRef = React.useRef<HTMLDivElement>(null);\n\n const charClamped = React.useMemo(() => {\n if (open || !maxChars || typeof text !== \"string\" || text.length <= maxChars) return null;\n const cut = text.slice(0, maxChars);\n const at = cut.lastIndexOf(\" \");\n return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + \"…\";\n }, [text, maxChars, open]);\n\n React.useLayoutEffect(() => {\n const node = bodyRef.current;\n if (maxChars || !node || !maxHeight) return;\n const measure = () => {\n const el = bodyRef.current;\n if (el) setOverflows(el.scrollHeight > maxHeight + 24);\n };\n measure();\n const RO = typeof ResizeObserver !== \"undefined\" ? ResizeObserver : null;\n if (!RO) return;\n const ro = new RO(measure);\n ro.observe(node);\n return () => ro.disconnect();\n }, [maxHeight, maxChars, children, text]);\n\n const clamped = maxChars ? !!charClamped : overflows && !open;\n const toggle = () => { setOpen((v) => { onToggle && onToggle(!v); return !v; }); };\n\n return (\n <div className={[\"fd-clamp\", clamped ? \"is-clamped\" : \"\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-clamp-body\" ref={bodyRef} style={!maxChars && clamped ? { maxHeight } : undefined}>\n {maxChars ? (charClamped != null ? charClamped : (text != null ? text : children)) : children}\n </div>\n {(maxChars ? (charClamped != null || open) : overflows) ? (\n <button type=\"button\" className=\"fd-clamp-more\" onClick={toggle} aria-expanded={open}>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n {open ? lessLabel : moreLabel}\n </button>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\nconst BANDS: Record<string, { n: number; label: string }> = {\n weak: { n: 1, label: \"Weak\" },\n adequate: { n: 2, label: \"Adequate\" },\n strong: { n: 3, label: \"Strong\" },\n dominant: { n: 4, label: \"Dominant\" },\n};\n\n/** CRP is a derived float (e.g. 151.63707315984357) — never render it raw. One decimal\n * matches every other CRP display in this library (BudgetReallocator, ChannelContribution). */\nfunction formatCrp(crp: number): string {\n return crp.toFixed(1);\n}\n\nexport interface CsiMeterProps {\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n size?: number;\n width?: number;\n gap?: number;\n}\n\nexport function CsiMeter({ band = \"weak\", size = 4, width = 5, gap = 2 }: CsiMeterProps) {\n const n = (BANDS[band] || BANDS.weak).n;\n return (\n <span className=\"fd-meter\" style={{ gap: gap + \"px\" }} aria-hidden=\"true\">\n {[1, 2, 3, 4].map((i) => (\n <span\n key={i}\n className={\"fd-meter-seg\" + (i <= n ? \" is-on\" : \"\")}\n style={{ width: width + \"px\", height: size + \"px\" }}\n />\n ))}\n </span>\n );\n}\n\n/**\n * Campus Saturation Index — the product's signature encoding. Four ordered bands\n * in a reserved teal ramp that appears nowhere else: blue is interaction, teal is\n * saturation. Never color-only — the band name and a 4-segment meter always ship\n * with the fill.\n */\nexport interface CsiBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n /** Cost per reachable person. Internal surfaces only — never client-facing. */\n crp?: number;\n size?: \"compact\" | \"medium\";\n /** The \"will become\" state while a reallocation is being dragged: 70% opacity, dashed edge. */\n preview?: boolean;\n /** Amber dot marking a Weak campus that can be fixed. */\n alert?: boolean;\n}\n\nexport function CsiBadge({ band = \"weak\", crp, size = \"compact\", preview = false, alert = false, className = \"\", ...rest }: CsiBadgeProps) {\n const b = BANDS[band] || BANDS.weak;\n return (\n <span\n className={[\"fd-csi\", \"fd-csi-\" + b.n, size === \"medium\" ? \"fd-csi-medium\" : \"fd-csi-compact\", preview ? \"fd-csi-preview\" : \"\", className].filter(Boolean).join(\" \")}\n {...rest}\n >\n {alert ? <span className=\"fd-badge-dot\" style={{ background: \"var(--csi-alert)\" }} aria-label=\"Fixable\" /> : null}\n <CsiMeter band={band} size={size === \"medium\" ? 11 : 9} width={size === \"medium\" ? 4 : 3} />\n {b.label}\n {crp !== undefined && crp !== null ? <span className=\"fd-csi-crp\">{formatCrp(crp)}</span> : null}\n </span>\n );\n}\n\nexport interface CsiHeroProps {\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n crp?: number;\n label?: string;\n className?: string;\n}\n\nexport function CsiHero({ band = \"weak\", crp, label, className = \"\" }: CsiHeroProps) {\n const b = BANDS[band] || BANDS.weak;\n const mark = \"var(--csi-\" + b.n + \"-mark)\";\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 10 }}>\n <span className=\"fd-csi-hero-num\" style={{ color: mark }}>\n {crp !== undefined && crp !== null ? formatCrp(crp) : \"\"}\n </span>\n <span className=\"fd-label-lg\" style={{ color: \"var(--text-2)\" }}>{label || b.label}</span>\n <span className=\"fd-meter\" style={{ gap: 3, color: mark, width: 120 } as React.CSSProperties}>\n {[1, 2, 3, 4].map((i) => (\n <span key={i} className={\"fd-meter-seg\" + (i <= b.n ? \" is-on\" : \"\")} style={{ height: 6, flex: 1 }} />\n ))}\n </span>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The product's dense read surface. Sticky overline header, hairline rows, no zebra,\n * numbers right-aligned and tabular. Renders its own skeleton rows so the table\n * never collapses while data is in flight.\n */\nexport interface DataTableColumn {\n key: string;\n label: string;\n /** Right-aligned tabular figures. Never center a number. */\n numeric?: boolean;\n /** Set widths explicitly; auto layout shifts as data arrives. */\n width?: string;\n sortable?: boolean;\n render?: (row: any) => React.ReactNode;\n}\nexport interface DataTableProps {\n columns: DataTableColumn[];\n rows: any[];\n compact?: boolean;\n selectedId?: string | number;\n onRowClick?: (row: any) => void;\n rowKey?: string;\n /** First load: nothing on screen yet, so skeleton rows are drawn. */\n loading?: boolean;\n /** A re-query (sort, filter, page) while the PREVIOUS rows are still rendered. Dims them,\n * makes them inert and shows an \"Updating…\" pill, so nobody acts on superseded data. */\n refreshing?: boolean;\n skeletonRows?: number;\n sort?: { key: string; dir: \"asc\" | \"desc\" };\n onSort?: (key: string) => void;\n className?: string;\n}\n\nexport function DataTable({\n columns = [], rows = [], compact = false, selectedId, onRowClick, rowKey = \"id\",\n loading = false, refreshing = false, skeletonRows = 6, sort, onSort, className = \"\", ...rest\n}: DataTableProps) {\n /* `loading` is the first load: no rows exist, so draw skeletons.\n `refreshing` is a re-query (sort, filter, page) where the OLD rows are still on screen —\n they must read as not-current, or the user acts on data the server has already superseded.\n Reuses the design system's documented stale tier (skeleton.css: fd-stale-region + fd-stale,\n dimmed, inert, with a sheen) and adds only the explicit label that tier lacks. */\n const stale = refreshing && !loading;\n /* The overlay lives in a host OUTSIDE .fd-table-wrap on purpose. The wrap carries\n overflow:auto for wide tables, which makes it the nearest scrollport — so a sticky pill\n inside it can never stick to the page's real scroller and scrolled straight off screen.\n The host has no overflow, so sticky resolves against .fd-scroll as intended.\n Rendered unconditionally so toggling stale causes no layout shift. */\n return (\n <div className=\"fd-table-host\">\n <div className={[\"fd-table-wrap\", className].filter(Boolean).join(\" \")}\n aria-busy={loading || refreshing ? \"true\" : undefined} {...rest}>\n <table className={[\"fd-table\", compact ? \"fd-table-compact\" : \"\"].filter(Boolean).join(\" \")}>\n <thead>\n <tr>\n {columns.map((c) => (\n <th key={c.key} scope=\"col\" style={{ width: c.width }}\n className={[c.numeric ? \"is-num\" : \"\", sort && sort.key === c.key ? \"is-sorted\" : \"\"].filter(Boolean).join(\" \")}\n aria-sort={sort && sort.key === c.key ? (sort.dir === \"asc\" ? \"ascending\" : \"descending\") : undefined}>\n {c.sortable && onSort ? (\n <button type=\"button\" onClick={() => onSort(c.key)}>\n {c.label}\n {sort && sort.key === c.key ? <i className={\"ph fd-caret ph-caret-\" + (sort.dir === \"asc\" ? \"up\" : \"down\")} /> : null}\n </button>\n ) : c.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className={stale ? \"fd-stale\" : undefined}>\n {loading\n ? Array.from({ length: skeletonRows }).map((_, i) => (\n <tr key={i}>\n {columns.map((c) => (\n <td key={c.key} className={c.numeric ? \"is-num\" : \"\"}>\n <span className=\"fd-skel fd-skel-text\" style={{ display: \"inline-block\", height: 13, width: c.numeric ? 52 : (i % 3 === 0 ? \"72%\" : \"88%\") }} />\n </td>\n ))}\n </tr>\n ))\n : rows.map((r) => (\n <tr key={r[rowKey]} aria-selected={selectedId === r[rowKey] ? \"true\" : undefined}\n onClick={onRowClick ? () => onRowClick(r) : undefined}\n style={onRowClick ? { cursor: \"pointer\" } : undefined}>\n {columns.map((c) => (\n <td key={c.key} className={c.numeric ? \"is-num\" : \"\"}>\n {c.render ? c.render(r) : r[c.key]}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {stale ? (\n <div className=\"fd-table-stale\">\n <span className=\"fd-table-stale-pill\" role=\"status\"><span className=\"fd-spinner\" aria-hidden=\"true\" /> Updating…</span>\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Button } from \"../actions/Button\";\nimport { Tag } from \"../feedback/Tag\";\n\nexport interface FilterFieldOption {\n value: string;\n label: string;\n}\n\ninterface FilterFieldBase {\n /** Filter id — the key this field reads/writes in `filters` and reports through\n * onFilterChange/onFilterRemove. Matches useServerTable's setFilter(id, value). */\n key: string;\n /** Human label shown in the \"add filter\" list and on the field's chip. */\n label: string;\n}\n\nexport interface FilterFieldText extends FilterFieldBase {\n type: \"text\";\n placeholder?: string;\n}\n\nexport interface FilterFieldSelect extends FilterFieldBase {\n type: \"select\";\n options: FilterFieldOption[];\n}\n\n/** A declared filter field. Add a variant here (and a branch below) for a new value picker. */\nexport type FilterField = FilterFieldText | FilterFieldSelect;\n\nexport interface FilterBarProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"onChange\"> {\n /** Every filter a consumer can add. Order here is the order in the \"add filter\" list. */\n fields: FilterField[];\n /** Straight off useServerTable — a value of undefined/\"\"/false reads as \"not set\",\n * same convention that hook already uses for activeFilterCount. */\n filters: Record<string, unknown>;\n /** Fires on every value edit. Maps 1:1 onto useServerTable's setFilter(id, value). */\n onFilterChange: (key: string, value: unknown) => void;\n /** Fires when a chip's × is clicked. Maps 1:1 onto useServerTable's clearFilter(id). */\n onFilterRemove: (key: string) => void;\n /** Which edge the \"add filter\" popover aligns to. Default \"left\" — the trigger sits\n * at the end of a left-to-right chip row, so its menu opens under its left edge. */\n align?: \"left\" | \"right\";\n className?: string;\n}\n\ntype Panel = { kind: \"add\" } | { kind: \"edit\"; key: string } | null;\n\n/** Same \"is this filter set\" rule as useServerTable's activeFilterCount, so a value this\n * component didn't just write (e.g. restored from a URL) still renders as a chip. */\nconst isSet = (v: unknown): boolean => !(v == null || v === \"\" || v === false);\n\n/**\n * FilterBar — the declarative filter system for a server-driven list.\n *\n * A consumer declares fields once (`{ key, label, type: \"text\" | \"select\", ... }`) and\n * hands this a live `filters` record plus onFilterChange/onFilterRemove — the same three\n * things useServerTable already exposes, so wiring one up is copy-paste, not glue code.\n * Every active filter renders as a Tag chip; this component holds no shadow copy of\n * filter values, only the transient \"which field's popover/input is open right now\" UI\n * state (`panel`), the same way SortMenu holds `open` but never sort state itself.\n *\n * Visual/interaction language is deliberately identical to SortMenu: a secondary Button\n * trigger, a `fd-view-enter` panel positioned with `top: calc(100% + 6px)`, the same\n * click-outside/Escape wiring, and the same `fd-stack`/`fd-row`/`fd-overline`/`fd-muted`/\n * `fd-body-sm` utility classes — so this reads as built by the same hand, not a new\n * import from elsewhere.\n */\nexport function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = \"left\", className = \"\", ...rest }: FilterBarProps) {\n const [panel, setPanel] = React.useState<Panel>(null);\n const rootRef = React.useRef<HTMLSpanElement>(null);\n const textInputRef = React.useRef<HTMLInputElement>(null);\n const optionsRef = React.useRef<HTMLSpanElement>(null);\n\n const editingField = panel && panel.kind === \"edit\" ? fields.find((f) => f.key === panel.key) : undefined;\n // The \"add\" list and a select field's option list are floating overlays that can be\n // dismissed by clicking anywhere else or pressing Escape — a text field's inline input\n // is dismissed by its own onBlur/onKeyDown instead, so it doesn't need this listener.\n const dismissible = !!panel && (panel.kind === \"add\" || (panel.kind === \"edit\" && editingField?.type === \"select\"));\n\n React.useEffect(() => {\n if (!dismissible) return;\n const away = (e: PointerEvent) => { if (rootRef.current && !rootRef.current.contains(e.target as Node)) setPanel(null); };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setPanel(null); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [dismissible]);\n\n // Focus lands in the field's new value input the moment it's added — a text field's\n // own <input>, or the currently-selected (else first) option in a select field's list.\n React.useEffect(() => {\n if (!panel || panel.kind !== \"edit\") return;\n if (editingField?.type === \"text\") {\n textInputRef.current?.focus();\n } else if (editingField?.type === \"select\" && optionsRef.current) {\n const target =\n optionsRef.current.querySelector<HTMLButtonElement>('[aria-selected=\"true\"]') ||\n optionsRef.current.querySelector<HTMLButtonElement>(\"button\");\n target?.focus();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [panel]);\n\n const addableFields = fields.filter((f) => !isSet(filters[f.key]));\n\n const startEditing = (key: string) => setPanel({ kind: \"edit\", key });\n\n return (\n <span className={className} style={{ position: \"relative\", display: \"inline-flex\", flexWrap: \"wrap\", alignItems: \"center\", gap: 8 }} ref={rootRef} {...rest}>\n {fields.map((field) => {\n const value = filters[field.key];\n const editing = panel?.kind === \"edit\" && panel.key === field.key;\n\n if (editing && field.type === \"text\") {\n return (\n <span\n key={field.key}\n className=\"fd-tag\"\n style={{ background: \"var(--surface-brand)\", borderColor: \"var(--border-brand)\", cursor: \"text\" }}\n >\n <input\n ref={textInputRef}\n value={(value as string | undefined) ?? \"\"}\n placeholder={field.placeholder || field.label}\n aria-label={field.label}\n onChange={(e) => onFilterChange(field.key, e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") setPanel(null);\n else if (e.key === \"Escape\") { e.stopPropagation(); setPanel(null); }\n }}\n onBlur={() => setPanel(null)}\n style={{ all: \"unset\", minWidth: 90, color: \"var(--text-on-surface-brand)\" }}\n />\n {isSet(value) ? (\n <span\n className=\"fd-tag-remove\"\n role=\"button\"\n aria-label={\"Remove \" + field.label}\n onClick={(e) => { e.stopPropagation(); onFilterRemove(field.key); setPanel(null); }}\n >\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </span>\n ) : null}\n </span>\n );\n }\n\n if (editing && field.type === \"select\") {\n const chosen = field.options.find((o) => o.value === value);\n return (\n <span key={field.key} style={{ position: \"relative\", display: \"inline-flex\" }}>\n <Tag selected onClick={() => setPanel(null)} onRemove={() => { if (isSet(value)) onFilterRemove(field.key); setPanel(null); }}>\n {field.label}{chosen ? \": \" + chosen.label : \"\"}\n </Tag>\n <span\n className=\"fd-view-enter\"\n style={{ position: \"absolute\", top: \"calc(100% + 6px)\", left: 0, zIndex: 120, minWidth: 200, maxWidth: \"calc(100vw - 32px)\", display: \"block\", background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 10, boxShadow: \"0 16px 44px rgba(11,13,17,.18)\", padding: 8 }}\n >\n <span className=\"fd-stack\" role=\"listbox\" aria-label={field.label} ref={optionsRef} style={{ gap: 2 }}>\n {field.options.map((o) => {\n const on = o.value === value;\n return (\n <button\n type=\"button\" key={o.value} role=\"option\" aria-selected={on}\n className=\"fd-row\"\n onClick={() => { onFilterChange(field.key, o.value); setPanel(null); }}\n style={{ gap: 8, padding: \"4px 8px\", borderRadius: 7, border: 0, width: \"100%\", textAlign: \"left\", cursor: \"pointer\", background: on ? \"var(--surface-brand)\" : \"transparent\" }}\n >\n <span className=\"fd-body-sm\" style={{ flex: 1, fontWeight: on ? 700 : 500, color: on ? \"var(--text-on-surface-brand)\" : \"var(--text)\" }}>{o.label}</span>\n </button>\n );\n })}\n </span>\n </span>\n </span>\n );\n }\n\n if (isSet(value)) {\n const chosen = field.type === \"select\" ? field.options.find((o) => o.value === value) : undefined;\n const display = chosen ? chosen.label : String(value);\n return (\n <Tag key={field.key} selected onClick={() => startEditing(field.key)} onRemove={() => onFilterRemove(field.key)}>\n {field.label}: {display}\n </Tag>\n );\n }\n\n return null;\n })}\n\n {addableFields.length > 0 ? (\n <span style={{ position: \"relative\", display: \"inline-flex\" }}>\n <Button\n size=\"sm\" variant=\"secondary\" icon=\"funnel\"\n aria-haspopup=\"menu\" aria-expanded={panel?.kind === \"add\"}\n onClick={() => setPanel(panel?.kind === \"add\" ? null : { kind: \"add\" })}\n >\n Filter\n </Button>\n {panel?.kind === \"add\" ? (\n <span\n className=\"fd-view-enter\"\n style={{ position: \"absolute\", top: \"calc(100% + 6px)\", [align]: 0, zIndex: 120, width: 220, maxWidth: \"calc(100vw - 32px)\", display: \"block\", background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 10, boxShadow: \"0 16px 44px rgba(11,13,17,.18)\", padding: 8 } as React.CSSProperties}\n >\n <span className=\"fd-stack\" role=\"menu\" aria-label=\"Add filter\" style={{ gap: 2 }}>\n <span className=\"fd-overline fd-muted\" style={{ padding: \"4px 8px 6px\" }}>Add filter</span>\n {addableFields.map((f) => (\n <button\n type=\"button\" key={f.key} role=\"menuitem\"\n className=\"fd-row\"\n onClick={() => startEditing(f.key)}\n style={{ gap: 8, padding: \"4px 8px\", borderRadius: 7, border: 0, width: \"100%\", textAlign: \"left\", cursor: \"pointer\", background: \"transparent\" }}\n >\n <span className=\"fd-body-sm\" style={{ flex: 1, color: \"var(--text)\" }}>{f.label}</span>\n </button>\n ))}\n </span>\n </span>\n ) : null}\n </span>\n ) : null}\n </span>\n );\n}\n","import * as React from \"react\";\n\n/**\n * A flat figure tile — no shadow, no background color, never more than four in a row.\n */\nexport interface StatTileProps extends React.HTMLAttributes<HTMLDivElement> {\n label: string;\n value?: React.ReactNode;\n sub?: React.ReactNode;\n /** \"+12.4%\" or \"-3.1%\" — colour and arrow follow the sign. */\n delta?: string;\n loading?: boolean;\n /** Thin one-line variant for stat rows above tables. */\n compact?: boolean;\n className?: string;\n}\n\nexport function StatTile({ label, value, sub, delta, loading = false, compact = false, className = \"\", ...rest }: StatTileProps) {\n return (\n <div className={[\"fd-stat\", compact ? \"fd-stat-compact\" : \"\", className].filter(Boolean).join(\" \")} {...rest}>\n {loading\n ? <span className=\"fd-skel fd-skel-text\" style={{ display: \"block\", height: compact ? 20 : 28, width: \"62%\" }} />\n : (\n <span className=\"fd-stat-top\">\n <span className=\"fd-stat-figure\">{value}</span>\n {delta ? (\n <span className={delta.startsWith(\"-\") ? \"fd-stat-delta-down\" : \"fd-stat-delta-up\"} style={{ fontWeight: 600, fontSize: \"var(--body-sm-size)\", flex: \"none\" }}>\n <i className={\"ph ph-arrow-\" + (delta.startsWith(\"-\") ? \"down\" : \"up\") + \"-right\"} aria-hidden=\"true\" /> {delta}\n </span>\n ) : null}\n </span>\n )}\n {!loading && sub ? <span className=\"fd-stat-sub\">{sub}</span> : null}\n {loading\n ? <span className=\"fd-skel fd-skel-text\" style={{ display: \"block\", height: 10, width: \"40%\", marginTop: 8 }} />\n : <span className=\"fd-stat-label\" style={{ display: \"block\" }}>{label}</span>}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/* ── highlighting ──────────────────────────────────────────────────────────\n A small, dependency-free tokenizer. It emits classed spans (real nodes, no\n HTML strings), so themes live in CSS and there is no injection surface. */\n\nconst JS_KW = /^(?:const|let|var|function|return|if|else|for|while|do|new|class|extends|import|from|export|default|await|async|try|catch|finally|throw|typeof|instanceof|of|in|switch|case|break|continue|delete|void|yield|static|get|set|this|super|interface|type|enum|implements|public|private|protected|readonly|abstract|as|satisfies|declare|namespace)$/;\n\ntype RuleClass = string | null;\ntype Rule = [RegExp, RuleClass | ((t: string) => RuleClass)];\n\nconst RULES: Record<string, Rule[]> = {\n js: [\n [/\\/\\/[^\\n]*/y, \"com\"], [/\\/\\*[\\s\\S]*?\\*\\//y, \"com\"],\n [/`(?:\\\\[\\s\\S]|\\$\\{[^}]*\\}|[^`\\\\])*`?/y, \"str\"],\n [/'(?:\\\\[\\s\\S]|[^'\\\\\\n])*'?/y, \"str\"], [/\"(?:\\\\[\\s\\S]|[^\"\\\\\\n])*\"?/y, \"str\"],\n [/\\b(?:true|false|null|undefined|NaN|Infinity)\\b/y, \"lit\"],\n [/\\b0[xb][0-9a-f_]+\\b|\\b\\d[\\d_]*(?:\\.\\d+)?(?:e[+-]?\\d+)?\\b/iy, \"num\"],\n [/[A-Za-z_$][\\w$]*/y, (t) => (JS_KW.test(t) ? \"kw\" : /^[A-Z]/.test(t) ? \"type\" : null)],\n [/[{}()[\\];,.]/y, \"pun\"], [/[+\\-*/%=<>!&|?:^~]+/y, \"op\"],\n ],\n py: [\n [/#[^\\n]*/y, \"com\"],\n [/\"\"\"[\\s\\S]*?\"\"\"|'''[\\s\\S]*?'''/y, \"str\"],\n [/f?'(?:\\\\[\\s\\S]|[^'\\\\\\n])*'?|f?\"(?:\\\\[\\s\\S]|[^\"\\\\\\n])*\"?/y, \"str\"],\n [/\\b(?:True|False|None)\\b/y, \"lit\"],\n [/\\b\\d[\\d_]*(?:\\.\\d+)?\\b/y, \"num\"],\n [/@[A-Za-z_][\\w.]*/y, \"fn\"],\n [/[A-Za-z_][\\w]*/y, (t) => (/^(?:def|class|return|if|elif|else|for|while|import|from|as|with|try|except|finally|raise|lambda|yield|global|nonlocal|assert|pass|break|continue|del|in|is|not|and|or|async|await|self)$/.test(t) ? \"kw\" : /^[A-Z]/.test(t) ? \"type\" : null)],\n [/[{}()[\\];,.:]/y, \"pun\"], [/[+\\-*/%=<>!&|^~]+/y, \"op\"],\n ],\n css: [\n [/\\/\\*[\\s\\S]*?\\*\\//y, \"com\"],\n [/'(?:[^'\\\\\\n]|\\\\.)*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/--[\\w-]+/y, \"type\"],\n [/@[\\w-]+/y, \"kw\"],\n [/#[0-9a-f]{3,8}\\b/iy, \"num\"],\n [/\\b\\d*\\.?\\d+(?:px|rem|em|%|vh|vw|s|ms|deg|fr|ch)?\\b/y, \"num\"],\n [/[.#]?[\\w-]+(?=\\s*\\{)/y, \"fn\"],\n [/[\\w-]+(?=\\s*:)/y, \"prop\"],\n [/[{}();:,]/y, \"pun\"], [/[>+~*]/y, \"op\"],\n ],\n html: [\n [/<!--[\\s\\S]*?-->/y, \"com\"],\n [/<\\/?[A-Za-z][\\w-]*/y, \"kw\"],\n [/'(?:[^'\\\\\\n]|\\\\.)*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/[A-Za-z-]+(?==)/y, \"prop\"],\n [/[<>/=]/y, \"pun\"],\n ],\n json: [\n [/\"(?:\\\\[\\s\\S]|[^\"\\\\])*\"(?=\\s*:)/y, \"prop\"],\n [/\"(?:\\\\[\\s\\S]|[^\"\\\\])*\"/y, \"str\"],\n [/\\b(?:true|false|null)\\b/y, \"lit\"],\n [/-?\\b\\d[\\d.]*(?:e[+-]?\\d+)?\\b/iy, \"num\"],\n [/[{}[\\],:]/y, \"pun\"],\n ],\n sql: [\n [/--[^\\n]*/y, \"com\"], [/\\/\\*[\\s\\S]*?\\*\\//y, \"com\"],\n [/'(?:[^'\\\\]|\\\\.|'')*'/y, \"str\"],\n [/\\b\\d+(?:\\.\\d+)?\\b/y, \"num\"],\n [/[A-Za-z_][\\w]*/y, (t) => (/^(?:select|from|where|join|left|right|inner|outer|on|group|order|by|having|limit|offset|insert|into|values|update|set|delete|create|table|alter|drop|index|view|with|as|and|or|not|null|is|in|between|like|case|when|then|else|end|distinct|count|sum|avg|min|max|coalesce|cast|union|all|asc|desc)$/i.test(t) ? \"kw\" : null)],\n [/[(),.;*]/y, \"pun\"], [/[=<>!+\\-/%|]+/y, \"op\"],\n ],\n bash: [\n [/#[^\\n]*/y, \"com\"],\n [/'[^'\\n]*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/\\$\\{?[A-Za-z_][\\w]*\\}?|\\$\\d/y, \"type\"],\n [/(?:^|\\n)\\s*[a-z_][\\w-]*/y, \"fn\"],\n [/\\b(?:if|then|fi|else|elif|for|in|do|done|while|case|esac|function|return|export|local|source|echo|cd|set)\\b/y, \"kw\"],\n [/--?[\\w-]+/y, \"prop\"],\n [/[|&;()<>]/y, \"pun\"],\n ],\n yaml: [\n [/#[^\\n]*/y, \"com\"],\n [/^[ \\t]*-?[ \\t]*[\\w.-]+(?=:)/my, \"prop\"],\n [/'[^'\\n]*'|\"[^\"\\n]*\"/y, \"str\"],\n [/\\b(?:true|false|null|yes|no)\\b/iy, \"lit\"],\n [/\\b\\d[\\d.]*\\b/y, \"num\"],\n [/[:,\\-[\\]{}]/y, \"pun\"],\n ],\n generic: [\n [/\\/\\/[^\\n]*|#[^\\n]*/y, \"com\"],\n [/'(?:[^'\\\\\\n]|\\\\.)*'|\"(?:[^\"\\\\\\n]|\\\\.)*\"/y, \"str\"],\n [/\\b\\d[\\d._]*\\b/y, \"num\"],\n [/[{}()[\\];,.:]/y, \"pun\"],\n ],\n};\n\nconst ALIAS: Record<string, string> = {\n javascript: \"js\", jsx: \"js\", ts: \"js\", typescript: \"js\", tsx: \"js\", mjs: \"js\", node: \"js\", vue: \"html\", svelte: \"html\",\n python: \"py\", scss: \"css\", less: \"css\", sass: \"css\", xml: \"html\", svg: \"html\", htm: \"html\",\n json5: \"json\", jsonc: \"json\", postgres: \"sql\", psql: \"sql\", mysql: \"sql\",\n sh: \"bash\", shell: \"bash\", zsh: \"bash\", console: \"bash\", yml: \"yaml\",\n};\n\nexport function languageLabel(lang?: string): string {\n if (!lang) return \"\";\n const map: Record<string, string> = { js: \"JavaScript\", jsx: \"JSX\", ts: \"TypeScript\", tsx: \"TSX\", py: \"Python\", python: \"Python\", sh: \"Shell\", bash: \"Shell\", html: \"HTML\", css: \"CSS\", json: \"JSON\", sql: \"SQL\", yaml: \"YAML\", yml: \"YAML\", md: \"Markdown\", diff: \"Diff\", vue: \"Vue\", go: \"Go\", rb: \"Ruby\", php: \"PHP\", java: \"Java\", rust: \"Rust\", swift: \"Swift\", kt: \"Kotlin\", c: \"C\", cpp: \"C++\", cs: \"C#\" };\n return map[lang.toLowerCase()] || lang.toUpperCase();\n}\n\n/** Tokenise source into [{t, c}] where c is a token class or null for plain text. */\nexport function tokenize(src: string, lang?: string): Array<{ t: string; c: string | null }> {\n const key = ALIAS[(lang || \"\").toLowerCase()] || (RULES[(lang || \"\").toLowerCase()] ? (lang || \"\").toLowerCase() : \"generic\");\n const rules = RULES[key] || RULES.generic;\n const out: Array<{ t: string; c: string | null }> = [];\n const text = src.length > 24000 ? src.slice(0, 24000) : src;\n let i = 0, plain = \"\";\n const flush = () => { if (plain) { out.push({ t: plain, c: null }); plain = \"\"; } };\n while (i < text.length) {\n let hit: { t: string; c: string | null } | null = null;\n for (const [re, cls] of rules) {\n re.lastIndex = i;\n const m = re.exec(text);\n if (m && m.index === i && m[0].length) {\n const c = typeof cls === \"function\" ? cls(m[0]) : cls;\n hit = { t: m[0], c };\n break;\n }\n }\n if (hit) { flush(); out.push(hit); i += hit.t.length; }\n else { plain += text[i]; i++; }\n }\n flush();\n if (src.length > text.length) out.push({ t: \"\\n… truncated\", c: \"com\" });\n return out;\n}\n\nfunction Highlighted({ code, lang }: { code: string; lang?: string }) {\n const toks = React.useMemo(() => tokenize(code, lang), [code, lang]);\n return <>{toks.map((tk, i) => (tk.c ? <span key={i} className={\"tok-\" + tk.c}>{tk.t}</span> : tk.t))}</>;\n}\n\nfunction useCopy(): [boolean, (text: string) => void] {\n const [done, setDone] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n // Restart the window on a repeat copy, and clear it on unmount, or a second\n // copy inherits the first's remaining time and blinks out early.\n React.useEffect(() => () => { if (timer.current) clearTimeout(timer.current); }, []);\n const copy = (text: string) => {\n const write = navigator.clipboard && navigator.clipboard.writeText\n ? navigator.clipboard.writeText(text)\n : Promise.reject();\n write.catch(() => {\n try {\n const ta = document.createElement(\"textarea\");\n ta.value = text; ta.style.position = \"fixed\"; ta.style.opacity = \"0\";\n document.body.appendChild(ta); ta.select(); document.execCommand(\"copy\"); ta.remove();\n } catch { /* noop */ }\n }).finally(() => {\n setDone(true);\n if (timer.current) clearTimeout(timer.current);\n timer.current = setTimeout(() => setDone(false), 1600);\n });\n };\n return [done, copy];\n}\n\nexport interface CodeBlockProps {\n code: string;\n language?: string;\n filename?: string;\n lineNumbers?: boolean;\n wrap?: boolean;\n /** Fold past this many lines. 0 disables. Default 26. */\n collapseAfter?: number;\n copyable?: boolean;\n actions?: React.ReactNode;\n className?: string;\n}\n\n/**\n * A fenced code block: language label, copy, soft-wrap toggle, optional line\n * numbers, and a fold for long listings.\n */\nexport function CodeBlock({\n code = \"\", language, filename, lineNumbers = false, wrap: wrapDefault = false,\n collapseAfter = 26, copyable = true, actions, className = \"\",\n}: CodeBlockProps) {\n const [wrap, setWrap] = React.useState(!!wrapDefault);\n const [open, setOpen] = React.useState(false);\n const [copied, copy] = useCopy();\n const body = String(code).replace(/\\n$/, \"\");\n const lines = body.split(\"\\n\");\n const foldable = collapseAfter > 0 && lines.length > collapseAfter + 6;\n const shown = foldable && !open ? lines.slice(0, collapseAfter).join(\"\\n\") : body;\n\n return (\n <div className={[\"fd-code\", wrap ? \"is-wrap\" : \"\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-code-head\">\n {filename ? <span className=\"fd-code-file\">{filename}</span> : null}\n <span className=\"fd-code-lang\">{languageLabel(language)}</span>\n <span className=\"fd-code-spacer\" />\n {actions}\n <button type=\"button\" className=\"fd-code-act\" onClick={() => setWrap((v) => !v)} aria-pressed={wrap} title={wrap ? \"No wrap\" : \"Soft wrap\"}>\n <i className={\"ph ph-text-\" + (wrap ? \"columns\" : \"align-left\")} aria-hidden=\"true\" />\n </button>\n {copyable ? (\n <button type=\"button\" className={\"fd-code-act\" + (copied ? \" is-done\" : \"\")} onClick={() => copy(body)}>\n <i className={\"ph ph-\" + (copied ? \"check\" : \"copy\")} aria-hidden=\"true\" />\n <span>{copied ? \"Copied\" : \"Copy\"}</span>\n </button>\n ) : null}\n </div>\n <div className=\"fd-code-body\">\n {lineNumbers ? (\n <pre className=\"fd-code-gutter\" aria-hidden=\"true\">{shown.split(\"\\n\").map((_, i) => (i + 1) + \"\\n\").join(\"\")}</pre>\n ) : null}\n <pre className=\"fd-code-pre\" tabIndex={0}><code><Highlighted code={shown} lang={language} /></code></pre>\n </div>\n {foldable ? (\n <button type=\"button\" className=\"fd-code-fold\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n {open ? \"Collapse\" : \"Show all \" + lines.length + \" lines\"}\n </button>\n ) : null}\n </div>\n );\n}\n\nexport interface DiffBlockProps { diff: string; filename?: string; language?: string; collapseAfter?: number; className?: string }\n\n/**\n * A unified diff. Renders +/- lines with their own gutters and a stat line —\n * the shape a code change should always take in a transcript.\n */\nexport function DiffBlock({ diff = \"\", filename, collapseAfter = 34, className = \"\" }: DiffBlockProps) {\n const [open, setOpen] = React.useState(false);\n const [copied, copy] = useCopy();\n const raw = String(diff).replace(/\\n$/, \"\");\n const all = raw.split(\"\\n\").map((line) => {\n if (/^(?:diff |index |---|\\+\\+\\+)/.test(line)) return { k: \"meta\", line };\n if (/^@@/.test(line)) return { k: \"hunk\", line };\n if (line.startsWith(\"+\")) return { k: \"add\", line };\n if (line.startsWith(\"-\")) return { k: \"del\", line };\n return { k: \"ctx\", line };\n });\n const adds = all.filter((l) => l.k === \"add\").length;\n const dels = all.filter((l) => l.k === \"del\").length;\n const foldable = collapseAfter > 0 && all.length > collapseAfter + 6;\n const rows = foldable && !open ? all.slice(0, collapseAfter) : all;\n\n return (\n <div className={[\"fd-code\", \"fd-diff\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-code-head\">\n <i className=\"ph ph-git-diff fd-code-icon\" aria-hidden=\"true\" />\n {filename ? <span className=\"fd-code-file\">{filename}</span> : <span className=\"fd-code-lang\">Diff</span>}\n <span className=\"fd-diff-stat fd-tabular\"><span className=\"is-add\">+{adds}</span><span className=\"is-del\">−{dels}</span></span>\n <span className=\"fd-code-spacer\" />\n <button type=\"button\" className={\"fd-code-act\" + (copied ? \" is-done\" : \"\")} onClick={() => copy(raw)}>\n <i className={\"ph ph-\" + (copied ? \"check\" : \"copy\")} aria-hidden=\"true\" />\n <span>{copied ? \"Copied\" : \"Copy\"}</span>\n </button>\n </div>\n <div className=\"fd-diff-body\">\n {rows.map((r, i) => (\n <div key={i} className={\"fd-diff-line is-\" + r.k}>\n <span className=\"fd-diff-mark\" aria-hidden=\"true\">{r.k === \"add\" ? \"+\" : r.k === \"del\" ? \"−\" : \"\"}</span>\n <code>{r.k === \"add\" || r.k === \"del\" ? r.line.slice(1) : r.line}</code>\n </div>\n ))}\n </div>\n {foldable ? (\n <button type=\"button\" className=\"fd-code-fold\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n {open ? \"Collapse\" : \"Show all \" + all.length + \" lines\"}\n </button>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { CodeBlock, DiffBlock } from \"./CodeBlock\";\nimport type { CodeBlockProps } from \"./CodeBlock\";\n\n/* ── inline ────────────────────────────────────────────────────────────────\n Everything renders to real React nodes. There is no HTML-string path, so the\n injection surface is closed by construction rather than by escaping. */\n\nconst SAFE = /^(?:https?:|mailto:|tel:|#|\\/|\\.{1,2}\\/)/i;\nconst safeHref = (h: unknown): string | null => (SAFE.test(String(h || \"\").trim()) ? String(h).trim() : null);\n\nconst INLINE: Array<[string, RegExp]> = [\n [\"code\", /`([^`\\n]+)`/],\n [\"image\", /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/],\n [\"link\", /\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/],\n [\"cite\", /\\[\\^([\\w.-]+)\\]/],\n [\"strongem\", /\\*\\*\\*([^*]+)\\*\\*\\*/],\n [\"strong\", /\\*\\*([^*]+?)\\*\\*|__([^_]+?)__/],\n [\"em\", /(?<![A-Za-z0-9])\\*([^*\\n]+?)\\*(?![A-Za-z0-9])|(?<![A-Za-z0-9_])_([^_\\n]+?)_(?![A-Za-z0-9_])/],\n [\"del\", /~~([^~]+)~~/],\n [\"autolink\", /<((?:https?:\\/\\/|mailto:)[^>\\s]+)>/],\n [\"bare\", /(?<![\\w@/])(https?:\\/\\/[^\\s<>()]+[^\\s<>().,;:!?])/],\n];\n\ninterface MdCtx {\n allowImages?: boolean;\n headingOffset?: number;\n renderCitation?: (marker: string) => React.ReactNode;\n onLinkClick?: (e: React.MouseEvent) => void;\n codeProps?: Partial<CodeBlockProps>;\n}\n\nfunction inlineNodes(src: string | null | undefined, ctx: MdCtx, keyBase: string): React.ReactNode[] {\n const out: React.ReactNode[] = [];\n let rest = String(src == null ? \"\" : src), guard = 0;\n const key = () => keyBase + \"-\" + out.length;\n while (rest && guard++ < 800) {\n let best: { kind: string; m: RegExpExecArray } | null = null;\n for (const [kind, re] of INLINE) {\n const m = re.exec(rest);\n if (m && (!best || m.index < best.m.index)) best = { kind, m };\n if (best && best.m.index === 0) break;\n }\n if (!best) break;\n const { kind, m } = best;\n if (m.index > 0) out.push(rest.slice(0, m.index));\n const g = (i: number) => m[i];\n if (kind === \"code\") out.push(<code key={key()} className=\"fd-md-code\">{g(1)}</code>);\n else if (kind === \"image\") {\n const src2 = safeHref(g(2));\n out.push(ctx.allowImages && src2\n ? <img key={key()} className=\"fd-md-img\" src={src2} alt={g(1) || \"\"} title={g(3) || undefined} loading=\"lazy\" />\n : <span key={key()} className=\"fd-md-imgalt\">{g(1) || \"image\"}</span>);\n } else if (kind === \"link\") {\n const href = safeHref(g(2));\n out.push(href\n ? <a key={key()} href={href} title={g(3) || undefined} target={/^https?:/i.test(href) ? \"_blank\" : undefined} rel=\"noopener noreferrer\" onClick={ctx.onLinkClick}>{inlineNodes(g(1), ctx, key())}</a>\n : <span key={key()}>{g(1)}</span>);\n } else if (kind === \"cite\") {\n out.push(ctx.renderCitation ? <React.Fragment key={key()}>{ctx.renderCitation(g(1))}</React.Fragment> : <sup key={key()} className=\"fd-md-cite\">{g(1)}</sup>);\n } else if (kind === \"strongem\") out.push(<strong key={key()}><em>{inlineNodes(g(1), ctx, key())}</em></strong>);\n else if (kind === \"strong\") out.push(<strong key={key()}>{inlineNodes(g(1) || g(2), ctx, key())}</strong>);\n else if (kind === \"em\") out.push(<em key={key()}>{inlineNodes(g(1) || g(2), ctx, key())}</em>);\n else if (kind === \"del\") out.push(<del key={key()}>{inlineNodes(g(1), ctx, key())}</del>);\n else if (kind === \"autolink\" || kind === \"bare\") {\n const href = safeHref(g(1));\n out.push(href ? <a key={key()} href={href} target=\"_blank\" rel=\"noopener noreferrer\" onClick={ctx.onLinkClick}>{g(1).replace(/^mailto:/, \"\")}</a> : g(1));\n }\n rest = rest.slice(m.index + m[0].length);\n }\n if (rest) out.push(rest);\n return out;\n}\n\n/* ── blocks ────────────────────────────────────────────────────────────── */\n\nconst RE = {\n fence: /^(\\s*)(`{3,}|~{3,})\\s*([\\w+#-]*)\\s*(?::\\s*(\\S+))?\\s*$/,\n heading: /^(#{1,6})\\s+(.*)$/,\n hr: /^\\s*(?:[-*_]\\s*){3,}$/,\n quote: /^\\s*>\\s?(.*)$/,\n li: /^(\\s*)([-*+]|\\d{1,3}[.)])\\s+(.*)$/,\n task: /^\\[([ xX])\\]\\s+(.*)$/,\n tableSep: /^\\s*\\|?[\\s:|-]*-[\\s:|-]*\\|?\\s*$/,\n};\n\nconst splitRow = (line: string): string[] => line.replace(/^\\s*\\|/, \"\").replace(/\\|\\s*$/, \"\").split(\"|\").map((c) => c.trim());\n\ntype ListItem = { checked?: boolean; children: Block[] };\n\ntype Block =\n | { t: \"code\"; lang: string; file: string; code: string }\n | { t: \"h\"; level: number; text: string }\n | { t: \"hr\" }\n | { t: \"quote\"; children: Block[] }\n | { t: \"list\"; ordered: boolean; start: number; items: ListItem[] }\n | { t: \"table\"; head: string[]; align: string[]; rows: string[][] }\n | { t: \"p\"; text: string };\n\nfunction parseBlocks(src: string): Block[] {\n const lines = String(src == null ? \"\" : src).replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const blocks: Block[] = [];\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n if (!line.trim()) { i++; continue; }\n\n const f = RE.fence.exec(line);\n if (f) {\n const close = new RegExp(\"^\\\\s*\" + f[2][0] + \"{\" + f[2].length + \",}\\\\s*$\");\n const buf: string[] = [];\n i++;\n while (i < lines.length && !close.test(lines[i])) buf.push(lines[i++]);\n i++;\n blocks.push({ t: \"code\", lang: f[3] || \"\", file: f[4] || \"\", code: buf.join(\"\\n\") });\n continue;\n }\n const h = RE.heading.exec(line);\n if (h) { blocks.push({ t: \"h\", level: h[1].length, text: h[2] }); i++; continue; }\n if (RE.hr.test(line)) { blocks.push({ t: \"hr\" }); i++; continue; }\n if (RE.quote.test(line)) {\n const buf: string[] = [];\n while (i < lines.length && (RE.quote.test(lines[i]) || (lines[i].trim() && buf.length && !RE.li.test(lines[i]) && !RE.fence.test(lines[i])))) {\n const q = RE.quote.exec(lines[i]);\n buf.push(q ? q[1] : lines[i].trim());\n i++;\n }\n blocks.push({ t: \"quote\", children: parseBlocks(buf.join(\"\\n\")) });\n continue;\n }\n if (line.includes(\"|\") && lines[i + 1] != null && RE.tableSep.test(lines[i + 1]) && lines[i + 1].includes(\"-\")) {\n const head = splitRow(line);\n const align = splitRow(lines[i + 1]).map((c) => (/^:-+:$/.test(c) ? \"center\" : /-+:$/.test(c) ? \"right\" : \"left\"));\n i += 2;\n const rows: string[][] = [];\n while (i < lines.length && lines[i].includes(\"|\") && lines[i].trim()) rows.push(splitRow(lines[i++]));\n blocks.push({ t: \"table\", head, align, rows });\n continue;\n }\n if (RE.li.test(line)) {\n const items: { raw: string[] }[] = [];\n const baseIndent = RE.li.exec(line)![1].length;\n const ordered = /\\d/.test(RE.li.exec(line)![2]);\n const start = ordered ? parseInt(RE.li.exec(line)![2], 10) : 1;\n while (i < lines.length) {\n const m = RE.li.exec(lines[i]);\n if (!m || m[1].length < baseIndent) {\n if (items.length && lines[i] && lines[i].trim() && lines[i].search(/\\S/) > baseIndent) { items[items.length - 1].raw.push(lines[i].trim()); i++; continue; }\n break;\n }\n if (m[1].length > baseIndent) { items[items.length - 1].raw.push(lines[i].slice(baseIndent + 2)); i++; continue; }\n if (ordered !== /\\d/.test(m[2])) break;\n items.push({ raw: [m[3]] });\n i++;\n while (i < lines.length && lines[i].trim() && !RE.li.test(lines[i]) && lines[i].search(/\\S/) > baseIndent) { items[items.length - 1].raw.push(lines[i].trim()); i++; }\n }\n blocks.push({\n t: \"list\", ordered, start,\n items: items.map((it) => {\n const joined = it.raw.join(\"\\n\");\n const task = RE.task.exec(joined);\n return task\n ? { checked: task[1].toLowerCase() === \"x\", children: parseBlocks(task[2]) }\n : { children: parseBlocks(joined) };\n }),\n });\n continue;\n }\n const buf: string[] = [];\n while (i < lines.length && lines[i].trim() && !RE.fence.test(lines[i]) && !RE.heading.test(lines[i]) && !RE.hr.test(lines[i]) && !RE.quote.test(lines[i]) && !RE.li.test(lines[i])) buf.push(lines[i++]);\n blocks.push({ t: \"p\", text: buf.join(\"\\n\") });\n }\n return blocks;\n}\n\nfunction renderBlocks(blocks: Block[], ctx: MdCtx, path: string): React.ReactNode[] {\n return blocks.map((b, i) => {\n const k = path + \"-\" + i;\n switch (b.t) {\n case \"code\": {\n if ((b.lang || \"\").toLowerCase() === \"diff\") return <DiffBlock key={k} diff={b.code} filename={b.file || undefined} />;\n return <CodeBlock key={k} code={b.code} language={b.lang} filename={b.file || undefined} {...(ctx.codeProps || {})} />;\n }\n case \"h\": {\n const lvl = Math.min(6, Math.max(1, b.level + (ctx.headingOffset || 0)));\n const Tag = (\"h\" + lvl) as React.ElementType;\n return <Tag key={k} className={\"fd-md-h fd-md-h\" + lvl}>{inlineNodes(b.text, ctx, k)}</Tag>;\n }\n case \"hr\": return <hr key={k} className=\"fd-md-hr\" />;\n case \"quote\": return <blockquote key={k} className=\"fd-md-quote\">{renderBlocks(b.children, ctx, k)}</blockquote>;\n case \"list\": {\n const Tag = (b.ordered ? \"ol\" : \"ul\") as React.ElementType;\n const isTask = b.items.some((it) => it.checked != null);\n return (\n <Tag key={k} className={\"fd-md-list\" + (isTask ? \" is-task\" : \"\")} start={b.ordered && b.start !== 1 ? b.start : undefined}>\n {b.items.map((it, j) => (\n <li key={k + \"-\" + j} className={it.checked != null ? (it.checked ? \"is-done\" : \"is-todo\") : undefined}>\n {it.checked != null ? (\n <span className=\"fd-md-task\" aria-hidden=\"true\"><i className={\"ph ph-\" + (it.checked ? \"check-square\" : \"square\")} /></span>\n ) : null}\n <span className=\"fd-md-li\">{renderBlocks(it.children, ctx, k + \"-\" + j)}</span>\n </li>\n ))}\n </Tag>\n );\n }\n case \"table\":\n return (\n <div key={k} className=\"fd-md-tablewrap\">\n <table className=\"fd-md-table\">\n <thead><tr>{b.head.map((c, j) => <th key={j} style={{ textAlign: (b.align[j] || \"left\") as React.CSSProperties[\"textAlign\"] }}>{inlineNodes(c, ctx, k + \"h\" + j)}</th>)}</tr></thead>\n <tbody>\n {b.rows.map((r, ri) => (\n <tr key={ri}>{b.head.map((_, ci) => <td key={ci} style={{ textAlign: (b.align[ci] || \"left\") as React.CSSProperties[\"textAlign\"] }}>{inlineNodes(r[ci] || \"\", ctx, k + ri + \"c\" + ci)}</td>)}</tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n default:\n return <p key={k} className=\"fd-md-p\">{inlineNodes(b.text, ctx, k)}</p>;\n }\n });\n}\n\nexport interface MarkdownProps {\n source: string;\n className?: string;\n codeProps?: Partial<CodeBlockProps>;\n allowImages?: boolean;\n headingOffset?: number;\n /** Renderer for `[^n]` markers. */\n renderCitation?: (marker: string) => React.ReactNode;\n onLinkClick?: (e: React.MouseEvent) => void;\n}\n\n/**\n * Read-only markdown → React nodes. Headings, emphasis, links, lists (incl. task\n * lists), quotes, tables, images, fenced code (handed to CodeBlock, `diff` to\n * DiffBlock) and `[^n]` citation markers.\n *\n * Deliberately read-only: an editor in readonly mode carries a contenteditable,\n * a context menu and popovers it will never use — per message.\n */\nexport function Markdown({\n source = \"\", className = \"\", codeProps, allowImages = true,\n headingOffset = 0, renderCitation, onLinkClick,\n}: MarkdownProps) {\n const ctx: MdCtx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };\n const blocks = React.useMemo(() => parseBlocks(source), [source]);\n return <div className={[\"fd-md\", className].filter(Boolean).join(\" \")}>{renderBlocks(blocks, ctx, \"b\")}</div>;\n}\n\n/** Inline-only markdown, for labels and single-line contexts. */\nexport function MarkdownInline({ source = \"\", className = \"\", onLinkClick }: { source: string; className?: string; onLinkClick?: (e: React.MouseEvent) => void }) {\n return <span className={[\"fd-md-inline\", className].filter(Boolean).join(\" \")}>{inlineNodes(source, { allowImages: false, onLinkClick }, \"i\")}</span>;\n}\n\n/** Strip markdown to plain text — for copy actions, titles and previews. */\nexport function markdownToText(src: string): string {\n return String(src == null ? \"\" : src)\n .replace(/```[\\w+#-]*\\n?([\\s\\S]*?)```/g, \"$1\")\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/^\\s{0,3}#{1,6}\\s+/gm, \"\")\n .replace(/\\*\\*\\*([^*]+)\\*\\*\\*|\\*\\*([^*]+)\\*\\*|__([^_]+)__/g, \"$1$2$3\")\n .replace(/(^|\\W)[*_]([^*_\\n]+)[*_](\\W|$)/g, \"$1$2$3\")\n .replace(/~~([^~]+)~~/g, \"$1\")\n .replace(/^\\s*>\\s?/gm, \"\")\n .trim();\n}\n","\n/**\n * A segmented bar — budget split by channel, delivery against a flight.\n * Unallocated space is hatched, so it looks unfinished rather than empty.\n */\nexport interface MeterSegment {\n label: string;\n value: number;\n /** Defaults to the categorical chart ramp in order. */\n color?: string;\n}\nexport interface MeterProps {\n segments: MeterSegment[];\n unallocated?: number;\n height?: number;\n label?: string;\n legend?: boolean;\n className?: string;\n}\n\nexport function Meter({ segments = [], unallocated = 0, height = 8, label, legend = false, className = \"\" }: MeterProps) {\n const total = segments.reduce((s, x) => s + x.value, 0) + unallocated;\n const pct = (v: number) => (total ? (v / total) * 100 : 0);\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 8 }}>\n {label ? <span className=\"fd-label-lg fd-secondary\">{label}</span> : null}\n <div className=\"fd-meterbar\" style={{ height }}>\n {segments.map((s, i) => (\n <span key={i} className=\"fd-meterbar-seg\" title={s.label}\n style={{ width: pct(s.value) + \"%\", background: s.color || \"var(--chart-\" + ((i % 8) + 1) + \")\", transition: \"width var(--dur-slow) var(--ease)\" }} />\n ))}\n {unallocated > 0 ? <span className=\"fd-meterbar-seg fd-meterbar-unallocated\" title=\"Unallocated\" style={{ width: pct(unallocated) + \"%\" }} /> : null}\n </div>\n {legend ? (\n <div className=\"fd-row\" style={{ gap: 16, flexWrap: \"wrap\" }}>\n {segments.map((s, i) => (\n <span key={i} className=\"fd-row fd-body-sm fd-secondary\" style={{ gap: 7 }}>\n <span style={{ width: 9, height: 9, borderRadius: 2, background: s.color || \"var(--chart-\" + ((i % 8) + 1) + \")\" }} />\n {s.label}\n </span>\n ))}\n {unallocated > 0 ? (\n <span className=\"fd-row fd-body-sm fd-secondary\" style={{ gap: 7 }}>\n <span className=\"fd-meterbar-unallocated\" style={{ width: 9, height: 9, borderRadius: 2 }} />Unallocated\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The standard footer for a server-driven table: range readout, rows-per-page,\n * and windowed page navigation. Presentational only — it holds no state.\n */\nexport interface PaginationProps extends React.HTMLAttributes<HTMLDivElement> {\n /** 1-indexed current page. */\n page?: number;\n pageSize?: number;\n /** Total matching rows on the server, not the length of the current page. */\n total?: number;\n pageSizes?: number[];\n onPageChange?: (page: number) => void;\n /** Omit to hide the rows-per-page control. */\n onPageSizeChange?: (pageSize: number) => void;\n loading?: boolean;\n /** Noun for the readout — \"rows\", \"campuses\", \"placements\". */\n unit?: string;\n className?: string;\n}\n\n/**\n * Pagination — the standard footer for every server-driven table.\n * Purely presentational: it reports intent through onPageChange / onPageSizeChange\n * and never derives its own state, so it stays honest against a real endpoint.\n */\nexport function Pagination({\n page = 1, pageSize = 25, total = 0, pageSizes = [10, 25, 50, 100],\n onPageChange, onPageSizeChange, loading = false, unit = \"rows\", className = \"\", ...rest\n}: PaginationProps) {\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const from = total === 0 ? 0 : (page - 1) * pageSize + 1;\n const to = Math.min(total, page * pageSize);\n const go = (p: number) => { if (onPageChange && p >= 1 && p <= totalPages && p !== page) onPageChange(p); };\n\n const nums: (number | string)[] = [];\n const span = 1;\n for (let i = 1; i <= totalPages; i++) {\n if (i === 1 || i === totalPages || Math.abs(i - page) <= span) nums.push(i);\n else if (nums[nums.length - 1] !== \"…\") nums.push(\"…\");\n }\n\n return (\n <div className={[\"fd-pag\", className].filter(Boolean).join(\" \")} {...rest}>\n <span className=\"fd-pag-count\">\n {loading ? <span className=\"fd-skel fd-skel-text\" style={{ display: \"inline-block\", height: 12, width: 108 }} />\n : total === 0 ? <>No {unit}</> : <><strong>{from.toLocaleString()}–{to.toLocaleString()}</strong> of {total.toLocaleString()} {unit}</>}\n </span>\n {onPageSizeChange ? (\n <label className=\"fd-pag-size\">\n <span>Rows</span>\n <select value={pageSize} onChange={(e) => onPageSizeChange(Number(e.target.value))} aria-label=\"Rows per page\">\n {pageSizes.map((n) => <option key={n} value={n}>{n}</option>)}\n </select>\n </label>\n ) : null}\n <span className=\"fd-pag-nav\">\n <button type=\"button\" onClick={() => go(1)} disabled={page <= 1} aria-label=\"First page\"><i className=\"ph ph-caret-double-left\" /></button>\n <button type=\"button\" onClick={() => go(page - 1)} disabled={page <= 1} aria-label=\"Previous page\"><i className=\"ph ph-caret-left\" /></button>\n {nums.map((n, i) => n === \"…\"\n ? <span key={\"e\" + i} className=\"fd-pag-gap\" aria-hidden=\"true\">…</span>\n : <button key={n} type=\"button\" onClick={() => go(n as number)} aria-current={n === page ? \"page\" : undefined}\n className={n === page ? \"is-current\" : \"\"}>{n}</button>)}\n <button type=\"button\" onClick={() => go(page + 1)} disabled={page >= totalPages} aria-label=\"Next page\"><i className=\"ph ph-caret-right\" /></button>\n <button type=\"button\" onClick={() => go(totalPages)} disabled={page >= totalPages} aria-label=\"Last page\"><i className=\"ph ph-caret-double-right\" /></button>\n </span>\n </div>\n );\n}\n","import * as React from \"react\";\n\nconst MIN = 60e3, HOUR = 36e5, DAY = 864e5;\n\n/** \"just now\" · \"4 min ago\" · \"in 4 min\" · \"Wed 5:00 PM\" · \"12 Mar\" */\nexport function formatRelative(value: string | Date, now?: number): string {\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n if (!t || isNaN(t)) return \"\";\n const ref = now || Date.now();\n const diff = t - ref;\n const abs = Math.abs(diff);\n const future = diff > 0;\n if (abs < 45e3) return future ? \"in a moment\" : \"just now\";\n if (abs < HOUR) { const m = Math.round(abs / MIN); return future ? \"in \" + m + \" min\" : m + \" min ago\"; }\n if (abs < 6 * HOUR) {\n const h = Math.floor(abs / HOUR), m = Math.round((abs % HOUR) / MIN);\n const s = h + \"h\" + (m ? \" \" + m + \"m\" : \"\");\n return future ? \"in \" + s : s + \" ago\";\n }\n const d = new Date(t);\n const sameDay = new Date(ref).toDateString() === d.toDateString();\n const time = d.toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n if (sameDay) return time;\n if (abs < 6 * DAY) return d.toLocaleDateString([], { weekday: \"short\" }) + \" \" + time;\n return d.toLocaleDateString([], { day: \"numeric\", month: \"short\" });\n}\n\n/** Absolute, for the title attribute. */\nexport function formatAbsolute(value: string | Date): string {\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n if (!t || isNaN(t)) return \"\";\n return new Date(t).toLocaleString([], { dateStyle: \"medium\", timeStyle: \"short\" });\n}\n\n/** Clock time only — \"3:42 PM\". */\nexport function formatClock(value: string | Date): string {\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n if (!t || isNaN(t)) return \"\";\n return new Date(t).toLocaleTimeString([], { hour: \"numeric\", minute: \"2-digit\" });\n}\n\n/** ms → \"1m 34s\" · \"12.4s\" · \"840ms\" */\nexport function formatDuration(ms: number): string {\n if (ms == null || isNaN(ms)) return \"\";\n if (ms < 1000) return Math.round(ms) + \"ms\";\n if (ms < 60e3) { const s = ms / 1000; return (s < 10 ? s.toFixed(1) : Math.round(s)) + \"s\"; }\n const m = Math.floor(ms / 60e3), s = Math.round((ms % 60e3) / 1000);\n if (m < 60) return m + \"m\" + (s ? \" \" + s + \"s\" : \"\");\n const h = Math.floor(m / 60);\n return h + \"h\" + (m % 60 ? \" \" + (m % 60) + \"m\" : \"\");\n}\n\nexport interface RelativeTimeProps { value: string | Date; prefix?: string; refresh?: boolean; className?: string }\n\n/**\n * A self-refreshing relative timestamp. Ticks no faster than the unit it shows,\n * and stops entirely once the value is days old.\n */\nexport function RelativeTime({ value, prefix, className = \"\", refresh = true, ...rest }: RelativeTimeProps) {\n const [, force] = React.useState(0);\n const t = value instanceof Date ? value.getTime() : Date.parse(value);\n React.useEffect(() => {\n if (!refresh || !t || isNaN(t)) return;\n const abs = Math.abs(t - Date.now());\n if (abs > DAY) return;\n const every = abs < HOUR ? 15e3 : 60e3;\n const id = setInterval(() => force((n) => n + 1), every);\n return () => clearInterval(id);\n }, [t, refresh]);\n if (!t || isNaN(t)) return null;\n return (\n <time className={className} dateTime={new Date(t).toISOString()} title={formatAbsolute(new Date(t))} {...rest}>\n {prefix ? prefix + \" \" : \"\"}{formatRelative(new Date(t))}\n </time>\n );\n}\n","import * as React from \"react\";\nimport { Popover, type Placement } from \"../actions/Popover\";\nimport { SegmentedMeter, type MeterSegmentInput } from \"./SegmentedMeter\";\n\nexport interface ScoreMeterProps {\n /** The score itself, 0-100. Shown as a plain integer next to the rail. */\n score: number;\n /** One segment per contributing thing, each already carrying its own colour. Widths\n * are proportional to `value` out of 100, so what doesn't contribute reads as the\n * empty remainder of the rail rather than as a missing segment. */\n segments: MeterSegmentInput[];\n /** Accessible name for the meter, e.g. \"Preference score\". Required — a bare bar with\n * a number next to it is meaningless to a screen reader without one. */\n label: string;\n /** Rail width in px. A fixed width (not a flexing one) is what lets a column of these\n * line up down a list. */\n width?: number;\n height?: number;\n /** Hide the numeral and show only the rail, for somewhere the number is already said. */\n showScore?: boolean;\n /** Content of the breakdown popover. Supplying it is what makes the meter clickable —\n * without it this renders as a plain, inert span. */\n breakdown?: React.ReactNode;\n /** Accessible name for the popover. Defaults to `label` + \" breakdown\". */\n breakdownLabel?: string;\n placement?: Placement;\n /** Width of the breakdown popover in px. */\n breakdownWidth?: number;\n className?: string;\n}\n\n/**\n * ScoreMeter — a small 0-100 score drawn as a categorical bar, optionally opening a\n * breakdown of how the score was arrived at.\n *\n * Not a new meter primitive: the rail IS SegmentedMeter (chosen over CsiMeter because a\n * score built from a variable number of differently-coloured contributions needs\n * per-segment colour and a variable segment count, and CsiMeter is fixed at four\n * segments all drawn in one `currentColor`) with its head and legend turned off, so the\n * proportional-width maths, the transition, the empty-remainder rail and the full\n * `role=\"meter\"` aria that SegmentedMeter already ships are used rather than reimplemented.\n * What this adds is the part SegmentedMeter deliberately lacks: a real trigger.\n *\n * The trigger is a `<button>`, never a div with an onClick — three things follow from\n * that, and all three are the reason it's a button. It is keyboard-operable and\n * announced as a control; SegmentedMeter's own `onClick` (which lands on a plain div)\n * is neither. And inside a drag source it is automatically safe: TransferList arms a\n * drag on any row pointerdown EXCEPT one originating inside a `button`, so the meter\n * stays clickable in a row you can also pick up and drag, with no extra coordination\n * between the two components.\n *\n * The popover is rendered as this component's own child rather than hoisted, which is\n * what makes it survive a virtualized list: the anchor and the open state live and die\n * together, so a row scrolled out of the mounted window takes its popover with it\n * instead of leaving an orphan pinned to a dead element. While the row IS mounted, the\n * popover tracks its anchor frame by frame (see usePopoverPosition), so it follows a row\n * that slides to a new slot when the list is re-sorted underneath it.\n */\nexport function ScoreMeter({\n score,\n segments,\n label,\n width = 56,\n height = 6,\n showScore = true,\n breakdown,\n breakdownLabel,\n placement = \"bottom-end\",\n breakdownWidth = 280,\n className = \"\",\n}: ScoreMeterProps) {\n const [open, setOpen] = React.useState(false);\n const ref = React.useRef<HTMLButtonElement>(null);\n const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));\n\n // The rail is aria-hidden and the accessible name is stated once on whatever wraps it\n // (the meter span, or the button). SegmentedMeter's own role=\"meter\" would otherwise\n // announce a second, unnamed \"Usage\" meter inside a control that has already said the\n // score — correct in isolation, duplicated noise here.\n const body = (\n <React.Fragment>\n <span className=\"fd-scoremeter-rail\" style={{ width }} aria-hidden=\"true\">\n <SegmentedMeter total={100} segments={segments} height={height} showTotal={false} showPercent={false} legend={false} />\n </span>\n {showScore ? (\n <span className=\"fd-scoremeter-value fd-tabular\" aria-hidden=\"true\">\n {value}\n </span>\n ) : null}\n </React.Fragment>\n );\n\n if (!breakdown) {\n return (\n <span\n className={[\"fd-scoremeter\", className].filter(Boolean).join(\" \")}\n role=\"meter\"\n aria-label={label}\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuetext={value + \" of 100\"}\n >\n {body}\n </span>\n );\n }\n\n return (\n <React.Fragment>\n <button\n type=\"button\"\n ref={ref}\n className={[\"fd-scoremeter\", \"fd-scoremeter-button\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n aria-label={label + \" \" + value + \" of 100 — show breakdown\"}\n onClick={() => setOpen((v) => !v)}\n >\n {body}\n </button>\n <Popover\n open={open}\n anchorRef={ref}\n placement={placement}\n width={breakdownWidth}\n padded\n label={breakdownLabel || label + \" breakdown\"}\n onClose={() => setOpen(false)}\n >\n {breakdown}\n </Popover>\n </React.Fragment>\n );\n}\n","import * as React from \"react\";\nimport { formatBytes } from \"../../kits/files.js\";\n\nconst VARIANT_FILL: Record<string, string> = {\n brand: \"var(--brand)\",\n neutral: \"var(--n-400)\",\n quiet: \"var(--n-300)\",\n ok: \"var(--ok-solid)\",\n warn: \"var(--warn-solid)\",\n danger: \"var(--danger-solid)\",\n info: \"var(--info-solid)\",\n};\nconst CHART = [\"var(--chart-1)\", \"var(--chart-2)\", \"var(--chart-3)\", \"var(--chart-4)\", \"var(--chart-5)\", \"var(--chart-6)\", \"var(--chart-7)\", \"var(--chart-8)\"];\n\nconst compact = (n: number): string => {\n if (n == null || isNaN(n)) return \"\";\n const a = Math.abs(n);\n if (a >= 1e9) return (n / 1e9).toFixed(a >= 1e10 ? 0 : 1).replace(/\\.0$/, \"\") + \"B\";\n if (a >= 1e6) return (n / 1e6).toFixed(a >= 1e7 ? 0 : 1).replace(/\\.0$/, \"\") + \"M\";\n if (a >= 1e3) return (n / 1e3).toFixed(a >= 1e4 ? 0 : 1).replace(/\\.0$/, \"\") + \"k\";\n return String(Math.round(n));\n};\n\nexport const meterFormats = {\n count: (n: number) => n.toLocaleString(),\n compact,\n bytes: formatBytes,\n percentOf: (total: number) => (n: number) => (total ? Math.round((n / total) * 100) : 0) + \"%\",\n};\n\nexport interface MeterSegmentInput {\n id?: string;\n label: string;\n value: number;\n variant?: \"brand\" | \"neutral\" | \"quiet\" | \"ok\" | \"warn\" | \"danger\" | \"info\";\n /** Any CSS colour; overrides variant. Defaults to the chart ramp in order. */\n color?: string;\n}\n\nexport interface SegmentedMeterProps {\n total: number;\n segments: MeterSegmentInput[];\n label?: string;\n /** Value formatter. meterFormats.compact | .count | .bytes */\n format?: (n: number) => string;\n height?: number;\n legend?: boolean;\n showTotal?: boolean;\n showPercent?: boolean;\n remainderLabel?: string;\n onClick?: () => void;\n className?: string;\n /** Base id for the meter's aria-labelledby target; falls back to React.useId(). */\n id?: string;\n}\n\n/**\n * A capacity bar split into categories — a context window, a disk quota, a budget\n * burn-down, a rate limit. Deliberately free of any AI vocabulary: it takes a total\n * and labelled segments, and reports the remainder as free space.\n *\n * A zero or missing total reports 0%, never NaN%.\n */\nexport function SegmentedMeter({\n total = 0,\n segments = [],\n label,\n format = compact,\n height = 6,\n legend = false,\n showTotal = true,\n showPercent = true,\n remainderLabel = \"Free\",\n onClick,\n className = \"\",\n id,\n}: SegmentedMeterProps) {\n const safeTotal = Number(total) > 0 ? Number(total) : 0;\n const items = segments.filter((s) => s && Number(s.value) > 0);\n const used = items.reduce((n, s) => n + Number(s.value), 0);\n const pct = safeTotal ? Math.min(100, Math.round((used / safeTotal) * 100)) : 0;\n const w = (v: number) => (safeTotal ? Math.max(0, Math.min(100, (Number(v) / safeTotal) * 100)) : 0);\n const fill = (s: MeterSegmentInput, i: number) => s.color || (s.variant ? VARIANT_FILL[s.variant] : undefined) || CHART[i % CHART.length];\n const generatedId = React.useId();\n const uid = id || generatedId;\n\n return (\n <div className={[\"fd-segmeter\", className].filter(Boolean).join(\" \")} onClick={onClick}>\n {(label || showTotal) ? (\n <div className=\"fd-segmeter-head\">\n {label ? <span className=\"fd-segmeter-label\" id={uid + \"-l\"}>{label}</span> : <span />}\n {showTotal ? (\n <span className=\"fd-segmeter-total fd-tabular\">\n {format(used)}<span className=\"fd-segmeter-sep\"> / </span>{safeTotal ? format(safeTotal) : \"—\"}\n {showPercent ? <span className=\"fd-segmeter-pct\"> ({pct}%)</span> : null}\n </span>\n ) : null}\n </div>\n ) : null}\n <div\n className=\"fd-segmeter-rail\"\n style={{ height }}\n role=\"meter\"\n aria-labelledby={label ? uid + \"-l\" : undefined}\n aria-label={label ? undefined : \"Usage\"}\n aria-valuenow={used}\n aria-valuemin={0}\n aria-valuemax={safeTotal || 100}\n aria-valuetext={format(used) + \" of \" + (safeTotal ? format(safeTotal) : \"unknown\") + \" — \" + pct + \"%\"}\n >\n {items.map((s, i) => (\n <span\n key={s.id || s.label || i}\n className=\"fd-segmeter-seg\"\n style={{ width: w(s.value) + \"%\", background: fill(s, i), transitionDelay: (i * 40) + \"ms\" }}\n title={s.label + \" · \" + format(s.value)}\n />\n ))}\n </div>\n {legend ? (\n <ul className=\"fd-segmeter-legend\">\n {items.map((s, i) => (\n <li key={s.id || s.label || i}>\n <span className=\"fd-segmeter-dot\" style={{ background: fill(s, i) }} aria-hidden=\"true\" />\n <span className=\"fd-segmeter-key\">{s.label}</span>\n <span className=\"fd-segmeter-val fd-tabular\">{format(s.value)}</span>\n </li>\n ))}\n {safeTotal && used < safeTotal ? (\n <li className=\"is-remainder\">\n <span className=\"fd-segmeter-dot is-empty\" aria-hidden=\"true\" />\n <span className=\"fd-segmeter-key\">{remainderLabel}</span>\n <span className=\"fd-segmeter-val fd-tabular\">{format(safeTotal - used)}</span>\n </li>\n ) : null}\n </ul>\n ) : null}\n </div>\n );\n}\n\nexport interface QuotaRowProps { label: React.ReactNode; percent: number; note?: React.ReactNode; tone?: \"brand\" | \"ok\" | \"warn\" | \"danger\"; className?: string }\n\n/**\n * One quota line: name, an optional reset note, a percentage and a bar.\n * Rate limits, plan allowances, storage tiers.\n */\nexport function QuotaRow({ label, percent = 0, note, tone, className = \"\" }: QuotaRowProps) {\n const p = Math.max(0, Math.min(100, Math.round(Number(percent) || 0)));\n const auto = p >= 90 ? \"danger\" : p >= 70 ? \"warn\" : \"brand\";\n return (\n <div className={[\"fd-quota\", className].filter(Boolean).join(\" \")}>\n <div className=\"fd-quota-head\">\n <span className=\"fd-quota-label\">{label}</span>\n {note ? <span className=\"fd-quota-note\">{note}</span> : null}\n <span className=\"fd-quota-pct fd-tabular\">{p}%</span>\n </div>\n <div className=\"fd-quota-rail\" role=\"meter\" aria-label={typeof label === \"string\" ? label : undefined} aria-valuenow={p} aria-valuemin={0} aria-valuemax={100}>\n <span className=\"fd-quota-fill\" style={{ width: p + \"%\", background: VARIANT_FILL[tone || auto] }} />\n </div>\n </div>\n );\n}\n","/**\n * File intake helpers — generic, no chat vocabulary.\n * Nothing here touches the DOM event lifecycle: extractors REPORT what they found,\n * the host decides whether to consume the event.\n *\n * Shared by the forms group and the chat kit — promoted to a top-level shared kit\n * since multiple component groups depend on it.\n */\n\n/* Shared file helpers for the forms group and the chat kit. Every component that\n handles a file speaks this Attachment shape — one type, not three. */\n/** The host library's file shape. Use it for every file everywhere. */\nexport interface Attachment {\n id: string;\n name: string;\n size: number;\n mime: string;\n url: string;\n /** Local preview while uploading. */\n blobUrl?: string;\n /** Non-null and < 100 means uploading. */\n progress?: number | null;\n thumb?: { url: string };\n /** Failed upload. Takes priority over progress. */\n error?: string;\n /** Free-text replacement for the size line, e.g. \"6 lines · pasted\". */\n meta?: string;\n /** Present only before upload; strip it before sending. */\n file?: File;\n}\n\nexport interface FileRejection { file: File; reason: \"type\" | \"size\"; message: string }\n\nexport function formatBytes(n: number): string {\n if (n == null || isNaN(n)) return \"\";\n if (n < 1024) return n + \" B\";\n const u = [\"KB\", \"MB\", \"GB\", \"TB\"];\n let v = n / 1024, i = 0;\n while (v >= 1024 && i < u.length - 1) { v /= 1024; i++; }\n return (v < 10 ? v.toFixed(1) : Math.round(v)) + \" \" + u[i];\n}\n\nexport function extensionOf(name: string): string {\n const m = /\\.([A-Za-z0-9]+)$/.exec(name || \"\");\n return m ? m[1].toLowerCase() : \"\";\n}\n\nconst ICON_BY_EXT: Record<string, string> = {\n pdf: \"file-pdf\", doc: \"file-doc\", docx: \"file-doc\", rtf: \"file-doc\",\n xls: \"file-xls\", xlsx: \"file-xls\", csv: \"file-csv\", tsv: \"file-csv\",\n ppt: \"file-ppt\", pptx: \"file-ppt\",\n zip: \"file-zip\", gz: \"file-zip\", tar: \"file-zip\", rar: \"file-zip\",\n js: \"file-js\", jsx: \"file-js\", ts: \"file-ts\", tsx: \"file-ts\",\n json: \"brackets-curly\", html: \"file-html\", css: \"file-css\", md: \"file-md\",\n py: \"file-py\", sql: \"database\", sh: \"terminal\", txt: \"file-text\", log: \"file-text\",\n};\n\n/** Phosphor icon name for a file: type first, extension second. */\nexport function iconForMime(mime?: string, name?: string): string {\n const m = (mime || \"\").toLowerCase();\n if (m.startsWith(\"image/\")) return \"image\";\n if (m.startsWith(\"video/\")) return \"video\";\n if (m.startsWith(\"audio/\")) return \"music-notes\";\n const byExt = ICON_BY_EXT[extensionOf(name || \"\")];\n if (byExt) return byExt;\n if (m === \"application/pdf\") return \"file-pdf\";\n if (m.startsWith(\"text/\")) return \"file-text\";\n return \"file\";\n}\n\nexport function isImage(mime?: string, name?: string): boolean {\n if ((mime || \"\").toLowerCase().startsWith(\"image/\")) return true;\n return [\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"avif\", \"svg\", \"bmp\"].includes(extensionOf(name || \"\"));\n}\n\n/** accept-attribute semantics: \".png,image/*,text/plain\" */\nexport function acceptMatches(file: File, accept?: string): boolean {\n if (!accept) return true;\n const mime = (file.type || \"\").toLowerCase();\n const name = (file.name || \"\").toLowerCase();\n return accept.split(\",\").map((s) => s.trim().toLowerCase()).filter(Boolean).some((rule) => {\n if (rule.startsWith(\".\")) return name.endsWith(rule);\n if (rule.endsWith(\"/*\")) return mime.startsWith(rule.slice(0, -1));\n return mime === rule;\n });\n}\n\n/** Split a FileList against accept + size. Rejections carry a reason string, never a silent drop. */\nexport function filterFiles(\n files: FileList | File[],\n opts?: { accept?: string; maxFileSize?: number },\n): { accepted: File[]; rejected: FileRejection[] } {\n const o = opts || {};\n const accepted: File[] = [], rejected: FileRejection[] = [];\n Array.from(files || []).forEach((file) => {\n if (!acceptMatches(file, o.accept)) { rejected.push({ file, reason: \"type\", message: (file.name || \"This file\") + \" isn't an accepted type.\" }); return; }\n if (o.maxFileSize && file.size > o.maxFileSize) { rejected.push({ file, reason: \"size\", message: (file.name || \"This file\") + \" is \" + formatBytes(file.size) + \" — the limit is \" + formatBytes(o.maxFileSize) + \".\" }); return; }\n accepted.push(file);\n });\n return { accepted, rejected };\n}\n\n/** Human name for a synthesised paste file: \"Pasted text (380 lines).txt\" */\nexport function pastedTextName(text: string): string {\n const lines = text.split(\"\\n\").length;\n if (lines === 1) return \"Pasted text (\" + text.length.toLocaleString() + \" characters).txt\";\n return \"Pasted text (\" + lines.toLocaleString() + \" lines).txt\";\n}\n\nfunction makeTextFile(text: string, name: string): File {\n const type = \"text/plain\";\n try {\n return new File([text], name, { type });\n } catch {\n const blob = new Blob([text], { type }) as File;\n Object.assign(blob, { name, lastModified: Date.now() });\n return blob;\n }\n}\n\n/** Legacy jQuery-style event shape — some hosts still normalise paste events this way. */\ntype ClipboardEventLike = ClipboardEvent & { originalEvent?: ClipboardEvent };\n\n/**\n * What a paste is carrying, in one pass. NEVER calls preventDefault — it returns\n * `source: null` when nothing was produced, so the host can let the event fall\n * through. That is what makes it reusable in any input.\n */\nexport function extractClipboardFiles(\n event: ClipboardEvent,\n opts?: { largePasteThreshold?: number; accept?: string; maxFileSize?: number; name?: string },\n): { files: File[]; source: \"files\" | \"text\" | null; rejected: FileRejection[]; text?: string } {\n const o = opts || {};\n const threshold = o.largePasteThreshold == null ? 4000 : o.largePasteThreshold;\n const evt = event as ClipboardEventLike;\n const dt = event && (evt.clipboardData || (evt.originalEvent && evt.originalEvent.clipboardData));\n if (!dt) return { files: [], source: null, rejected: [] };\n\n const raw = Array.from(dt.files || []);\n const fromItems: File[] = raw.length\n ? raw\n : Array.from(dt.items || [])\n .filter((i) => i.kind === \"file\")\n .map((i) => i.getAsFile())\n .filter((f): f is File => f !== null);\n\n if (fromItems.length) {\n const { accepted, rejected } = filterFiles(fromItems, o);\n return { files: accepted, source: accepted.length ? \"files\" : null, rejected };\n }\n\n const text = dt.getData ? dt.getData(\"text/plain\") : \"\";\n if (threshold > 0 && text && text.length > threshold) {\n const file = makeTextFile(text, o.name || pastedTextName(text));\n const { accepted, rejected } = filterFiles([file], { accept: o.accept, maxFileSize: o.maxFileSize });\n return { files: accepted, source: accepted.length ? \"text\" : null, rejected, text };\n }\n return { files: [], source: null, rejected: [] };\n}\n\nlet attachmentSeq = 0;\n/**\n * Local, immediately-renderable stand-in for a file being uploaded.\n * Shape is the host library's file type — id/name/size/mime/url/progress/thumb/error.\n */\nexport function toAttachment(file: File, extra?: Partial<Attachment>): Attachment {\n const url = typeof URL !== \"undefined\" && URL.createObjectURL ? URL.createObjectURL(file) : \"\";\n const image = isImage(file.type, file.name);\n const base: Attachment = {\n id: \"att_\" + (++attachmentSeq) + \"_\" + Date.now().toString(36),\n name: file.name || \"file\",\n size: file.size || 0,\n mime: file.type || \"application/octet-stream\",\n url,\n blobUrl: url,\n progress: null,\n thumb: image && url ? { url } : undefined,\n file,\n };\n return Object.assign(base, extra || {});\n}\n\nexport function revokeAttachment(att: Attachment): void {\n try { if (att && att.blobUrl) URL.revokeObjectURL(att.blobUrl); } catch { /* noop */ }\n}\n\n/**\n * Namespace export — `const { formatBytes } = window.<Namespace>.FileKit;`\n */\nexport const FileKit = {\n formatBytes,\n extensionOf,\n iconForMime,\n isImage,\n acceptMatches,\n filterFiles,\n pastedTextName,\n extractClipboardFiles,\n toAttachment,\n revokeAttachment,\n};\n","import * as React from \"react\";\nimport { Button } from \"../actions/Button\";\n\nexport interface SortMenuField {\n /** Sort key sent to the endpoint. */\n key: string;\n /** Human label shown in the menu and on the collapsed trigger. */\n label: string;\n /** Numeric fields read \"lowest/highest first\" instead of \"A to Z\". */\n numeric?: boolean;\n}\n\nexport interface SortMenuProps extends React.HTMLAttributes<HTMLSpanElement> {\n fields: SortMenuField[];\n /** Current sort, straight from the endpoint's response envelope. */\n sort?: { key: string; dir: \"asc\" | \"desc\" } | null;\n onSort?: (key: string, dir: \"asc\" | \"desc\") => void;\n /** Which edge the popover aligns to. Default \"right\". */\n align?: \"left\" | \"right\";\n /** Trigger button height, same scale as every other control in the kit (Button,\n * Input). Default \"md\" — matches Input/SearchField's own default height, since\n * this is most often placed directly alongside a SearchField in one header row\n * (see TransferList) and the two need to line up. Pass \"sm\" for a denser,\n * standalone placement. */\n size?: \"sm\" | \"md\";\n className?: string;\n}\n\n/**\n * SortMenu — the sort control for every server-driven table.\n *\n * A raw \"sort=crp&dir=desc\" readout tells a user what the machine is doing, not what\n * they asked for. This states the field in words and offers both directions as explicit\n * targets, so choosing \"highest first\" is one click rather than a toggle you have to\n * click twice and then verify.\n *\n * Direction wording follows the field type — numeric fields read \"lowest/highest first\",\n * text fields \"A to Z\" — while both use the same arrow pair, because varying the icon by\n * type encodes a distinction nobody asked for and reads as inconsistency.\n *\n * Purely presentational: reports intent through onSort(key, dir) and never holds sort\n * state, so it stays honest against a real endpoint.\n */\nexport function SortMenu({ fields = [], sort, onSort, align = \"right\", size = \"md\", className = \"\", ...rest }: SortMenuProps) {\n const [open, setOpen] = React.useState(false);\n const ref = React.useRef<HTMLSpanElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n\n const cur = fields.find((f) => f.key === (sort && sort.key));\n const dir = sort && sort.dir;\n\n const arrow = (f: SortMenuField, d: \"asc\" | \"desc\") => {\n const on = cur && cur.key === f.key && dir === d;\n const label = d === \"asc\" ? (f.numeric ? \"lowest first\" : \"A to Z\") : (f.numeric ? \"highest first\" : \"Z to A\");\n return (\n <button type=\"button\" aria-label={f.label + \", \" + label} aria-pressed={on} onClick={() => onSort && onSort(f.key, d)}\n style={{ display: \"grid\", placeItems: \"center\", width: 26, height: 26, borderRadius: 6, cursor: \"pointer\",\n border: \"1px solid \" + (on ? \"var(--brand)\" : \"var(--border)\"),\n background: on ? \"var(--brand)\" : \"var(--surface)\", color: on ? \"#fff\" : \"var(--text-muted)\" }}>\n <i className={\"ph ph-arrow-\" + (d === \"asc\" ? \"up\" : \"down\")} style={{ fontSize: 13 }} />\n </button>\n );\n };\n\n return (\n <span className={className} style={{ position: \"relative\", display: \"inline-flex\" }} ref={ref} {...rest}>\n <Button size={size} variant=\"secondary\" icon={dir === \"asc\" ? \"sort-ascending\" : \"sort-descending\"} onClick={() => setOpen(!open)}>\n {cur ? cur.label : \"Unsorted\"}\n <i className={\"ph ph-\" + (dir === \"asc\" ? \"arrow-up\" : \"arrow-down\")} style={{ fontSize: 12, marginLeft: 6, opacity: 0.75 }} />\n </Button>\n {open ? (\n <span className=\"fd-view-enter\" style={{ position: \"absolute\", top: \"calc(100% + 6px)\", [align]: 0, zIndex: 120, width: 280, maxWidth: \"calc(100vw - 32px)\", display: \"block\", background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 10, boxShadow: \"0 16px 44px rgba(11,13,17,.18)\", padding: 8 } as React.CSSProperties}>\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span className=\"fd-overline fd-muted\" style={{ padding: \"4px 8px 6px\" }}>Sort by</span>\n {fields.map((f) => {\n const active = cur && cur.key === f.key;\n return (\n <span key={f.key} className=\"fd-row\" style={{ gap: 8, padding: \"4px 8px\", borderRadius: 7, background: active ? \"var(--surface-brand)\" : \"transparent\" }}>\n <span className=\"fd-body-sm\" style={{ flex: 1, fontWeight: active ? 700 : 500, color: active ? \"var(--text-on-surface-brand)\" : \"var(--text)\" }}>{f.label}</span>\n {arrow(f, \"asc\")}\n {arrow(f, \"desc\")}\n </span>\n );\n })}\n </span>\n </span>) : null}\n </span>\n );\n}\n","import * as React from \"react\";\nimport { formatDuration } from \"./RelativeTime\";\n\nconst KIND_ICON: Record<string, string> = { tool: \"wrench\", search: \"magnifying-glass\", read: \"file-text\", write: \"pencil-simple\", reasoning: \"brain\", run: \"terminal\", fetch: \"cloud-arrow-down\" };\n\nexport interface Step {\n id: string;\n /** Short verb + target: \"Queried calls table\". */\n label: string;\n kind?: \"tool\" | \"search\" | \"read\" | \"write\" | \"reasoning\" | \"run\" | \"fetch\";\n /** Raw input/output or reasoning text, behind a disclosure. */\n detail?: string;\n durationMs?: number;\n status?: \"running\" | \"ok\" | \"error\";\n}\n\n/** Flat collapsible rows — never one card per tool call. */\nexport interface StepListProps { steps: Step[]; label?: string; defaultOpen?: boolean; open?: boolean; onToggle?: (open: boolean) => void; showDurations?: boolean; dense?: boolean; className?: string }\n\n/**\n * A flat, collapsible list of work steps — one row per step, never one card per\n * call. A long run stays readable: it is a list, not a stack.\n */\nexport function StepList({\n steps = [], label, defaultOpen = false, open: openProp, onToggle,\n showDurations = true, dense = false, className = \"\",\n}: StepListProps) {\n const [openState, setOpenState] = React.useState(defaultOpen);\n const open = openProp == null ? openState : openProp;\n const [expanded, setExpanded] = React.useState<Record<string, boolean>>({});\n if (!steps.length) return null;\n\n const running = steps.some((s) => s.status === \"running\");\n const failed = steps.filter((s) => s.status === \"error\").length;\n const total = steps.reduce((n, s) => n + (s.durationMs || 0), 0);\n const current = steps.filter((s) => s.status === \"running\").slice(-1)[0];\n\n const summary = label || (running\n ? (current ? current.label : \"Working\")\n : (total ? \"Worked for \" + formatDuration(total) : \"Steps\"));\n\n const toggle = () => {\n const next = !open;\n if (openProp == null) setOpenState(next);\n onToggle && onToggle(next);\n };\n\n return (\n <div className={[\"fd-steps\", dense ? \"is-dense\" : \"\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")}>\n <button type=\"button\" className=\"fd-steps-head\" onClick={toggle} aria-expanded={open}>\n {running ? <span className=\"fd-steps-spin\" aria-hidden=\"true\" /> : <i className={\"ph ph-\" + (failed ? \"warning-circle\" : \"check-circle\")} aria-hidden=\"true\" />}\n <span className=\"fd-steps-title\">{summary}</span>\n <span className=\"fd-steps-count fd-tabular\">\n {steps.length} step{steps.length === 1 ? \"\" : \"s\"}\n {failed ? <span className=\"fd-steps-failed\"> · {failed} failed</span> : null}\n </span>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\") + \" fd-steps-caret\"} aria-hidden=\"true\" />\n </button>\n {open ? (\n <ol className=\"fd-steps-list\">\n {steps.map((s, i) => {\n const id = s.id || i;\n const isOpen = !!expanded[id];\n const icon = KIND_ICON[s.kind || \"\"] || \"dot-outline\";\n return (\n <li key={id} className={\"fd-step is-\" + (s.status || \"ok\")}>\n <div className=\"fd-step-row\">\n <span className=\"fd-step-icon\" aria-hidden=\"true\">\n {s.status === \"running\" ? <span className=\"fd-steps-spin\" /> : <i className={\"ph ph-\" + icon} />}\n </span>\n {s.detail ? (\n <button type=\"button\" className=\"fd-step-label\" aria-expanded={isOpen}\n onClick={() => setExpanded((m) => Object.assign({}, m, { [id]: !isOpen }))}>\n <span>{s.label}</span>\n <i className={\"ph ph-caret-\" + (isOpen ? \"up\" : \"down\")} aria-hidden=\"true\" />\n </button>\n ) : <span className=\"fd-step-label is-static\">{s.label}</span>}\n {s.status === \"error\" ? <span className=\"fd-step-badge is-error\">failed</span> : null}\n {showDurations && s.durationMs ? <span className=\"fd-step-dur fd-tabular\">{formatDuration(s.durationMs)}</span> : null}\n </div>\n {s.detail && isOpen ? <pre className=\"fd-step-detail\">{s.detail}</pre> : null}\n </li>\n );\n })}\n </ol>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** Number of rows kept mounted above and below the visible band. Two buffers this size\n * (one per edge) plus the visible band itself is what keeps the mounted node count\n * bounded — see the file doc comment below for why 20 is the right number here. */\nexport const VIRTUAL_LIST_BUFFER_ROWS = 20;\n\n/** Default px of empty space left at the bottom of every row slot, which is what reads\n * as the gap between two cards. See VirtualListProps.rowGap. */\nexport const VIRTUAL_LIST_ROW_GAP = 6;\n\n/** Where the caller's loaded slice sits inside the full collection. `firstItemIndex` is\n * the absolute index of items[0]; `count` is how many are loaded. For a caller that\n * holds the whole collection this is simply { firstItemIndex: 0, count: items.length }. */\nexport interface VirtualLoadedBand {\n firstItemIndex: number;\n count: number;\n}\n\nexport interface VirtualWindow {\n /** ABSOLUTE index of the first row a viewport of this height would actually show. */\n visibleStart: number;\n /** ABSOLUTE index of the last row a viewport of this height would actually show (inclusive). */\n visibleEnd: number;\n /** ABSOLUTE index of the first row that should be mounted in the DOM (visibleStart minus\n * the buffer), clamped to the loaded band — a row the caller hasn't loaded can't mount. */\n startIndex: number;\n /** ABSOLUTE index of the last row that should be mounted in the DOM (inclusive). */\n endIndex: number;\n /** Full scrollable height in px — this is what makes the scrollbar/scroll range honest\n * about the whole collection even though only a slice of it is ever mounted, and it is\n * computed from the TOTAL count, never from how many rows happen to be loaded. */\n totalHeight: number;\n /** px the mounted block must be pushed down so its rows land at their real scroll position. */\n offsetY: number;\n}\n\n/**\n * Pure windowing math: given a scroll position and the shape of the data, decide which\n * row indices are visible and which should actually be mounted. Kept free of React and\n * the DOM on purpose — see VirtualList's doc comment for why this is exported and tested\n * on its own rather than only indirectly through a mounted component.\n *\n * Every fixed-height virtualizer boils down to integer division: row i sits at\n * `i * itemHeight` px, so scrollTop/itemHeight lands on the first partially-visible row\n * and (scrollTop + viewportHeight)/itemHeight lands on the last one. Everything else here\n * is clamping that to the buffer, to the real item count, and to whatever slice of it the\n * caller currently has in memory.\n *\n * Every index this returns is ABSOLUTE — an index into the whole collection, not into the\n * caller's loaded array. That distinction is the entire point of `loaded`: a caller that\n * keeps a sliding window (say 50 rows retained out of 4,000, discarding rows as it scrolls\n * rather than accumulating them) still gets row 3,214 drawn at 3,214 * itemHeight and a\n * scrollbar sized for 4,000 rows. Compute positions off array indices instead and the\n * whole list jumps every time the window slides.\n */\nexport function computeVirtualWindow(opts: {\n scrollTop: number;\n viewportHeight: number;\n itemHeight: number;\n /** TOTAL rows in the collection, loaded or not. */\n itemCount: number;\n /** Which slice of that total is actually in memory. Defaults to \"all of it\". */\n loaded?: VirtualLoadedBand;\n bufferRows?: number;\n}): VirtualWindow {\n const { scrollTop, viewportHeight, itemHeight, itemCount, bufferRows = VIRTUAL_LIST_BUFFER_ROWS } = opts;\n const loaded = opts.loaded || { firstItemIndex: 0, count: itemCount };\n\n if (itemCount <= 0 || itemHeight <= 0) {\n return { visibleStart: 0, visibleEnd: -1, startIndex: 0, endIndex: -1, totalHeight: 0, offsetY: 0 };\n }\n\n const lastPossible = itemCount - 1;\n const visibleStart = Math.min(lastPossible, Math.max(0, Math.floor(scrollTop / itemHeight)));\n const visibleRows = Math.max(1, Math.ceil(viewportHeight / itemHeight));\n const visibleEnd = Math.min(lastPossible, visibleStart + visibleRows - 1);\n\n // The mounted band is the visible band plus a buffer, intersected with what's loaded.\n // The intersection can come out empty (the user dragged the scrollbar clear past the\n // loaded slice), which is reported honestly as endIndex < startIndex rather than as\n // some nearest-loaded-row fudge — nothing is mountable there until the caller fetches.\n const loadedFirst = Math.max(0, loaded.firstItemIndex);\n const loadedLast = Math.min(lastPossible, loaded.firstItemIndex + loaded.count - 1);\n const startIndex = Math.max(loadedFirst, Math.max(0, visibleStart - bufferRows));\n const endIndex = Math.min(loadedLast, Math.min(lastPossible, visibleEnd + bufferRows));\n\n return {\n visibleStart,\n visibleEnd,\n startIndex,\n endIndex,\n totalHeight: itemCount * itemHeight,\n offsetY: startIndex * itemHeight,\n };\n}\n\n/**\n * Given the current window and the LOADED band, says whether the visible band has come\n * within one buffer's width of either edge of what's currently in memory — the signal\n * VirtualList uses to ask its caller for more. Threading it through the *visible* band\n * (not the mounted one) means the caller gets asked while the buffer still has rows left\n * to show, not only once the user has scrolled past all of them.\n *\n * Measured against the loaded band rather than the total, because \"do I need to fetch\"\n * is a question about memory, not about the collection: a caller holding rows 800-849 of\n * 4,000 needs more in BOTH directions even though it is nowhere near either end.\n */\nexport function computeNeedMore(\n win: Pick<VirtualWindow, \"visibleStart\" | \"visibleEnd\">,\n loaded: VirtualLoadedBand,\n bufferRows: number = VIRTUAL_LIST_BUFFER_ROWS\n): { start: boolean; end: boolean } {\n if (loaded.count <= 0) return { start: true, end: true };\n return {\n start: win.visibleStart - loaded.firstItemIndex <= bufferRows,\n end: loaded.firstItemIndex + loaded.count - 1 - win.visibleEnd <= bufferRows,\n };\n}\n\nexport interface VirtualListProps<T> {\n /** Whatever the caller currently has loaded — not the full remote collection. */\n items: T[];\n /** Fixed row height in px. Every row is assumed to be exactly this tall. */\n itemHeight: number;\n /** px of the row's slot left empty at the bottom, which is what reads as the gap\n * between two cards. A real prop rather than a constant because the right gap depends\n * on how much the row itself weighs: a one-line 44px row wants the 6px default, a\n * two-line card wants more air. Note it comes OUT of itemHeight — the slot is still\n * exactly itemHeight tall, so the scroll math is untouched by changing this. */\n rowGap?: number;\n /** Called with the ABSOLUTE index of the row (its index in the whole collection), which\n * is not the same as its index in `items` once a sliding window is in play. */\n renderItem: (item: T, index: number) => React.ReactNode;\n /** Fired when the visible band comes within one buffer's width of an edge of what's\n * loaded and that edge isn't known to be exhausted. The caller owns fetching — this\n * only asks. The window is handed over too so a caller running a sliding window can\n * answer a big scrollbar jump (visible band nowhere near the loaded band) by fetching\n * around `win.visibleStart` instead of stepping a page at a time towards it. */\n onNeedMore: (direction: \"start\" | \"end\", win: VirtualWindow) => void;\n /** Which edges of `items` still have more behind them. Omitted/undefined reads as \"yes,\n * there might be more\" for that edge, since an unknown edge is the common starting state. */\n hasMore?: { start?: boolean; end?: boolean };\n /** Absolute index of `items[0]` in the full collection. Non-zero when the caller keeps a\n * sliding window and has discarded the rows above. */\n firstItemIndex?: number;\n /** Size of the WHOLE collection, when the caller knows it and is holding only a slice.\n * Defaults to firstItemIndex + items.length, i.e. \"what's loaded is all there is\". This\n * is what the scrollbar is sized against, so a caller that discards rows as it scrolls\n * gets a scroll range that stays still instead of shrinking under the user. */\n totalCount?: number;\n /** Suppresses onNeedMore while a fetch the caller already started is in flight. Drives the\n * small pinned spinner at the bottom of the list — rows already mounted stay exactly as\n * they are, since this only ever means \"more is being appended,\" never \"what's on screen\n * might be stale.\" For the append-vs-replace distinction, see `refreshing` below. */\n loading?: boolean;\n /** True while the caller is replacing the WHOLE result set (a search or sort change), as\n * opposed to `loading` appending more onto the end. `items` is expected to still be the\n * PREVIOUS result set while this is true — this renders it underneath a full-panel scrim\n * instead of clearing to empty, so a search/sort edit never blanks the list while the new\n * page is in flight. Swap `items` to the new rows once they land and this back to false. */\n refreshing?: boolean;\n /** Copy shown in the `refreshing` overlay's centered card, next to its spinner. */\n refreshingLabel?: string;\n keyOf: (item: T) => string | number;\n /** Viewport height in px. Default (400) is ten rows at the kit's --control-h-md (44px). */\n height?: number;\n emptyState?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * VirtualList — a fixed-height windowed viewport for a list the caller may be streaming\n * in from a few thousand rows at a time.\n *\n * Why fixed row height only: variable-height virtualization needs a measurement pass\n * (render off-screen, read the real height, then correct the scroll math) which is a\n * meaningfully bigger and more fragile piece of engineering than this kit needs for any\n * consumer it has today. Every current use case is a single-line-or-two row of known,\n * consistent height, so the simplest correct approach is the right one: the caller states\n * itemHeight, and the math is plain arithmetic (see computeVirtualWindow).\n *\n * Why plain onScroll + scrollTop math instead of IntersectionObserver: an observer would\n * still need one sentinel per boundary and a ResizeObserver alongside it to keep the\n * scroll track honest as itemCount changes — no less code, and it trades arithmetic you\n * can unit test for browser timing you can't. scrollTop/clientHeight are synchronous and\n * exact, so the windowing math stays a pure function (computeVirtualWindow, exported and\n * tested on its own below) with the component itself doing nothing but reading scrollTop\n * and rendering the slice that function names.\n *\n * The window keeps ~10 rows actually visible plus a VIRTUAL_LIST_BUFFER_ROWS-row buffer\n * mounted above and below (~50 rows mounted at once at the default height), which is\n * enough that fast wheel/trackpad scrolling never outruns the mounted band before the\n * next onScroll fires, without ever mounting more than a small bounded slice regardless\n * of how many thousand rows `items` holds.\n *\n * `items` does not have to be the whole collection, or even start at the top of it.\n * `firstItemIndex`/`totalCount` let the caller hand over a SLIDING WINDOW — say 50 rows\n * retained out of 4,000, fetching ten at a time in either direction and DISCARDING the\n * rows that fall out the other side. Every position here is computed from the absolute\n * index, so discarding rows above the viewport doesn't move the rows below it, and the\n * scrollbar stays sized to `totalCount` rather than shrinking to whatever is still in\n * memory. Keeping a window is strictly the caller's business — this component never\n * decides what to drop, it only refuses to assume that `items[0]` is row zero.\n *\n * Fully controlled: this holds no item data and no page state, only the scroll position\n * needed to compute the window. The caller owns fetching more rows (onNeedMore) and\n * knowing when an edge is exhausted (hasMore).\n */\nexport function VirtualList<T>({\n items,\n itemHeight,\n rowGap = VIRTUAL_LIST_ROW_GAP,\n renderItem,\n onNeedMore,\n hasMore,\n firstItemIndex = 0,\n totalCount,\n loading = false,\n refreshing = false,\n refreshingLabel = \"Searching…\",\n keyOf,\n height = 400,\n emptyState,\n className = \"\",\n style,\n}: VirtualListProps<T>) {\n const [scrollTop, setScrollTop] = React.useState(0);\n\n const loaded = React.useMemo<VirtualLoadedBand>(\n () => ({ firstItemIndex, count: items.length }),\n [firstItemIndex, items.length]\n );\n const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);\n\n const bandKey = firstItemIndex + \":\" + items.length;\n\n const win = React.useMemo(\n () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),\n [scrollTop, height, itemHeight, total, loaded]\n );\n const need = React.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);\n\n const wantStart = need.start && hasMore?.start !== false;\n const wantEnd = need.end && hasMore?.end !== false;\n\n // What each edge was last asked about: the loaded band, plus which buffer-width bucket\n // of the collection the viewport was sitting in. Repeating the ask is suppressed while\n // both are unchanged, so a caller isn't called on every scroll tick for the same thing.\n //\n // The bucket is the part that stops this from deadlocking, and it is there because it\n // already did once. Keying on the band alone means an ask is spent whether or not the\n // caller acts on it: a caller that declines one — it thought a fetch was still in\n // flight, it was mid-render, it dropped it — is then never asked again for that band,\n // no matter how far the user keeps scrolling, and the list simply stops loading. With\n // the bucket in the key the ask renews every buffer's width of further scrolling, which\n // is both bounded (one ask per 20 rows travelled, not one per scroll event) and\n // impossible to get permanently stuck in. `loading` remains the way to say \"I'm already\n // fetching, hold off\" — a guard the caller controls, rather than one it can't clear.\n const bucket = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);\n const askKey = bandKey + \"@\" + bucket;\n const asked = React.useRef<{ start: string | null; end: string | null }>({ start: null, end: null });\n\n React.useEffect(() => {\n if (loading || !wantStart || asked.current.start === askKey) return;\n asked.current.start = askKey;\n onNeedMore(\"start\", win);\n }, [wantStart, loading, askKey, onNeedMore, win]);\n\n React.useEffect(() => {\n if (loading || !wantEnd || asked.current.end === askKey) return;\n asked.current.end = askKey;\n onNeedMore(\"end\", win);\n }, [wantEnd, loading, askKey, onNeedMore, win]);\n\n // Which of `items`' keys are new since the last commit — drives each fresh row's\n // brief fade/scale-in. Compared against the FULL `items` array (not the mounted\n // window), so scrolling a already-loaded row into view is never mistaken for a\n // newly-added one; only a row genuinely absent from the previous commit's `items`\n // gets the enter treatment. Read during render off last commit's snapshot, then\n // that snapshot is advanced in an effect after paint — never mutated inline during\n // render itself.\n const lastKeysRef = React.useRef<Set<string | number> | null>(null);\n const newKeys = React.useMemo(() => {\n const prev = lastKeysRef.current;\n if (!prev) return new Set<string | number>(); // first mount — nothing \"new\" to animate in\n const fresh = new Set<string | number>();\n for (const item of items) {\n const k = keyOf(item);\n if (!prev.has(k)) fresh.add(k);\n }\n return fresh;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items]);\n React.useEffect(() => {\n lastKeysRef.current = new Set(items.map(keyOf));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [items]);\n\n const gapStyle = { \"--fd-vlist-gap\": rowGap + \"px\" } as React.CSSProperties;\n\n if (!items.length && !loading && !refreshing && emptyState) {\n return (\n <div className={[\"fd-vlist-wrap\", className].filter(Boolean).join(\" \")} style={{ height, position: \"relative\", ...style }}>\n <div className=\"fd-vlist fd-scrollbar\" style={{ height: \"100%\", overflow: \"auto\" }}>\n {emptyState}\n </div>\n </div>\n );\n }\n\n const rows: React.ReactNode[] = [];\n for (let i = win.startIndex; i <= win.endIndex; i++) {\n const item = items[i - firstItemIndex];\n if (item === undefined) continue;\n const key = keyOf(item);\n rows.push(\n <div\n key={key}\n className=\"fd-vlist-row\"\n style={{ height: itemHeight, boxSizing: \"border-box\", transform: \"translateY(\" + i * itemHeight + \"px)\" }}\n >\n <div className={newKeys.has(key) ? \"fd-vlist-row-content fd-vlist-row-enter\" : \"fd-vlist-row-content\"}>\n {renderItem(item, i)}\n </div>\n </div>\n );\n }\n\n return (\n <div className={[\"fd-vlist-wrap\", className].filter(Boolean).join(\" \")} style={{ height, position: \"relative\", ...gapStyle, ...style }}>\n <div\n className=\"fd-vlist fd-scrollbar\"\n style={{ height: \"100%\", overflowY: \"auto\", overflowX: \"hidden\", position: \"relative\" }}\n onScroll={(e) => setScrollTop(e.currentTarget.scrollTop)}\n >\n <div style={{ height: win.totalHeight, position: \"relative\" }}>{rows}</div>\n {loading ? (\n <div style={{ position: \"sticky\", bottom: 0, left: 0, right: 0, display: \"grid\", placeItems: \"center\", padding: \"8px 0\", background: \"var(--surface)\" }}>\n <span className=\"fd-spinner\" aria-hidden=\"true\" />\n </div>\n ) : null}\n </div>\n {refreshing ? (\n <div className=\"fd-vlist-refresh-scrim\">\n <div className=\"fd-vlist-refresh-card\">\n <span className=\"fd-spinner\" aria-hidden=\"true\" />\n <span className=\"fd-body-sm\">{refreshingLabel}</span>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { IconButton } from \"../actions/IconButton\";\n\nexport interface EntityRowAction {\n /** Phosphor icon name, e.g. \"plus\" */\n icon: string;\n /** Accessible name for the action button. */\n label: string;\n onClick: () => void;\n /** Tints the icon — \"add\" reads as constructive (ok-text), \"remove\" as destructive\n * (danger-text). No effect on layout, only color, so a caller can still pass any icon. */\n tone?: \"add\" | \"remove\";\n}\n\n/** Width in px a metric cell takes when it doesn't ask for its own. Wide enough for a\n * five-digit grouped number plus its glyph at --overline-size. */\nexport const ENTITY_ROW_METRIC_WIDTH = 74;\n\nexport interface EntityRowMetric {\n /** Stable identity for the column. Falls back to `label`, which is what actually has\n * to match between rows for a column to line up, so an id is only needed when two\n * columns legitimately share a label. */\n id?: string;\n /** What the number means — \"students\", \"ad units\". Never rendered as running text:\n * it is the metric's accessible name (and its tooltip), so the row stays scannable\n * as numbers while a screen reader still hears \"1,240 students\". */\n label: string;\n value: React.ReactNode;\n /** Phosphor icon name shown before the value, e.g. \"student\". */\n icon?: string;\n /** Fixed cell width in px. Same value on the same column of every row is what makes\n * the strip a real aligned column rather than text that happens to sit near text. */\n width?: number;\n tone?: \"default\" | \"muted\" | \"danger\";\n}\n\n/**\n * Everything about a row that is CONTENT rather than behaviour — what the row says, as\n * opposed to what it does. Split out from EntityRowProps as its own type on purpose: a\n * caller that renders the same row twice (TransferList renders every row a second time\n * as the drag ghost) hands one of these around whole, so a prop added here can't be\n * silently dropped by the second render site the way individually-spread props were.\n */\nexport interface EntityRowContent {\n title: string;\n /** A secondary line — a count, a subtitle, whatever the caller's data has that a raw\n * title doesn't. Optional because plenty of rows are fine with just a name. Sits\n * inline after the title; for numbers that must line up row-to-row use `metrics`. */\n meta?: React.ReactNode;\n /** An aligned strip of small numbers below the title — fixed-width cells, so the same\n * column lands at the same x on every row. Rendering more than one number through\n * `meta` instead would produce a ragged line that happens to contain numbers. */\n metrics?: EntityRowMetric[];\n /** A small interactive element pinned to the end of the metric strip — the row's\n * score meter, a menu, a flag. Anything focusable belongs in a real `<button>`: the\n * row is a drag source, and TransferList's drag arming explicitly skips any\n * pointerdown originating inside a button, which is what keeps this clickable. */\n accessory?: React.ReactNode;\n /** Whole-row state colour. \"danger\" repaints fill, border and title (e.g. a school\n * with no sellable inventory) — the tone tokens are --erow-danger-*, defined for\n * both themes. Default is the ordinary card treatment. */\n tone?: \"default\" | \"danger\";\n}\n\nexport interface EntityRowProps extends EntityRowContent {\n action?: EntityRowAction;\n /** Marks the row a drag source: shows the grip icon and a grab cursor, and reports\n * `onPointerDown` so the caller's own pointer-based drag (see TransferList) can pick\n * the gesture up from there. Deliberately NOT the native HTML `draggable` attribute\n * (see the file doc comment for why) — this row never starts a native browser drag. */\n draggable?: boolean;\n onPointerDown?: (e: React.PointerEvent<HTMLDivElement>) => void;\n style?: React.CSSProperties;\n className?: string;\n}\n\nconst METRIC_TONE_COLOR: Record<string, string | undefined> = {\n default: \"var(--text-2)\",\n muted: \"var(--text-muted)\",\n danger: \"var(--danger-text)\",\n};\n\nexport interface EntityRowMetricsProps {\n metrics: EntityRowMetric[];\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * The aligned number strip, on its own so the SAME columns can be rendered outside a\n * row — TransferList's per-side footer totals are literally this component with the\n * same widths, which is the only way a totals line can stay lined up with the rows it\n * totals without the two places agreeing on magic numbers by hand.\n */\nexport function EntityRowMetrics({ metrics, className = \"\", style }: EntityRowMetricsProps) {\n return (\n <span className={[\"fd-erow-metrics\", className].filter(Boolean).join(\" \")} style={style}>\n {metrics.map((m, i) => (\n <span\n key={m.id || m.label || i}\n className={[\"fd-erow-metric\", m.tone && m.tone !== \"default\" ? \"is-\" + m.tone : \"\"].filter(Boolean).join(\" \")}\n style={{ width: (m.width || ENTITY_ROW_METRIC_WIDTH) + \"px\", color: METRIC_TONE_COLOR[m.tone || \"default\"] }}\n title={m.label}\n >\n {m.icon ? <i className={\"ph ph-\" + m.icon} aria-hidden=\"true\" /> : null}\n <span className=\"fd-erow-metric-value fd-tabular\">{m.value}</span>\n <span className=\"fd-sr\">{\" \" + m.label}</span>\n </span>\n ))}\n </span>\n );\n}\n\n/**\n * EntityRow — a single row for a name plus an optional aligned strip of numbers, an\n * optional accessory and an optional action, meant to be stamped out by the hundreds\n * inside a VirtualList.\n *\n * A real card per row, not flat text: its own surface distinct from the list's\n * background (`--surface-2` against the list's `--surface`), a hairline border, a soft\n * rest-state shadow that lifts on hover — the same `--r-md`/`--e-1`/`--e-2` elevation\n * vocabulary Card itself uses (see styles/components.css's \".fd-erow\" rules), just at\n * the tighter radius a compact row reads better at than Card's own `--r-lg`. Height is\n * still left to the caller (it fills 100% of its parent) because VirtualList is what\n * actually fixes row height, and duplicating that number here would be one more place a\n * future change has to remember to update — the card treatment lives entirely in\n * padding/border/shadow, not height. The border is --erow-border rather than --border\n * for a measured reason: the card and the panel behind it are 1.06:1 apart in light\n * mode, so the inter-card gap is only visible if the hairline carries it.\n *\n * The row lays out as one or two lines depending on what it's given: title (plus inline\n * `meta`) always, and a second line holding the metric strip and accessory only when\n * there is one. That keeps a plain name-only row exactly as tall and as quiet as it\n * always was while letting a richer row carry three numbers and a meter.\n *\n * The drag/drop split is deliberate: a row only ever needs to say \"I am the thing being\n * dragged\" (draggable + onPointerDown), never \"something was dropped on me\" — nothing in\n * this kit drops one row onto another to reorder it, only a row onto a list to move it\n * there. Putting the drop handling on every row would mean wiring the same drop logic N\n * times over instead of once on the list container that actually owns it (see\n * TransferList's own doc comment for why it drives a pointer-based custom drag rather than\n * native HTML5 DnD — in short, a native drag image is a static snapshot, not a live\n * element, so it can't sustain a persistent tilt that follows the cursor), so this only\n * exposes the source half of the contract: `onPointerDown` hands the gesture off to\n * whatever the caller wants to do with it (TransferList starts tracking a drag once the\n * pointer has moved past a small threshold, so a plain click still reads as a click).\n * The action button exists precisely so drag-and-drop is never the only way to do the\n * same move — pointer-only and keyboard users get an equally real affordance, not a\n * degraded fallback.\n */\nexport function EntityRow({\n title,\n meta,\n metrics,\n accessory,\n tone = \"default\",\n action,\n draggable = false,\n onPointerDown,\n style,\n className = \"\",\n}: EntityRowProps) {\n const hasStrip = (metrics && metrics.length > 0) || accessory != null;\n return (\n <div\n onPointerDown={onPointerDown}\n className={[\"fd-erow\", tone === \"danger\" ? \"fd-erow-danger\" : \"\", className].filter(Boolean).join(\" \")}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n height: \"100%\",\n padding: \"0 12px\",\n cursor: draggable ? \"grab\" : undefined,\n // Own the gesture on touch too — without this, a touch-drag on a draggable row\n // starts the page scrolling instead of (or as well as) the pointer drag.\n touchAction: draggable ? \"none\" : undefined,\n ...style,\n }}\n >\n {draggable ? (\n <i className=\"ph ph-dots-six-vertical\" aria-hidden=\"true\" style={{ fontSize: 14, flex: \"none\", color: \"var(--text-muted)\" }} />\n ) : null}\n <span className=\"fd-erow-body\">\n <span className=\"fd-erow-titleline\">\n <span className=\"fd-erow-title fd-body-sm\">{title}</span>\n {meta ? <span className=\"fd-erow-meta\">{meta}</span> : null}\n </span>\n {hasStrip ? (\n <span className=\"fd-erow-strip\">\n {metrics && metrics.length ? <EntityRowMetrics metrics={metrics} /> : null}\n {accessory ? <span className=\"fd-erow-accessory\">{accessory}</span> : null}\n </span>\n ) : null}\n </span>\n {action ? (\n <IconButton\n icon={action.icon}\n label={action.label}\n size=\"sm\"\n onClick={action.onClick}\n style={{ color: action.tone === \"add\" ? \"var(--ok-text)\" : action.tone === \"remove\" ? \"var(--danger-text)\" : undefined }}\n />\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { SearchField } from \"../forms/SearchField\";\nimport { SortMenu, type SortMenuField } from \"./SortMenu\";\nimport { VirtualList, type VirtualWindow } from \"./VirtualList\";\nimport { EntityRow, type EntityRowContent } from \"./EntityRow\";\nimport { EmptyState } from \"../feedback/EmptyState\";\n\nexport type TransferListSide = \"left\" | \"right\";\n\nexport interface TransferListSideProps<T> {\n /** Whatever this side currently has loaded — not its full remote collection. */\n items: T[];\n /** Total matching count on the server, if known — shown next to the label. */\n total?: number;\n loading?: boolean;\n /** True while this side's WHOLE result set is being replaced (a search or sort\n * change), not merely appended to. `items` should still be the previous result set\n * while this is true — see VirtualList's own `refreshing` prop, which this threads\n * straight through. */\n refreshing?: boolean;\n search: string;\n onSearchChange: (value: string) => void;\n sort?: { key: string; dir: \"asc\" | \"desc\" } | null;\n sortFields: SortMenuField[];\n onSort: (key: string, dir: \"asc\" | \"desc\") => void;\n onNeedMore: (direction: \"start\" | \"end\", win: VirtualWindow) => void;\n hasMore?: { start?: boolean; end?: boolean };\n /** Absolute index of `items[0]` in this side's full collection, and the size of that\n * collection — threaded straight through to this side's VirtualList so each side can\n * independently run a sliding window. See VirtualList's own docs. */\n firstItemIndex?: number;\n totalCount?: number;\n /** Heading text for this side. Fully caller-supplied — this component has no opinion\n * about what the two sides represent. Stays a plain string because it is also woven\n * into the search field's and the move action's accessible names; anything richer\n * than a name belongs in `header`. */\n label?: string;\n /** A slot above the search row, under the label. */\n header?: React.ReactNode;\n /** A slot below the list — where a running totals line for this side goes. A real slot\n * rather than more `label`, because totals are structured content (typically an\n * EntityRowMetrics strip using the same widths as the rows, so the columns line up\n * with the numbers they total) and `label` is a string that gets concatenated. */\n footer?: React.ReactNode;\n /** Copy shown in the full-panel drop overlay while a drag is over this side. Falls\n * back to a generic \"Drop here\" (plus `label`, if set) when omitted — set this for\n * exact per-side wording (e.g. \"Drop to add to audience\" / \"Drop to remove from\n * audience\"), since that phrasing is about what a drop here DOES, which only the\n * caller's domain actually knows. */\n dropLabel?: string;\n}\n\nexport interface TransferListProps<T> {\n left: TransferListSideProps<T>;\n right: TransferListSideProps<T>;\n keyOf: (item: T) => string | number;\n /** Everything a row SAYS, as one object — title, meta, the aligned metric strip, the\n * accessory, the row tone. One render prop returning one EntityRowContent rather than\n * a render prop per field, because a dragged row is rendered a SECOND time as the\n * ghost that follows the cursor: with per-field props that second call has to\n * remember to pass each of them, and the version of this component that did exactly\n * that quietly dropped every field but title and meta off the dragged card. Handing\n * the same object to both render sites makes that class of bug unrepresentable. */\n renderRow: (item: T) => EntityRowContent;\n /** Fired by both a drag-drop and the equivalent +/- click. The caller owns actually\n * moving the item between whatever backing lists it maintains — this component never\n * mutates `left.items`/`right.items` itself. */\n onMove: (item: T, from: TransferListSide, to: TransferListSide) => void;\n /** Row height fed straight through to each side's VirtualList. Default (64) fits the\n * two-line card an EntityRow becomes once it carries a metric strip and an accessory:\n * a 56px card (title line + strip line, 10px of vertical padding) plus the 8px gap.\n * A list of bare title-only rows should pass 44 (the kit's --control-h-md, which is\n * what EntityRow's single-line form is tuned to) with a matching smaller rowGap. */\n itemHeight?: number;\n /** px of each row slot left empty, which is what draws the gap between two cards.\n * Default 8 — see the --erow-border token note for why a card on this kit's surfaces\n * needs both a real gap and a real hairline before the separation is visible. */\n rowGap?: number;\n /** Viewport height fed straight through to each side's VirtualList. */\n listHeight?: number;\n className?: string;\n}\n\nconst emptyHasMore: { start?: boolean; end?: boolean } = {};\n\n/** Pointer clientX/clientY has to move at least this many px past pointerdown before a\n * press-and-hold on a row reads as a drag rather than a click — without a threshold,\n * the action button's own click (which also fires pointerdown first) would be swallowed\n * the instant it started, and a plain unsteady tap would spuriously start a drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\ninterface DragState<T> {\n item: T;\n from: TransferListSide;\n key: string | number;\n pointerId: number;\n /** Pointer position, in row-local coordinates, at pickup — keeps the ghost glued to\n * wherever on the card the user actually grabbed it, instead of snapping to a corner. */\n offsetX: number;\n offsetY: number;\n width: number;\n height: number;\n /** Latest pointer position in viewport coordinates. */\n x: number;\n y: number;\n}\n\n/**\n * TransferList — a dual-list picker for moving items between two collections, by drag or\n * by a click, over a search box and a sort control each side owns independently.\n *\n * Deliberately named \"left\"/\"right\" rather than e.g. \"available\"/\"selected\": the product\n * this ships for is one particular use of it, but nothing about moving rows between two\n * lists is specific to that use, and baking in \"available\"/\"selected\" (or worse, this\n * kit's actual first consumer's own vocabulary) would make every *other* two-list picker\n * this kit will ever be asked for a second component instead of a second set of props. A\n * caller wanting domain words passes them through `label`/`dropLabel`.\n *\n * A pointer-based custom drag, not native HTML5 DnD, and not a library: this kit ships\n * zero runtime dependencies on purpose, and a pointer-events implementation (pointerdown/\n * pointermove/pointerup driving a portaled ghost element) is still zero-dependency — just\n * more code than `draggable`. It replaced an earlier native-HTML5-DnD version once the\n * spec called for a real \"card lifts out of the list and tilts, following the cursor\"\n * feel: a native drag image (`dataTransfer.setDragImage`) is a static snapshot taken once\n * at dragstart, not a live element, so it can't sustain a persistent rotation that tracks\n * the pointer for the duration of the drag — only owning the pointer events ourselves can.\n * Each row's pointerdown (via EntityRow's `onPointerDown`) arms a potential drag; nothing\n * visually happens until the pointer actually moves past `DRAG_THRESHOLD_PX`, so a plain\n * click (on the row, or on its +/- action button) is never mistaken for one. Once armed,\n * window-level pointermove/pointerup/pointercancel listeners (not per-row ones, since the\n * row being dragged gets replaced by a placeholder mid-drag) track the gesture to\n * completion; which side the pointer is currently over is decided by hit-testing each\n * side's own bounding rect against the pointer position, not by any per-row target.\n *\n * The +/- action on every row is not a fallback bolted on for accessibility box-ticking:\n * it is the same onMove call a drop makes, exposed as a first-class equivalent, because\n * drag-and-drop alone would silently exclude anyone not using a mouse.\n *\n * Each side owns a `header` and a `footer` slot in addition to its `label`. `label` stays\n * a plain string because it is also woven into that side's search field and move-action\n * accessible names and gets a count concatenated onto it; the slots are where real\n * content goes — a running totals line in the footer, rendered with EntityRowMetrics at\n * the same column widths the rows use, so the totals sit under the numbers they total.\n *\n * Fully controlled and stateless about the actual item sets: `left`/`right` are handed in\n * whole, this never copies or reorders them, and the only state kept locally is which row\n * is mid-drag and which side a drag is currently over — pure interaction feedback, thrown\n * away the moment the drag ends. Each side may independently be a sliding window over a\n * much larger collection (`firstItemIndex`/`totalCount`, threaded to its VirtualList).\n */\nexport function TransferList<T>({\n left,\n right,\n keyOf,\n renderRow,\n onMove,\n itemHeight = 64,\n rowGap = 8,\n listHeight = 440,\n className = \"\",\n}: TransferListProps<T>) {\n const [drag, setDrag] = React.useState<DragState<T> | null>(null);\n const [dragOverSide, setDragOverSide] = React.useState<TransferListSide | null>(null);\n const dragRef = React.useRef<DragState<T> | null>(null);\n const armedRef = React.useRef<{\n item: T;\n from: TransferListSide;\n key: string | number;\n pointerId: number;\n startX: number;\n startY: number;\n offsetX: number;\n offsetY: number;\n width: number;\n height: number;\n } | null>(null);\n const sideRefs = React.useRef<Record<TransferListSide, HTMLDivElement | null>>({ left: null, right: null });\n\n const hitTestSide = React.useCallback((x: number, y: number): TransferListSide | null => {\n for (const side of [\"left\", \"right\"] as TransferListSide[]) {\n const el = sideRefs.current[side];\n if (!el) continue;\n const r = el.getBoundingClientRect();\n if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) return side;\n }\n return null;\n }, []);\n\n const findItem = React.useCallback(\n (side: TransferListSide, key: string | number): T | undefined =>\n (side === \"left\" ? left.items : right.items).find((it) => keyOf(it) === key),\n [left.items, right.items, keyOf]\n );\n\n const beginDrag = (e: React.PointerEvent<HTMLDivElement>, item: T, from: TransferListSide) => {\n if (e.button !== 0) return;\n // Never arm a drag from the row's own +/- action button — that's a plain click\n // target in its own right (see EntityRowAction), not a drag handle.\n if ((e.target as HTMLElement).closest && (e.target as HTMLElement).closest(\"button\")) return;\n // Stop the browser's own native text-selection/drag gesture from starting at the\n // same time as ours — without this, a real mouse drag leaves a stray text\n // selection highlight across whatever the pointer passes over mid-drag.\n e.preventDefault();\n const rect = e.currentTarget.getBoundingClientRect();\n armedRef.current = {\n item,\n from,\n key: keyOf(item),\n pointerId: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n offsetX: e.clientX - rect.left,\n offsetY: e.clientY - rect.top,\n width: rect.width,\n height: rect.height,\n };\n };\n\n React.useEffect(() => {\n const onMovePointer = (e: PointerEvent) => {\n const armed = armedRef.current;\n if (!armed || e.pointerId !== armed.pointerId) return;\n if (!dragRef.current) {\n const dx = e.clientX - armed.startX;\n const dy = e.clientY - armed.startY;\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD_PX) return;\n const started: DragState<T> = {\n item: armed.item,\n from: armed.from,\n key: armed.key,\n pointerId: armed.pointerId,\n offsetX: armed.offsetX,\n offsetY: armed.offsetY,\n width: armed.width,\n height: armed.height,\n x: e.clientX,\n y: e.clientY,\n };\n dragRef.current = started;\n setDrag(started);\n } else {\n dragRef.current = { ...dragRef.current, x: e.clientX, y: e.clientY };\n setDrag(dragRef.current);\n }\n const hit = hitTestSide(e.clientX, e.clientY);\n setDragOverSide(hit && hit !== armed.from ? hit : null);\n };\n\n const endDrag = (e: PointerEvent) => {\n const armed = armedRef.current;\n if (!armed || e.pointerId !== armed.pointerId) return;\n const wasDragging = dragRef.current;\n armedRef.current = null;\n dragRef.current = null;\n setDrag(null);\n setDragOverSide(null);\n if (!wasDragging) return; // never crossed the threshold — this was a click, not a drag\n const hit = hitTestSide(e.clientX, e.clientY);\n if (hit && hit !== armed.from) {\n const item = findItem(armed.from, armed.key);\n if (item !== undefined) onMove(item, armed.from, hit);\n }\n };\n\n window.addEventListener(\"pointermove\", onMovePointer);\n window.addEventListener(\"pointerup\", endDrag);\n window.addEventListener(\"pointercancel\", endDrag);\n return () => {\n window.removeEventListener(\"pointermove\", onMovePointer);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n };\n }, [hitTestSide, findItem, onMove]);\n\n // Suppress text selection for the duration of an actual drag — with the ghost\n // portaled to document.body and tracking the pointer across the whole page, an\n // ordinary mouse-drag gesture would otherwise select surrounding page text as it goes.\n React.useEffect(() => {\n if (!drag || typeof document === \"undefined\") return;\n const prev = document.body.style.userSelect;\n document.body.style.userSelect = \"none\";\n return () => {\n document.body.style.userSelect = prev;\n };\n }, [drag]);\n\n const renderSide = (side: TransferListSide, cfg: TransferListSideProps<T>, opposite: TransferListSide) => {\n const showOverlay = drag != null && dragOverSide === side;\n return (\n <div\n ref={(el) => {\n sideRefs.current[side] = el;\n }}\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n padding: 10,\n borderRadius: 10,\n border: \"1px solid \" + (dragOverSide === side ? \"var(--brand)\" : \"var(--border)\"),\n background: \"var(--surface)\",\n position: \"relative\",\n }}\n >\n {cfg.label ? (\n <span className=\"fd-overline fd-muted\">\n {cfg.label}\n {cfg.total != null ? \" (\" + cfg.total.toLocaleString() + \")\" : \"\"}\n </span>\n ) : null}\n {cfg.header ? <div className=\"fd-tlist-header\">{cfg.header}</div> : null}\n <span className=\"fd-row\" style={{ gap: 8 }}>\n <SearchField value={cfg.search} onChange={cfg.onSearchChange} placeholder=\"Search\" aria-label={(cfg.label || side) + \" search\"} style={{ flex: 1 }} />\n <SortMenu fields={cfg.sortFields} sort={cfg.sort} onSort={cfg.onSort} align={side === \"left\" ? \"left\" : \"right\"} />\n </span>\n <VirtualList\n items={cfg.items}\n itemHeight={itemHeight}\n rowGap={rowGap}\n height={listHeight}\n keyOf={keyOf}\n loading={cfg.loading}\n refreshing={cfg.refreshing}\n hasMore={cfg.hasMore || emptyHasMore}\n firstItemIndex={cfg.firstItemIndex}\n totalCount={cfg.totalCount}\n onNeedMore={cfg.onNeedMore}\n emptyState={<EmptyState icon=\"tray\" title=\"Nothing here\" />}\n renderItem={(item) => {\n const isBeingDragged = drag != null && drag.from === side && drag.key === keyOf(item);\n if (isBeingDragged) {\n // The vacated slot reads as an obviously-empty placeholder, not a\n // still-there-but-faded real row — the real card is off with the pointer\n // (see the portaled ghost below), tilted, not sitting here at all.\n return <div className=\"fd-erow-placeholder\" aria-hidden=\"true\" />;\n }\n return (\n <EntityRow\n {...renderRow(item)}\n draggable\n onPointerDown={(e) => beginDrag(e, item, side)}\n action={{\n icon: side === \"left\" ? \"plus\" : \"minus\",\n label: (side === \"left\" ? \"Move to \" : \"Move from \") + (side === \"left\" ? right.label || \"the other list\" : left.label || \"the other list\"),\n tone: side === \"left\" ? \"add\" : \"remove\",\n onClick: () => onMove(item, side, opposite),\n }}\n />\n );\n }}\n />\n {cfg.footer ? <div className=\"fd-tlist-footer\">{cfg.footer}</div> : null}\n {showOverlay ? (\n <div className=\"fd-tlist-drop-overlay\" aria-hidden=\"true\">\n <span className=\"fd-tlist-drop-card\">\n <i className=\"ph ph-tray-arrow-down\" style={{ fontSize: 18 }} aria-hidden=\"true\" />\n <span className=\"fd-body-sm\" style={{ fontWeight: 600 }}>\n {cfg.dropLabel || \"Drop here\" + (cfg.label ? \" — \" + cfg.label : \"\")}\n </span>\n </span>\n </div>\n ) : null}\n </div>\n );\n };\n\n return (\n <div className={[\"fd-tlist\", className].filter(Boolean).join(\" \")} style={{ display: \"flex\", gap: 16, alignItems: \"flex-start\" }}>\n {renderSide(\"left\", left, \"right\")}\n {renderSide(\"right\", right, \"left\")}\n {drag\n ? createPortal(\n <div\n aria-hidden=\"true\"\n className=\"fd-erow-ghost\"\n style={{\n position: \"fixed\",\n left: 0,\n top: 0,\n width: drag.width,\n height: drag.height,\n transform: `translate(${drag.x - drag.offsetX}px, ${drag.y - drag.offsetY}px) rotate(-3deg)`,\n pointerEvents: \"none\",\n zIndex: 1000,\n }}\n >\n {/* The SAME content object the in-list row is built from — spread whole,\n never field-by-field, so the card that follows the cursor can never\n end up a stripped-down version of the card it was lifted out of. */}\n <EntityRow {...renderRow(drag.item)} draggable className=\"fd-erow-dragging\" />\n </div>,\n document.body\n )\n : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * Labelled text field. 44px tall, 8px radius, hairline border, blue focus ring.\n */\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n label?: string;\n help?: string;\n /** Present = error state. Replaces help text. */\n error?: string;\n /** Static text inside the field, left — e.g. \"$\" */\n prefix?: React.ReactNode;\n /** Static text inside the field, right — e.g. \"CPM\" */\n suffix?: React.ReactNode;\n /** Phosphor icon name shown left of the input */\n icon?: string;\n /** Right-aligned tabular figures. Use for every money or count field. */\n numeric?: boolean;\n required?: boolean;\n size?: \"md\" | \"lg\";\n /** Inline spinner on the right — for async validation or a value still arriving. */\n loading?: boolean;\n /** Applied to the outer .fd-field element — this is where width belongs. */\n style?: React.CSSProperties;\n /** Applied to the inner input element. Rarely needed. */\n inputStyle?: React.CSSProperties;\n}\n\nexport function Input({\n label, help, error, prefix, suffix, icon, numeric = false, required = false,\n size = \"md\", loading = false, disabled = false, id, className = \"\", style, inputStyle, ...rest\n}: InputProps) {\n const fieldId = id || (rest.name ? \"fd-\" + rest.name : undefined);\n const box = [\n \"fd-input\",\n numeric ? \"fd-input-num\" : \"\",\n error ? \"fd-input-error\" : \"\",\n disabled ? \"fd-input-disabled\" : \"\",\n size === \"lg\" ? \"fd-input-lg\" : \"\",\n className\n ].filter(Boolean).join(\" \");\n\n return (\n <div className=\"fd-field\" style={style}>\n {label ? (\n <label className=\"fd-field-label\" htmlFor={fieldId}>\n {label}{required ? <span className=\"fd-field-req\" aria-hidden=\"true\">*</span> : null}\n </label>\n ) : null}\n <div className={box}>\n {icon ? <span className=\"fd-input-icon\"><i className={\"ph ph-\" + icon} aria-hidden=\"true\" /></span> : null}\n {prefix ? <span className=\"fd-input-affix\">{prefix}</span> : null}\n <input id={fieldId} disabled={disabled} style={inputStyle} aria-invalid={error ? \"true\" : undefined} {...rest} />\n {loading ? <span className=\"fd-spinner\" style={{ color: \"var(--text-muted)\" }} aria-label=\"Loading\" /> : null}\n {suffix && !loading ? <span className=\"fd-input-affix\">{suffix}</span> : null}\n </div>\n {error ? (\n <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n ) : help ? (\n <span className=\"fd-field-help\">{help}</span>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Input } from \"./Input\";\n\nexport interface SearchFieldProps {\n /** Current search text. */\n value: string;\n /** Fires with the new text on every keystroke — a plain string, not a raw\n * DOM event, so this drops in above a filterable list with zero boilerplate. */\n onChange: (value: string) => void;\n placeholder?: string;\n /** Fires when the clear (\"x\") button is pressed. Defaults to onChange(\"\"). */\n onClear?: () => void;\n /** Applied to the outer .fd-field element — this is where width belongs. */\n style?: React.CSSProperties;\n className?: string;\n /** Visible field label, same as Input. Most search fields skip this and rely on placeholder. */\n label?: string;\n disabled?: boolean;\n id?: string;\n name?: string;\n \"aria-label\"?: string;\n}\n\n/**\n * SearchField — the one keyword field that belongs above a filterable list.\n *\n * A thin wrapper around Input: a magnifying-glass icon on the left (Input's\n * own `icon` prop) and a clear (\"x\") button on the right that appears only\n * once there's something to clear. The clear button rides in Input's\n * existing `suffix` slot rather than inventing new inset layout, and its\n * styling matches Select's clearable \"x\" (`ph-x-circle`, `all: unset`,\n * `text-muted`) so every clear affordance in the kit looks the same.\n *\n * Controlled, string-in/string-out. Debouncing is the consumer's job (or a\n * future concern) — building it in here would be hidden behavior a caller\n * can't see or override.\n */\nexport function SearchField({\n value, onChange, placeholder, onClear, style, className, label, disabled, id, name, ...rest\n}: SearchFieldProps) {\n const clear = onClear || (() => onChange(\"\"));\n return (\n <Input\n id={id}\n name={name}\n label={label}\n icon=\"magnifying-glass\"\n value={value}\n disabled={disabled}\n placeholder={placeholder}\n style={style}\n className={className}\n onChange={(e) => onChange(e.target.value)}\n suffix={\n value ? (\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={clear}\n style={{ all: \"unset\", cursor: \"pointer\", color: \"var(--text-muted)\", display: \"grid\", placeItems: \"center\", padding: 2 }}\n >\n <i className=\"ph ph-x-circle\" style={{ fontSize: 15 }} aria-hidden=\"true\" />\n </button>\n ) : undefined\n }\n {...rest}\n />\n );\n}\n","import * as React from \"react\";\n\n/**\n * Multi-select control with a 44px comfortable hit area.\n */\nexport interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label: React.ReactNode;\n description?: React.ReactNode;\n /** Renders as a bordered selectable card — for the big, calm choices. */\n card?: boolean;\n indeterminate?: boolean;\n}\n\nexport function Checkbox({ label, description, card = false, indeterminate = false, className = \"\", ...rest }: CheckboxProps) {\n const ref = React.useRef<HTMLInputElement>(null);\n React.useEffect(() => { if (ref.current) ref.current.indeterminate = indeterminate; }, [indeterminate]);\n return (\n <label className={[\"fd-choice\", card ? \"fd-choice-card\" : \"\", className].filter(Boolean).join(\" \")}>\n <span className=\"fd-choice-input\">\n <input ref={ref} type=\"checkbox\" {...rest} />\n <span className=\"fd-choice-box\" aria-hidden=\"true\">\n <i className={indeterminate ? \"ph ph-minus\" : \"ph ph-check\"} />\n </span>\n </span>\n <span className=\"fd-choice-text\">\n <span className=\"fd-choice-title\">{label}</span>\n {description ? <span className=\"fd-choice-desc\">{description}</span> : null}\n </span>\n </label>\n );\n}\n","import * as React from \"react\";\n\n/** One-of-many control. Share a name across the group. */\nexport interface RadioProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label: React.ReactNode;\n description?: React.ReactNode;\n card?: boolean;\n}\n\nexport function Radio({ label, description, card = false, className = \"\", ...rest }: RadioProps) {\n return (\n <label className={[\"fd-choice\", card ? \"fd-choice-card\" : \"\", className].filter(Boolean).join(\" \")}>\n <span className=\"fd-choice-input\">\n <input type=\"radio\" {...rest} />\n <span className=\"fd-choice-box fd-choice-box-round\" aria-hidden=\"true\"><span className=\"fd-choice-dot\" /></span>\n </span>\n <span className=\"fd-choice-text\">\n <span className=\"fd-choice-title\">{label}</span>\n {description ? <span className=\"fd-choice-desc\">{description}</span> : null}\n </span>\n </label>\n );\n}\n","import * as React from \"react\";\n\n/** An immediate on/off setting — no Save button. Use Checkbox inside forms instead. */\nexport interface SwitchProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: React.ReactNode;\n description?: React.ReactNode;\n}\n\nexport function Switch({ label, description, className = \"\", ...rest }: SwitchProps) {\n return (\n <label className={[\"fd-switch\", className].filter(Boolean).join(\" \")}>\n <input type=\"checkbox\" role=\"switch\" {...rest} />\n <span className=\"fd-switch-track\"><span className=\"fd-switch-thumb\" /></span>\n {label ? (\n <span className=\"fd-choice-text\">\n <span className=\"fd-switch-label\">{label}</span>\n {description ? <span className=\"fd-choice-desc\">{description}</span> : null}\n </span>\n ) : null}\n </label>\n );\n}\n","import * as React from \"react\";\n\n/** Multi-line field. Same chrome as Input; vertical resize only. */\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {\n label?: string;\n help?: string;\n error?: string;\n required?: boolean;\n rows?: number;\n /** Applied to the field wrapper. */\n style?: React.CSSProperties;\n}\n\nexport function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = \"\", style, ...rest }: TextareaProps) {\n const fieldId = id || (rest.name ? \"fd-\" + rest.name : undefined);\n const box = [\"fd-input\", \"fd-input-textarea\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\", className].filter(Boolean).join(\" \");\n return (\n <div className=\"fd-field\" style={style}>\n {label ? <label className=\"fd-field-label\" htmlFor={fieldId}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={box}>\n <textarea id={fieldId} rows={rows} disabled={disabled} aria-invalid={error ? \"true\" : undefined} {...rest} />\n </div>\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** Numeric field with thousands formatting on blur, +/- steppers with hold-to-repeat acceleration, arrow keys (shift = bigStep), and min/max clamping. */\nexport interface NumberInputProps {\n label?: string; help?: string; error?: string;\n prefix?: string; suffix?: string;\n required?: boolean; disabled?: boolean;\n min?: number; max?: number; step?: number;\n /** Larger step used while holding the steppers or shift+arrows. */\n bigStep?: number;\n /** Thousands-format the display when not editing. Default true. */\n format?: boolean;\n value?: number | string;\n /** Called with {target:{value}} where value is a number. */\n onChange?: (e: any) => void;\n placeholder?: string;\n style?: any; className?: string;\n}\n\nexport function NumberInput({\n label, help, error, prefix, suffix, required = false, disabled = false,\n min = -Infinity, max = Infinity, step = 1, bigStep, value, onChange,\n format = true, className = \"\", style, placeholder\n}: NumberInputProps) {\n const num = (v: any): number | null => { const n = Number(String(v == null ? \"\" : v).replace(/[^0-9.-]/g, \"\")); return isNaN(n) ? null : n; };\n const [text, setText] = React.useState(value == null || value === \"\" ? \"\" : String(value));\n const [editing, setEditing] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => { if (!editing) setText(value == null || value === \"\" ? \"\" : String(value)); }, [value, editing]);\n const clamp = (n: number) => Math.min(max, Math.max(min, n));\n const fire = (n: number) => onChange && onChange({ target: { value: n } });\n const bump = (dir: number, mult = 1) => {\n const cur = num(text) ?? num(value) ?? (min === -Infinity ? 0 : min);\n const next = clamp(cur + dir * (bigStep && mult > 1 ? bigStep : step) * (bigStep ? 1 : mult));\n setText(String(next)); fire(next);\n };\n const hold = (dir: number) => {\n bump(dir);\n let n = 0;\n const tick = () => { n++; bump(dir, n > 6 ? 4 : 1); timer.current = setTimeout(tick, n > 12 ? 40 : n > 6 ? 70 : 120); };\n timer.current = setTimeout(tick, 420);\n };\n const release = () => { if (timer.current) clearTimeout(timer.current); };\n React.useEffect(() => () => { if (timer.current) clearTimeout(timer.current); }, []);\n const shown = editing ? text : (() => { const n = num(text); return n == null ? \"\" : (format ? n.toLocaleString() : String(n)); })();\n const box = [\"fd-input\", \"fd-input-num\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \");\n return (\n <div className={[\"fd-field\", className].filter(Boolean).join(\" \")} style={style}>\n {label ? <label className=\"fd-field-label\">{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={box} style={{ gap: 8 }}>\n {prefix ? <span className=\"fd-input-affix\">{prefix}</span> : null}\n <input inputMode=\"numeric\" disabled={disabled} placeholder={placeholder} value={shown}\n onFocus={() => setEditing(true)}\n onBlur={() => { setEditing(false); const n = num(text); if (n != null) { const c = clamp(n); setText(String(c)); fire(c); } }}\n onChange={(e) => { setText(e.target.value); const n = num(e.target.value); if (n != null) fire(n); }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowUp\") { e.preventDefault(); bump(1, e.shiftKey ? 2 : 1); }\n else if (e.key === \"ArrowDown\") { e.preventDefault(); bump(-1, e.shiftKey ? 2 : 1); }\n }} />\n {suffix ? <span className=\"fd-input-affix\">{suffix}</span> : null}\n <span className=\"fd-row\" style={{ gap: 4, flex: \"none\" }}>\n <button type=\"button\" className=\"fd-stepbtn\" aria-label=\"Decrease\" disabled={disabled || (num(text) ?? 0) <= min}\n onPointerDown={() => hold(-1)} onPointerUp={release} onPointerLeave={release}><i className=\"ph ph-minus\" /></button>\n <button type=\"button\" className=\"fd-stepbtn\" aria-label=\"Increase\" disabled={disabled || (num(text) ?? 0) >= max}\n onPointerDown={() => hold(1)} onPointerUp={release} onPointerLeave={release}><i className=\"ph ph-plus\" /></button>\n </span>\n </div>\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/** Rich popover select: animated listbox, keyboard nav + type-ahead, search over 8 options, option icons, descriptions, meta and groups. API-compatible with the old native select. */\nexport interface SelectOption { value: string; label: string; description?: string; icon?: string; meta?: any; group?: string; disabled?: boolean }\nexport interface SelectProps {\n label?: string; help?: string; error?: string;\n options: Array<string | SelectOption>;\n placeholder?: string; required?: boolean; disabled?: boolean;\n /** Options still arriving — the control locks and shows a spinner. */\n loading?: boolean;\n /** Force the search box on/off; default: on when over 8 options. */\n searchable?: boolean;\n /** Show an x that clears back to placeholder. */\n clearable?: boolean;\n /** Pick several: `value` is an array, the popover stays open, options get\n * checkboxes, and a footer offers Select all / Clear. */\n multiple?: boolean;\n /** With `multiple`, override the collapsed box text for 2+ selections. */\n summary?: (values: string[]) => string;\n value?: string | string[];\n /** Called with {target:{value}} like a native select — an array when `multiple`. */\n onChange?: (e: any) => void;\n name?: string;\n /** Applied to the outer .fd-field element — this is where width belongs. */\n style?: any; className?: string;\n /** Element id — forwarded to the trigger button and the label's htmlFor. Not present on the original .d.ts but required by the source markup. */\n id?: string;\n}\n\nconst norm = (o: string | SelectOption): SelectOption => (typeof o === \"string\" ? { value: o, label: o } : o);\n\ninterface PopPos {\n left: number;\n width: number;\n top: number | null;\n bottom: number | null;\n up: boolean;\n maxH: number;\n}\n\nfunction usePopPos(open: boolean, ref: React.RefObject<HTMLElement>, estH: number, estW?: number): PopPos | null {\n const [pos, setPos] = React.useState<PopPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !ref.current) { setPos(null); return; }\n const calc = () => {\n const r = ref.current!.getBoundingClientRect();\n const below = window.innerHeight - r.bottom;\n const up = below < estH && r.top > below;\n const w = Math.max(r.width, estW || 0);\n const maxH = Math.min(window.innerHeight - 16, Math.max(160, (up ? r.top : below) - 14));\n setPos({\n left: Math.max(8, Math.min(r.left, window.innerWidth - w - 8)), width: r.width,\n top: up ? null : r.bottom + 6, bottom: up ? window.innerHeight - r.top + 6 : null, up, maxH,\n });\n };\n calc();\n window.addEventListener(\"scroll\", calc, true);\n window.addEventListener(\"resize\", calc);\n return () => { window.removeEventListener(\"scroll\", calc, true); window.removeEventListener(\"resize\", calc); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n return pos;\n}\n\nconst popStyle = (pos: PopPos, extra: React.CSSProperties): React.CSSProperties => ({\n position: \"fixed\", left: pos.left, top: pos.top == null ? \"auto\" : pos.top, bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n transformOrigin: pos.up ? \"bottom center\" : \"top center\", maxHeight: pos.maxH, overflowY: \"auto\", ...extra,\n});\n\nexport function Select({\n label, help, error, options = [], placeholder = \"Select…\", required = false,\n disabled = false, loading = false, value, onChange, searchable, clearable = false,\n multiple = false, summary,\n id, className = \"\", style, ...rest\n}: SelectProps) {\n const opts = options.map(norm);\n const vals = multiple ? (Array.isArray(value) ? value : value ? [value] : []) : [];\n const isOn = (v: string) => (multiple ? vals.includes(v) : v === value);\n const hasSearch = searchable === undefined ? opts.length > 8 : searchable;\n const [open, setOpen] = React.useState(false);\n const [q, setQ] = React.useState(\"\");\n const [active, setActive] = React.useState(-1);\n const rootRef = React.useRef<HTMLDivElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const popRef = React.useRef<HTMLDivElement>(null);\n const listRef = React.useRef<HTMLDivElement>(null);\n const typeBuf = React.useRef({ s: \"\", t: 0 });\n const selected = multiple ? null : opts.find((o) => o.value === value);\n const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];\n const pos = usePopPos(open, boxRef, hasSearch ? 390 : 340, 260);\n const boxText = multiple\n ? (chosen.length === 0 ? placeholder\n : chosen.length === 1 ? chosen[0].label\n : summary ? summary(chosen.map((o) => o.value)) : chosen.length + \" selected\")\n : (selected ? selected.label : placeholder);\n\n const visible = q ? opts.filter((o) => (o.label + \" \" + (o.description || \"\") + \" \" + (o.group || \"\")).toLowerCase().includes(q.toLowerCase())) : opts;\n\n const fire = (v: string | string[]) => { onChange && onChange({ target: { value: v } }); };\n const pick = (o: SelectOption) => {\n if (o.disabled) return;\n if (multiple) { fire(vals.includes(o.value) ? vals.filter((v) => v !== o.value) : [...vals, o.value]); return; }\n fire(o.value); setOpen(false);\n };\n const toggle = () => {\n if (disabled || loading) return;\n if (!open) { setQ(\"\"); setActive(Math.max(0, opts.findIndex((o) => isOn(o.value)))); }\n setOpen(!open);\n };\n\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (rootRef.current && rootRef.current.contains(e.target as Node)) return;\n if (popRef.current && popRef.current.contains(e.target as Node)) return;\n setOpen(false);\n };\n document.addEventListener(\"pointerdown\", away);\n return () => document.removeEventListener(\"pointerdown\", away);\n }, [open]);\n\n React.useEffect(() => {\n if (!open || active < 0 || !listRef.current) return;\n const el = listRef.current.querySelector('[data-i=\"' + active + '\"]') as HTMLElement | null;\n if (el) {\n const L = listRef.current, top = el.offsetTop - L.offsetTop;\n if (top < L.scrollTop) L.scrollTop = top - 4;\n else if (top + el.offsetHeight > L.scrollTop + L.clientHeight) L.scrollTop = top + el.offsetHeight - L.clientHeight + 4;\n }\n }, [active, open]);\n\n const onKey = (e: React.KeyboardEvent<HTMLElement>) => {\n if (disabled) return;\n if (!open && (e.key === \"Enter\" || e.key === \" \" || e.key === \"ArrowDown\" || e.key === \"ArrowUp\")) { e.preventDefault(); toggle(); return; }\n if (!open) {\n if (e.key.length === 1 && /\\S/.test(e.key)) {\n const now = Date.now();\n typeBuf.current = { s: (now - typeBuf.current.t < 700 ? typeBuf.current.s : \"\") + e.key.toLowerCase(), t: now };\n const hit = opts.find((o) => o.label.toLowerCase().startsWith(typeBuf.current.s));\n if (hit && !multiple) fire(hit.value);\n }\n return;\n }\n if (e.key === \"Escape\") { e.preventDefault(); setOpen(false); }\n else if (e.key === \"ArrowDown\") { e.preventDefault(); setActive((a) => Math.min(visible.length - 1, a + 1)); }\n else if (e.key === \"ArrowUp\") { e.preventDefault(); setActive((a) => Math.max(0, a - 1)); }\n else if (e.key === \"Home\") { e.preventDefault(); setActive(0); }\n else if (e.key === \"End\") { e.preventDefault(); setActive(visible.length - 1); }\n else if (e.key === \"Enter\") { e.preventDefault(); if (visible[active]) pick(visible[active]); }\n else if (e.key === \"Tab\") setOpen(false);\n };\n\n const groups: { g: string; items: { o: SelectOption; i: number }[] }[] = [];\n visible.forEach((o, i) => {\n const g = o.group || \"\";\n const last = groups[groups.length - 1];\n if (!last || last.g !== g) groups.push({ g, items: [{ o, i }] });\n else last.items.push({ o, i });\n });\n\n const fieldId = id || (rest.name ? \"fd-\" + rest.name : undefined);\n const box = [\"fd-input\", \"fd-select\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \");\n return (\n <div className={[\"fd-field\", \"fd-popfield\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")} style={style} ref={rootRef}>\n {label ? <label className=\"fd-field-label\" htmlFor={fieldId} onClick={toggle}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={box} style={{ cursor: disabled ? \"not-allowed\" : \"pointer\" }} ref={boxRef}>\n <button type=\"button\" id={fieldId} disabled={disabled || loading} onClick={toggle} onKeyDown={onKey}\n role=\"combobox\" aria-expanded={open} aria-haspopup=\"listbox\"\n style={{ all: \"unset\", flex: 1, minWidth: 0, display: \"flex\", alignItems: \"center\", gap: 8, cursor: \"inherit\", overflow: \"hidden\" }}>\n {selected && selected.icon ? <i className={\"ph ph-\" + selected.icon} style={{ flex: \"none\", color: \"var(--text-2)\" }} /> : null}\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", color: (multiple ? chosen.length : selected) ? \"var(--text)\" : \"var(--text-muted)\" }}>\n {boxText}\n </span>\n {multiple && chosen.length > 1 ? <span className=\"fd-mono\" style={{ flex: \"none\", fontSize: 11, fontWeight: 700, padding: \"1px 6px\", borderRadius: 99, background: \"var(--brand)\", color: \"#fff\" }}>{chosen.length}</span> : null}\n </button>\n {clearable && (multiple ? chosen.length > 0 : selected) && !loading ? (\n <button type=\"button\" aria-label=\"Clear\" onClick={(e) => { e.stopPropagation(); fire(multiple ? [] : \"\"); }}\n style={{ all: \"unset\", cursor: \"pointer\", color: \"var(--text-muted)\", display: \"grid\", placeItems: \"center\", padding: 2 }}>\n <i className=\"ph ph-x-circle\" style={{ fontSize: 15 }} />\n </button>) : null}\n {loading\n ? <span className=\"fd-spinner\" style={{ color: \"var(--text-muted)\" }} aria-label=\"Loading options\" />\n : <span className=\"fd-select-caret\" onClick={toggle}><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>}\n </div>\n {open && pos ? createPortal(\n <div className={\"fd-pop\" + (pos.up ? \" is-up\" : \"\")} ref={popRef}\n style={popStyle(pos, { minWidth: Math.max(pos.width, 260), maxWidth: 380, zIndex: 130, overflowY: \"hidden\" })}>\n {hasSearch ? (\n <div className=\"fd-pop-search\">\n <i className=\"ph ph-magnifying-glass\" style={{ color: \"var(--text-muted)\", fontSize: 14 }} />\n <input autoFocus placeholder=\"Search…\" value={q} onKeyDown={onKey}\n onChange={(e) => { setQ(e.target.value); setActive(0); }} />\n {q ? <span className=\"fd-body-sm fd-muted\">{visible.length}</span> : null}\n </div>) : null}\n <div className=\"fd-pop-list\" role=\"listbox\" aria-multiselectable={multiple || undefined} ref={listRef} style={{ maxHeight: Math.max(120, pos.maxH - (hasSearch ? 64 : 12) - (multiple ? 42 : 0)) }}>\n {visible.length === 0 ? <div className=\"fd-pop-empty\">Nothing matches \"{q}\".</div> : groups.map((grp) => (\n <React.Fragment key={grp.g || \"_\"}>\n {grp.g ? <div className=\"fd-pop-group\">{grp.g}</div> : null}\n {grp.items.map(({ o, i }) => (\n <button type=\"button\" key={String(o.value)} data-i={i} role=\"option\" aria-selected={isOn(o.value)}\n aria-disabled={o.disabled || undefined}\n className={[\"fd-opt\", i === active ? \"is-active\" : \"\", isOn(o.value) ? \"is-selected\" : \"\"].filter(Boolean).join(\" \")}\n onMouseEnter={() => setActive(i)} onClick={() => pick(o)}>\n {multiple ? (\n <span aria-hidden=\"true\" style={{ flex: \"none\", display: \"grid\", placeItems: \"center\", width: 16, height: 16, borderRadius: 4, border: \"1.5px solid \" + (isOn(o.value) ? \"var(--brand)\" : \"var(--border-strong, var(--border))\"), background: isOn(o.value) ? \"var(--brand)\" : \"var(--surface)\", color: \"#fff\" }}>\n {isOn(o.value) ? <i className=\"ph ph-check\" style={{ fontSize: 11 }} /> : null}\n </span>) : null}\n {o.icon ? <span className=\"fd-opt-icon\"><i className={\"ph ph-\" + o.icon} /></span> : null}\n <span style={{ flex: 1, minWidth: 0 }}>\n <span className=\"fd-opt-label\">{o.label}</span>\n {o.description ? <span className=\"fd-opt-desc\">{o.description}</span> : null}\n </span>\n {o.meta ? <span className=\"fd-opt-meta\">{o.meta}</span> : null}\n {multiple ? null : <span className=\"fd-opt-check\">{o.value === value ? <i className=\"ph ph-check\" /> : null}</span>}\n </button>\n ))}\n </React.Fragment>\n ))}\n </div>\n {multiple ? (\n <div className=\"fd-row\" style={{ gap: 10, padding: \"8px 12px\", borderTop: \"1px solid var(--border)\" }}>\n <button type=\"button\" onClick={() => fire(visible.filter((o) => !o.disabled).map((o) => o.value))}\n style={{ all: \"unset\", cursor: \"pointer\", fontSize: \"var(--body-sm-size)\", fontWeight: 600, color: \"var(--brand)\" }}>Select all</button>\n <span style={{ flex: 1 }} />\n <span className=\"fd-body-sm fd-muted\">{vals.length} of {opts.length}</span>\n <button type=\"button\" disabled={!vals.length} onClick={() => fire([])}\n style={{ all: \"unset\", cursor: vals.length ? \"pointer\" : \"default\", fontSize: \"var(--body-sm-size)\", fontWeight: 600, color: vals.length ? \"var(--text-2)\" : \"var(--text-muted)\" }}>Clear</button>\n </div>) : null}\n </div>, document.body) : null}\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\nconst MONTHS = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\nconst DOW = [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"];\nconst iso = (d: Date) => d.getFullYear() + \"-\" + String(d.getMonth() + 1).padStart(2, \"0\") + \"-\" + String(d.getDate()).padStart(2, \"0\");\nconst parse = (s?: string | null): Date | null => { if (!s) return null; const [y, m, d] = s.split(\"-\").map(Number); return new Date(y, m - 1, d); };\nconst fmt = (s?: string | null) => { const d = parse(s); return d ? MONTHS[d.getMonth()].slice(0, 3) + \" \" + d.getDate() + \", \" + d.getFullYear() : \"\"; };\n\ninterface PopPos {\n left: number;\n width: number;\n top: number | null;\n bottom: number | null;\n up: boolean;\n maxH: number;\n}\n\nfunction usePopPos(open: boolean, ref: React.RefObject<HTMLElement>, estH: number, estW?: number): PopPos | null {\n const [pos, setPos] = React.useState<PopPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !ref.current) { setPos(null); return; }\n const calc = () => {\n const r = ref.current!.getBoundingClientRect();\n const below = window.innerHeight - r.bottom;\n const up = below < estH && r.top > below;\n const w = Math.max(r.width, estW || 0);\n const maxH = Math.min(window.innerHeight - 16, Math.max(160, (up ? r.top : below) - 14));\n setPos({\n left: Math.max(8, Math.min(r.left, window.innerWidth - w - 8)), width: r.width,\n top: up ? null : r.bottom + 6, bottom: up ? window.innerHeight - r.top + 6 : null, up, maxH,\n });\n };\n calc();\n window.addEventListener(\"scroll\", calc, true);\n window.addEventListener(\"resize\", calc);\n return () => { window.removeEventListener(\"scroll\", calc, true); window.removeEventListener(\"resize\", calc); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n return pos;\n}\nconst popStyle = (pos: PopPos, extra: React.CSSProperties): React.CSSProperties => ({\n position: \"fixed\", left: pos.left, top: pos.top == null ? \"auto\" : pos.top, bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n transformOrigin: pos.up ? \"bottom center\" : \"top center\", maxHeight: pos.maxH, overflowY: \"auto\", ...extra,\n});\n\n/** Calendar popover date field. Click the title to drill month -> year; range mode picks start then end with live hover preview. Values are ISO strings (\"2026-03-01\"). */\nexport interface DatePickerProps {\n label?: string; help?: string; error?: string;\n required?: boolean; disabled?: boolean;\n /** false: value is \"YYYY-MM-DD\". true: value is {start, end}. */\n range?: boolean;\n value?: any;\n /** Called with {target:{value}} — string, or {start,end} in range mode. */\n onChange?: (e: any) => void;\n placeholder?: string;\n style?: any; className?: string;\n}\n\n/** The bare calendar, for embedding in custom surfaces. months=2 renders two side-by-side months (used by range mode). */\nexport interface CalendarProps { value?: any; range?: boolean; onPick: (v: any) => void; initialMonth?: string; months?: number }\n\nexport function Calendar({ value, range = false, onPick, initialMonth, months = 1 }: CalendarProps) {\n const today = new Date();\n const sel = range ? value || {} : { start: value, end: value };\n const anchor = parse(sel.start) || parse(initialMonth) || today;\n const [vy, setVy] = React.useState(anchor.getFullYear());\n const [vm, setVm] = React.useState(anchor.getMonth());\n const [mode, setMode] = React.useState(\"days\"); // days | months | years\n const [hover, setHover] = React.useState<string | null>(null);\n const s = parse(sel.start), e = parse(sel.end);\n const hoverEnd = range && s && !e && hover ? parse(hover) : null;\n const inRange = (d: Date) => {\n const lo = s, hi = e || hoverEnd;\n return lo && hi && d > (lo < hi ? lo : hi) && d < (lo < hi ? hi : lo);\n };\n const isEdge = (d: Date) => (s && iso(d) === iso(s)) || (e && iso(d) === iso(e));\n const clickDay = (d: Date) => {\n const v = iso(d);\n if (!range) { onPick(v); return; }\n if (!sel.start || (sel.start && sel.end)) onPick({ start: v, end: \"\" });\n else {\n const a = parse(sel.start)!;\n onPick(d < a ? { start: v, end: sel.start } : { start: sel.start, end: v });\n }\n };\n const nav = (d: number) => { let m = vm + d, y = vy; if (m < 0) { m = 11; y--; } if (m > 11) { m = 0; y++; } setVm(m); setVy(y); };\n const monthGrid = (y: number, m: number) => {\n const startPad = new Date(y, m, 1).getDay();\n const cells: Date[] = [];\n for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));\n return (\n <div className=\"fd-cal-grid\" style={{ width: months > 1 ? 252 : \"auto\", flex: \"none\" }} onMouseLeave={() => setHover(null)}>\n {DOW.map((d) => <span key={d} className=\"fd-cal-dow\">{d}</span>)}\n {cells.map((d, i) => (\n <button type=\"button\" key={i}\n className={[\"fd-cal-day\", d.getMonth() !== m ? \"is-out\" : \"\", iso(d) === iso(today) ? \"is-today\" : \"\", inRange(d) ? \"in-range\" : \"\", isEdge(d) ? \"is-edge\" : \"\"].filter(Boolean).join(\" \")}\n onClick={() => clickDay(d)} onMouseEnter={() => range && setHover(iso(d))}>\n {d.getDate()}\n </button>\n ))}\n </div>\n );\n };\n const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;\n return (\n <div className=\"fd-cal\" style={{ width: months > 1 && mode === \"days\" ? \"auto\" : undefined }}>\n <div className=\"fd-cal-head\">\n <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Previous\" onClick={() => mode === \"years\" ? setVy(vy - 12) : mode === \"months\" ? setVy(vy - 1) : nav(-1)}><i className=\"ph ph-caret-left\" /></button>\n <button type=\"button\" className=\"fd-cal-title\" onClick={() => setMode(mode === \"days\" ? \"months\" : mode === \"months\" ? \"years\" : \"days\")}>\n {mode === \"days\" ? MONTHS[vm] + \" \" + vy : mode === \"months\" ? vy : (vy - 5) + \" – \" + (vy + 6)}\n <i className=\"ph ph-caret-down\" style={{ fontSize: 10, marginLeft: 6, color: \"var(--text-muted)\" }} />\n </button>\n {months > 1 && mode === \"days\" ? <span className=\"fd-cal-title\" style={{ cursor: \"default\", background: \"none\" }}>{MONTHS[nextM] + \" \" + nextY}</span> : null}\n <button type=\"button\" className=\"fd-btn-icon\" aria-label=\"Next\" onClick={() => mode === \"years\" ? setVy(vy + 12) : mode === \"months\" ? setVy(vy + 1) : nav(1)}><i className=\"ph ph-caret-right\" /></button>\n </div>\n {mode === \"days\" ? (\n <div style={{ display: \"flex\", gap: 18 }}>\n {monthGrid(vy, vm)}\n {months > 1 ? monthGrid(nextY, nextM) : null}\n </div>\n ) : mode === \"months\" ? (\n <div className=\"fd-cal-grid-months\">\n {MONTHS.map((m, i) => (\n <button type=\"button\" key={m} className={\"fd-cal-cell\" + (i === vm && s && s.getFullYear() === vy ? \" is-sel\" : \"\")}\n onClick={() => { setVm(i); setMode(\"days\"); }}>{m.slice(0, 3)}</button>\n ))}\n </div>\n ) : (\n <div className=\"fd-cal-grid-months\">\n {Array.from({ length: 12 }, (_, i) => vy - 5 + i).map((y) => (\n <button type=\"button\" key={y} className={\"fd-cal-cell\" + (y === vy ? \" is-sel\" : \"\")}\n onClick={() => { setVy(y); setMode(\"months\"); }}>{y}</button>\n ))}\n </div>\n )}\n <div className=\"fd-cal-foot\">\n <button type=\"button\" className=\"fd-btn fd-btn-link\" style={{ fontSize: 12.5 }}\n onClick={() => { setVy(today.getFullYear()); setVm(today.getMonth()); setMode(\"days\"); }}>Today</button>\n <span style={{ flex: 1 }} />\n {range && sel.start ? <span className=\"fd-body-sm fd-muted\">{fmt(sel.start)}{sel.end ? \" → \" + fmt(sel.end) : \" → pick an end\"}</span> : null}\n </div>\n </div>\n );\n}\n\nexport function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, className = \"\", style, ...rest }: DatePickerProps) {\n const [open, setOpen] = React.useState(false);\n const rootRef = React.useRef<HTMLDivElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const popRef = React.useRef<HTMLDivElement>(null);\n const pos = usePopPos(open, boxRef, 430, range ? 600 : 316);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (rootRef.current && rootRef.current.contains(e.target as Node)) return;\n if (popRef.current && popRef.current.contains(e.target as Node)) return;\n setOpen(false);\n };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n const display = range\n ? (value && value.start ? fmt(value.start) + (value.end ? \" → \" + fmt(value.end) : \" → …\") : \"\")\n : fmt(value);\n const toggle = () => { if (!disabled) setOpen(!open); };\n return (\n <div className={[\"fd-field\", \"fd-popfield\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")} style={style} ref={rootRef}>\n {label ? <label className=\"fd-field-label\" onClick={toggle}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={[\"fd-input\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \")} style={{ cursor: disabled ? \"not-allowed\" : \"pointer\" }} onClick={toggle} ref={boxRef}>\n <span className=\"fd-input-icon\"><i className=\"ph ph-calendar-blank\" aria-hidden=\"true\" /></span>\n <button type=\"button\" disabled={disabled} onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); toggle(); } }}\n style={{ all: \"unset\", flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", cursor: \"inherit\", color: display ? \"var(--text)\" : \"var(--text-muted)\" }} {...rest}>\n {display || placeholder || (range ? \"Pick a date range\" : \"Pick a date\")}\n </button>\n <span className=\"fd-select-caret\"><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>\n </div>\n {open && pos ? createPortal(\n <div className={\"fd-pop\" + (pos.up ? \" is-up\" : \"\")} ref={popRef} style={popStyle(pos, { width: \"max-content\", minWidth: 0, zIndex: 130 })}>\n <Calendar range={range} months={range ? 2 : 1} value={value}\n onPick={(v: any) => { onChange && onChange({ target: { value: v } }); if (!range || (v.start && v.end)) setOpen(false); }} />\n </div>, document.body) : null}\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\nconst pad = (n: number) => String(n).padStart(2, \"0\");\n\ninterface PopPos {\n left: number;\n width: number;\n top: number | null;\n bottom: number | null;\n up: boolean;\n maxH: number;\n}\n\nfunction usePopPos(open: boolean, ref: React.RefObject<HTMLElement>, estH: number, estW?: number): PopPos | null {\n const [pos, setPos] = React.useState<PopPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !ref.current) { setPos(null); return; }\n const calc = () => {\n const r = ref.current!.getBoundingClientRect();\n const below = window.innerHeight - r.bottom;\n const up = below < estH && r.top > below;\n const w = Math.max(r.width, estW || 0);\n const maxH = Math.min(window.innerHeight - 16, Math.max(160, (up ? r.top : below) - 14));\n setPos({\n left: Math.max(8, Math.min(r.left, window.innerWidth - w - 8)), width: r.width,\n top: up ? null : r.bottom + 6, bottom: up ? window.innerHeight - r.top + 6 : null, up, maxH,\n });\n };\n calc();\n window.addEventListener(\"scroll\", calc, true);\n window.addEventListener(\"resize\", calc);\n return () => { window.removeEventListener(\"scroll\", calc, true); window.removeEventListener(\"resize\", calc); };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n return pos;\n}\nconst popStyle = (pos: PopPos, extra: React.CSSProperties): React.CSSProperties => ({\n position: \"fixed\", left: pos.left, top: pos.top == null ? \"auto\" : pos.top, bottom: pos.bottom == null ? \"auto\" : pos.bottom,\n transformOrigin: pos.up ? \"bottom center\" : \"top center\", maxHeight: pos.maxH, overflowY: \"auto\", ...extra,\n});\n\n/** Analog clock-face time field: tap or drag the hand to set the hour, auto-advances to minutes; AM/PM chips; \"Now\" shortcut. Value is 24h \"HH:MM\". */\nexport interface TimePickerProps {\n label?: string; help?: string; error?: string;\n required?: boolean; disabled?: boolean;\n /** 24h \"HH:MM\", e.g. \"14:30\". */\n value?: string;\n /** Called with {target:{value}}. */\n onChange?: (e: any) => void;\n placeholder?: string;\n style?: any; className?: string;\n}\n\n/** The bare clock face, for embedding (e.g. below a Calendar). */\nexport interface ClockFaceProps { value?: string; onChange: (v: string) => void }\n\nexport function ClockFace({ value = \"09:00\", onChange }: ClockFaceProps) {\n let [h24, m] = value.split(\":\").map(Number);\n if (isNaN(h24)) h24 = 9;\n if (isNaN(m)) m = 0;\n const pm = h24 >= 12;\n const h12 = h24 % 12 === 0 ? 12 : h24 % 12;\n const [mode, setMode] = React.useState(\"h\"); // h | m\n const faceRef = React.useRef<HTMLDivElement>(null);\n const dragging = React.useRef(false);\n const set = (h: number, mm: number, isPm: boolean) => onChange((isPm ? (h % 12) + 12 : h % 12) + \":\" + pad(mm));\n const R = 108, NR = 80;\n const nums = mode === \"h\" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);\n const selNum = mode === \"h\" ? h12 : m;\n const angleOf = (n: number) => (mode === \"h\" ? (n % 12) * 30 : (n / 5) * 30) - 90;\n const fromPointer = (e: React.PointerEvent) => {\n const r = faceRef.current!.getBoundingClientRect();\n const x = e.clientX - r.left - R, y = e.clientY - r.top - R;\n let deg = Math.atan2(y, x) * 180 / Math.PI + 90;\n if (deg < 0) deg += 360;\n if (mode === \"h\") {\n const h = Math.round(deg / 30) % 12 || 12;\n set(h === 12 ? 12 : h, m, pm);\n } else {\n const mm = Math.round(deg / 6) % 60;\n set(h12, mm, pm);\n }\n };\n const down = (e: React.PointerEvent) => { dragging.current = true; faceRef.current && faceRef.current.setPointerCapture && faceRef.current.setPointerCapture(e.pointerId); fromPointer(e); };\n const move = (e: React.PointerEvent) => { if (dragging.current) fromPointer(e); };\n const upH = () => { if (dragging.current) { dragging.current = false; if (mode === \"h\") setMode(\"m\"); } };\n const handAngle = mode === \"h\" ? (h12 % 12) * 30 : m * 6;\n const minuteOff = mode === \"m\" && m % 5 !== 0;\n return (\n <div style={{ padding: \"4px 14px 14px\" }}>\n <div className=\"fd-clock-digits\">\n <button type=\"button\" className={\"fd-clock-digit\" + (mode === \"h\" ? \" is-active\" : \"\")} onClick={() => setMode(\"h\")}>{pad(h12)}</button>\n <span style={{ fontSize: 24, fontWeight: 700, color: \"var(--text-muted)\" }}>:</span>\n <button type=\"button\" className={\"fd-clock-digit\" + (mode === \"m\" ? \" is-active\" : \"\")} onClick={() => setMode(\"m\")}>{pad(m)}</button>\n <span className=\"fd-stack\" style={{ gap: 3, marginLeft: 8 }}>\n {[\"AM\", \"PM\"].map((ap) => (\n <button type=\"button\" key={ap} onClick={() => set(h12, m, ap === \"PM\")}\n style={{ border: \"1px solid \" + ((ap === \"PM\") === pm ? \"var(--brand)\" : \"var(--border)\"), background: (ap === \"PM\") === pm ? \"var(--surface-brand)\" : \"var(--surface)\", color: (ap === \"PM\") === pm ? \"var(--brand)\" : \"var(--text-muted)\", borderRadius: 6, font: \"inherit\", fontSize: 11, fontWeight: 700, padding: \"3px 8px\", cursor: \"pointer\" }}>{ap}</button>\n ))}\n </span>\n </div>\n <div className=\"fd-clock\" ref={faceRef} onPointerDown={down} onPointerMove={move} onPointerUp={upH}>\n <span className=\"fd-clock-hand\" style={{ height: NR - (minuteOff ? 14 : 16), transform: \"translateX(-50%) rotate(\" + handAngle + \"deg)\", bottom: \"50%\" }} />\n <span className=\"fd-clock-pivot\" />\n {minuteOff ? <span style={{ position: \"absolute\", left: \"50%\", top: \"50%\", width: 10, height: 10, margin: -5, borderRadius: \"50%\", border: \"2px solid var(--brand)\", background: \"var(--surface)\", transform: \"rotate(\" + handAngle + \"deg) translateY(-\" + (NR - 6) + \"px)\", transformOrigin: \"center\", pointerEvents: \"none\" }} /> : null}\n {nums.map((n) => {\n const a = angleOf(n) * Math.PI / 180;\n return (\n <span key={n} className={\"fd-clock-num\" + (n === selNum || (mode === \"m\" && n === Math.round(m / 5) * 5 % 60 && m % 5 === 0) ? \" is-sel\" : \"\")}\n style={{ left: R + Math.cos(a) * NR, top: R + Math.sin(a) * NR }}>\n {mode === \"m\" ? pad(n) : n}\n </span>\n );\n })}\n </div>\n <div className=\"fd-row\" style={{ justifyContent: \"center\", gap: 6 }}>\n <span className=\"fd-body-sm fd-muted\">{mode === \"h\" ? \"Pick the hour — drag or tap\" : \"Now the minutes\"}</span>\n </div>\n </div>\n );\n}\n\nexport function TimePicker({ label, help, error, required = false, disabled = false, value = \"\", onChange, placeholder = \"Pick a time\", className = \"\", style }: TimePickerProps) {\n const [open, setOpen] = React.useState(false);\n const rootRef = React.useRef<HTMLDivElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const popRef = React.useRef<HTMLDivElement>(null);\n const pos = usePopPos(open, boxRef, 420, 262);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => {\n if (rootRef.current && rootRef.current.contains(e.target as Node)) return;\n if (popRef.current && popRef.current.contains(e.target as Node)) return;\n setOpen(false);\n };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n const disp = () => {\n if (!value) return \"\";\n const [h, m] = value.split(\":\").map(Number);\n return (h % 12 === 0 ? 12 : h % 12) + \":\" + pad(m) + \" \" + (h >= 12 ? \"PM\" : \"AM\");\n };\n const toggle = () => { if (!disabled) setOpen(!open); };\n return (\n <div className={[\"fd-field\", \"fd-popfield\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")} style={style} ref={rootRef}>\n {label ? <label className=\"fd-field-label\" onClick={toggle}>{label}{required ? <span className=\"fd-field-req\">*</span> : null}</label> : null}\n <div className={[\"fd-input\", error ? \"fd-input-error\" : \"\", disabled ? \"fd-input-disabled\" : \"\"].filter(Boolean).join(\" \")} style={{ cursor: disabled ? \"not-allowed\" : \"pointer\" }} onClick={toggle} ref={boxRef}>\n <span className=\"fd-input-icon\"><i className=\"ph ph-clock\" aria-hidden=\"true\" /></span>\n <button type=\"button\" disabled={disabled} onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") { e.preventDefault(); toggle(); } }}\n style={{ all: \"unset\", flex: 1, cursor: \"inherit\", color: value ? \"var(--text)\" : \"var(--text-muted)\" }}>\n {disp() || placeholder}\n </button>\n <span className=\"fd-select-caret\"><i className=\"ph ph-caret-down\" aria-hidden=\"true\" /></span>\n </div>\n {open && pos ? createPortal(\n <div className={\"fd-pop\" + (pos.up ? \" is-up\" : \"\")} ref={popRef} style={popStyle(pos, { width: 262, minWidth: 0, zIndex: 130 })}>\n <ClockFace value={value || \"09:00\"} onChange={(v) => onChange && onChange({ target: { value: v } })} />\n <div className=\"fd-cal-foot\" style={{ margin: \"0 14px 12px\", paddingTop: 10 }}>\n <button type=\"button\" className=\"fd-btn fd-btn-link\" style={{ fontSize: 12.5 }}\n onClick={() => { const d = new Date(); onChange && onChange({ target: { value: d.getHours() + \":\" + pad(d.getMinutes()) } }); }}>Now</button>\n <span style={{ flex: 1 }} />\n <button type=\"button\" className=\"fd-btn fd-btn-primary fd-btn-sm\" onClick={() => setOpen(false)}>Done</button>\n </div>\n </div>, document.body) : null}\n {error ? <span className=\"fd-field-error\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{error}</span>\n : help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * Continuous value control. In the media planner this is the reallocation slider:\n * a live chip follows the handle while dragging and the commit is explicit.\n */\nexport interface SliderProps {\n label?: string;\n min?: number;\n max?: number;\n step?: number;\n value?: number;\n onChange?: (value: number) => void;\n /** Renders the value in the chip and header, e.g. v => \"$\" + v.toLocaleString() */\n format?: (value: number) => string;\n showChip?: boolean;\n help?: string;\n className?: string;\n}\n\nexport function Slider({\n label, min = 0, max = 100, step = 1, value, onChange,\n format = (v: number) => String(v), showChip = true, help, className = \"\", ...rest\n}: SliderProps) {\n const [dragging, setDragging] = React.useState(false);\n const v = value === undefined ? min : Number(value);\n const pct = max === min ? 0 : ((v - min) / (max - min)) * 100;\n return (\n <div className={[\"fd-field\", className].filter(Boolean).join(\" \")}>\n {label ? (\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n <span className=\"fd-field-label\">{label}</span>\n <span className=\"fd-num\" style={{ color: \"var(--text-2)\" }}>{format(v)}</span>\n </div>\n ) : null}\n <div className=\"fd-slider\">\n <span className=\"fd-slider-fill\" style={{ width: pct + \"%\" }} />\n {showChip && dragging ? (\n <span className=\"fd-slider-chip\" style={{ left: pct + \"%\" }}>{format(v)}</span>\n ) : null}\n <input type=\"range\" min={min} max={max} step={step} value={v}\n onChange={onChange ? (e) => onChange!(Number(e.target.value)) : undefined}\n onPointerDown={() => setDragging(true)}\n onPointerUp={() => setDragging(false)}\n onBlur={() => setDragging(false)}\n aria-label={label} {...rest} />\n </div>\n {help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/** Dual-thumb range slider: drag either thumb or the rail, value bubbles while dragging or focused, tick marks with labels, optional magnetic snap, keyboard (arrows, shift for 10%, Home/End). */\nexport interface RangeSliderProps {\n label?: string; help?: string;\n min?: number; max?: number; step?: number;\n /** [low, high] */\n value: [number, number];\n onChange: (v: [number, number]) => void;\n /** Minimum distance the thumbs keep between them. */\n minGap?: number;\n /** Tick stops; label is optional. */\n marks?: Array<{ value: number; label?: string }>;\n /** Ordinal mode: unevenly spaced legal values (numbers, or {value,label}); the\n * slider then travels in even steps between them and reports real values.\n * Infinity is allowed for an open upper bound — give it a label like \"No limit\". */\n stops?: Array<number | { value: number; label?: string }>;\n /** Magnetically snap to nearby marks while dragging. */\n snap?: boolean;\n format?: (v: number) => string;\n className?: string;\n}\n\nexport function RangeSlider({\n label, min = 0, max = 100, step = 1, value, onChange, minGap = 0,\n marks = [], snap = false, stops, format, help, className = \"\", ...rest\n}: RangeSliderProps & Record<string, any>): JSX.Element {\n // Hooks must run unconditionally on every render (Rules of Hooks) — declared\n // here even though ordinal mode below doesn't use them, since it delegates\n // to a nested <RangeSlider> instance rather than using this one's state.\n const fmt = format || ((v: number) => String(v));\n const [a, b] = value || [min, max];\n const [drag, setDrag] = React.useState<number | null>(null); // 0 | 1 | null\n const [focus, setFocus] = React.useState<number | null>(null);\n const railRef = React.useRef<HTMLSpanElement>(null);\n const pct = (v: number) => max === min ? 0 : ((v - min) / (max - min)) * 100;\n const clampPair = (i: number, v: number): [number, number] => {\n v = Math.min(max, Math.max(min, Math.round(v / step) * step));\n if (snap && marks.length) {\n const near = marks.reduce((best, m) => Math.abs(m.value - v) < Math.abs(best - v) ? m.value : best, Infinity);\n if (Math.abs(near - v) <= (max - min) * 0.015) v = near;\n }\n const pair: [number, number] = i === 0 ? [Math.min(v, b - minGap), b] : [a, Math.max(v, a + minGap)];\n return pair;\n };\n const fromEvent = (e: { clientX: number }) => {\n const r = railRef.current!.getBoundingClientRect();\n return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);\n };\n React.useEffect(() => {\n if (drag === null) return;\n const mv = (e: PointerEvent) => onChange && onChange(clampPair(drag, fromEvent(e)));\n const upH = () => setDrag(null);\n window.addEventListener(\"pointermove\", mv);\n window.addEventListener(\"pointerup\", upH);\n return () => { window.removeEventListener(\"pointermove\", mv); window.removeEventListener(\"pointerup\", upH); };\n }, [drag, a, b]);\n\n /* Ordinal mode: with `stops` the slider works in index space, so unevenly\n spaced breakpoints (0, 5k, 10k … 100k, No limit) get even handle travel and\n only ever land on a legal value. Delegates to the linear implementation. */\n if (stops && stops.length > 1) {\n const S: Array<{ value: number; label?: string }> = stops.map((s) => (typeof s === \"object\" ? s : { value: s }));\n const num = (v: any) => (v === Infinity || v == null ? Number.MAX_SAFE_INTEGER : v);\n const idxOf = (v: any) => S.reduce((best, s, i) => (Math.abs(num(s.value) - num(v)) < Math.abs(num(S[best].value) - num(v)) ? i : best), 0);\n const labelOf = (i: number) => { const s = S[Math.round(i)] || S[0]; return s.label != null ? s.label : String(s.value); };\n const thin = S.length > 7 ? Math.ceil(S.length / 5) : 1;\n const pair = value || [S[0].value, S[S.length - 1].value];\n return (\n <RangeSlider {...rest} label={label} help={help} className={className}\n min={0} max={S.length - 1} step={1} minGap={minGap}\n value={[idxOf(pair[0]), idxOf(pair[1])]}\n onChange={(p) => onChange && onChange([S[p[0]].value, S[p[1]].value])}\n marks={marks.length ? marks : S.map((_s, i) => ({ value: i, label: (i === 0 || i === S.length - 1 || i % thin === 0) ? labelOf(i) : undefined }))}\n format={format ? (i: number) => format!(S[Math.round(i)].value) : labelOf} />\n );\n }\n const startDrag = (i: number) => (e: React.PointerEvent) => {\n e.preventDefault();\n (e.target as Element).setPointerCapture && (e.target as Element).setPointerCapture(e.pointerId);\n setDrag(i);\n };\n const onRailDown = (e: React.PointerEvent) => {\n const v = fromEvent(e);\n const i = Math.abs(v - a) <= Math.abs(v - b) ? 0 : 1;\n onChange && onChange(clampPair(i, v));\n setDrag(i);\n };\n const key = (i: number) => (e: React.KeyboardEvent) => {\n const big = (max - min) / 10;\n let d = 0;\n if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") d = -(e.shiftKey ? big : step);\n else if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") d = e.shiftKey ? big : step;\n else if (e.key === \"Home\") { onChange(clampPair(i, min)); e.preventDefault(); return; }\n else if (e.key === \"End\") { onChange(clampPair(i, max)); e.preventDefault(); return; }\n else return;\n e.preventDefault();\n onChange && onChange(clampPair(i, (i === 0 ? a : b) + d));\n };\n const showChip = (i: number) => drag === i || focus === i;\n const hasLabels = marks.some((m) => m.label);\n return (\n <div className={[\"fd-field\", className].filter(Boolean).join(\" \")} {...rest}>\n {label ? (\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n <span className=\"fd-field-label\">{label}</span>\n <span className=\"fd-num\" style={{ color: \"var(--text-2)\" }}>{fmt(a)} – {fmt(b)}</span>\n </div>\n ) : null}\n <div className={\"fd-range\" + (hasLabels ? \" has-labels\" : \"\")} onPointerDown={onRailDown}>\n <span className=\"fd-range-rail\" ref={railRef} />\n <span className=\"fd-range-fill\" style={{ left: pct(a) + \"%\", width: (pct(b) - pct(a)) + \"%\" }} />\n {marks.map((m) => (\n <React.Fragment key={m.value}>\n <span className={\"fd-range-mark\" + (m.value >= a && m.value <= b ? \" is-in\" : \"\")} style={{ left: pct(m.value) + \"%\" }} />\n {m.label ? <span className=\"fd-range-mark-label\" style={{ left: pct(m.value) + \"%\" }}>{m.label}</span> : null}\n </React.Fragment>\n ))}\n {[a, b].map((v, i) => (\n <span key={i} className={\"fd-range-thumb\" + (drag === i ? \" is-drag\" : \"\")} style={{ left: pct(v) + \"%\" }}\n tabIndex={0} role=\"slider\" aria-valuemin={min} aria-valuemax={max} aria-valuenow={v}\n aria-label={(label || \"Range\") + (i === 0 ? \" minimum\" : \" maximum\")}\n onPointerDown={startDrag(i)} onKeyDown={key(i)}\n onFocus={() => setFocus(i)} onBlur={() => setFocus(null)}>\n <span className=\"fd-range-chip\" style={{ opacity: showChip(i) ? 1 : undefined }}>{fmt(v)}</span>\n </span>\n ))}\n </div>\n {help ? <span className=\"fd-field-help\">{help}</span> : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { filterFiles, toAttachment } from \"../../kits/files\";\nimport type { Attachment, FileRejection } from \"../../kits/files\";\n\nexport interface DropzoneProps {\n onFiles?: (files: File[]) => void;\n onReject?: (rejections: FileRejection[]) => void;\n accept?: string;\n maxFileSize?: number;\n multiple?: boolean;\n disabled?: boolean;\n label?: string;\n hint?: string;\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * A drop target that wraps any content. Reports accepted files and rejections;\n * it never uploads anything itself.\n */\nexport function Dropzone({\n onFiles, onReject, accept, maxFileSize, multiple = true, disabled = false,\n label = \"Drop files to attach\", hint, children, className = \"\", style,\n}: DropzoneProps) {\n const [over, setOver] = React.useState(false);\n const depth = React.useRef(0);\n\n const has = (e: React.DragEvent) => {\n const dt = e.dataTransfer;\n if (!dt) return false;\n return Array.from(dt.types || []).indexOf(\"Files\") !== -1;\n };\n\n const enter = (e: React.DragEvent) => { if (disabled || !has(e)) return; depth.current++; setOver(true); };\n const leave = () => { depth.current = Math.max(0, depth.current - 1); if (!depth.current) setOver(false); };\n const over_ = (e: React.DragEvent) => { if (disabled || !has(e)) return; e.preventDefault(); e.dataTransfer.dropEffect = \"copy\"; };\n const drop = (e: React.DragEvent) => {\n if (disabled || !has(e)) return;\n e.preventDefault();\n depth.current = 0; setOver(false);\n const picked = multiple ? Array.from(e.dataTransfer.files) : Array.from(e.dataTransfer.files).slice(0, 1);\n const { accepted, rejected } = filterFiles(picked, { accept, maxFileSize });\n if (rejected.length && onReject) onReject(rejected);\n if (accepted.length && onFiles) onFiles(accepted);\n };\n\n return (\n <div\n className={[\"fd-dropzone\", over ? \"is-over\" : \"\", className].filter(Boolean).join(\" \")}\n style={style}\n onDragEnter={enter} onDragLeave={leave} onDragOver={over_} onDrop={drop}\n >\n {children}\n {over ? (\n <div className=\"fd-dropzone-veil\" aria-hidden=\"true\">\n <div className=\"fd-dropzone-card\">\n <i className=\"ph ph-tray-arrow-down\" />\n <span className=\"fd-dropzone-label\">{label}</span>\n {hint ? <span className=\"fd-dropzone-hint\">{hint}</span> : null}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nexport interface FilePickButtonProps extends Omit<DropzoneProps, \"children\" | \"label\" | \"hint\" | \"style\"> { label?: string; icon?: string; children?: React.ReactNode }\n\n/** A file input behind any trigger. Resets between picks so re-picking the same file fires. */\nexport function FilePickButton({\n onFiles, onReject, accept, maxFileSize, multiple = true, disabled,\n label = \"Attach files\", icon = \"paperclip\", className = \"\", children,\n}: FilePickButtonProps) {\n const ref = React.useRef<HTMLInputElement>(null);\n return (\n <React.Fragment>\n <button\n type=\"button\" className={[\"fd-attachbtn\", className].filter(Boolean).join(\" \")} disabled={disabled}\n aria-label={label} title={label} onClick={() => ref.current && ref.current.click()}\n >\n {children != null ? children : <i className={\"ph ph-\" + icon} aria-hidden=\"true\" />}\n </button>\n <input\n ref={ref} type=\"file\" accept={accept} multiple={multiple} className=\"fd-sr\"\n onChange={(e) => {\n const { accepted, rejected } = filterFiles(e.target.files as FileList, { accept, maxFileSize });\n if (rejected.length && onReject) onReject(rejected);\n if (accepted.length && onFiles) onFiles(accepted);\n e.target.value = \"\";\n }}\n />\n </React.Fragment>\n );\n}\n\nexport type FileUploadHandler = (file: File, onProgress: (pct: number) => void, signal?: AbortSignal) => Promise<{ url: string; thumb?: { url: string } } | void>;\n\n/**\n * Upload orchestration for a staged set of files: progress per file, per-file\n * errors, retry, and cancel — the same behaviour an upload field has.\n *\n * `upload(file, onProgress, signal)` must resolve to `{url, thumb?}` or throw.\n * Nothing here knows what a chat is; it is the app's upload handler that does.\n */\nexport function useStagedFiles(\n upload?: FileUploadHandler,\n opts?: { onUploaded?: (a: Attachment) => void; onError?: (e: unknown, a: Attachment) => void }\n): {\n items: Attachment[];\n add: (files: File[] | FileList) => Attachment[];\n remove: (a: Attachment) => void;\n retry: (a: Attachment) => void;\n clear: () => void;\n busy: boolean;\n setItems: (items: Attachment[]) => void;\n} {\n const o = opts || {};\n const [items, setItems] = React.useState<Attachment[]>([]);\n const controllers = React.useRef<Record<string, AbortController | null>>({});\n\n const patch = (id: string, next: Partial<Attachment>) => setItems((list) => list.map((f) => (f.id === id ? Object.assign({}, f, next) : f)));\n\n const run = React.useCallback((att: Attachment) => {\n if (!upload) return;\n const ac = typeof AbortController !== \"undefined\" ? new AbortController() : null;\n controllers.current[att.id] = ac;\n patch(att.id, { progress: 0, error: undefined });\n Promise.resolve()\n .then(() => upload!(att.file as File, (p) => patch(att.id, { progress: Math.max(0, Math.min(99, p)) }), ac ? ac.signal : undefined))\n .then((res) => {\n const r = res || {};\n patch(att.id, { progress: 100, url: (r as any).url || att.url, thumb: (r as any).thumb || att.thumb, error: undefined, remote: true } as any);\n o.onUploaded && o.onUploaded(att);\n })\n .catch((err) => {\n if (ac && ac.signal.aborted) return;\n patch(att.id, { progress: null, error: (err && err.message) || \"Upload failed\" } as any);\n o.onError && o.onError(err, att);\n })\n .finally(() => { delete controllers.current[att.id]; });\n }, [upload]);\n\n const add = React.useCallback((files: File[] | FileList) => {\n if (!upload) return []; // nowhere to put it: refuse rather than strand it\n const atts = Array.from(files).map((f) => toAttachment(f));\n setItems((list) => list.concat(atts));\n atts.forEach(run);\n return atts;\n }, [upload, run]);\n\n const remove = React.useCallback((att: Attachment) => {\n const ac = controllers.current[att.id];\n if (ac) { try { ac.abort(); } catch (_e) { /* noop */ } delete controllers.current[att.id]; }\n setItems((list) => list.filter((f) => f.id !== att.id));\n }, []);\n\n const retry = React.useCallback((att: Attachment) => { run(att); }, [run]);\n const clear = React.useCallback(() => {\n Object.values(controllers.current).forEach((ac) => { try { ac && ac.abort(); } catch (_e) { /* noop */ } });\n controllers.current = {};\n setItems([]);\n }, []);\n\n const busy = items.some((f) => f.progress != null && f.progress < 100 && !f.error);\n return { items, add, remove, retry, clear, busy, setItems };\n}\n\n/** Namespace export — useStagedFiles is a hook, so it cannot be capital-initial itself. */\nexport const DropzoneKit = { useStagedFiles };\n","import * as React from \"react\";\nimport { formatBytes, iconForMime, isImage } from \"../../kits/files\";\nimport type { Attachment } from \"../../kits/files\";\n\nconst truncateMiddle = (name: string, max = 34) => {\n if (!name || name.length <= max) return name;\n const ext = /\\.[A-Za-z0-9]+$/.exec(name);\n const tail = ext ? ext[0] : \"\";\n const head = name.slice(0, Math.max(6, max - tail.length - 2));\n return head + \"…\" + tail;\n};\n\nfunction Progress({ value }: { value: number }) {\n return (\n <span className=\"fd-file-prog\" role=\"progressbar\" aria-valuenow={Math.round(value)} aria-valuemin={0} aria-valuemax={100}>\n <span className=\"fd-file-prog-fill\" style={{ width: Math.max(4, Math.min(100, value)) + \"%\" }} />\n </span>\n );\n}\n\nexport interface FileChipProps { file: Attachment; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void; compact?: boolean; className?: string }\n\n/**\n * A compact file row: icon or thumbnail, name, size, live upload progress,\n * error state, and an optional remove control. One file component everywhere —\n * images get real thumbnails, video gets a play badge, uploads get a bar.\n */\nexport function FileChip({ file, onOpen, onRemove, onRetry, compact = false, className = \"\" }: FileChipProps) {\n if (!file) return null;\n const uploading = file.progress != null && file.progress < 100 && !file.error;\n const image = isImage(file.mime, file.name);\n const thumb = (file.thumb && file.thumb.url) || (image ? file.blobUrl || file.url : null);\n const meta = file.meta || (file.size ? formatBytes(file.size) : \"\");\n const clickable = !!onOpen && !uploading;\n\n return (\n <div className={[\"fd-file\", compact ? \"is-compact\" : \"\", file.error ? \"is-error\" : \"\", uploading ? \"is-uploading\" : \"\", className].filter(Boolean).join(\" \")}>\n <button\n type=\"button\" className=\"fd-file-main\" disabled={!clickable}\n onClick={clickable ? () => onOpen!(file) : undefined}\n title={file.name + (meta ? \" · \" + meta : \"\")}\n >\n <span className=\"fd-file-icon\">\n {thumb ? <img src={thumb} alt=\"\" /> : <i className={\"ph ph-\" + iconForMime(file.mime, file.name)} aria-hidden=\"true\" />}\n {(file.mime || \"\").startsWith(\"video/\") ? <i className=\"ph ph-play fd-file-play\" aria-hidden=\"true\" /> : null}\n </span>\n <span className=\"fd-file-text\">\n <span className=\"fd-file-name\">{truncateMiddle(file.name, compact ? 26 : 40)}</span>\n <span className=\"fd-file-meta\">\n {file.error\n ? <span className=\"fd-file-err\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{file.error}</span>\n : uploading ? <span className=\"fd-tabular\">{Math.round(file.progress as number)}% uploaded</span>\n : meta}\n </span>\n </span>\n </button>\n {uploading ? <Progress value={file.progress as number} /> : null}\n {file.error && onRetry ? (\n <button type=\"button\" className=\"fd-file-act\" onClick={() => onRetry!(file)} aria-label={\"Retry upload of \" + file.name}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {onRemove ? (\n <button type=\"button\" className=\"fd-file-act\" onClick={() => onRemove!(file)} aria-label={\"Remove \" + file.name}>\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n );\n}\n\nexport interface FileTileProps { file: Attachment; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; maxHeight?: number; className?: string }\n\n/**\n * An image-forward tile. Pasted screenshots belong here, not in a chip —\n * the picture is the content.\n */\nexport function FileTile({ file, onOpen, onRemove, maxHeight = 200, className = \"\" }: FileTileProps) {\n if (!file) return null;\n const src = (file.thumb && file.thumb.url) || file.blobUrl || file.url;\n const uploading = file.progress != null && file.progress < 100 && !file.error;\n return (\n <figure className={[\"fd-tile\", uploading ? \"is-uploading\" : \"\", file.error ? \"is-error\" : \"\", className].filter(Boolean).join(\" \")}>\n <button type=\"button\" className=\"fd-tile-btn\" onClick={onOpen ? () => onOpen!(file) : undefined} disabled={!onOpen}>\n {src ? <img src={src} alt={file.name || \"\"} style={{ maxHeight }} loading=\"lazy\" />\n : <span className=\"fd-tile-fallback\"><i className={\"ph ph-\" + iconForMime(file.mime, file.name)} aria-hidden=\"true\" /></span>}\n </button>\n {uploading ? <Progress value={file.progress as number} /> : null}\n {file.error ? <figcaption className=\"fd-tile-err\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{file.error}</figcaption> : null}\n {onRemove ? (\n <button type=\"button\" className=\"fd-tile-x\" onClick={() => onRemove!(file)} aria-label={\"Remove \" + file.name}>\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </figure>\n );\n}\n\n/**\n * One row of uniform tiles — the staging tray. Same size whatever the type:\n * images crop to fill, documents show a truncated name and their size.\n * Overflow scrolls sideways instead of growing the tray.\n */\nexport interface FileStripProps { files: Attachment[]; size?: number; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void; className?: string }\n\nexport function FileStrip({ files = [], size = 68, onOpen, onRemove, onRetry, className = \"\" }: FileStripProps) {\n const list = files.filter(Boolean);\n if (!list.length) return null;\n return (\n <div className={[\"fd-filestrip\", \"fd-scrollbar\", className].filter(Boolean).join(\" \")} style={{ \"--fd-cell\": size + \"px\" } as React.CSSProperties}>\n {list.map((f) => <FileCell key={f.id || f.name} file={f} onOpen={onOpen} onRemove={onRemove} onRetry={onRetry} />)}\n </div>\n );\n}\n\nconst shortName = (name: string, keep = 5) => {\n const s = String(name || \"file\");\n const ext = /\\.([A-Za-z0-9]{1,5})$/.exec(s);\n const tail = ext ? \".\" + ext[1] : \"\";\n const stem = tail ? s.slice(0, -tail.length) : s;\n return stem.length > keep ? stem.slice(0, keep) + \"…\" + tail : stem + tail;\n};\n\ninterface FileCellProps { file: Attachment; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void }\n\nfunction FileCell({ file, onOpen, onRemove, onRetry }: FileCellProps) {\n const uploading = file.progress != null && file.progress < 100 && !file.error;\n const image = isImage(file.mime, file.name);\n const thumb = (file.thumb && file.thumb.url) || (image ? file.blobUrl || file.url : null);\n const label = file.name + (file.size ? \" · \" + formatBytes(file.size) : \"\");\n return (\n <div className={[\"fd-cell\", file.error ? \"is-error\" : \"\", uploading ? \"is-uploading\" : \"\"].filter(Boolean).join(\" \")} title={file.error ? file.name + \" — \" + file.error : label}>\n <button type=\"button\" className=\"fd-cell-main\" onClick={onOpen ? () => onOpen!(file) : undefined} disabled={!onOpen || uploading} aria-label={\"Open \" + file.name}>\n {thumb ? <img src={thumb} alt=\"\" /> : (\n <span className=\"fd-cell-doc\">\n <i className={\"ph ph-\" + iconForMime(file.mime, file.name)} aria-hidden=\"true\" />\n <span className=\"fd-cell-name\">{shortName(file.name)}</span>\n <span className=\"fd-cell-size\">{file.meta || formatBytes(file.size)}</span>\n </span>\n )}\n {(file.mime || \"\").startsWith(\"video/\") ? <i className=\"ph ph-play fd-cell-play\" aria-hidden=\"true\" /> : null}\n </button>\n {uploading ? <Progress value={file.progress as number} /> : null}\n {file.error ? (\n <span className=\"fd-cell-err\" aria-hidden=\"true\"><i className=\"ph ph-warning-circle\" /></span>\n ) : null}\n {file.error && onRetry ? (\n <button type=\"button\" className=\"fd-cell-x is-retry\" onClick={() => onRetry!(file)} aria-label={\"Retry upload of \" + file.name}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {onRemove ? (\n <button type=\"button\" className=\"fd-cell-x\" onClick={() => onRemove!(file)} aria-label={\"Remove \" + file.name}>\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n );\n}\n\n/** Images as tiles, everything else as chips. */\nexport interface FileGridProps { files: Attachment[]; onOpen?: (f: Attachment) => void; onRemove?: (f: Attachment) => void; onRetry?: (f: Attachment) => void; tiles?: boolean; maxHeight?: number; compact?: boolean; className?: string }\n\n/**\n * A set of files: images as tiles, everything else as chips.\n * `tiles={false}` forces the compact all-chips form for tight columns.\n */\nexport function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeight = 200, compact = false, className = \"\" }: FileGridProps) {\n const list = files.filter(Boolean);\n if (!list.length) return null;\n const pics = tiles ? list.filter((f) => isImage(f.mime, f.name)) : [];\n const rest = list.filter((f) => pics.indexOf(f) === -1);\n return (\n <div className={[\"fd-filegrid\", className].filter(Boolean).join(\" \")}>\n {pics.length ? (\n <div className=\"fd-filegrid-tiles\">\n {pics.map((f) => <FileTile key={f.id || f.name} file={f} onOpen={onOpen} onRemove={onRemove} maxHeight={maxHeight} />)}\n </div>\n ) : null}\n {rest.length ? (\n <div className=\"fd-filegrid-chips\">\n {rest.map((f) => <FileChip key={f.id || f.name} file={f} onOpen={onOpen} onRemove={onRemove} onRetry={onRetry} compact={compact} />)}\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\n\n/* ── rich markdown composer ────────────────────────────────────────────────\n A contenteditable whose text content is EXACTLY the markdown source, one\n element per line. Because the caret lives in the real text, decoration is\n free: headings can be bigger, bold can be bold, quotes can be indented —\n there is no mirror to keep in metric lockstep. Markers stay in the text\n (dimmed), so what you typed is always what gets sent.\n\n All structural input — Enter, paste, line breaks — is intercepted, and the\n DOM is re-synced line by line after every change, so the browser never gets\n to invent nested divs. */\n\nconst isMac = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || \"\");\n\nconst INLINE_RE = /(\\*\\*\\*[^*\\n]+\\*\\*\\*|\\*\\*[^*\\n]+\\*\\*|__[^_\\n]+__|~~[^~\\n]+~~|`[^`\\n]+`|\\*[^*\\s][^*\\n]*\\*|(?<![A-Za-z0-9_])_[^_\\s][^_\\n]*_|\\[[^\\]\\n]*\\]\\([^)\\s\\n]*\\)|https?:\\/\\/\\S+)/g;\n\n/** [text, className] pairs whose concatenation equals the input, exactly. */\nfunction inlineParts(text: string): Array<[string, string]> {\n const out: Array<[string, string]> = [];\n let last = 0, m: RegExpExecArray | null;\n INLINE_RE.lastIndex = 0;\n while ((m = INLINE_RE.exec(text))) {\n if (m.index > last) out.push([text.slice(last, m.index), \"\"]);\n const tk = m[0];\n const wrap = (n: number, cls: string) => { out.push([tk.slice(0, n), \"rme-mk\"], [tk.slice(n, tk.length - n), cls], [tk.slice(tk.length - n), \"rme-mk\"]); };\n if (/^\\*\\*\\*/.test(tk)) wrap(3, \"rme-b rme-i\");\n else if (/^\\*\\*/.test(tk) || /^__/.test(tk)) wrap(2, \"rme-b\");\n else if (/^~~/.test(tk)) wrap(2, \"rme-s\");\n else if (/^`/.test(tk)) wrap(1, \"rme-c\");\n else if (/^\\[/.test(tk)) {\n const cut = tk.indexOf(\"](\");\n out.push([\"[\", \"rme-mk\"], [tk.slice(1, cut), \"rme-lk\"], [tk.slice(cut, tk.length), \"rme-mk\"]);\n } else if (/^https?:/.test(tk)) out.push([tk, \"rme-lk\"]);\n else wrap(1, \"rme-i\");\n last = m.index + tk.length;\n }\n if (last < text.length) out.push([text.slice(last), \"\"]);\n return out.filter((p) => p[0] !== \"\");\n}\n\nconst RE_H = /^(#{1,6})(\\s+)(.*)$/;\nconst RE_LI = /^(\\s*)([-*+]|\\d{1,3}[.)])(\\s+)(\\[[ xX]\\]\\s+)?(.*)$/;\nconst RE_Q = /^(\\s*)(>+)(\\s*)(.*)$/;\nconst RE_FENCE = /^\\s*(```|~~~)(.*)$/;\n\n/** Build one line element. Its textContent is the source line, character for character. */\nfunction buildLine(doc: Document, line: string, inFence: boolean): HTMLElement {\n const el = doc.createElement(\"div\");\n el.className = \"fd-rme-line\";\n el.setAttribute(\"data-src\", line);\n const put = (text: string, cls: string) => {\n if (!text) return;\n if (!cls) { el.appendChild(doc.createTextNode(text)); return; }\n const s = doc.createElement(\"span\");\n s.className = cls;\n s.textContent = text;\n el.appendChild(s);\n };\n\n const fence = RE_FENCE.exec(line);\n if (fence || inFence) {\n el.classList.add(\"is-code\");\n if (fence) { put(fence[1], \"rme-mk\"); put(fence[2], \"rme-lang\"); }\n else put(line, \"\");\n if (!line) el.appendChild(doc.createElement(\"br\"));\n return el;\n }\n\n const h = RE_H.exec(line);\n if (h) {\n el.classList.add(\"is-h\" + h[1].length);\n put(h[1], \"rme-mk\"); put(h[2], \"rme-mk\");\n inlineParts(h[3]).forEach(([t, c]) => put(t, c));\n return el;\n }\n const q = RE_Q.exec(line);\n if (q && q[2]) {\n el.classList.add(\"is-quote\");\n put(q[1], \"\"); put(q[2] + q[3], \"rme-mk\");\n inlineParts(q[4]).forEach(([t, c]) => put(t, c));\n return el;\n }\n const li = RE_LI.exec(line);\n if (li) {\n el.classList.add(\"is-li\");\n if (li[1]) el.style.paddingLeft = (li[1].length * 8) + \"px\";\n put(li[1], \"\"); put(li[2], \"rme-bullet\"); put(li[3], \"rme-mk\");\n if (li[4]) put(li[4], /x/i.test(li[4]) ? \"rme-task is-done\" : \"rme-task\");\n inlineParts(li[5]).forEach(([t, c]) => put(t, c));\n return el;\n }\n if (/^\\s*\\|/.test(line)) {\n el.classList.add(\"is-table\");\n put(line, \"\");\n return el;\n }\n if (/^\\s*(?:[-*_]\\s*){3,}$/.test(line)) {\n el.classList.add(\"is-rule\");\n put(line, \"rme-mk\");\n return el;\n }\n\n const parts = inlineParts(line);\n if (!parts.length) el.appendChild(doc.createElement(\"br\"));\n else parts.forEach(([t, c]) => put(t, c));\n return el;\n}\n\n/* ── caret <-> character offset ─────────────────────────────────────────────\n One walk produces both the source text and the offsets of the selection\n endpoints, so the two can never disagree. It tolerates a flattened DOM\n (select-all-and-type, autocorrect, drag-drop) because the next sync rebuilds\n the structure from the text it read. */\n\nconst IS_BLOCK = (n: Node): boolean => n.nodeType === 1 && /^(DIV|P|LI|H[1-6]|BLOCKQUOTE|PRE|SECTION)$/.test((n as Element).tagName);\n\nconst lineTextOf = (el: Element): string => {\n let s = \"\";\n el.childNodes.forEach((n) => { s += (n.nodeType === 1 && (n as Element).tagName === \"BR\") ? \"\" : (n.textContent || \"\"); });\n return s;\n};\n\ninterface CaretPoint { node: Node; offset: number }\n\nfunction readDom(root: Element, points?: Array<CaretPoint | null | undefined>): { text: string; points: number[] } {\n const pts = points || [];\n const out: Array<number | null> = pts.map(() => null);\n let text = \"\";\n\n const hit = (node: Node, resolve: (offset: number) => number) => {\n pts.forEach((p, i) => { if (out[i] == null && p && p.node === node) out[i] = resolve(p.offset); });\n };\n const childPrefix = (el: Element, upto: number) => {\n let n = 0;\n for (let j = 0; j < upto && j < el.childNodes.length; j++) {\n const c = el.childNodes[j];\n n += (c.nodeType === 1 && (c as Element).tagName === \"BR\") ? 0 : (c.textContent || \"\").length;\n }\n return n;\n };\n\n const walkInline = (el: Element) => {\n el.childNodes.forEach((n) => {\n if (n.nodeType === 3) {\n hit(n, (o) => text.length + Math.min(o, (n as Text).nodeValue!.length));\n text += (n as Text).nodeValue;\n } else if (n.nodeType === 1 && (n as Element).tagName !== \"BR\") {\n hit(n, (o) => text.length + childPrefix(n as Element, o));\n walkInline(n as Element);\n }\n });\n };\n\n const children = Array.from(root.childNodes);\n let first = true;\n children.forEach((n) => {\n if (IS_BLOCK(n)) {\n if (!first) text += \"\\n\";\n first = false;\n hit(n, (o) => text.length + childPrefix(n as Element, o));\n walkInline(n as Element);\n } else if (n.nodeType === 1 && (n as Element).tagName === \"BR\") {\n text += \"\\n\";\n first = false;\n } else {\n first = false;\n hit(n, (o) => text.length + Math.min(o || 0, ((n as Text).nodeValue || \"\").length));\n text += n.textContent || \"\";\n }\n });\n\n // a caret dropped on the root itself addresses a child index\n pts.forEach((p, i) => {\n if (out[i] != null || !p || p.node !== root) return;\n let t = 0;\n for (let j = 0; j < p.offset && j < children.length; j++) {\n const c = children[j];\n t += IS_BLOCK(c) ? (j ? 1 : 0) + lineTextOf(c as Element).length : (c.textContent || \"\").length;\n }\n out[i] = t;\n });\n\n return { text, points: out.map((v) => (v == null ? text.length : v)) };\n}\n\nfunction placeCaret(root: Element, offset: number): void {\n const lines = Array.from(root.children);\n let remaining = Math.max(0, offset);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const len = (line.textContent || \"\").length;\n if (remaining <= len || i === lines.length - 1) {\n const walker = document.createTreeWalker(line, NodeFilter.SHOW_TEXT);\n let t: Node | null, seen = 0, target: Text | null = null, targetOffset = 0;\n while ((t = walker.nextNode())) {\n const L = (t as Text).nodeValue!.length;\n if (seen + L >= remaining) { target = t as Text; targetOffset = Math.min(L, remaining - seen); break; }\n seen += L; target = t as Text; targetOffset = L;\n }\n const sel = window.getSelection();\n const range = document.createRange();\n if (target) range.setStart(target, targetOffset);\n else range.setStart(line, 0);\n range.collapse(true);\n sel!.removeAllRanges();\n sel!.addRange(range);\n return;\n }\n remaining -= len + 1;\n }\n}\n\n/* Structure-tolerant read-back lives in readDom above. */\n\nfunction syncDom(root: Element, value: any): void {\n const lines = String(value == null ? \"\" : value).split(\"\\n\");\n const doc = root.ownerDocument;\n let inFence = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const wasFence = inFence;\n if (RE_FENCE.test(line)) inFence = !inFence;\n const existing = root.children[i];\n const key = (wasFence ? \"1|\" : \"0|\") + line;\n if (existing && existing.getAttribute(\"data-key\") === key) continue;\n const next = buildLine(doc, line, wasFence);\n next.setAttribute(\"data-key\", key);\n if (existing) root.replaceChild(next, existing);\n else root.appendChild(next);\n }\n while (root.children.length > lines.length) root.removeChild(root.lastChild as Node);\n}\n\nconst LIST_CONT = RE_LI;\n\nexport interface MarkdownEditorHandle {\n focus(opts?: FocusOptions): void;\n blur(): void;\n readonly element: HTMLElement | null;\n getSelection(): { start: number; end: number };\n replaceRange(start: number, end: number, text: string, caretAt?: number): void;\n insert(text: string): void;\n wrapSelection(before: string, after?: string, placeholder?: string): void;\n prefixLines(prefix: string): void;\n}\nexport interface EditorTrigger { type: \"slash\" | \"mention\"; query: string; from: number; to: number }\n\n/**\n * Rich markdown composer. A contenteditable whose text content IS the markdown\n * source, one element per line — so headings can be bigger and bold can be bold\n * without a mirror to keep in metric lockstep.\n *\n * Keydown ordering contract: the host sees the event FIRST (onKeyDown), may call\n * preventDefault(), and the editor then checks defaultPrevented and skips its own\n * handling. onPaste follows the same contract.\n */\nexport interface MarkdownEditorProps {\n value: string;\n onChange?: (next: string) => void;\n onSubmit?: (value: string) => void;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onPaste?: (e: React.ClipboardEvent) => void;\n onTrigger?: (t: EditorTrigger | null) => void;\n placeholder?: string;\n disabled?: boolean;\n readOnly?: boolean;\n maxLength?: number;\n minRows?: number;\n maxRows?: number;\n autoFocus?: boolean;\n /** Enter sends, Shift+Enter inserts a newline. Default true. */\n submitOnEnter?: boolean;\n ariaLabel?: string;\n className?: string;\n id?: string;\n}\n\n/**\n * The composer field.\n *\n * Keydown ordering contract — the host sees the event FIRST:\n * editor emits onKeyDown → host may call preventDefault()\n * → editor checks event.defaultPrevented and skips its own handling\n * Emitting after the internal handler would make the host's preventDefault\n * arrive too late. onPaste follows the same contract.\n */\nexport const MarkdownEditor = React.forwardRef<MarkdownEditorHandle, MarkdownEditorProps>(function MarkdownEditor({\n value = \"\", onChange, onSubmit, onKeyDown, onPaste, onTrigger,\n placeholder = \"\", disabled = false, readOnly = false, maxLength,\n minRows = 1, maxRows = 12, autoFocus = false,\n submitOnEnter = true, ariaLabel = \"Message\", className = \"\", id,\n}, ref) {\n const boxRef = React.useRef<HTMLDivElement>(null);\n const composing = React.useRef(false);\n const pendingCaret = React.useRef<number | null>(null);\n\n /* keep the DOM in step with `value`, then restore the caret */\n React.useLayoutEffect(() => {\n const root = boxRef.current;\n if (!root || composing.current) return;\n const active = document.activeElement === root || root.contains(document.activeElement);\n syncDom(root, value);\n const caret = pendingCaret.current;\n pendingCaret.current = null;\n if (active && caret != null) placeCaret(root, caret);\n }, [value]);\n\n React.useEffect(() => { if (autoFocus && boxRef.current) boxRef.current.focus(); }, [autoFocus]);\n\n const caretNow = (): number => {\n const root = boxRef.current;\n const sel = window.getSelection();\n if (!root || !sel || !sel.rangeCount) return 0;\n const r = sel.getRangeAt(0);\n return readDom(root, [{ node: r.startContainer, offset: r.startOffset }]).points[0];\n };\n\n const selectionNow = (): { start: number; end: number } => {\n const root = boxRef.current;\n const sel = window.getSelection();\n if (!root || !sel || !sel.rangeCount) return { start: value.length, end: value.length };\n const r = sel.getRangeAt(0);\n const read = readDom(root, [{ node: r.startContainer, offset: r.startOffset }, { node: r.endContainer, offset: r.endOffset }]);\n const [a, b] = read.points;\n return { start: Math.min(a, b), end: Math.max(a, b) };\n };\n\n const commit = (next: string, caret?: number | null) => {\n if (maxLength && next.length > maxLength) return;\n pendingCaret.current = caret == null ? null : caret;\n onChange && onChange(next);\n if (onTrigger) detect(next, caret == null ? next.length : caret);\n };\n\n const api: MarkdownEditorHandle = {\n focus: (o) => boxRef.current && boxRef.current.focus(o),\n blur: () => { boxRef.current && boxRef.current.blur(); },\n get element() { return boxRef.current; },\n getSelection: selectionNow,\n replaceRange: (start, end, text, caretAt) => {\n const next = value.slice(0, start) + text + value.slice(end);\n commit(next, caretAt == null ? start + text.length : caretAt);\n },\n insert: (text) => { const s = selectionNow(); api.replaceRange(s.start, s.end, text); },\n wrapSelection: (before, after, placeholderText) => {\n const s = selectionNow();\n const sel = value.slice(s.start, s.end);\n const close = after == null ? before : after;\n const already = value.slice(s.start - before.length, s.start) === before && value.slice(s.end, s.end + close.length) === close;\n if (already) {\n const next = value.slice(0, s.start - before.length) + sel + value.slice(s.end + close.length);\n commit(next, s.start - before.length + sel.length);\n return;\n }\n const inner = sel || placeholderText || \"\";\n const next = value.slice(0, s.start) + before + inner + close + value.slice(s.end);\n commit(next, sel ? s.start + before.length + inner.length + close.length : s.start + before.length + inner.length);\n },\n prefixLines: (prefix) => {\n const s = selectionNow();\n const from = value.lastIndexOf(\"\\n\", Math.max(0, s.start - 1)) + 1;\n const toRaw = value.indexOf(\"\\n\", s.end);\n const to = toRaw === -1 ? value.length : toRaw;\n const block = value.slice(from, to);\n const on = block.split(\"\\n\").every((l) => !l.trim() || l.startsWith(prefix));\n const next = block.split(\"\\n\").map((l) => (on ? l.replace(prefix, \"\") : prefix + l)).join(\"\\n\");\n api.replaceRange(from, to, next, from + next.length);\n },\n };\n React.useImperativeHandle(ref, () => api);\n\n /* trigger detection: / at line start, @ anywhere */\n function detect(text: string, caret: number) {\n if (!onTrigger) return;\n const upto = text.slice(0, caret);\n const line = upto.slice(upto.lastIndexOf(\"\\n\") + 1);\n const slash = /^\\/([\\w-]*)$/.exec(line);\n if (slash) { onTrigger({ type: \"slash\", query: slash[1], from: caret - slash[0].length, to: caret }); return; }\n const at = /(?:^|\\s)@([\\w./-]*)$/.exec(upto);\n if (at) { const tok = at[0].replace(/^\\s/, \"\"); onTrigger({ type: \"mention\", query: at[1], from: caret - tok.length, to: caret }); return; }\n onTrigger(null);\n }\n\n const newlineAtCaret = () => {\n const s = selectionNow();\n const lineStart = value.lastIndexOf(\"\\n\", Math.max(0, s.start - 1)) + 1;\n const line = value.slice(lineStart, s.start);\n const li = LIST_CONT.exec(line);\n const q = RE_Q.exec(line);\n if (li && li[5].trim()) {\n const bullet = /\\d/.test(li[2]) ? (parseInt(li[2], 10) + 1) + li[2].replace(/\\d+/, \"\") : li[2];\n const ins = \"\\n\" + li[1] + bullet + li[3] + (li[4] ? \"[ ] \" : \"\");\n api.replaceRange(s.start, s.end, ins);\n return;\n }\n if (li && !li[5].trim()) { api.replaceRange(lineStart, s.end, \"\", lineStart); return; }\n if (q && q[2] && q[4].trim()) { api.replaceRange(s.start, s.end, \"\\n\" + q[1] + q[2] + q[3]); return; }\n api.replaceRange(s.start, s.end, \"\\n\");\n };\n\n const keydown = (e: React.KeyboardEvent) => {\n onKeyDown && onKeyDown(e); // host first\n if (e.defaultPrevented) return;\n if ((e as unknown as { isComposing?: boolean }).isComposing || e.keyCode === 229) { composing.current = true; return; }\n\n const mod = isMac ? e.metaKey : e.ctrlKey;\n if (mod && !e.altKey) {\n const k = e.key.toLowerCase();\n if (k === \"b\") { e.preventDefault(); api.wrapSelection(\"**\", \"**\", \"bold\"); return; }\n if (k === \"i\") { e.preventDefault(); api.wrapSelection(\"_\", \"_\", \"italic\"); return; }\n if (k === \"e\") { e.preventDefault(); api.wrapSelection(\"`\", \"`\", \"code\"); return; }\n if (k === \"k\") {\n e.preventDefault();\n const s = selectionNow();\n const sel = value.slice(s.start, s.end) || \"text\";\n api.replaceRange(s.start, s.end, \"[\" + sel + \"](url)\", s.start + sel.length + 3);\n return;\n }\n }\n\n if (e.key === \"Enter\") {\n e.preventDefault(); // we own every line break\n if (e.shiftKey || !submitOnEnter) newlineAtCaret();\n else onSubmit && onSubmit(value);\n return;\n }\n if (e.key === \"Tab\") {\n const s = selectionNow();\n const fences = (value.slice(0, s.start).match(/```|~~~/g) || []).length;\n const line = value.slice(value.lastIndexOf(\"\\n\", Math.max(0, s.start - 1)) + 1, s.start);\n if (fences % 2 === 1 || RE_LI.test(line)) { e.preventDefault(); api.insert(\" \"); }\n }\n };\n\n const beforeInput = (e: React.FormEvent<HTMLDivElement> & { inputType?: string }) => {\n if (e.inputType === \"insertParagraph\" || e.inputType === \"insertLineBreak\") {\n e.preventDefault();\n newlineAtCaret();\n }\n };\n\n const input = () => {\n const root = boxRef.current;\n if (!root || composing.current) return;\n const sel = window.getSelection();\n const r = sel && sel.rangeCount ? sel.getRangeAt(0) : null;\n const read = readDom(root, r ? [{ node: r.startContainer, offset: r.startOffset }] : []);\n commit(read.text, r ? read.points[0] : read.text.length);\n };\n\n const paste = (e: React.ClipboardEvent) => {\n onPaste && onPaste(e); // host first — it may turn this into a file\n if (e.defaultPrevented) return;\n const text = e.clipboardData && e.clipboardData.getData(\"text/plain\");\n if (text == null) return;\n e.preventDefault(); // plain text only: never accept pasted HTML\n const s = selectionNow();\n api.replaceRange(s.start, s.end, text.replace(/\\r\\n?/g, \"\\n\"));\n };\n\n const lh = 1.55;\n return (\n <div className={[\"fd-rme-wrap\", disabled ? \"is-disabled\" : \"\", className].filter(Boolean).join(\" \")}>\n <div\n ref={boxRef} id={id} className=\"fd-rme\"\n contentEditable={!disabled && !readOnly}\n suppressContentEditableWarning\n role=\"textbox\" aria-multiline=\"true\" aria-label={ariaLabel}\n spellCheck={true} autoCapitalize=\"sentences\"\n style={{ minHeight: (minRows * lh) + \"em\", maxHeight: (maxRows * lh) + \"em\" }}\n onKeyDown={keydown}\n onBeforeInput={beforeInput as any}\n onInput={input}\n onPaste={paste}\n onCompositionStart={() => { composing.current = true; }}\n onCompositionEnd={() => { composing.current = false; input(); }}\n onKeyUp={() => { if (onTrigger) detect(value, caretNow()); }}\n onClick={() => { if (onTrigger) detect(value, caretNow()); }}\n />\n {!value ? <span className=\"fd-rme-ph\" aria-hidden=\"true\">{placeholder}</span> : null}\n </div>\n );\n});\n","import * as React from \"react\";\nimport { Popover } from \"../actions/Popover\";\nimport { Avatar } from \"../feedback/Avatar\";\nimport { Badge } from \"../feedback/Badge\";\nimport { SessionKit } from \"../../kits/session\";\n\n/* The account menu every flytedesk app puts in its top right.\n\n Drop-in: <AccountMenu onNavigate={(href) => …} /> renders the signed-in user from\n SessionKit and shows an Administration section only to those who can reach it — a menu\n full of items that error on click is worse than a shorter menu.\n\n `links` and `adminLinks` are overridable so each app can add its own destinations\n without forking the component. */\n\nexport interface AccountMenuLink {\n id: string; label: string; icon: string;\n href?: string;\n /** Hidden unless the signed-in user holds this permission. */\n perm?: string;\n badge?: string;\n onSelect?: () => void;\n}\nexport interface AccountMenuProps {\n links?: AccountMenuLink[];\n /** Administration section. Each entry is filtered by its own `perm`. */\n adminLinks?: AccountMenuLink[];\n /** Preferred over href navigation — lets an SPA route without a page load. */\n onNavigate?: (href: string | undefined, item: AccountMenuLink) => void;\n onSignOut?: () => void;\n showRoles?: boolean;\n /** Demo affordance: impersonate another member to see their UI. Default true. */\n allowUserSwitch?: boolean;\n className?: string;\n}\n\nconst DEFAULT_LINKS: AccountMenuLink[] = [\n { id: \"profile\", label: \"Your profile\", icon: \"user-circle\", href: \"../admin/index.html#profile\" },\n { id: \"preferences\", label: \"Preferences\", icon: \"sliders-horizontal\", href: \"../admin/index.html#preferences\" }\n];\n\nconst DEFAULT_ADMIN_LINKS: AccountMenuLink[] = [\n { id: \"users\", label: \"Users\", icon: \"users-three\", href: \"../admin/index.html#users\", perm: \"users.view\" },\n { id: \"roles\", label: \"Roles & permissions\", icon: \"shield-check\", href: \"../admin/index.html#roles\", perm: \"roles.manage\" },\n { id: \"flags\", label: \"Feature flags\", icon: \"toggle-right\", href: \"../admin/index.html#flags\", perm: \"flags.manage\" }\n];\n\ninterface ItemProps {\n item: AccountMenuLink;\n onPick: (item: AccountMenuLink) => void;\n}\n\nfunction Item({ item, onPick }: ItemProps) {\n return (\n <button type=\"button\" role=\"menuitem\" className=\"fd-acct-item\"\n onClick={() => onPick(item)}>\n <i className={\"ph ph-\" + item.icon} aria-hidden=\"true\" />\n <span style={{ flex: 1 }}>{item.label}</span>\n {item.badge ? <Badge tone=\"neutral\">{item.badge}</Badge> : null}\n </button>\n );\n}\n\n/**\n * The avatar button + popover every flytedesk app puts in its top right.\n * Reads the signed-in user from SessionKit; shows Administration only to those who can use it.\n */\nexport function AccountMenu({\n links = DEFAULT_LINKS,\n adminLinks = DEFAULT_ADMIN_LINKS,\n onNavigate,\n onSignOut,\n showRoles = true,\n allowUserSwitch = true,\n className = \"\",\n ...rest\n}: AccountMenuProps) {\n const session = SessionKit.useSession();\n const [open, setOpen] = React.useState(false);\n const [switching, setSwitching] = React.useState(false);\n const ref = React.useRef<HTMLButtonElement>(null);\n const user = session.user;\n\n const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));\n const pick = (item: AccountMenuLink) => {\n setOpen(false);\n if (item.onSelect) return item.onSelect();\n if (onNavigate) return onNavigate(item.href, item);\n if (item.href) window.location.href = item.href;\n };\n const signOut = () => {\n setOpen(false);\n if (onSignOut) return onSignOut();\n window.alert(\"Signed out. (Simulated — no auth provider is wired up.)\");\n };\n\n return (\n <>\n <button type=\"button\" ref={ref} className={[\"fd-acct-trigger\", className].filter(Boolean).join(\" \")}\n aria-haspopup=\"menu\" aria-expanded={open} aria-label={\"Account — \" + user.name}\n onClick={() => setOpen((o) => !o)} {...rest}>\n <Avatar name={user.name} size=\"sm\" />\n <i className=\"ph ph-caret-down\" aria-hidden=\"true\" style={{ fontSize: 11, color: \"var(--text-muted)\" }} />\n </button>\n <Popover open={open} anchorRef={ref} onClose={() => setOpen(false)} placement=\"bottom-end\" width={272}>\n <div role=\"menu\" className=\"fd-stack\" style={{ gap: 0 }}>\n <div className=\"fd-row\" style={{ gap: 10, padding: \"12px 14px\", borderBottom: \"1px solid var(--border)\" }}>\n <Avatar name={user.name} />\n <span className=\"fd-stack\" style={{ gap: 1, minWidth: 0, flex: 1 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 700 }}>{user.name}</span>\n <span className=\"fd-body-sm fd-muted fd-table-trunc\">{user.email}</span>\n </span>\n </div>\n\n {showRoles && session.roles.length ? (\n <div className=\"fd-row\" style={{ gap: 6, padding: \"10px 14px\", flexWrap: \"wrap\", borderBottom: \"1px solid var(--border)\" }}>\n {session.roles.map((r) => <Badge key={r.id} tone={r.id === \"owner\" ? \"success\" : \"neutral\"}>{r.name}</Badge>)}\n </div>\n ) : null}\n\n <div className=\"fd-acct-group\">\n {links.map((l) => <Item key={l.id} item={l} onPick={pick} />)}\n </div>\n\n {visibleAdmin.length ? (\n <div className=\"fd-acct-group\" style={{ borderTop: \"1px solid var(--border)\" }}>\n <span className=\"fd-overline fd-muted\" style={{ padding: \"8px 14px 4px\", display: \"block\" }}>Administration</span>\n {visibleAdmin.map((l) => <Item key={l.id} item={l} onPick={pick} />)}\n </div>\n ) : null}\n\n {/* Demo affordance: impersonate another member to see the UI their roles produce.\n A real deployment gates this behind an audited support tool, never a menu. */}\n {allowUserSwitch ? (\n <div className=\"fd-acct-group\" style={{ borderTop: \"1px solid var(--border)\" }}>\n <button type=\"button\" role=\"menuitem\" className=\"fd-acct-item\" onClick={() => setSwitching((s) => !s)}>\n <i className=\"ph ph-user-switch\" aria-hidden=\"true\" />\n <span style={{ flex: 1 }}>View as another member</span>\n <i className={\"ph ph-caret-\" + (switching ? \"up\" : \"down\")} aria-hidden=\"true\" style={{ fontSize: 11 }} />\n </button>\n {switching ? (\n <div className=\"fd-stack\" style={{ gap: 0, maxHeight: 208, overflowY: \"auto\" }}>\n {session.allUsers.filter((u) => u.status === \"active\").map((u) => (\n <button key={u.id} type=\"button\" className=\"fd-acct-item\" data-current={u.id === user.id ? \"true\" : \"false\"}\n onClick={() => { SessionKit.setActiveUser(u.id); setOpen(false); setSwitching(false); }}>\n <Avatar name={u.name} size=\"sm\" />\n <span className=\"fd-stack\" style={{ gap: 0, flex: 1, minWidth: 0, alignItems: \"flex-start\" }}>\n <span style={{ fontWeight: u.id === user.id ? 700 : 500 }}>{u.name}</span>\n <span className=\"fd-muted\" style={{ fontSize: 11.5 }}>{u.roles.join(\", \")}</span>\n </span>\n {u.id === user.id ? <i className=\"ph ph-check\" aria-hidden=\"true\" style={{ color: \"var(--ok-text)\" }} /> : null}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"fd-acct-group\" style={{ borderTop: \"1px solid var(--border)\" }}>\n <button type=\"button\" role=\"menuitem\" className=\"fd-acct-item\" data-danger=\"true\" onClick={signOut}>\n <i className=\"ph ph-sign-out\" aria-hidden=\"true\" />\n <span style={{ flex: 1 }}>Sign out</span>\n </button>\n </div>\n </div>\n </Popover>\n </>\n );\n}\n","import * as React from \"react\";\n\n/* Session, RBAC and feature flags — the front-end half of access control.\n Reusable across every flytedesk project: the planner, the platform app, the admin app.\n\n Nothing here is a security boundary. Permissions gate the UI so people are not shown\n affordances they cannot use; the server must re-check every one of them. A hidden button\n is a courtesy, not a control.\n\n Wire to a real backend by replacing loadSession() with a fetch of\n GET /me → { user, roles, permissions, flags }. Everything else is derived. */\n\nexport interface PermissionItem { key: string; label: string; detail: string }\nexport interface PermissionGroup { group: string; items: PermissionItem[] }\nexport interface Role { id: string; name: string; system: boolean; description: string; permissions: string[] }\nexport interface Flag {\n key: string; project: string; label: string; description: string;\n /** Kill switch. False means off for everyone, whatever the targeting says. */\n enabled: boolean;\n /** 0-100. Bucketed on a stable hash of the user id so answers never flicker. */\n rollout: number;\n /** Role ids the flag is forced on for. */\n roles: string[];\n /** Per-user overrides, highest precedence: { userId: true | false } */\n users: Record<string, boolean>;\n owner?: string; updated?: string;\n /* Not declared in the original session.d.ts (which only covers the fields common to every\n flag record) but present on every entry in FLAGS and read by roadmap() below — filled in\n here from the session.js implementation, same as the six SessionKit members. */\n /** Which screen this flag gates, if any. */\n screen?: string;\n /** Target ship date for an unshipped feature. */\n eta?: string | null;\n /** Date this shipped — set instead of `eta` once it's done. */\n shippedAt?: string;\n /** Build phase index into PHASES. */\n phase?: number;\n /** Human estimate, e.g. \"4 days\". */\n effort?: string;\n /** What has to be built for this to be real. */\n backend?: string;\n /** Other flag keys this depends on. */\n dependsOn?: string[];\n}\nexport interface User {\n id: string; name: string; email: string; title?: string; team?: string;\n roles: string[]; status: \"active\" | \"invited\" | \"suspended\";\n lastActive?: string; joined?: string; sso?: boolean; timezone?: string;\n phone?: string; bio?: string; notify?: Record<string, boolean>;\n}\nexport interface Session {\n user: User; roles: Role[]; permissions: string[];\n /** Resolved flag key → on/off for THIS user. */\n flags: Record<string, boolean>;\n allRoles: Role[]; allFlags: Flag[]; allUsers: User[];\n}\nexport interface FlagExplanation { on: boolean; reason: string; detail: string }\n\n/** One row of the build roadmap. Not declared in session.js's own PHASES shape but inferred\n * from how PHASES entries are constructed and consumed by roadmap() below. */\ninterface Phase { n: number; name: string; start: string; end: string; why: string }\n\n/** roadmap()'s per-flag result row. Not declared in session.d.ts (roadmap() itself is one of\n * the six SessionKit members missing from that file) — inferred from what roadmap() actually\n * builds and returns for each flag. */\nexport interface RoadmapItem {\n key: string; label: string; project: string; description: string;\n backend?: string; effort?: string; owner?: string; dependsOn: string[];\n screen: string | null; enabled: boolean;\n /** Which build phase this sits in, and why that phase comes where it does. */\n phase?: number; phaseName: string; phaseWhy: string | null; phaseStart: string | null;\n /** Derived, not stored: whether every endpoint the feature needs is wired. */\n implemented: boolean;\n date: string | null;\n /** True when the only date on record is when the UI was designed, not when it ships. */\n dateIsDesign: boolean;\n status: \"shipped\" | \"next\" | \"planned\";\n}\n/** roadmap()'s return shape. */\nexport interface RoadmapResult {\n items: RoadmapItem[];\n /** Index of the first unshipped item — everything above it is history. */\n nextIndex: number;\n shipped: number;\n remaining: number;\n}\n\nconst PERMISSION_CATALOG: PermissionGroup[] = [\n { group: \"Plans\", items: [\n { key: \"plan.view\", label: \"View plans\", detail: \"Read any plan in the workspace.\" },\n { key: \"plan.edit\", label: \"Edit plans\", detail: \"Reallocate budget, add or remove campuses, swap placements.\" },\n { key: \"plan.solve\", label: \"Run the solver\", detail: \"Trigger a solve. Consumes engine capacity.\" },\n { key: \"plan.delete\", label: \"Delete plans\", detail: \"Irreversible once the retention window closes.\" }\n ] },\n { group: \"Delivery\", items: [\n { key: \"export.run\", label: \"Export workbooks\", detail: \"Generate the client spreadsheet.\" },\n { key: \"share.manage\", label: \"Manage share links\", detail: \"Create, revoke and re-pin client links.\" },\n { key: \"client.view\", label: \"Open client view\", detail: \"See the presentation surface clients receive.\" }\n ] },\n { group: \"Model\", items: [\n { key: \"model.view\", label: \"View the model\", detail: \"Read formulas, weights and provenance.\" },\n { key: \"model.edit\", label: \"Change coefficients\", detail: \"Alter the numbers every plan is scored with.\" }\n ] },\n { group: \"Administration\", items: [\n { key: \"users.view\", label: \"View users\", detail: \"See the member directory.\" },\n { key: \"users.manage\", label: \"Manage users\", detail: \"Invite, edit, deactivate, assign roles.\" },\n { key: \"roles.manage\", label: \"Manage roles\", detail: \"Create roles and change what they grant.\" },\n { key: \"flags.manage\", label: \"Manage feature flags\", detail: \"Toggle features across projects and audiences.\" },\n { key: \"audit.view\", label: \"View the audit log\", detail: \"Read who changed what, when.\" },\n { key: \"roadmap.view\", label: \"View the roadmap\", detail: \"See which features are wired to the backend and what is next.\" }\n ] }\n];\n\nconst ALL_PERMISSIONS: string[] = PERMISSION_CATALOG.flatMap((g) => g.items.map((i) => i.key));\n\n/** Roles are named permission bundles. `system: true` roles cannot be deleted. */\nconst ROLES: Role[] = [\n { id: \"owner\", name: \"Owner\", system: true, description: \"Unrestricted. Every permission, including destructive ones.\",\n permissions: ALL_PERMISSIONS },\n { id: \"admin\", name: \"Administrator\", system: true, description: \"Runs the workspace and its people. Cannot change the scoring model.\",\n permissions: [\"plan.view\", \"plan.edit\", \"plan.solve\", \"export.run\", \"share.manage\", \"client.view\", \"model.view\", \"users.view\", \"users.manage\", \"roles.manage\", \"flags.manage\", \"audit.view\", \"roadmap.view\"] },\n { id: \"planner\", name: \"Planner\", system: false, description: \"Builds and edits plans. The default for the demand team.\",\n permissions: [\"plan.view\", \"plan.edit\", \"plan.solve\", \"export.run\", \"share.manage\", \"client.view\", \"model.view\", \"roadmap.view\"] },\n { id: \"analyst\", name: \"Analyst\", system: false, description: \"Reads everything, changes nothing. For QA and finance.\",\n permissions: [\"plan.view\", \"model.view\", \"audit.view\", \"client.view\", \"roadmap.view\"] },\n { id: \"model-admin\", name: \"Model administrator\", system: false, description: \"May change scoring coefficients — the numbers behind every plan the company ships.\",\n permissions: [\"plan.view\", \"model.view\", \"model.edit\", \"roadmap.view\"] },\n { id: \"sales\", name: \"Account lead\", system: false, description: \"Presents plans to clients without editing them.\",\n permissions: [\"plan.view\", \"client.view\", \"share.manage\", \"export.run\"] }\n];\n\n/* Feature flags. Precedence, highest first:\n 1. user override (explicit allow/deny for one person)\n 2. role targeting (on for these roles)\n 3. rollout percentage (stable hash of userId, so a user's answer never flickers)\n 4. enabled (the global switch)\n A flag with `enabled: false` is off for everyone regardless of targeting — that is the\n kill switch, and it must not be overridable or it is not a kill switch. */\n/* Every screen and every discrete feature carries its own flag, so a capability can be\n released, targeted or killed without touching its neighbours.\n\n `implemented` is a SEPARATE axis from `enabled`. All of this UI is designed and working\n against a simulated transport; `implemented` records whether the REAL backend is wired.\n enabled=false → hidden entirely. Nobody sees it.\n enabled + implemented=false → visible but inert: blurred, with a coming-soon banner.\n enabled + implemented=true → the live feature.\n That distinction is what makes the roadmap honest — it is a backend plan, not a design plan.\n\n Roadmap fields: shippedAt for what is done, eta + effort for what is not, backend for what\n actually has to be built, dependsOn so the ordering is derived rather than asserted. */\nconst PHASES: Phase[] = [\n {\n \"n\": 0,\n \"name\": \"Shipped\",\n \"start\": \"2026-08-18\",\n \"end\": \"2026-08-18\",\n \"why\": \"Documentation rendered from code. No backend, so these were done the moment the design was.\"\n },\n {\n \"n\": 1,\n \"name\": \"Identity and gating\",\n \"start\": \"2026-08-24\",\n \"end\": \"2026-09-11\",\n \"why\": \"None of this exists yet and everything else assumes it: who is acting, what they may do, and the switch that lets unfinished work ship dark. Version attribution, the audit trail and every gate in the app resolve against it.\"\n },\n {\n \"n\": 2,\n \"name\": \"Data in\",\n \"start\": \"2026-09-14\",\n \"end\": \"2026-09-25\",\n \"why\": \"Nothing can be scored until inventory is normalised and a brief exists to constrain it. Two independent surfaces, so they run in parallel.\"\n },\n {\n \"n\": 3,\n \"name\": \"The engine\",\n \"start\": \"2026-09-28\",\n \"end\": \"2026-10-09\",\n \"why\": \"The solver IS the product. Largest single piece of work, and every screen downstream is a view of its output.\"\n },\n {\n \"n\": 4,\n \"name\": \"Read the plan\",\n \"start\": \"2026-10-12\",\n \"end\": \"2026-10-30\",\n \"why\": \"Four read-only surfaces over solve output. Excluded schools ships WITH them, not later — planners will not trust a solve they cannot audit.\"\n },\n {\n \"n\": 5,\n \"name\": \"Change it safely\",\n \"start\": \"2026-11-02\",\n \"end\": \"2026-11-20\",\n \"why\": \"Version history lands before the first editing surface. Mutations without append-only snapshots are how plans get lost.\"\n },\n {\n \"n\": 6,\n \"name\": \"Get it to the client\",\n \"start\": \"2026-11-23\",\n \"end\": \"2026-12-11\",\n \"why\": \"A plan that cannot leave the tool has no value. Workbook export precedes the client view: planners live in spreadsheets.\"\n },\n {\n \"n\": 7,\n \"name\": \"Scale the tables\",\n \"start\": \"2026-12-14\",\n \"end\": \"2026-12-24\",\n \"why\": \"The pilot has 35 line items; production has 3,729. These are the ergonomics that make that difference survivable.\"\n },\n {\n \"n\": 8,\n \"name\": \"Explain the plan\",\n \"start\": \"2027-01-04\",\n \"end\": \"2027-01-22\",\n \"why\": \"The charts and nudges that turn a table of numbers into an argument. Genuinely optional — the plan is usable without them.\"\n },\n {\n \"n\": 9,\n \"name\": \"Tuning criteria and alternatives\",\n \"start\": \"2027-01-25\",\n \"end\": \"2027-02-12\",\n \"why\": \"Judgement tools. They need a stable plan and working versioning underneath them.\"\n },\n {\n \"n\": 10,\n \"name\": \"Trust the model\",\n \"start\": \"2027-02-15\",\n \"end\": \"2027-02-26\",\n \"why\": \"Showing the working, and letting the model owner tune it. Needs versioning so a coefficient change is attributable.\"\n },\n {\n \"n\": 11,\n \"name\": \"Operate at scale\",\n \"start\": \"2027-03-01\",\n \"end\": \"2027-03-12\",\n \"why\": \"The admin refinements that only matter once there are enough people and enough history to need them.\"\n },\n {\n \"n\": 12,\n \"name\": \"Creative operations\",\n \"start\": \"2027-03-15\",\n \"end\": \"2027-03-26\",\n \"why\": \"Adjacent to planning — needed before the college side can transact against a plan.\"\n },\n {\n \"n\": 13,\n \"name\": \"The assistant\",\n \"start\": \"2027-03-29\",\n \"end\": \"2027-04-16\",\n \"why\": \"Last on purpose. It is a faster path to things the app can already do, so it has no value until those things work.\"\n }\n];\n\nconst FLAGS: Flag[] = [\n // ---- Media Planner · brief and solve ----------------------------------\n { key: \"planner.setup\", project: \"Media Planner\", label: \"Campaign setup\", screen: \"setup\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-09-25\", phase: 2, effort: \"4 days\", backend: \"Campaign CRUD, brief persistence.\",\n description: \"The brief: budget, flight, geography, objective, channel priorities.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.briefParse\", project: \"Media Planner\", label: \"Describe-the-plan parsing\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"4 days\", backend: \"LLM extraction endpoint returning structured brief fields plus measurable criteria.\",\n dependsOn: [\"planner.setup\"], description: \"Turns a plain-language brief into structured fields and tuning criteria.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.goals\", project: \"Media Planner\", label: \"Tuning criteria and reviewer\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"1 week\", backend: \"Criteria store plus the reviewer that scores a solved plan against each criterion.\",\n dependsOn: [\"planner.briefParse\"], description: \"Measurable criteria the reviewer checks after every solve.\", owner: \"Dana Reyes\", updated: \"Aug 17\" },\n { key: \"planner.goalTweaks\", project: \"Media Planner\", label: \"Reviewer tweaks\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"6 days\", backend: \"Tweak records with an ordered change list, apply/revert as plan versions, and a refine prompt that re-plans under a constraint.\",\n dependsOn: [\"planner.goals\", \"planner.versions\"], description: \"Proposed plan changes attached to a missed criterion, applied or reverted as a unit.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.import\", project: \"Media Planner\", label: \"Inventory import\", screen: \"import\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-09-25\", phase: 2, effort: \"1 week\", backend: \"Workbook upload, column mapping, row validation as a job.\",\n description: \"The supply workbook: what is actually available to buy.\", owner: \"Marcus Webb\", updated: \"Aug 14\" },\n { key: \"planner.solve\", project: \"Media Planner\", label: \"Solver\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-09\", phase: 3, effort: \"2 weeks\", backend: \"The engine itself: candidate ranking, funding loop, placement fitting, CRP scoring.\",\n dependsOn: [\"planner.import\", \"planner.setup\"], description: \"Fits placements across campuses and scores the result.\", owner: \"Engineering\", updated: \"Aug 15\" },\n\n // ---- Media Planner · plan screens -------------------------------------\n { key: \"planner.overview\", project: \"Media Planner\", label: \"Plan overview\", screen: \"overview\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"4 days\", backend: \"One plan document: header, funded campuses, mix vs target, attention flags.\",\n dependsOn: [\"planner.solve\"], description: \"The plan in one screen, ordered by the three questions a planner asks.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.attentionFlags\", project: \"Media Planner\", label: \"Attention flags\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Rule pass over the solved plan producing flagged campuses with a stated cost to fix.\",\n dependsOn: [\"planner.overview\"], description: \"The 'needs your attention' list: campuses a rule says are wrong, with what fixing costs.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.saturationDistribution\", project: \"Media Planner\", label: \"Saturation distribution\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Enrollment-weighted CRP distribution with the floor percentile marked.\",\n dependsOn: [\"planner.overview\"], description: \"Where every campus sits on the saturation scale, and where the floor lands.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.mixGap\", project: \"Media Planner\", label: \"Mix vs target\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Realized channel mix against the objective's target mix, with a reason per gap.\",\n dependsOn: [\"planner.overview\"], description: \"Realized media mix against target, and why each gap exists.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.decisionTrace\", project: \"Media Planner\", label: \"Decision trace\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-26\", phase: 10, effort: \"2 weeks\", backend: \"Per-decision audit the engine emits during a solve: every campus considered, every placement weighed, and why each was taken or dropped.\",\n dependsOn: [\"planner.solve\"], description: \"The full reasoning behind a solve, readable after the fact.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.schools\", project: \"Media Planner\", label: \"School mix\", screen: \"schools\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"4 days\", backend: \"Server-side sort, filter and pagination over funded campuses.\",\n dependsOn: [\"planner.overview\"], description: \"Every funded campus with its saturation band and spend.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.reallocate\", project: \"Media Planner\", label: \"Budget reallocation\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"6 days\", backend: \"Debounced re-score preview plus a commit that snapshots a version.\",\n dependsOn: [\"planner.schools\", \"planner.versions\"], description: \"Drag budget between campuses and see the re-score before committing.\", owner: \"Dana Reyes\", updated: \"Aug 17\" },\n { key: \"planner.campusDetail\", project: \"Media Planner\", label: \"Campus detail\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"4 days\", backend: \"Per-campus rollup: channel contribution, surround-sound breadth, placement list.\",\n dependsOn: [\"planner.schools\"], description: \"Why one campus scores what it scores.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.channelContribution\", project: \"Media Planner\", label: \"Channel contribution\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Per-channel CRP contribution within a campus, weighted.\",\n dependsOn: [\"planner.campusDetail\"], description: \"Which channels built this campus's score, and how much each added.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.surroundSound\", project: \"Media Planner\", label: \"Surround sound\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"2 days\", backend: \"Category breadth per campus and the resulting bonus multiplier.\",\n dependsOn: [\"planner.campusDetail\"], description: \"How many channel categories a campus covers, and the bonus it earns.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.campusNudges\", project: \"Media Planner\", label: \"Campus recommendations\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"6 days\", backend: \"Per-campus recommendation engine: the cheapest next move and its projected CRP effect, applyable as a version.\",\n dependsOn: [\"planner.campusDetail\",\"planner.reallocate\"], description: \"The cheapest single change that would improve this campus.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.placements\", project: \"Media Planner\", label: \"Placement book\", screen: \"placements\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"1 week\", backend: \"Line-item list with server-side filters across school, media, status, month and cost.\",\n dependsOn: [\"planner.solve\"], description: \"Every line item, with what it contributes to saturation.\", owner: \"Marcus Webb\", updated: \"Aug 17\" },\n { key: \"planner.placementSwap\", project: \"Media Planner\", label: \"Placement swap\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"4 days\", backend: \"Ranked alternatives per placement with CRP and cost deltas, plus a swap that re-scores the campus.\",\n dependsOn: [\"planner.placements\"], description: \"Replace a placement with an engine-ranked alternative.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.savedViews\", project: \"Media Planner\", label: \"Saved table views\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Per-team named column sets, filters and sort, shared across the workspace.\",\n dependsOn: [\"planner.placements\"], description: \"Named column and filter sets, shared with the team.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.bulkEdit\", project: \"Media Planner\", label: \"Bulk placement actions\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"2 days\", backend: \"Batch status change and removal, with a queued re-score.\",\n dependsOn: [\"planner.placements\"], description: \"Select many line items and change status or remove them at once.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.columnPicker\", project: \"Media Planner\", label: \"Column picker\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"1 day\", backend: \"Column preference persistence per user, per table.\",\n dependsOn: [\"planner.placements\"], description: \"Choose which of the fourteen placement columns are shown.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.groupBy\", project: \"Media Planner\", label: \"Group rows\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Server-side grouping with per-group spend and CRP subtotals.\",\n dependsOn: [\"planner.placements\"], description: \"Group the placement book by school or media, with subtotals.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.csvExport\", project: \"Media Planner\", label: \"CSV export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"1 day\", backend: \"Streamed CSV of the current query — all filters and columns applied server-side.\",\n dependsOn: [\"planner.placements\"], description: \"Export exactly the rows and columns on screen.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.excluded\", project: \"Media Planner\", label: \"Excluded schools\", screen: \"excluded\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-10-30\", phase: 4, effort: \"4 days\", backend: \"Every considered-but-unfunded campus with its reason and cost-to-include.\",\n dependsOn: [\"planner.solve\"], description: \"The trust screen: what was considered and why it lost.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.addCampus\", project: \"Media Planner\", label: \"Add an excluded campus\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"4 days\", backend: \"Funding plan that pulls from unallocated then trims the strongest campus, as a version.\",\n dependsOn: [\"planner.excluded\", \"planner.reallocate\"], description: \"Fund a campus the engine excluded, and see what it costs.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.map\", project: \"Media Planner\", label: \"Geographic map\", screen: \"map\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"1 week\", backend: \"Campus coordinates and state rollups; geometry is static.\",\n dependsOn: [\"planner.schools\"], description: \"Campus map with saturation-scaled markers.\", owner: \"Dana Reyes\", updated: \"Aug 17\" },\n { key: \"planner.flights\", project: \"Media Planner\", label: \"Flight calendar\", screen: \"flights\", enabled: true, rollout: 60,\n roles: [\"planner\", \"owner\"], users: { u_marcus: false },\n eta: \"2027-01-22\", phase: 8, effort: \"6 days\", backend: \"Per-week spend distribution and a flight-shift mutation that preserves CRP.\",\n dependsOn: [\"planner.placements\"], description: \"Placements as flight bars over the campaign weeks.\", owner: \"Marcus Webb\", updated: \"Aug 17\" },\n\n // ---- Media Planner · analysis ----------------------------------------\n { key: \"planner.scenarios\", project: \"Media Planner\", label: \"Scenario compare\", screen: \"scenarios\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"7 days\", backend: \"Solve the same brief under multiple strategies, persist each as a scenario, promote one to working.\",\n dependsOn: [\"planner.solve\", \"planner.versions\"], description: \"Three strategies side by side with a campus matrix.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.versions\", project: \"Media Planner\", label: \"Version history\", screen: \"versions\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-11-20\", phase: 5, effort: \"6 days\", backend: \"Append-only snapshots with per-campus diffs and restore-as-new-head.\",\n dependsOn: [\"planner.solve\"], description: \"Append-only plan snapshots with pairwise diff and restore.\", owner: \"Dana Reyes\", updated: \"Aug 16\" },\n { key: \"planner.versionDiff\", project: \"Media Planner\", label: \"Version compare\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"3 days\", backend: \"Pairwise diff between any two snapshots, per campus, with CRP and spend deltas.\",\n dependsOn: [\"planner.versions\"], description: \"Pick two versions and see exactly what changed.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.versionRestore\", project: \"Media Planner\", label: \"Restore a version\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"2 days\", backend: \"Append-only restore: snapshots the chosen version as a new head so history is never rewritten.\",\n dependsOn: [\"planner.versions\"], description: \"Make an earlier version current without losing anything.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.scenarioPromote\", project: \"Media Planner\", label: \"Promote a scenario\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"3 days\", backend: \"Swap the working plan to a scenario's allocation as a new version.\",\n dependsOn: [\"planner.scenarios\",\"planner.versions\"], description: \"Make an alternative strategy the working plan.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.scenarioDuplicate\", project: \"Media Planner\", label: \"Duplicate a scenario\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-02-12\", phase: 9, effort: \"2 days\", backend: \"Scenario CRUD so a planner can branch and adjust one independently.\",\n dependsOn: [\"planner.scenarios\"], description: \"Branch a scenario and adjust it without touching the plan.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.flightShift\", project: \"Media Planner\", label: \"Shift a flight\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2027-01-22\", phase: 8, effort: \"3 days\", backend: \"Flight window mutation with weekly spend recomputation. Pacing only — CRP is flight-length invariant.\",\n dependsOn: [\"planner.flights\"], description: \"Move a placement's run dates and re-pace the week.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.algorithm\", project: \"Media Planner\", label: \"Algorithm documentation\", screen: \"algorithm\", enabled: true, rollout: 100, roles: [], users: {},\n eta: null, shippedAt: \"2026-08-18\", phase: 0, effort: \"1 week\", backend: \"Read-only model config: weights, exponents, thresholds and provenance.\",\n description: \"How every number is produced, with each constant's provenance.\", owner: \"Priya Raman\", updated: \"Aug 17\" },\n { key: \"planner.algorithmConfig\", project: \"Media Planner\", label: \"Live coefficient editing\", enabled: false, rollout: 0,\n roles: [\"model-admin\"], users: {},\n eta: \"2027-02-26\", phase: 10, effort: \"6 days\", backend: \"Audited coefficient writes, a simulate endpoint that re-scores without saving, and per-plan coefficient pinning.\",\n dependsOn: [\"planner.algorithm\", \"planner.versions\"], description: \"Edit scoring coefficients from the UI. Off until the audit trail ships.\", owner: \"Engineering\", updated: \"Aug 15\" },\n { key: \"planner.algorithmSimulate\", project: \"Media Planner\", label: \"Coefficient simulation\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-02-26\", phase: 10, effort: \"1 week\", backend: \"Re-score the working plan under proposed coefficients without saving them.\",\n dependsOn: [\"planner.algorithmConfig\"], description: \"See what a weight change would do before committing it.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"planner.apiSpec\", project: \"Media Planner\", label: \"API specification\", screen: \"api\", enabled: true, rollout: 100, roles: [], users: {},\n eta: null, shippedAt: \"2026-08-18\", phase: 0, effort: \"3 days\", backend: \"None — generated from the same declarations the client calls.\",\n description: \"The backend contract, rendered from the spec the front end calls.\", owner: \"Engineering\", updated: \"Aug 17\" },\n { key: \"planner.roadmap\", project: \"Media Planner\", label: \"Roadmap\", screen: \"roadmap\", enabled: true, rollout: 100, roles: [], users: {},\n eta: null, shippedAt: \"2026-08-18\", phase: 0, effort: \"3 days\", backend: \"None — derived from the flag registry.\",\n description: \"What is wired to the backend, and what is next.\", owner: \"Engineering\", updated: \"Today\" },\n\n // ---- Media Planner · delivery ----------------------------------------\n { key: \"planner.export\", project: \"Media Planner\", label: \"Export and share\", screen: \"export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"3 days\", backend: \"Workbook generation as a job, returning a signed download URL.\",\n dependsOn: [\"planner.overview\"], description: \"The spreadsheet, treated as a first-class deliverable.\", owner: \"Ana Duarte\", updated: \"Aug 12\" },\n { key: \"planner.clientView\", project: \"Media Planner\", label: \"Client view\", screen: \"client\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"1 week\", backend: \"Token-scoped read-only payload carrying presence bands only — CRP must never leave authenticated surfaces.\",\n dependsOn: [\"planner.export\"], description: \"The presentation surface clients receive. No CRP figures.\", owner: \"Ana Duarte\", updated: \"Aug 12\" },\n { key: \"planner.shareLinks\", project: \"Media Planner\", label: \"Share links\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"sales\"], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"4 days\", backend: \"Version-pinned tokens with expiry, revocation and view analytics.\",\n dependsOn: [\"planner.clientView\", \"planner.versions\"], description: \"Client links pinned to a version, with expiry and view counts.\", owner: \"Ana Duarte\", updated: \"Today\" },\n { key: \"planner.exportXlsx\", project: \"Media Planner\", label: \"Workbook export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"4 days\", backend: \"Sheet-for-sheet workbook build matching the legacy template, as a job returning a signed URL.\",\n dependsOn: [\"planner.export\"], description: \"The client spreadsheet, sheet for sheet.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.exportPdf\", project: \"Media Planner\", label: \"PDF export\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"3 days\", backend: \"Server-side render of the client view to a paginated PDF at a pinned version.\",\n dependsOn: [\"planner.clientView\"], description: \"The client-facing plan as a PDF, pinned to a version.\", owner: \"Marcus Webb\", updated: \"Today\" },\n { key: \"planner.clientPreview\", project: \"Media Planner\", label: \"Client view preview\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Read-only render of the client payload inside the admin surface.\",\n dependsOn: [\"planner.clientView\"], description: \"See what the client sees without leaving the planner.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.clientPresentation\", project: \"Media Planner\", label: \"Presentation settings\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\",\"planner\"], users: {},\n eta: \"2026-12-11\", phase: 6, effort: \"3 days\", backend: \"Per-link presentation options persisted on the share link: narrative, placement detail, spend visibility.\",\n dependsOn: [\"planner.shareLinks\"], description: \"Choose what the client sees: narrative, placement detail, spend figures.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.clientPlacementDetail\", project: \"Media Planner\", label: \"Client placement lists\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2026-12-24\", phase: 7, effort: \"2 days\", backend: \"Per-campus placement lists in the client payload, band language only.\",\n dependsOn: [\"planner.clientView\"], description: \"What runs where, per campus, on the client page.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.assistant\", project: \"Media Planner\", label: \"Plan assistant\", enabled: true, rollout: 40,\n roles: [\"owner\", \"admin\", \"planner\"], users: { u_priya: true },\n eta: \"2027-04-16\", phase: 13, effort: \"2 weeks\", backend: \"Threaded chat over the plan, job escalation for engine questions, and packets the planner can apply as real mutations.\",\n dependsOn: [\"planner.overview\", \"chat.agentPanel\"], description: \"Docked chat that can propose and apply plan changes.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"planner.assistantApply\", project: \"Media Planner\", label: \"Assistant apply\", enabled: true, rollout: 40, roles: [\"owner\", \"admin\", \"planner\"], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"6 days\", backend: \"Validate a packet against the live plan, then route it to the matching mutation endpoint.\",\n dependsOn: [\"planner.assistant\", \"planner.reallocate\"], description: \"Turn an assistant proposal into a committed plan change.\", owner: \"Dana Reyes\", updated: \"Today\" },\n\n // ---- Platform --------------------------------------------------------\n { key: \"planner.assistantHistory\", project: \"Media Planner\", label: \"Assistant thread history\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"3 days\", backend: \"Thread list, rename and delete scoped to a context, with transcript persistence.\",\n dependsOn: [\"planner.assistant\"], description: \"Past conversations, resumable and deletable.\", owner: \"Dana Reyes\", updated: \"Today\" },\n { key: \"platform.creativeReview\", project: \"Platform\", label: \"Creative review\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-03-26\", phase: 12, effort: \"6 days\", backend: \"Creative upload, approval states, reviewer assignment.\",\n description: \"College-side creative approval flow.\", owner: \"Ana Duarte\", updated: \"Aug 09\" },\n { key: \"platform.verification\", project: \"Platform\", label: \"Screen verification\", enabled: true, rollout: 80, roles: [], users: {},\n eta: \"2027-03-26\", phase: 12, effort: \"1 week\", backend: \"Photo upload with EXIF and geo validation against the placement's location.\",\n dependsOn: [\"platform.creativeReview\"], description: \"Photo proof-of-posting on physical placements.\", owner: \"Ana Duarte\", updated: \"Aug 14\" },\n\n // ---- Admin -----------------------------------------------------------\n { key: \"admin.users\", project: \"Admin\", label: \"User directory\", screen: \"users\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\"], users: {},\n eta: \"2026-09-11\", phase: 1, effort: \"4 days\", backend: \"Member CRUD, invitations, status transitions.\",\n description: \"Who is in the workspace and what they hold.\", owner: \"Engineering\", updated: \"Aug 16\" },\n { key: \"admin.roles\", project: \"Admin\", label: \"Roles and permissions\", screen: \"roles\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\"], users: {},\n eta: \"2026-09-11\", phase: 1, effort: \"1 week\", backend: \"Role definitions, permission grants, and server-side enforcement on every route.\",\n dependsOn: [\"admin.users\"], description: \"Named permission bundles, and what each one grants.\", owner: \"Engineering\", updated: \"Aug 16\" },\n { key: \"admin.flags\", project: \"Admin\", label: \"Feature flags\", screen: \"flags\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\"], users: {},\n eta: \"2026-09-11\", phase: 1, effort: \"4 days\", backend: \"Flag registry with rollout bucketing, role targeting and per-user overrides.\",\n description: \"Every project's flags, with their targeting rules.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"admin.audit\", project: \"Admin\", label: \"Audit log\", screen: \"audit\", enabled: true, rollout: 100, roles: [\"owner\", \"admin\", \"analyst\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"4 days\", backend: \"Append-only change records with an 18-month retention window.\",\n dependsOn: [\"admin.roles\"], description: \"Every administrative change, append-only.\", owner: \"Engineering\", updated: \"Aug 16\" },\n { key: \"admin.bulkInvite\", project: \"Admin\", label: \"Bulk invite\", enabled: false, rollout: 0, roles: [\"owner\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"2 days\", backend: \"CSV parse, per-row validation, and a partial-success invitation batch.\",\n dependsOn: [\"admin.users\"], description: \"CSV upload to invite many members at once.\", owner: \"Engineering\", updated: \"Aug 11\" },\n { key: \"admin.ssoEnforcement\", project: \"Admin\", label: \"Enforce SSO\", enabled: false, rollout: 0, roles: [], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"3 days\", backend: \"SAML assertion handling, just-in-time provisioning, and a break-glass path.\",\n dependsOn: [\"admin.roles\"], description: \"Require SAML for every member. Locks out password sign-in.\", owner: \"Engineering\", updated: \"Aug 05\" },\n\n // ---- Agent Chat ------------------------------------------------------\n { key: \"admin.roleEditor\", project: \"Admin\", label: \"Role permission editor\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"4 days\", backend: \"Role CRUD with a permission matrix and an effective-permission resolver.\",\n dependsOn: [\"admin.roles\"], description: \"Change what a role grants, permission by permission.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"admin.flagTargeting\", project: \"Admin\", label: \"Flag targeting\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"4 days\", backend: \"Evaluation order: user override, role, rollout percentage by stable hash, then the global switch.\",\n dependsOn: [\"admin.flags\"], description: \"Target a flag by user, role or rollout percentage.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"admin.auditExport\", project: \"Admin\", label: \"Audit export\", enabled: true, rollout: 100, roles: [\"owner\",\"admin\"], users: {},\n eta: \"2027-03-12\", phase: 11, effort: \"1 day\", backend: \"Streamed CSV of the audit query, with retention-window enforcement.\",\n dependsOn: [\"admin.audit\"], description: \"Export the audit trail for a date range.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"chat.agentPanel\", project: \"Agent Chat\", label: \"Agent panel\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"1 week\", backend: \"Thread resolution, message send, job polling, and cancellation.\",\n description: \"The embeddable assistant surface itself.\", owner: \"Engineering\", updated: \"Today\" },\n { key: \"chat.attachments\", project: \"Agent Chat\", label: \"Chat attachments\", enabled: true, rollout: 100, roles: [], users: {},\n eta: \"2027-04-16\", phase: 13, effort: \"3 days\", backend: \"Staged upload with virus scanning, then reference by id in the turn.\",\n dependsOn: [\"chat.agentPanel\"], description: \"Attach files to a question.\", owner: \"Engineering\", updated: \"Today\" }\n];\n\nconst USERS: User[] = [\n { id: \"u_dana\", name: \"Dana Reyes\", email: \"dana@flytedesk.com\", title: \"Senior media planner\", team: \"Demand\",\n roles: [\"planner\", \"admin\"], status: \"active\", lastActive: \"2 minutes ago\", joined: \"Mar 2024\", sso: true,\n timezone: \"America/Denver\", phone: \"+1 303 555 0142\" },\n { id: \"u_marcus\", name: \"Marcus Webb\", email: \"marcus@flytedesk.com\", title: \"Media planner\", team: \"Demand\",\n roles: [\"planner\"], status: \"active\", lastActive: \"Yesterday\", joined: \"Sep 2024\", sso: true, timezone: \"America/New_York\" },\n { id: \"u_priya\", name: \"Priya Raman\", email: \"priya@flytedesk.com\", title: \"Data scientist\", team: \"Engineering\",\n roles: [\"model-admin\", \"analyst\"], status: \"active\", lastActive: \"4 hours ago\", joined: \"Jan 2025\", sso: true, timezone: \"America/Los_Angeles\" },\n { id: \"u_ana\", name: \"Ana Duarte\", email: \"ana@flytedesk.com\", title: \"Account lead\", team: \"Revenue\",\n roles: [\"sales\"], status: \"active\", lastActive: \"1 hour ago\", joined: \"Jun 2023\", sso: true, timezone: \"America/Chicago\" },\n { id: \"u_jules\", name: \"Jules Okonkwo\", email: \"jules@flytedesk.com\", title: \"VP Revenue\", team: \"Revenue\",\n roles: [\"owner\"], status: \"active\", lastActive: \"3 days ago\", joined: \"Feb 2022\", sso: true, timezone: \"America/New_York\" },\n { id: \"u_sam\", name: \"Sam Whitfield\", email: \"sam@flytedesk.com\", title: \"Finance analyst\", team: \"Finance\",\n roles: [\"analyst\"], status: \"active\", lastActive: \"Aug 14\", joined: \"Nov 2024\", sso: false, timezone: \"America/Denver\" },\n { id: \"u_tess\", name: \"Tess Nakamura\", email: \"tess@flytedesk.com\", title: \"Media planner\", team: \"Demand\",\n roles: [\"planner\"], status: \"invited\", lastActive: \"—\", joined: \"Invited Aug 16\", sso: false, timezone: \"America/Denver\" },\n { id: \"u_ben\", name: \"Ben Alvarez\", email: \"ben@flytedesk.com\", title: \"Account lead\", team: \"Revenue\",\n roles: [\"sales\"], status: \"suspended\", lastActive: \"Jul 02\", joined: \"Apr 2023\", sso: true, timezone: \"America/Chicago\" }\n];\n\n/** Stable 0–99 bucket from a string, so rollout answers never flicker between reloads. */\nfunction bucket(seed: string): number {\n let h = 2166136261;\n for (let i = 0; i < seed.length; i++) { h ^= seed.charCodeAt(i); h = Math.imul(h, 16777619); }\n return Math.abs(h) % 100;\n}\n\nconst STORE = \"fd.session.v1\";\n\ninterface StoredSession { userId?: string; profile?: Partial<User> }\n\nfunction readStored(): StoredSession | null {\n try { return JSON.parse(localStorage.getItem(STORE) || \"null\"); } catch { return null; }\n}\nfunction writeStored(patch: Partial<StoredSession>): StoredSession | null {\n try {\n const next = Object.assign({}, readStored(), patch);\n localStorage.setItem(STORE, JSON.stringify(next));\n return next;\n } catch { return null; }\n}\n\n/** Build the session document a real GET /me would return. */\nfunction buildSession(userId: string, overrides?: { users?: User[]; roles?: Role[]; flags?: Flag[] }): Session {\n const users = (overrides && overrides.users) || USERS;\n const roles = (overrides && overrides.roles) || ROLES;\n const flags = (overrides && overrides.flags) || FLAGS;\n const user = users.find((u) => u.id === userId) || users[0];\n const held = roles.filter((r) => user.roles.indexOf(r.id) >= 0);\n const permissions = [...new Set(held.flatMap((r) => r.permissions))];\n const resolved: Record<string, boolean> = {};\n flags.forEach((f) => { resolved[f.key] = evaluateFlag(f, user); });\n return { user, roles: held, permissions, flags: resolved, allRoles: roles, allFlags: flags, allUsers: users };\n}\n\n/** The precedence rule, in one place so the admin UI and the app can never disagree. */\nfunction evaluateFlag(flag: Flag, user: User): boolean {\n if (!flag.enabled) return false; // kill switch wins\n if (user && flag.users && flag.users[user.id] != null) return !!flag.users[user.id];\n if (flag.roles && flag.roles.length) {\n if (user && user.roles.some((r) => flag.roles.indexOf(r) >= 0)) return true;\n if (flag.rollout >= 100) return true;\n return false;\n }\n if (flag.rollout >= 100) return true;\n if (flag.rollout <= 0) return false;\n return user ? bucket(flag.key + \":\" + user.id) < flag.rollout : false;\n}\n\n/** Why a flag resolved the way it did — shown in the admin UI, invaluable in support. */\nfunction explainFlag(flag: Flag, user: User): FlagExplanation {\n if (!flag.enabled) return { on: false, reason: \"Globally off\", detail: \"The kill switch overrides all targeting.\" };\n if (user && flag.users && flag.users[user.id] != null) {\n const on = !!flag.users[user.id];\n return { on, reason: on ? \"User override — on\" : \"User override — off\", detail: \"Set explicitly for \" + user.name + \".\" };\n }\n if (flag.roles && flag.roles.length && user && user.roles.some((r) => flag.roles.indexOf(r) >= 0)) {\n return { on: true, reason: \"Role targeted\", detail: \"Held role matches \" + flag.roles.join(\", \") + \".\" };\n }\n if (flag.rollout >= 100) return { on: true, reason: \"Fully rolled out\", detail: \"100% of users.\" };\n if (flag.rollout <= 0) {\n return flag.roles && flag.roles.length\n ? { on: false, reason: \"Not targeted\", detail: \"Limited to \" + flag.roles.join(\", \") + \"; rollout is 0%.\" }\n : { on: false, reason: \"Rollout 0%\", detail: \"Enabled but not released to anyone.\" };\n }\n const b = user ? bucket(flag.key + \":\" + user.id) : null;\n return b != null && b < flag.rollout\n ? { on: true, reason: \"In rollout\", detail: \"Bucket \" + b + \" is below the \" + flag.rollout + \"% threshold.\" }\n : { on: false, reason: \"Outside rollout\", detail: \"Bucket \" + b + \" is at or above the \" + flag.rollout + \"% threshold.\" };\n}\n\nconst listeners = new Set<(s: Session) => void>();\nlet current: Session | null = null;\n\ndeclare global {\n interface Window {\n /** Admin-app-injected overrides for the demo dataset, read by loadSession(). */\n __FD_ADMIN_OVERRIDES?: { users?: User[]; roles?: Role[]; flags?: Flag[] };\n }\n}\n\n/** Replace this with `fetch(API + \"/me\")` to go live. */\nfunction loadSession(userId?: string): Session {\n const stored = readStored();\n const id = userId || (stored && stored.userId) || USERS[0].id;\n current = buildSession(id, window.__FD_ADMIN_OVERRIDES);\n if (stored && stored.profile) Object.assign(current.user, stored.profile);\n return current;\n}\n\nfunction getSession(): Session { return current || loadSession(); }\n\nfunction setActiveUser(userId: string): Session {\n writeStored({ userId });\n current = null;\n const s = loadSession(userId);\n listeners.forEach((fn) => fn(s));\n return s;\n}\n\n/** Local profile edits persist so the demo keeps them across reloads. */\nfunction saveProfile(patch: Partial<User>): User {\n const s = getSession();\n Object.assign(s.user, patch);\n const stored: StoredSession = readStored() || {};\n writeStored({ profile: Object.assign({}, stored.profile, patch) });\n listeners.forEach((fn) => fn(getSession()));\n return s.user;\n}\n\n/** Recompute after the admin app mutates users/roles/flags. */\nfunction refresh(): Session {\n const id = getSession().user.id;\n current = null;\n const s = loadSession(id);\n listeners.forEach((fn) => fn(s));\n return s;\n}\n\nfunction subscribe(fn: (s: Session) => void): () => void { listeners.add(fn); return () => listeners.delete(fn); }\n\nfunction can(permission: string | string[]): boolean {\n if (!permission) return true;\n const s = getSession();\n const list = Array.isArray(permission) ? permission : [permission];\n return list.every((p) => s.permissions.indexOf(p) >= 0);\n}\nfunction canAny(permissions: string[]): boolean {\n const s = getSession();\n return (permissions || []).some((p) => s.permissions.indexOf(p) >= 0);\n}\nfunction hasRole(roleId: string): boolean { return getSession().user.roles.indexOf(roleId) >= 0; }\nfunction flagOn(key: string): boolean { return !!getSession().flags[key]; }\n\n/** The flag registry entry, whatever the session shape.\n * Not declared in session.d.ts — see the module doc comment on SessionKit below. */\nfunction findFlag(key: string): Flag | null { return (getSession().allFlags || []).find((f) => f.key === key) || null; }\n\n/* Release state ONLY: is this feature turned on for this member (kill switch, rollout bucket,\n role, per-user override). Whether its backend exists is a different question with a different\n owner — RuntimeKit.status() computes it from the endpoints the feature declares, so no record\n anywhere claims to be implemented. Mixing the two here is what let a typed `implemented: true`\n outrank the code. */\nfunction flagState(key: string): \"on\" | \"off\" {\n if (!key) return \"on\";\n const f = findFlag(key);\n if (!f) return \"on\"; // unknown key: never hide working UI\n return flagOn(key) ? \"on\" : \"off\";\n}\nfunction isEnabled(key: string): boolean { return flagState(key) !== \"off\"; }\nfunction flagVisible(key: string): boolean { return isEnabled(key); }\n/* Deprecated: \"live\" used to mean released AND wired. Ask RuntimeKit.isComplete() for the second\n half — kept only so older call sites do not break. */\nfunction flagLive(key: string): boolean { return isEnabled(key); }\n\n/* Roadmap, derived from the registry rather than maintained beside it — a roadmap kept in a\n second place is a roadmap that goes stale. Ordered by date so the timeline is chronological\n regardless of how the flags happen to be listed. */\nfunction roadmap(overrides?: { flags?: Flag[]; isComplete?: (key: string) => boolean }): RoadmapResult {\n const flags = (overrides && overrides.flags) || (getSession().allFlags || []);\n // Injected rather than imported: session.ts must not depend on runtime.ts (runtime.ts has no\n // opinion about sessions, and a cycle between them would be the wrong shape). The consumer\n // passes RuntimeKit.isComplete; without it every feature reads as pending, which is the safe\n // direction — it under-claims instead of over-claiming.\n const isComplete = (overrides && overrides.isComplete) || (() => false);\n const items: RoadmapItem[] = flags.map((f): RoadmapItem => {\n const done = !!isComplete(f.key);\n /* Fall back to shippedAt when a record has no eta. Filtering on a missing date used to be\n harmless because shipped records were `done` and used shippedAt; with completeness derived,\n nothing is done, so 36 records lost their date and vanished from the page — including the\n very features whose coming-soon cards link here. A designed-on date is still a real date;\n it is labelled as one rather than pretended to be a ship date. */\n const date = done ? (f.shippedAt || f.eta) : (f.eta || f.shippedAt);\n const phaseInfo: Partial<Phase> = (f.phase != null ? PHASES[f.phase] : undefined) || {};\n return {\n key: f.key, label: f.label, project: f.project, description: f.description,\n backend: f.backend, effort: f.effort, owner: f.owner, dependsOn: f.dependsOn || [],\n screen: f.screen || null, enabled: f.enabled,\n /* Which build phase this sits in, and why that phase comes where it does. */\n phase: f.phase, phaseName: phaseInfo.name || \"Unscheduled\",\n phaseWhy: phaseInfo.why || null,\n phaseStart: phaseInfo.start || null,\n /* Derived, not stored. */\n implemented: done,\n date: date || null,\n /* True when the only date we have is when the UI was designed, not when it ships. */\n dateIsDesign: !done && !f.eta && !!f.shippedAt,\n status: done ? \"shipped\" : (f.enabled ? \"next\" : \"planned\")\n };\n }).filter((i) => i.date);\n /* Phase order, not date order. Two features in the same phase are deliberately unordered\n relative to each other — the phase is the commitment, the day inside it is not. */\n items.sort((a, b) => ((a.phase ?? 0) - (b.phase ?? 0)) || String(a.date).localeCompare(String(b.date)) || a.label.localeCompare(b.label));\n // The first unshipped item is where the reader should land: everything above is history.\n const nextIndex = items.findIndex((i) => !i.implemented);\n return {\n items, nextIndex: nextIndex < 0 ? items.length : nextIndex,\n shipped: items.filter((i) => i.implemented).length,\n remaining: items.filter((i) => !i.implemented).length\n };\n}\n\n/** React binding. Re-renders on user switch, profile save, or admin mutation. */\nfunction useSession(): Session {\n const [s, setS] = React.useState<Session>(getSession);\n React.useEffect(() => subscribe(setS), []);\n return s;\n}\n\n/**\n * Session, RBAC and feature flags for every flytedesk app.\n *\n * Not a security boundary: permissions gate the UI so people aren't shown affordances they\n * cannot use. The server must re-check all of it.\n *\n * To go live, replace loadSession() with a fetch of GET /me → { user, roles, permissions, flags }.\n */\nexport const SessionKit = {\n PERMISSION_CATALOG, ALL_PERMISSIONS, ROLES, FLAGS, USERS,\n loadSession, getSession, setActiveUser, saveProfile, refresh, subscribe,\n can, canAny, hasRole, flagOn, useSession,\n findFlag, flagState, isEnabled, flagVisible, flagLive, roadmap,\n evaluateFlag, explainFlag, bucket, buildSession\n};\n","import * as React from \"react\";\nimport { Card } from \"../surfaces/Card\";\nimport { Badge } from \"../feedback/Badge\";\nimport { Tag } from \"../feedback/Tag\";\nimport { Flag } from \"../feedback/Flag\";\nimport { Button } from \"../actions/Button\";\nimport { Input } from \"../forms/Input\";\nimport { Collapsible } from \"../surfaces/Collapsible\";\n\n/* A drop-in browser for a simulated API contract.\n\n Every flytedesk app that ships a simulated backend needs the same screen: the endpoint\n list engineers build from. Rather than fork the planner's version per app, this takes the\n spec as data.\n\n Required:\n spec — [{ id, method, path, title, purpose, usedBy[], latency:[lo,hi],\n request, response, notes?, isList? }]\n onRequest — (id, params) => Promise<any> the app's simulated transport\n\n Optional:\n modules — [{ id, label, icon, endpoints:[id] }] maps app screens to the endpoints\n they call. Rendered as the primary filter, because \"what does this screen\n need\" is the question engineers actually arrive with.\n groups — [[label, [id]]] lifecycle grouping for the list itself\n conventions — [[label, text]] cross-cutting rules (auth, errors, pagination)\n*/\n\nexport interface EndpointSpec {\n id: string;\n method: \"GET\" | \"POST\" | \"PATCH\" | \"PUT\" | \"DELETE\";\n path: string;\n title: string;\n purpose: string;\n usedBy?: string[];\n /** [lo, hi] ms. Doubles as the latency SLO the UI's loading states are designed around. */\n latency: [number, number];\n request?: unknown;\n query?: unknown;\n response: unknown;\n notes?: string;\n /** Marks a paged list returning the { rows, pager, sort, filter } envelope. */\n isList?: boolean;\n}\nexport interface SpecModule { id: string; label: string; icon?: string; endpoints: string[] }\n\nexport interface ApiSpecBrowserProps {\n spec?: EndpointSpec[];\n /** The app's simulated transport: (id, params) => Promise<any>. Powers \"Try it\". */\n onRequest: (id: string, params: unknown) => Promise<unknown>;\n /** Screen → endpoints map. Rendered as the primary filter. */\n modules?: SpecModule[];\n /** Lifecycle grouping: [[label, endpointIds]] */\n groups?: Array<[string, string[]]>;\n title?: string;\n kicker?: string;\n lede?: string;\n /** Where the spec lives and how to swap in the real transport. */\n sourceNote?: string;\n conventions?: Array<[string, string]>;\n openQuestions?: Array<[string, string, string]>;\n className?: string;\n}\n\nconst METHOD_TONE: Record<string, \"success\" | \"info\" | \"warning\" | \"danger\"> = { GET: \"success\", POST: \"info\", PATCH: \"warning\", PUT: \"warning\", DELETE: \"danger\" };\n\nexport function Json({ obj }: { obj: unknown }) {\n return <pre className=\"fd-json\">{JSON.stringify(obj, null, 2)}</pre>;\n}\n\ntype TriedState = \"busy\" | { ms: number; data?: unknown; error?: string } | null;\n\ninterface EndpointProps {\n s: EndpointSpec;\n onRequest: (id: string, params: unknown) => Promise<unknown>;\n}\n\nfunction Endpoint({ s, onRequest }: EndpointProps) {\n const [tried, setTried] = React.useState<TriedState>(null);\n const run = async () => {\n setTried(\"busy\");\n const t0 = (window.performance || Date).now();\n try {\n const data = await onRequest(s.id, s.request || (s.isList ? { page: 1, pageSize: 5 } : {}));\n setTried({ ms: Math.round((window.performance || Date).now() - t0), data });\n } catch (e) {\n setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String((e as any) && (e as any).message || e) });\n }\n };\n return (\n <Card elevation=\"flat\" padded={false}>\n <div className=\"fd-stack\" style={{ gap: 0 }}>\n <div className=\"fd-row\" style={{ gap: 10, padding: \"14px 18px\", flexWrap: \"wrap\" }}>\n <Badge tone={METHOD_TONE[s.method] || \"neutral\"}>{s.method}</Badge>\n <code className=\"fd-mono\" style={{ fontSize: 12.5, fontWeight: 600, color: \"var(--text)\", wordBreak: \"break-all\" }}>{s.path}</code>\n {s.isList ? <Badge tone=\"neutral\" icon=\"rows\">Paged list</Badge> : null}\n <span style={{ flex: 1 }} />\n <span className=\"fd-body-sm fd-muted fd-mono\">{s.latency[0]}–{s.latency[1]}ms</span>\n <Button size=\"sm\" variant=\"secondary\" icon=\"play\" loading={tried === \"busy\"} onClick={run}>Try it</Button>\n </div>\n <div className=\"fd-stack\" style={{ gap: 14, padding: \"0 18px 16px\" }}>\n <div className=\"fd-stack\" style={{ gap: 6 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 700 }}>{s.title}</span>\n <p className=\"fd-body-sm fd-secondary\" style={{ margin: 0, textWrap: \"pretty\" }}>{s.purpose}</p>\n {s.usedBy && s.usedBy.length ? (\n <span className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\" }}>{s.usedBy.map((u) => <Tag key={u}>{u}</Tag>)}</span>\n ) : null}\n </div>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(280px,1fr))\", gap: 12, alignItems: \"start\" }}>\n {s.request ? <div className=\"fd-stack\" style={{ gap: 6 }}><span className=\"fd-overline fd-muted\">Request body</span><Json obj={s.request} /></div> : null}\n {s.query ? <div className=\"fd-stack\" style={{ gap: 6 }}><span className=\"fd-overline fd-muted\">Query</span><Json obj={s.query} /></div> : null}\n <div className=\"fd-stack\" style={{ gap: 6 }}><span className=\"fd-overline fd-muted\">Response 200</span><Json obj={s.response} /></div>\n </div>\n {s.notes ? <Flag tone=\"info\" statement=\"Implementation note\" cost={s.notes} actions={null} /> : null}\n {tried && tried !== \"busy\" ? (\n <div className=\"fd-stack\" style={{ gap: 6 }}>\n <span className=\"fd-row\" style={{ gap: 8 }}>\n <span className=\"fd-overline fd-muted\">Simulated response</span>\n <Badge tone={tried.error ? \"danger\" : \"success\"} icon=\"timer\">{tried.ms}ms</Badge>\n </span>\n <Json obj={tried.error ? { error: tried.error } : tried.data} />\n </div>\n ) : null}\n </div>\n </div>\n </Card>\n );\n}\n\n/** Drop-in browser for a simulated API contract. Takes the spec as data. */\nexport function ApiSpecBrowser({\n spec = [],\n onRequest,\n modules,\n groups,\n title = \"API specification\",\n kicker = \"Architecture\",\n lede,\n sourceNote,\n conventions,\n openQuestions,\n className = \"\",\n ...rest\n}: ApiSpecBrowserProps) {\n const [q, setQ] = React.useState(\"\");\n const [method, setMethod] = React.useState<string | null>(null);\n const [mod, setMod] = React.useState<string | null>(null);\n const [listOnly, setListOnly] = React.useState(false);\n\n const activeModule = modules && modules.find((m) => m.id === mod);\n const hits = spec.filter((s) =>\n (!method || s.method === method) &&\n (!listOnly || s.isList) &&\n (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) &&\n (!q || (s.path + \" \" + s.title + \" \" + s.purpose + \" \" + (s.usedBy || []).join(\" \")).toLowerCase().includes(q.toLowerCase())));\n\n const effGroups: Array<[string, string[]]> = groups && groups.length\n ? groups\n : [[\"All endpoints\", spec.map((s) => s.id)]];\n const methods = [...new Set(spec.map((s) => s.method))];\n const listCount = spec.filter((s) => s.isList).length;\n\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 20, maxWidth: 1100 }} {...rest}>\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n {kicker ? <span className=\"fd-overline fd-muted\">{kicker}</span> : null}\n <h1 className=\"fd-h1\" style={{ margin: 0 }}>{title}</h1>\n {lede ? <p className=\"fd-body fd-secondary fd-prose\" style={{ margin: 0 }}>{lede}</p> : null}\n </div>\n\n {modules && modules.length ? (\n <div className=\"fd-stack\" style={{ gap: 8 }}>\n <span className=\"fd-overline fd-muted\">Filter by screen — every endpoint that screen depends on</span>\n <div className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\" }}>\n <Tag icon=\"stack\" selected={!mod} onClick={() => setMod(null)}>All screens <span className=\"fd-mono\">{spec.length}</span></Tag>\n {modules.map((m) => (\n <Tag key={m.id} icon={m.icon} selected={mod === m.id} onClick={() => setMod(mod === m.id ? null : m.id)}>\n {m.label} <span className=\"fd-mono\">{m.endpoints.length}</span>\n </Tag>\n ))}\n </div>\n {/* With one screen selected the list becomes an integration checklist — the most\n useful thing this page can be to someone picking up a ticket. */}\n {activeModule ? (\n <Flag tone=\"info\" statement={activeModule.label + \" calls \" + activeModule.endpoints.length + \" endpoints.\"}\n cost={\"Integration checklist for this screen: \" + activeModule.endpoints.join(\", \") + \". Wire these and the screen is done.\"}\n actions={<Button size=\"sm\" variant=\"ghost\" icon=\"x\" onClick={() => setMod(null)}>Show all screens</Button>} />\n ) : null}\n </div>\n ) : null}\n\n {sourceNote ? <Flag tone=\"info\" statement=\"Design-first: this page is the spec.\" cost={sourceNote} actions={null} /> : null}\n\n <div className=\"fd-row\" style={{ gap: 10, flexWrap: \"wrap\" }}>\n <Input icon=\"magnifying-glass\" placeholder=\"Find an endpoint, screen, or behavior\" value={q} onChange={(e) => setQ(e.target.value)} style={{ width: 300 }} />\n {methods.map((m) => (\n <Tag key={m} selected={method === m} onClick={() => setMethod(method === m ? null : m)}>\n {m} <span className=\"fd-mono\">{spec.filter((s) => s.method === m).length}</span>\n </Tag>\n ))}\n {listCount ? (\n <Tag icon=\"rows\" selected={listOnly} onClick={() => setListOnly(!listOnly)}>\n Paged lists <span className=\"fd-mono\">{listCount}</span>\n </Tag>\n ) : null}\n <span style={{ flex: 1 }} />\n <span className=\"fd-body-sm fd-muted\">{hits.length} of {spec.length} endpoints{listCount ? \" · \" + listCount + \" paged\" : \"\"}</span>\n </div>\n\n {hits.length === 0 ? (\n <Card elevation=\"flat\"><p className=\"fd-body-sm fd-muted\" style={{ margin: 0 }}>No endpoint matches those filters.</p></Card>\n ) : effGroups.map(([g, ids]) => {\n const items = hits.filter((s) => ids.indexOf(s.id) >= 0);\n if (!items.length) return null;\n return (\n <div key={g} className=\"fd-stack\" style={{ gap: 12 }}>\n <span className=\"fd-label-lg\">{g}</span>\n {items.map((s) => <Endpoint key={s.id} s={s} onRequest={onRequest} />)}\n </div>\n );\n })}\n\n {conventions && conventions.length ? (\n <Card title=\"Cross-cutting conventions\" elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n {conventions.map(([k, v]) => (\n <div key={k} className=\"fd-row\" style={{ gap: 12, alignItems: \"flex-start\" }}>\n <span className=\"fd-overline fd-muted\" style={{ width: 110, flex: \"none\", paddingTop: 2 }}>{k}</span>\n <span className=\"fd-body-sm fd-secondary\" style={{ textWrap: \"pretty\" }}>{v}</span>\n </div>\n ))}\n </div>\n </Card>\n ) : null}\n\n {openQuestions && openQuestions.length ? (\n <Collapsible icon=\"list-checks\" title=\"Open questions before implementation\" subtitle={openQuestions.length + \" unresolved\"}>\n <div className=\"fd-stack\" style={{ gap: 8 }}>\n {openQuestions.map(([id, question, why]) => (\n <div key={id} className=\"fd-row\" style={{ gap: 10, alignItems: \"flex-start\", padding: \"8px 0\", borderTop: \"1px solid var(--border)\" }}>\n <Badge tone=\"danger\">{id}</Badge>\n <span className=\"fd-stack\" style={{ gap: 2, flex: 1 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 600 }}>{question}</span>\n <span className=\"fd-body-sm fd-muted\">{why}</span>\n </span>\n </div>\n ))}\n </div>\n </Collapsible>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Card, CardRow } from \"../surfaces/Card\";\nimport { Badge } from \"../feedback/Badge\";\nimport { Button } from \"../actions/Button\";\nimport { Avatar } from \"../feedback/Avatar\";\nimport { Input } from \"../forms/Input\";\nimport { Select } from \"../forms/Select\";\nimport { Switch } from \"../forms/Switch\";\nimport { Textarea } from \"../forms/Textarea\";\nimport { SessionKit } from \"../../kits/session\";\nimport type { User } from \"../../kits/session\";\n\n/* The profile page, shared by every flytedesk app.\n\n Deliberately narrow: identity, working preferences, notifications, sessions. Anything\n billing- or plan-shaped belongs to the platform's own settings, not here.\n\n Roles are shown but never editable — a user promoting themselves is the whole reason RBAC\n exists. The card points at the admin surface instead.\n\n Pass `onSave` to persist through your own endpoint; the default writes through\n SessionKit.saveProfile so the demo keeps edits across reloads. */\n\nexport interface DeviceSession { id: string; device: string; where: string; when: string; current?: boolean }\nexport interface ProfilePageProps {\n /** Defaults to the signed-in user from SessionKit. */\n user?: User;\n /** Persist through your own endpoint. Defaults to SessionKit.saveProfile. */\n onSave?: (draft: Partial<User>) => void | Promise<void>;\n onNavigate?: (href: string) => void;\n sessions?: DeviceSession[];\n showSessions?: boolean;\n className?: string;\n}\n\nconst TIMEZONES = [\"America/New_York\", \"America/Chicago\", \"America/Denver\", \"America/Los_Angeles\", \"America/Anchorage\", \"Pacific/Honolulu\", \"Europe/London\", \"Europe/Berlin\"];\nconst NOTIFY = [\n { key: \"planShared\", label: \"A plan is shared with me\", detail: \"Someone sends you a plan or a client link.\" },\n { key: \"planChanged\", label: \"A plan I own changes\", detail: \"Budget moves, campuses added or removed.\" },\n { key: \"goalMissed\", label: \"The reviewer flags a missed criterion\", detail: \"After every solve, if a criterion is short.\" },\n { key: \"flagChanged\", label: \"A feature flag affecting me changes\", detail: \"Someone toggles a feature you can see.\" },\n { key: \"weekly\", label: \"Weekly digest\", detail: \"Monday summary of plan activity.\" }\n];\n\ninterface ProfileDraft {\n name: string; title: string; email: string; phone: string; timezone: string; bio: string;\n notify: Record<string, boolean>;\n}\n\n/**\n * The shared profile page: identity, working preferences, notifications, devices.\n * Roles are shown but never editable — self-promotion is the reason RBAC exists.\n */\nexport function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = \"\", ...rest }: ProfilePageProps) {\n const session = SessionKit.useSession();\n const user = userProp || session.user;\n const [draft, setDraft] = React.useState<ProfileDraft>(() => ({\n name: user.name || \"\", title: user.title || \"\", email: user.email || \"\",\n phone: user.phone || \"\", timezone: user.timezone || TIMEZONES[2],\n bio: user.bio || \"\", notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }\n }));\n const [saving, setSaving] = React.useState(false);\n const [saved, setSaved] = React.useState(false);\n const set = <K extends keyof ProfileDraft>(k: K, v: ProfileDraft[K]) => { setDraft((d) => Object.assign({}, d, { [k]: v })); setSaved(false); };\n const setNotify = (k: string) => { setDraft((d) => Object.assign({}, d, { notify: Object.assign({}, d.notify, { [k]: !d.notify[k] }) })); setSaved(false); };\n\n const dirty = draft.name !== (user.name || \"\") || draft.title !== (user.title || \"\") ||\n draft.phone !== (user.phone || \"\") || draft.timezone !== (user.timezone || TIMEZONES[2]) ||\n draft.bio !== (user.bio || \"\") || JSON.stringify(draft.notify) !== JSON.stringify(user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true });\n\n const save = async () => {\n setSaving(true);\n if (onSave) await onSave(draft); else SessionKit.saveProfile(draft);\n setSaving(false); setSaved(true);\n };\n\n const liveSessions: DeviceSession[] = sessions || [\n { id: \"s1\", device: \"MacBook Pro · Chrome\", where: \"Denver, CO\", when: \"Active now\", current: true },\n { id: \"s2\", device: \"iPhone 15 · Safari\", where: \"Denver, CO\", when: \"2 hours ago\" },\n { id: \"s3\", device: \"Windows · Edge\", where: \"Chicago, IL\", when: \"Aug 12\" }\n ];\n\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 20, maxWidth: 860 }} {...rest}>\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n <span className=\"fd-overline fd-muted\">Account</span>\n <h1 className=\"fd-h1\" style={{ margin: 0 }}>Your profile</h1>\n <p className=\"fd-body fd-secondary fd-prose\" style={{ margin: 0 }}>\n How you appear to colleagues and clients across every flytedesk app, and what we send you.\n </p>\n </div>\n\n <Card elevation=\"flat\">\n <div className=\"fd-row\" style={{ gap: 16, flexWrap: \"wrap\", alignItems: \"flex-start\" }}>\n <Avatar name={draft.name || user.name} size=\"lg\" />\n <div className=\"fd-stack\" style={{ gap: 4, flex: 1, minWidth: 200 }}>\n <span className=\"fd-h3\" style={{ margin: 0 }}>{draft.name || user.name}</span>\n <span className=\"fd-body-sm fd-muted\">{draft.title || \"No title set\"} · {user.team || \"No team\"}</span>\n <span className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\", paddingTop: 4 }}>\n {session.roles.map((r) => <Badge key={r.id} tone={r.id === \"owner\" ? \"success\" : \"neutral\"}>{r.name}</Badge>)}\n {user.sso ? <Badge tone=\"info\" icon=\"shield-check\">SSO</Badge> : null}\n </span>\n </div>\n <Button variant=\"secondary\" size=\"sm\" icon=\"image\">Change photo</Button>\n </div>\n </Card>\n\n {/* Card has no `subtitle` slot in the ported component (source bug) — composed here as a\n two-line title node using the same fd-body-sm/fd-muted idiom AccountMenu uses elsewhere. */}\n <Card\n title={\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span>Identity</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontWeight: 400 }}>Name and title appear on plans you share</span>\n </span>\n }\n elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 14 }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(220px,1fr))\", gap: 14 }}>\n <Input label=\"Full name\" value={draft.name} onChange={(e) => set(\"name\", e.target.value)} />\n <Input label=\"Job title\" value={draft.title} onChange={(e) => set(\"title\", e.target.value)} placeholder=\"e.g. Senior media planner\" />\n </div>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(220px,1fr))\", gap: 14 }}>\n <Input label=\"Work email\" value={draft.email} readOnly disabled\n help={user.sso ? \"Managed by your identity provider — change it there.\" : \"Contact an administrator to change this.\"} />\n <Input label=\"Phone\" value={draft.phone} onChange={(e) => set(\"phone\", e.target.value)} placeholder=\"Optional\" />\n </div>\n <Textarea label=\"Short bio\" value={draft.bio} onChange={(e) => set(\"bio\", e.target.value)} rows={3}\n placeholder=\"Optional — shown to colleagues on shared plans.\"\n help=\"Never shown to clients.\" />\n </div>\n </Card>\n\n <Card title=\"Working preferences\" elevation=\"flat\">\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit,minmax(220px,1fr))\", gap: 14 }}>\n <Select label=\"Time zone\" value={draft.timezone} onChange={(e) => set(\"timezone\", e.target.value)} options={TIMEZONES}\n help=\"Flight dates and schedules render in this zone.\" />\n <Select label=\"Start of week\" options={[\"Monday\", \"Sunday\"]} placeholder=\"Monday\" />\n </div>\n </Card>\n\n <Card\n title={\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span>Notifications</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontWeight: 400 }}>Email only for now — in-app notifications are on the roadmap</span>\n </span>\n }\n elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 14 }}>\n {NOTIFY.map((n) => (\n <Switch key={n.key} checked={!!draft.notify[n.key]} onChange={() => setNotify(n.key)} label={n.label} description={n.detail} />\n ))}\n </div>\n </Card>\n\n <Card\n title={\n <span className=\"fd-stack\" style={{ gap: 2 }}>\n <span>Access</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontWeight: 400 }}>What your roles grant you</span>\n </span>\n }\n elevation=\"flat\"\n action={<Button size=\"sm\" variant=\"ghost\" icon=\"arrow-right\"\n onClick={() => onNavigate && onNavigate(\"#roles\")}>See role definitions</Button>}>\n <div className=\"fd-stack\" style={{ gap: 0 }}>\n <CardRow label=\"Roles\">{session.roles.map((r) => r.name).join(\", \") || \"None\"}</CardRow>\n <CardRow label=\"Permissions\">{session.permissions.length} granted</CardRow>\n <CardRow label=\"Member since\">{user.joined || \"—\"}</CardRow>\n </div>\n <p className=\"fd-body-sm fd-muted\" style={{ margin: \"12px 0 0\" }}>\n You cannot change your own roles — that is the point of them. An administrator manages roles from Admin → Users.\n </p>\n </Card>\n\n {showSessions ? (\n <Card title=\"Signed-in devices\" elevation=\"flat\"\n action={<Button size=\"sm\" variant=\"ghost\" icon=\"sign-out\">Sign out everywhere</Button>}>\n <div className=\"fd-stack\" style={{ gap: 0 }}>\n {liveSessions.map((s) => (\n <div key={s.id} className=\"fd-row\" style={{ gap: 12, padding: \"10px 0\", borderTop: \"1px solid var(--border)\", flexWrap: \"wrap\" }}>\n <i className=\"ph ph-device-mobile\" style={{ fontSize: 16, color: \"var(--text-muted)\" }} aria-hidden=\"true\" />\n <span className=\"fd-stack\" style={{ gap: 1, flex: 1, minWidth: 160 }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 600 }}>{s.device}</span>\n <span className=\"fd-body-sm fd-muted\">{s.where} · {s.when}</span>\n </span>\n {s.current ? <Badge tone=\"success\" dot>This device</Badge> : <Button size=\"sm\" variant=\"ghost\">Revoke</Button>}\n </div>\n ))}\n </div>\n </Card>\n ) : null}\n\n <div className=\"fd-row\" style={{ gap: 10, flexWrap: \"wrap\", position: \"sticky\", bottom: 0, padding: \"12px 14px\",\n borderRadius: 10, background: \"var(--surface)\", border: \"1px solid var(--border)\", boxShadow: \"0 -4px 16px rgba(11,13,17,.06)\" }}>\n <span className=\"fd-body-sm\" style={{ fontWeight: 600, flex: 1 }}>\n {saved ? \"Saved.\" : dirty ? \"Unsaved changes\" : \"No pending changes\"}\n </span>\n <Button size=\"sm\" variant=\"ghost\" disabled={!dirty || saving}\n onClick={() => { setDraft({ name: user.name || \"\", title: user.title || \"\", email: user.email || \"\", phone: user.phone || \"\", timezone: user.timezone || TIMEZONES[2], bio: user.bio || \"\", notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true } }); setSaved(false); }}>\n Discard\n </Button>\n <Button size=\"sm\" icon=\"check\" disabled={!dirty} loading={saving} onClick={save}>Save changes</Button>\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { Card } from \"../surfaces/Card\";\nimport { Badge } from \"../feedback/Badge\";\nimport { Tag } from \"../feedback/Tag\";\nimport { Flag } from \"../feedback/Flag\";\nimport { Button } from \"../actions/Button\";\nimport { Input } from \"../forms/Input\";\nimport { Select } from \"../forms/Select\";\nimport { StatTile } from \"../data/StatTile\";\nimport { SessionKit } from \"../../kits/session\";\nimport type { RoadmapItem } from \"../../kits/session\";\nimport { RuntimeKit } from \"../../kits/runtime\";\n\n/* The roadmap is DERIVED from the flag registry, not maintained beside it — a roadmap kept in\n a second file is a roadmap that goes stale within a fortnight. Every entry's date, status and\n dependency list comes from the flag that gates the feature.\n\n The reading order is the argument: the whole UI is already designed and working against a\n simulated transport, so this timeline only ever describes BACKEND work. Shipped items sit\n above the \"you are here\" line, upcoming ones below, and the scroll container opens at that\n line so the first thing in view is what comes next rather than what is finished. */\n\nexport interface RoadmapTimelineProps {\n /** Called with a flag key when the reader clicks one — route it to your flag admin. */\n onOpenFlag?: (flagKey: string) => void;\n /** Heading. Default \"Roadmap\". */\n title?: string;\n /** Replaces the default explanation of what the timeline covers. */\n lede?: string;\n}\n\nconst STATUS: Record<string, { tone: \"success\" | \"warning\" | \"neutral\"; icon: string; label: string }> = {\n shipped: { tone: \"success\", icon: \"check-circle\", label: \"Wired\" },\n next: { tone: \"warning\", icon: \"traffic-cone\", label: \"Not wired\" },\n planned: { tone: \"neutral\", icon: \"circle-dashed\", label: \"Not released\" }\n};\nconst PROJECT_ICON: Record<string, string> = { \"Media Planner\": \"chart-line-up\", Platform: \"buildings\", Admin: \"shield-check\", \"Agent Chat\": \"chat-circle-dots\" };\n\nconst fmtDate = (iso: string | null) => {\n const d = new Date(String(iso) + \"T00:00:00\");\n return isNaN(d as unknown as number) ? iso : d.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\", year: \"numeric\" });\n};\n\ninterface RoadmapCardProps {\n item: RoadmapItem;\n byKey: Record<string, RoadmapItem>;\n onOpenFlag?: (flagKey: string) => void;\n}\n\nfunction RoadmapCard({ item, byKey, onOpenFlag }: RoadmapCardProps) {\n const s = STATUS[item.status] || STATUS.planned;\n const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);\n const blocking = deps.filter((d) => !d.implemented);\n return (\n <Card elevation=\"flat\">\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n <div className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\" }}>\n <span className=\"fd-body\" style={{ fontWeight: 700, flex: 1, minWidth: 140 }}>{item.label}</span>\n <Badge tone=\"neutral\" icon={PROJECT_ICON[item.project] || \"squares-four\"}>{item.project}</Badge>\n <Badge tone={s.tone} icon={s.icon}>{s.label}</Badge>\n </div>\n <p className=\"fd-body-sm fd-secondary\" style={{ margin: 0, textWrap: \"pretty\" }}>{item.description}</p>\n {item.backend ? (\n <div className=\"fd-row\" style={{ gap: 10, alignItems: \"flex-start\" }}>\n <span className=\"fd-overline fd-muted\" style={{ width: 62, flex: \"none\", paddingTop: 2 }}>Backend</span>\n <span className=\"fd-body-sm\" style={{ flex: 1, textWrap: \"pretty\" }}>{item.backend}</span>\n </div>\n ) : null}\n <div className=\"fd-row\" style={{ gap: 12, flexWrap: \"wrap\" }}>\n {item.effort ? <span className=\"fd-body-sm fd-muted\"><i className=\"ph ph-hourglass-medium\" /> {item.effort}</span> : null}\n <span className=\"fd-body-sm fd-muted\"><i className=\"ph ph-user\" /> {item.owner}</span>\n {item.screen ? <Badge tone=\"neutral\" icon=\"browser\">screen</Badge> : null}\n <span style={{ flex: 1 }} />\n <button type=\"button\" onClick={() => onOpenFlag && onOpenFlag(item.key)}\n style={{ all: \"unset\", cursor: \"pointer\", display: \"inline-flex\", alignItems: \"center\", gap: 5 }}>\n <code className=\"fd-mono\" style={{ fontSize: 11, color: \"var(--brand)\" }}>{item.key}</code>\n </button>\n </div>\n {deps.length ? (\n <div className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\", paddingTop: 6, borderTop: \"1px solid var(--border)\" }}>\n <span className=\"fd-overline fd-muted\" style={{ paddingTop: 3 }}>After</span>\n {deps.map((d) => (\n <Tag key={d.key} icon={d.implemented ? \"check\" : \"clock\"}>{d.label}</Tag>\n ))}\n </div>\n ) : null}\n {blocking.length && !item.implemented ? (\n <span className=\"fd-body-sm\" style={{ color: \"var(--warn-text)\" }}>\n Blocked until {blocking.map((d) => d.label).join(\" and \")} {blocking.length === 1 ? \"is\" : \"are\"} wired.\n </span>\n ) : null}\n </div>\n </Card>\n );\n}\n\n/**\n * A vertical, chronological map of what is wired to the real backend and what is next.\n *\n * Derived entirely from the feature-flag registry (`SessionKit.roadmap()`) — status is each\n * flag's `implemented` field, ordering comes from its date, and blocking relationships come\n * from its `dependsOn`. Nothing here is maintained separately, so it cannot drift from what\n * the apps actually do.\n *\n * Shipped work sits above a \"you are here\" marker and upcoming work below it; the scroll\n * container opens at that marker, so the first thing in view is what comes next.\n */\nexport function RoadmapTimeline({ onOpenFlag, title = \"Roadmap\", lede }: RoadmapTimelineProps) {\n const session = SessionKit.useSession();\n const [project, setProject] = React.useState(\"\");\n const [q, setQ] = React.useState(\"\");\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const nowRef = React.useRef<HTMLDivElement>(null);\n\n const rm = React.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);\n const byKey = React.useMemo(() => {\n const m: Record<string, RoadmapItem> = {};\n rm.items.forEach((i: RoadmapItem) => { m[i.key] = i; });\n return m;\n }, [rm]);\n\n const items: RoadmapItem[] = rm.items.filter((i: RoadmapItem) =>\n (!project || i.project === project) &&\n (!q || (i.label + \" \" + i.description + \" \" + (i.backend || \"\") + \" \" + i.key).toLowerCase().includes(q.toLowerCase())));\n const projects = [...new Set(rm.items.map((i: RoadmapItem) => i.project))];\n\n // Open at the \"you are here\" line: history above, what's next in view. Runs on the filtered\n // list too, since filtering moves the boundary. Two frames, because era headers and card text\n // change the track's height after the first paint — measuring too early lands in the wrong place.\n React.useEffect(() => {\n let raf1 = 0, raf2 = 0;\n const place = () => {\n const box = scrollRef.current, mark = nowRef.current;\n if (!box) return;\n // No pending work: show the end of the timeline rather than leaving it at the top.\n if (!mark) { box.scrollTop = box.scrollHeight; return; }\n // Put the marker just under the top edge so its label is readable — an offset large\n // enough to scroll it out of view defeats the purpose of having a label at all.\n box.scrollTop = Math.max(0, mark.offsetTop - 28);\n };\n raf1 = requestAnimationFrame(() => { place(); raf2 = requestAnimationFrame(place); });\n return () => { cancelAnimationFrame(raf1); cancelAnimationFrame(raf2); };\n }, [project, q, rm.nextIndex]);\n\n const firstPending = items.findIndex((i) => !i.implemented);\n const shippedShown = items.filter((i) => i.implemented).length;\n /* parseInt(\"1 week\") is 1 and parseInt(\"4 days\") is 4, so summing the raw numbers mixed two\n units and labelled the result \"wk\". Normalise to working days first. */\n const days = items.filter((i) => !i.implemented).reduce((s, i) => {\n const m = String(i.effort).match(/(\\d+)\\s*(day|week)/);\n return s + (m ? Number(m[1]) * (m[2] === \"week\" ? 5 : 1) : 0);\n }, 0);\n const nextPhase = items.find((i) => !i.implemented);\n\n let lastPhase: number | null | undefined = null;\n return (\n <div className=\"fd-stack\" style={{ gap: 16, maxWidth: 1000 }}>\n <div className=\"fd-stack\" style={{ gap: 10 }}>\n <span className=\"fd-overline fd-muted\">Architecture</span>\n <h1 className=\"fd-h1\" style={{ margin: 0 }}>{title}</h1>\n <p className=\"fd-body fd-secondary fd-prose\" style={{ margin: 0 }}>\n {lede || \"Every screen and feature in these tools is already designed and working against a simulated backend. This is the plan for connecting them to the real one — so the only work described here is server work.\"}\n </p>\n </div>\n\n <div className=\"fd-grid-stats is-thin\">\n <StatTile compact label=\"Wired\" value={String(rm.shipped)} sub={\"of \" + rm.items.length + \" features\"} />\n <StatTile compact label=\"Remaining\" value={String(rm.remaining)} sub=\"backend work\" />\n <StatTile compact label=\"Est. effort\" value={days ? days + \" days\" : \"—\"} sub=\"sum of estimates, not calendar\" />\n <StatTile compact label=\"Up next\" value={nextPhase ? \"Phase \" + nextPhase.phase : \"—\"} sub={nextPhase ? nextPhase.phaseName : \"all wired\"} />\n </div>\n\n <div className=\"fd-row\" style={{ gap: 10, flexWrap: \"wrap\" }}>\n <Input icon=\"magnifying-glass\" placeholder=\"Find a feature or a piece of backend work\" value={q} onChange={(e) => setQ(e.target.value)} style={{ width: 300 }} />\n <Select placeholder=\"All projects\" value={project} onChange={(e) => setProject(e.target.value)} options={projects} style={{ width: 190 }} />\n <span style={{ flex: 1 }} />\n <Button size=\"sm\" variant=\"secondary\" icon=\"arrow-down\"\n onClick={() => { const b = scrollRef.current, m = nowRef.current; if (b) b.scrollTop = m ? Math.max(0, m.offsetTop - 28) : b.scrollHeight; }}>\n Jump to now\n </Button>\n </div>\n\n <Flag tone=\"info\" statement=\"Shipped means its endpoints are live — nothing here is marked done by hand.\"\n cost=\"A feature counts as shipped only when every endpoint it declares is served by the real backend, so this page cannot drift from the app. Dates are targets, not commitments; effort is the size of the backend work, and the ordering follows each feature's dependencies — a slip early in the list moves everything below it.\"\n actions={null} />\n\n <div className=\"fd-rm\">\n <div className=\"fd-rm-scroll\" ref={scrollRef}>\n <div className=\"fd-rm-track\">\n <span className=\"fd-rm-spine\">\n <span className=\"fd-rm-spine-done\" style={{ height: items.length ? (100 * shippedShown / items.length) + \"%\" : \"0%\" }} />\n </span>\n {items.map((item, n) => {\n /* Group by build phase, not by quarter. A quarter header says when; a phase header\n says what unblocks what, which is the only reason the order is what it is. */\n const showPhase = item.phase !== lastPhase;\n lastPhase = item.phase;\n const inPhase = items.filter((i) => i.phase === item.phase).length;\n const isBoundary = n === firstPending;\n return (\n <React.Fragment key={item.key}>\n {showPhase ? (\n <div className=\"fd-rm-era\">\n <span className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\", alignItems: \"baseline\" }}>\n <span style={{ fontWeight: 700 }}>{item.phase === 0 ? \"Shipped\" : \"Phase \" + item.phase + \" — \" + item.phaseName}</span>\n {item.phase === 0 ? null : (\n <span className=\"fd-mono\" style={{ opacity: 0.7, fontWeight: 400 }}>\n {fmtDate(item.phaseStart)} – {fmtDate(item.date)}\n </span>)}\n <span style={{ opacity: 0.7, fontWeight: 400 }}>· {inPhase} feature{inPhase === 1 ? \"\" : \"s\"}</span>\n </span>\n {item.phaseWhy ? <p className=\"fd-rm-era-why\">{item.phaseWhy}</p> : null}\n </div>\n ) : null}\n {isBoundary ? (\n <div className=\"fd-rm-now\" ref={nowRef}>\n <span className=\"fd-rm-now-pill\"><i className=\"ph ph-map-pin\" /> You are here — everything above is wired</span>\n </div>\n ) : null}\n <div className=\"fd-rm-row\">\n <span className={\"fd-rm-dot \" + (item.implemented ? \"is-shipped\" : item.status === \"next\" ? \"is-next\" : \"\")} />\n <div className=\"fd-rm-date\">\n {fmtDate(item.date)}\n <br />\n <span style={{ opacity: 0.75 }}>{item.implemented ? \"shipped\" : \"phase \" + item.phase}</span>\n </div>\n <RoadmapCard item={item} byKey={byKey} onOpenFlag={onOpenFlag} />\n </div>\n </React.Fragment>\n );\n })}\n {!items.length ? <p className=\"fd-body-sm fd-muted\">Nothing matches that filter.</p> : null}\n </div>\n </div>\n </div>\n\n <p className=\"fd-body-sm fd-muted\" style={{ margin: 0 }}>\n Derived from the feature-flag registry — each entry's status is its flag's <code className=\"fd-mono\">implemented</code> field,\n so this page cannot drift from what the apps actually do.\n </p>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/* Runtime mode and feature completeness.\n\n The correction this file exists to make: completeness is NOT a field on a feature record.\n A row in a table saying `implemented: true` is a claim someone typed; it drifts the moment\n code changes, and nothing enforces it. The code already knows — a feature is complete when\n the endpoints it depends on are served by a real backend. So that is where it is declared,\n and everything else is derived.\n\n Two code-owned lists, both here, both meant to be edited by whoever ships the backend:\n\n WIRED_ENDPOINTS endpoint ids the REAL service answers. Empty today: every request in this\n build goes to the simulated transport. Add an id the day it goes live.\n CLIENT_ONLY features that need no backend at all — pure front-end behaviour. These are\n complete by construction and must never be obstructed.\n\n A feature declares the endpoints it needs via `RuntimeKit.declare()`. It is complete when\n every one of those endpoints is wired. Nothing to keep in sync, nothing to forget: ship the\n endpoint, add its id, and every feature that depended on it stops being under construction.\n\n This package ships with WIRED_ENDPOINTS permanently empty — it has no way to know which\n endpoints any given consuming app has actually wired up. A consumer that has shipped real\n backend work for a feature tells this module so via `RuntimeKit.wireEndpoints(ids)`, the\n mirror of `declare()`: call it once, early (before first render), with the real list. Additive\n and idempotent, same as `declare()` — safe to call from more than one place in a consuming\n app without one caller clobbering another's ids.\n\n MODE is the other half. Under construction is the honest state for a demo, but it is useless\n for design review — you cannot evaluate a screen through a blur. So:\n\n live what a user would see today. Every incomplete feature is obstructed.\n test every feature usable, no obstruction, all data simulated.\n\n Test mode is not a bypass of a specific gate — it is a statement about the whole build, which\n is why it is one switch and not a per-feature escape. Admins only: a member seeing test mode\n would be looking at a product that does not exist yet. */\n\n/** Runtime mode and computed feature completeness. */\nexport interface FeatureStatus {\n /** Every endpoint this feature needs is served by the real backend. */\n complete: boolean;\n /** Endpoint ids still unserved. */\n missing: string[];\n /** No requirements were declared — treated as incomplete (fails closed). */\n undeclared?: boolean;\n /** Needs no backend at all. */\n clientOnly?: boolean;\n}\nexport interface RuntimeSummary { total: number; complete: number; incomplete: number; endpointsWired: number }\n\nconst WIRED_ENDPOINTS: string[] = [\n // Nothing yet. Every id below would come from a real service:\n // \"plan.get\", \"placements.list\", …\n];\n\nconst CLIENT_ONLY: string[] = [\n // Rendered from code and the flag registry — no request, so nothing to wait for.\n \"planner.apiSpec\", \"planner.algorithm\", \"planner.roadmap\"\n];\n\n/* What each feature needs. This is the artifact that replaces `implemented` on the record: it is\n read by engineers as a checklist and by the UI as truth. Endpoint ids match the API spec.\n A feature not listed here fails closed — see status(). */\nconst FEATURE_NEEDS: Record<string, string[]> = {\n // Media Planner · brief and solve\n \"planner.setup\": [\"brief.update\"],\n \"planner.briefParse\": [\"brief.parse\"],\n \"planner.goals\": [\"goals.create\", \"goals.update\", \"goals.delete\", \"goals.review\"],\n \"planner.goalTweaks\": [\"tweaks.list\", \"goals.applyTweak\", \"tweaks.revert\", \"tweaks.refine\", \"goals.dismissTweak\"],\n \"planner.import\": [\"inventory.import\", \"inventory.mapMediaType\", \"inventory.ackWarning\", \"inventory.request\"],\n \"planner.solve\": [\"plan.solve\"],\n\n // Media Planner · plan screens\n \"planner.overview\": [\"plan.get\"],\n \"planner.attentionFlags\": [\"plan.get\"],\n \"planner.saturationDistribution\": [\"plan.get\"],\n \"planner.mixGap\": [\"plan.get\"],\n \"planner.decisionTrace\": [\"plan.model\"],\n \"planner.schools\": [\"schools.list\"],\n \"planner.reallocate\": [\"reallocate.preview\", \"reallocate.commit\"],\n \"planner.campusDetail\": [\"schools.list\", \"placements.list\"],\n \"planner.channelContribution\": [\"placements.list\"],\n \"planner.surroundSound\": [\"placements.list\"],\n \"planner.campusNudges\": [\"campus.applyRecommendation\"],\n \"planner.placements\": [\"placements.list\"],\n \"planner.placementSwap\": [\"placements.alternatives\", \"placements.swap\"],\n \"planner.savedViews\": [\"views.save\"],\n \"planner.bulkEdit\": [\"placements.update\"],\n \"planner.columnPicker\": [\"prefs.update\"],\n \"planner.groupBy\": [\"placements.list\"],\n \"planner.csvExport\": [\"placements.list\"],\n \"planner.excluded\": [\"excluded.list\"],\n \"planner.addCampus\": [\"excluded.include\"],\n \"planner.map\": [\"geo.campuses\", \"geo.states\"],\n \"planner.flights\": [\"flights.list\"],\n \"planner.flightShift\": [\"flights.shift\"],\n \"planner.scenarios\": [\"scenarios.list\", \"scenarios.matrix\"],\n \"planner.scenarioPromote\": [\"scenarios.promote\"],\n \"planner.scenarioDuplicate\": [\"scenarios.create\", \"scenarios.delete\"],\n \"planner.versions\": [\"versions.list\"],\n \"planner.versionDiff\": [\"versions.list\"],\n \"planner.versionRestore\": [\"versions.restore\"],\n \"planner.algorithmConfig\": [\"config.get\", \"config.update\", \"config.reset\"],\n \"planner.algorithmSimulate\": [\"config.simulate\"],\n\n // Media Planner · delivery\n \"planner.export\": [\"plan.get\"],\n \"planner.exportXlsx\": [\"export.xlsx\"],\n \"planner.exportPdf\": [\"export.pdf\"],\n \"planner.clientView\": [\"client.view\"],\n \"planner.clientPreview\": [\"client.view\"],\n \"planner.clientPresentation\": [\"presentation.update\"],\n \"planner.clientPlacementDetail\": [\"client.view\"],\n \"planner.shareLinks\": [\"share.list\", \"share.create\", \"share.update\", \"share.revoke\"],\n\n // Assistant\n \"planner.assistant\": [\"chat.resolveThread\", \"chat.sendMessage\", \"chat.getJob\", \"chat.getThread\"],\n \"planner.assistantApply\": [\"chat.sendMessage\", \"plan.undo\"],\n \"planner.assistantHistory\": [\"chat.listThreads\", \"chat.createThread\", \"chat.deleteThread\"],\n \"chat.agentPanel\": [\"chat.resolveThread\", \"chat.sendMessage\"],\n \"chat.attachments\": [\"chat.uploadAttachment\"],\n\n // Admin\n \"admin.users\": [\"users.list\"],\n \"admin.roles\": [\"roles.list\", \"permissions.list\"],\n \"admin.flags\": [\"flags.list\"],\n \"admin.audit\": [\"audit.list\"],\n \"admin.bulkInvite\": [\"users.invite\"],\n \"admin.ssoEnforcement\": [\"users.update\"],\n \"admin.roleEditor\": [\"roles.create\", \"roles.update\", \"roles.delete\"],\n \"admin.flagTargeting\": [\"flags.update\", \"flags.evaluate\"],\n \"admin.auditExport\": [\"audit.export\"],\n\n // Platform (college-side)\n \"platform.creativeReview\": [\"plan.get\"],\n \"platform.verification\": [\"plan.get\"]\n};\n\nconst MODE_STORE = \"fd.runtime.mode.v1\";\nconst listeners = new Set<(mode: \"live\" | \"test\") => void>();\nlet needs: Record<string, string[]> = {}; // featureKey -> endpoint ids\n\nfunction read(): \"live\" | \"test\" {\n try {\n const v = localStorage.getItem(MODE_STORE);\n return v === \"test\" || v === \"live\" ? v : \"live\";\n } catch { return \"live\"; }\n}\nfunction emit(): void { listeners.forEach((fn) => fn(mode)); }\n\nlet mode: \"live\" | \"test\" = read();\n\nexport const RuntimeKit = {\n WIRED_ENDPOINTS,\n CLIENT_ONLY,\n FEATURE_NEEDS,\n\n /** Register what each feature needs: { \"planner.flights\": [\"flights.list\", \"flights.shift\"] } */\n declare(map: Record<string, string[]>): void { needs = Object.assign({}, needs, map || {}); },\n needsOf(key: string): string[] { return needs[key] || []; },\n /** Every declared feature, for the admin surface. */\n declared(): string[] { return Object.keys(needs); },\n\n /** Tell this module which endpoints the consuming app has actually wired to a real backend.\n * Additive — merges into WIRED_ENDPOINTS, never replaces it, so multiple call sites in a\n * consuming app (or a call that runs more than once, e.g. React strict-mode double-invoke)\n * compose safely instead of one clobbering another. Call once, early, before first render:\n * status() reads WIRED_ENDPOINTS live but nothing here triggers a re-render on its own. */\n wireEndpoints(ids: string[]): void {\n (ids || []).forEach((id) => { if (WIRED_ENDPOINTS.indexOf(id) < 0) WIRED_ENDPOINTS.push(id); });\n },\n\n isEndpointWired(id: string): boolean { return WIRED_ENDPOINTS.indexOf(id) >= 0; },\n\n /** The whole point: complete is computed, never stored. */\n status(key: string): FeatureStatus {\n if (CLIENT_ONLY.indexOf(key) >= 0) return { complete: true, clientOnly: true, missing: [] };\n const req = needs[key];\n // A feature nobody declared is treated as needing a backend. Failing closed is right here:\n // an undeclared feature quietly reading as \"done\" is exactly the drift this file removes.\n if (!req || !req.length) return { complete: false, undeclared: true, missing: [] };\n const missing = req.filter((id) => WIRED_ENDPOINTS.indexOf(id) < 0);\n return { complete: missing.length === 0, missing: missing };\n },\n isComplete(key: string): boolean { return RuntimeKit.status(key).complete; },\n\n getMode(): \"live\" | \"test\" { return mode; },\n isTest(): boolean { return mode === \"test\"; },\n setMode(next: \"live\" | \"test\"): void {\n const m: \"live\" | \"test\" = next === \"test\" ? \"test\" : \"live\";\n if (m === mode) return;\n mode = m;\n try { localStorage.setItem(MODE_STORE, m); } catch { /* private mode */ }\n emit();\n },\n subscribe(fn: (mode: \"live\" | \"test\") => void): () => void { listeners.add(fn); return () => listeners.delete(fn); },\n\n /** Counts for the admin surface and the mode popover. */\n summary(): RuntimeSummary {\n const keys = Object.keys(needs).concat(CLIENT_ONLY.filter((k) => !needs[k]));\n let complete = 0;\n keys.forEach((k) => { if (RuntimeKit.isComplete(k)) complete++; });\n return { total: keys.length, complete: complete, incomplete: keys.length - complete,\n endpointsWired: WIRED_ENDPOINTS.length };\n }\n};\n\nRuntimeKit.declare(FEATURE_NEEDS);\n\nexport function useRuntimeMode(): \"live\" | \"test\" {\n const [m, setM] = React.useState<\"live\" | \"test\">(RuntimeKit.getMode());\n React.useEffect(() => RuntimeKit.subscribe(setM), []);\n return m;\n}\n/** True when this feature should be shown obstructed right now. */\nexport function useFeatureStatus(key: string): FeatureStatus & { mode: \"live\" | \"test\"; obstruct: boolean } {\n const m = useRuntimeMode();\n const st = RuntimeKit.status(key);\n return { mode: m, complete: st.complete, missing: st.missing, undeclared: !!st.undeclared,\n clientOnly: !!st.clientOnly, obstruct: m === \"live\" && !st.complete };\n}\n\n/* Capital-initial aliases: only names starting with a capital reach window.<Namespace>, so a\n consuming app destructuring these hooks from the bundle would get undefined. The lowercase\n names stay for in-bundle imports; these are what a consumer reads. */\nexport const UseRuntimeMode = useRuntimeMode;\nexport const UseFeatureStatus = useFeatureStatus;\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\n\n/* Wraps a feature that is designed and working against the simulated transport but not yet\n wired to the real backend. The point is to let people SEE what is coming without being able\n to act on it — a disabled button teaches nothing, and hiding it entirely teaches nothing\n either. So: the real UI, blurred, behind a construction banner, fully inert.\n\n Inert is enforced three ways, because any one of them alone leaks:\n pointer-events stops mouse and touch\n inert attribute removes descendants from the tab order and the a11y tree\n aria-hidden keeps screen readers out of a surface nobody can use\n The banner itself sits outside the inert subtree so it stays readable.\n\n `bypassKey` opens a deliberate exception for the people building the thing: an administrator\n can unblur and use it. That is not a hole in the gate — the gate protects users from acting on\n a surface whose writes go nowhere, and an admin already knows. The escape stays honest: a\n persistent bar remains on screen saying the data is simulated, so nobody forgets which side of\n the line they are on, and re-blurring is one click away. */\n\nconst BYPASS_STORE = \"fd.soon.bypass.v1\";\n\nfunction readBypassed(): string[] {\n try { return JSON.parse(sessionStorage.getItem(BYPASS_STORE) || \"[]\"); } catch (e) { return []; }\n}\nfunction writeBypassed(list: string[]): void {\n try { sessionStorage.setItem(BYPASS_STORE, JSON.stringify(list)); } catch (e) { /* private mode */ }\n}\n/* Session-scoped, not local: the bypass is for one working session. Persisting it across days\n would quietly become the default state and the warning would stop being read. */\nfunction useBypass(key?: string): [boolean, (next: boolean) => void] {\n const [on, setOn] = React.useState(() => !!key && readBypassed().indexOf(key) >= 0);\n React.useEffect(() => { setOn(!!key && readBypassed().indexOf(key) >= 0); }, [key]);\n const set = (next: boolean) => {\n if (!key) return;\n const list = readBypassed().filter((k) => k !== key);\n if (next) list.push(key);\n writeBypassed(list);\n setOn(next);\n };\n return [on, set];\n}\n\ninterface SoonCardProps {\n label?: string;\n detail?: string;\n backend?: string | null;\n eta?: string | null;\n effort?: string;\n onRoadmap?: () => void;\n allowed?: boolean;\n onBypass?: () => void;\n}\nfunction SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }: SoonCardProps) {\n return (\n <>\n <span className=\"fd-soon-badge\">\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n {label}\n </span>\n {detail ? <span className=\"fd-soon-detail\">{detail}</span> : null}\n {backend ? <span className=\"fd-soon-backend\"><span className=\"fd-overline\">Needs</span> {backend}</span> : null}\n {eta || effort || onRoadmap ? (\n <span className=\"fd-soon-meta\">\n {eta ? <span><i className=\"ph ph-calendar-blank\" aria-hidden=\"true\" /> {eta}</span> : null}\n {effort ? <span><i className=\"ph ph-hourglass-medium\" aria-hidden=\"true\" /> {effort}</span> : null}\n {onRoadmap ? (\n <button type=\"button\" className=\"fd-soon-link\" onClick={onRoadmap}>\n See the roadmap <i className=\"ph ph-arrow-right\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </span>\n ) : null}\n {allowed ? (\n <button type=\"button\" className=\"fd-soon-view\" onClick={onBypass}>\n <i className=\"ph ph-eye\" aria-hidden=\"true\" /> View and use it anyway\n </button>\n ) : null}\n </>\n );\n}\n\ninterface HoverCardPos {\n left: number;\n top?: number;\n bottom?: number;\n width: number;\n}\n/* The inline popover is positioned fixed from the trigger's rect, not absolutely inside it:\n these markers sit in toolbars and table rows that scroll and clip, and an absolutely\n positioned card gets cut off or drags the row's width around. */\nfunction useHoverCard(open: boolean): [React.RefObject<HTMLSpanElement>, HoverCardPos | null] {\n const anchor = React.useRef<HTMLSpanElement>(null);\n const [pos, setPos] = React.useState<HoverCardPos | null>(null);\n React.useLayoutEffect(() => {\n if (!open || !anchor.current) { setPos(null); return; }\n const place = () => {\n if (!anchor.current) return;\n const r = anchor.current.getBoundingClientRect();\n const W = 340, GAP = 10, PAD = 12;\n const below = window.innerHeight - r.bottom;\n const up = below < 190 && r.top > below;\n setPos({\n left: Math.max(PAD, Math.min(r.left + r.width / 2 - W / 2, window.innerWidth - W - PAD)),\n top: up ? undefined : r.bottom + GAP,\n bottom: up ? window.innerHeight - r.top + GAP : undefined,\n width: W\n });\n };\n place();\n window.addEventListener(\"scroll\", place, true);\n window.addEventListener(\"resize\", place);\n return () => { window.removeEventListener(\"scroll\", place, true); window.removeEventListener(\"resize\", place); };\n }, [open]);\n return [anchor, pos];\n}\n\nexport interface ComingSoonProps {\n /** Banner headline. Default \"Coming soon\". */\n label?: string;\n /** Target date, already formatted for display. */\n eta?: string | null;\n /** Rough size of the remaining work, e.g. \"3 weeks\". */\n effort?: string;\n /** What has to be built on the server for this to go live. */\n backend?: string | null;\n /** One line describing the feature itself. */\n detail?: string;\n /** Blur radius in px. Default 3 — enough to stop reading, not enough to hide the shape. */\n blur?: number;\n minHeight?: number | string;\n /** \"block\" wraps a panel; \"inline\" wraps a single control (button, chip, menu item). */\n variant?: \"block\" | \"inline\";\n /** Renders a \"See the roadmap\" link when supplied. */\n onRoadmap?: () => void;\n /**\n * Flag key identifying this feature. Supply it together with `canBypass` to offer a\n * \"View and use it anyway\" escape — the choice is remembered for the session (sessionStorage,\n * not localStorage: a bypass that survives days becomes the silent default).\n */\n bypassKey?: string;\n /**\n * Whether this viewer may unblur. Gate on a permission the people building the feature hold\n * (`flags.manage`). While bypassed the feature is fully interactive, with a persistent,\n * non-dismissible bar stating that writes go to the simulated backend.\n */\n canBypass?: boolean;\n children?: React.ReactNode;\n className?: string;\n}\n\n/**\n * A feature that is designed and working but not yet wired to the real backend: the real UI,\n * blurred, behind a construction banner, and fully inert (`pointer-events`, the `inert`\n * attribute, and `aria-hidden`). Lets people see what is coming without acting on it.\n *\n * Usually reached through `FeatureGate`, which resolves the flag state for you. Use this\n * directly only when the gating decision is already made elsewhere.\n */\nexport function ComingSoon({\n label = \"Coming soon\",\n eta,\n effort,\n backend,\n detail,\n blur = 3,\n minHeight,\n /** \"block\" wraps a panel; \"inline\" wraps a single control (button, chip, menu item). */\n variant = \"block\",\n onRoadmap,\n /** Flag key. Supplying it AND `canBypass` lets the viewer unblur and use the feature. */\n bypassKey,\n canBypass = false,\n children,\n className = \"\",\n ...rest\n}: ComingSoonProps): JSX.Element {\n const [bypassed, setBypassed] = useBypass(bypassKey);\n const allowed = canBypass && !!bypassKey;\n const inline = variant === \"inline\";\n const tip = [label, detail, backend ? \"Needs \" + backend : null, eta ? \"ETA \" + eta : null, effort]\n .filter(Boolean).join(\" · \");\n\n if (inline) {\n if (allowed && bypassed) {\n return (\n <span className={[\"fd-soon-inline-on\", className].filter(Boolean).join(\" \")} {...rest}>\n {children}\n <button type=\"button\" className=\"fd-soon-cone\" title={\"Unwired — writes go to the simulated backend. \" + tip + \" Click to re-blur.\"}\n onClick={() => setBypassed(false)} aria-label=\"Re-blur this unwired feature\">\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n </button>\n </span>\n );\n }\n return (\n <InlineSoon label={label} detail={detail} backend={backend} eta={eta} effort={effort}\n onRoadmap={onRoadmap} allowed={allowed} onBypass={() => setBypassed(true)}\n blur={blur} tip={tip} className={className} rest={rest}>\n {children}\n </InlineSoon>\n );\n }\n\n if (allowed && bypassed) {\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 14 }} {...rest}>\n <div className=\"fd-soon-bar\" role=\"status\">\n <span className=\"fd-soon-badge\">\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n Unwired feature — you are using it anyway\n </span>\n <span className=\"fd-soon-bar-detail\">\n Every action here writes to the simulated backend, so nothing you do persists beyond this session.\n </span>\n <span className=\"fd-soon-bar-actions\">\n {onRoadmap ? (\n <button type=\"button\" className=\"fd-soon-link\" onClick={onRoadmap}>\n Roadmap <i className=\"ph ph-arrow-right\" aria-hidden=\"true\" />\n </button>\n ) : null}\n <button type=\"button\" className=\"fd-soon-link\" onClick={() => setBypassed(false)}>\n <i className=\"ph ph-eye-slash\" aria-hidden=\"true\" /> Re-blur\n </button>\n </span>\n </div>\n {children}\n </div>\n );\n }\n\n return (\n <div className={[\"fd-soon\", className].filter(Boolean).join(\" \")} style={minHeight ? { minHeight } : undefined} {...rest}>\n <div className=\"fd-soon-under\" style={{ filter: \"blur(\" + blur + \"px) saturate(.62)\" }} {...{ inert: \"\" } as any} aria-hidden=\"true\">\n {children}\n </div>\n <div className=\"fd-soon-veil\" />\n <div className=\"fd-soon-note\" role=\"note\">\n <SoonCard label={label} detail={detail} backend={backend} eta={eta} effort={effort}\n onRoadmap={onRoadmap} allowed={allowed} onBypass={() => setBypassed(true)} />\n </div>\n </div>\n );\n}\n\ninterface InlineSoonProps {\n label?: string;\n detail?: string;\n backend?: string | null;\n eta?: string | null;\n effort?: string;\n onRoadmap?: () => void;\n allowed?: boolean;\n onBypass?: () => void;\n blur: number;\n tip: string;\n className?: string;\n /** Leftover DOM attributes forwarded from ComingSoon's own `...rest` — untyped, same as upstream. */\n rest: any;\n children?: React.ReactNode;\n}\nfunction InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }: InlineSoonProps) {\n const [open, setOpen] = React.useState(false);\n const [anchor, pos] = useHoverCard(open);\n const close = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const show = () => {\n if (close.current) { clearTimeout(close.current); close.current = null; }\n setOpen(true);\n };\n /* A short grace period so moving the pointer from the cone into the card does not dismiss it —\n the card carries a link and a button, so it has to be reachable. */\n const hide = () => {\n if (close.current) clearTimeout(close.current);\n close.current = setTimeout(() => {\n const a = document.activeElement;\n // Focus may have moved from the cone into the card (roadmap link, bypass button) — that is\n // still \"inside\", so do not dismiss.\n if (a && (a.closest(\".fd-soon-inline\") || a.closest(\".fd-soon-hovercard\"))) return;\n setOpen(false);\n }, 140);\n };\n React.useEffect(() => () => { if (close.current) clearTimeout(close.current); }, []);\n\n return (\n <span ref={anchor} className={[\"fd-soon\", \"fd-soon-inline\", className].filter(Boolean).join(\" \")}\n onMouseEnter={show} onMouseLeave={hide} onFocus={show} onBlur={hide} {...rest}>\n <span className=\"fd-soon-under\" style={{ filter: \"blur(\" + Math.min(blur, 1.1) + \"px) saturate(.66)\" }} {...{ inert: \"\" } as any} aria-hidden=\"true\">\n {children}\n </span>\n <button type=\"button\" className=\"fd-soon-cone-mark\" aria-label={tip} title={tip}\n aria-expanded={open} onFocus={show} onBlur={hide}\n onClick={() => (open ? setOpen(false) : show())}>\n <i className=\"ph ph-traffic-cone\" aria-hidden=\"true\" />\n </button>\n {open && pos ? createPortal(\n <div className=\"fd-soon-note fd-soon-hovercard\" role=\"tooltip\"\n style={{ position: \"fixed\", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width }}\n onMouseEnter={show} onMouseLeave={hide}>\n <SoonCard label={label} detail={detail} backend={backend} eta={eta} effort={effort}\n onRoadmap={onRoadmap} allowed={allowed} onBypass={onBypass} />\n </div>, document.body) : null}\n </span>\n );\n}\n\nexport function formatEta(iso?: string | null): string | null {\n if (!iso) return null;\n const d = new Date(iso + \"T00:00:00\");\n if (isNaN(d.getTime())) return iso;\n return d.toLocaleDateString(undefined, { month: \"short\", year: \"numeric\" });\n}\n\n/* Capital-initial alias: only names starting with a capital reach window.<Namespace>, so\n consuming apps could not call formatEta and were printing raw ISO dates instead. */\nexport const FormatEta = formatEta;\n","import * as React from \"react\";\nimport { SessionKit, type Flag } from \"../../kits/session\";\nimport { ComingSoon, formatEta } from \"./ComingSoon\";\nimport { useFeatureStatus } from \"../../kits/runtime\";\n\n/* Permission and feature gating. Two deliberately different failure modes:\n\n Gate — the user is not allowed. Say so, because silence reads as a bug and\n generates a support ticket. `silent` hides instead, for chrome like a\n toolbar button where an explanation would be noise.\n FeatureGate — the feature does not exist for this user, so it leaves no trace: silence,\n not an explanation, or you have leaked the roadmap. Its third state is the\n interesting one — released but not yet wired to the backend, which renders\n the real UI inert behind a coming-soon banner. */\n\nexport interface PermissionDeniedProps {\n permission?: string | string[];\n title?: string;\n detail?: string;\n compact?: boolean;\n className?: string;\n}\n/** Explains a block rather than hiding it — silence reads as a bug and files a ticket. */\nexport function PermissionDenied({ permission, title, detail, compact = false, className = \"\", ...rest }: PermissionDeniedProps) {\n const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")}\n style={{ gap: 10, alignItems: \"flex-start\", padding: compact ? \"14px 16px\" : \"28px 24px\",\n borderRadius: 10, border: \"1px dashed var(--border-strong)\", background: \"var(--surface-2)\",\n maxWidth: 560, textAlign: \"left\" }} {...rest}>\n <span className=\"fd-row\" style={{ gap: 8 }}>\n <i className=\"ph ph-lock-simple\" style={{ fontSize: 16, color: \"var(--text-muted)\" }} aria-hidden=\"true\" />\n <span className={compact ? \"fd-label-lg\" : \"fd-h3\"}>{title || \"You do not have access to this\"}</span>\n </span>\n <p className=\"fd-body-sm fd-secondary\" style={{ margin: 0, textWrap: \"pretty\" }}>\n {detail || \"Your roles do not grant this. An administrator can change that from Admin → Users.\"}\n </p>\n {need.length ? (\n <span className=\"fd-row\" style={{ gap: 6, flexWrap: \"wrap\" }}>\n <span className=\"fd-overline fd-muted\">Requires</span>\n {need.map((p) => (\n <code key={p} className=\"fd-mono\" style={{ fontSize: 11.5, padding: \"2px 7px\", borderRadius: 5,\n border: \"1px solid var(--border)\", background: \"var(--surface)\" }}>{p}</code>\n ))}\n </span>\n ) : null}\n </div>\n );\n}\n\nexport interface GateProps {\n /** All of these must be held. */\n perm?: string | string[];\n /** At least one of these must be held. */\n anyOf?: string[];\n role?: string | string[];\n /** Render nothing instead of an explanation — for chrome like toolbar buttons. */\n silent?: boolean;\n fallback?: React.ReactNode;\n compact?: boolean;\n children?: React.ReactNode;\n}\n/** Permission gate. Denied by default shows PermissionDenied. */\nexport function Gate({ perm, anyOf, role, silent = false, fallback, compact = false, children }: GateProps): React.ReactNode {\n SessionKit.useSession();\n let ok = true;\n if (perm) ok = ok && SessionKit.can(perm);\n if (anyOf) ok = ok && SessionKit.canAny(anyOf);\n if (role) ok = ok && (Array.isArray(role) ? role.some(SessionKit.hasRole) : SessionKit.hasRole(role));\n if (ok) return children;\n if (fallback !== undefined) return fallback;\n if (silent) return null;\n return <PermissionDenied permission={perm || anyOf} compact={compact} />;\n}\n\nexport interface FeatureGateProps {\n flag: string;\n fallback?: React.ReactNode;\n children?: React.ReactNode;\n /** Renders a \"See the roadmap\" link inside the ComingSoon banner when supplied. */\n onRoadmap?: () => void;\n /** Blur radius in px for the underlying, inert UI. Passed through to ComingSoon. */\n blur?: number;\n minHeight?: number | string;\n /** Overrides the ComingSoon banner headline. Defaults to the flag's own label (or a generic one). */\n label?: string;\n /** \"block\" wraps a panel; \"inline\" wraps a single control (button, chip, menu item). Default \"block\". */\n variant?: \"block\" | \"inline\";\n /** When false, an incomplete-in-live-mode feature renders `fallback` instead of the ComingSoon banner. Default true. */\n preview?: boolean;\n /** Permission that lets the viewer bypass the ComingSoon veil and use the feature early. Default \"flags.manage\". */\n bypassPerm?: string;\n}\n/** Feature gate. ALWAYS silent when off — an unreleased feature should leave no trace. */\nexport function FeatureGate({ flag, fallback = null, children, onRoadmap, blur, minHeight, label,\n variant = \"block\", preview = true, bypassPerm = \"flags.manage\" }: FeatureGateProps): React.ReactNode {\n SessionKit.useSession();\n const rt = useFeatureStatus(flag);\n // Rollout, roles and per-user overrides — the only thing the flag record decides.\n if (!SessionKit.isEnabled(flag)) return fallback;\n // Test mode: the whole build is understood to be simulated, so nothing is obstructed.\n if (rt.complete || rt.mode === \"test\") return children;\n // Incomplete in live mode. `preview={false}` opts a call site out — use it where a blurred\n // panel would be worse than nothing, e.g. a single toolbar button.\n if (!preview) return fallback;\n const f: Partial<Flag> = SessionKit.findFlag(flag) || {};\n const missing = rt.missing || [];\n return (\n <ComingSoon label={label || (variant === \"inline\" ? f.label || \"Not wired yet\" : \"Designed — backend not wired yet\")}\n detail={f.description}\n backend={f.backend || (missing.length\n ? missing.length + \" endpoint\" + (missing.length === 1 ? \"\" : \"s\") + \" not yet served: \" + missing.join(\", \")\n : null)}\n variant={variant}\n eta={formatEta(f.eta)} effort={f.effort} blur={blur} minHeight={minHeight} onRoadmap={onRoadmap}\n bypassKey={flag} canBypass={!bypassPerm || SessionKit.can(bypassPerm)}>\n {children}\n </ComingSoon>\n );\n}\n\n/** Inline \"why is this disabled\" affordance for buttons that must stay visible. */\nexport function PermissionHint({ perm, children }: { perm: string | string[]; children?: React.ReactNode }): React.ReactNode {\n SessionKit.useSession();\n if (SessionKit.can(perm)) return children;\n return (\n <span title={\"Requires \" + (Array.isArray(perm) ? perm.join(\", \") : perm)}\n style={{ display: \"inline-flex\", opacity: 0.45, cursor: \"not-allowed\" }} aria-disabled=\"true\">\n <span style={{ pointerEvents: \"none\" }}>{children}</span>\n </span>\n );\n}\n","import * as React from \"react\";\nimport { RuntimeKit, useRuntimeMode } from \"../../kits/runtime\";\n\n/* The build-mode control. Lives in the header where the request log used to, because they are\n two views of one fact: what this build is talking to.\n\n live a lightning bolt. The default, and what a user would see. Clicking explains why so much\n is under construction and offers test mode.\n test a flask with a live request count. Everything is usable, nothing is obstructed, and the\n count makes it impossible to forget that every response is simulated. The same popover\n carries the request log and the way back.\n\n Admin-only by call site (`canToggle`) — a member switching to test mode would be evaluating a\n product that does not exist. When they cannot toggle, the control is not rendered at all\n rather than shown disabled: the mode is not their concern. */\n\nexport interface ModeSwitchProps {\n /** Render nothing unless true. Pass SessionKit.can(\"flags.manage\"). */\n canToggle?: boolean;\n /** Simulated requests this session — shown as a count badge in test mode. */\n requestCount?: number;\n onClearLog?: () => void;\n /** Request-log body, rendered inside the popover in test mode only. */\n renderLog?: () => React.ReactNode;\n onOpenSpec?: () => void;\n summary?: { total: number; complete: number; incomplete: number; endpointsWired: number };\n}\n/** Header control: lightning in live mode, flask + request count in test mode. */\nexport function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }: ModeSwitchProps): React.ReactNode {\n const mode = useRuntimeMode();\n const [open, setOpen] = React.useState(false);\n const ref = React.useRef<HTMLSpanElement>(null);\n React.useEffect(() => {\n if (!open) return;\n const away = (e: PointerEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); };\n const esc = (e: KeyboardEvent) => { if (e.key === \"Escape\") setOpen(false); };\n document.addEventListener(\"pointerdown\", away);\n document.addEventListener(\"keydown\", esc);\n return () => { document.removeEventListener(\"pointerdown\", away); document.removeEventListener(\"keydown\", esc); };\n }, [open]);\n if (!canToggle) return null;\n\n const test = mode === \"test\";\n const s = summary || RuntimeKit.summary();\n const go = (next: \"live\" | \"test\") => { RuntimeKit.setMode(next); setOpen(false); };\n\n return (\n <span style={{ position: \"relative\", display: \"inline-flex\" }} ref={ref}>\n <button type=\"button\" onClick={() => setOpen(!open)}\n aria-label={test ? \"Test mode — \" + requestCount + \" simulated requests\" : \"Live mode\"}\n aria-expanded={open}\n title={test ? \"Test mode — every response is simulated. Click to inspect requests or return to live mode.\"\n : \"Live mode — incomplete features are shown under construction. Click for test mode.\"}\n className={\"fd-mode-btn\" + (test ? \" is-test\" : \"\") + (open ? \" is-open\" : \"\")}>\n <i className={\"ph \" + (test ? \"ph-flask\" : \"ph-lightning\")} style={{ fontSize: 17 }} />\n {test && requestCount ? (\n <span key={requestCount} className=\"fd-mono fd-mode-count\">{requestCount > 99 ? \"99+\" : requestCount}</span>\n ) : null}\n </button>\n\n {open ? (\n <span className=\"fd-view-enter fd-mode-pop\">\n <span className=\"fd-row\" style={{ gap: 10, padding: \"12px 14px\", borderBottom: \"1px solid var(--border)\" }}>\n <span className={\"fd-badge \" + (test ? \"fd-badge-warning\" : \"fd-badge-neutral\")}>\n <i className={\"ph \" + (test ? \"ph-flask\" : \"ph-lightning\")} aria-hidden=\"true\" />\n {test ? \"Test mode\" : \"Live mode\"}\n </span>\n {test ? <span className=\"fd-body-sm fd-muted fd-mono\">{requestCount} simulated request{requestCount === 1 ? \"\" : \"s\"}</span> : null}\n <span style={{ flex: 1 }} />\n {test && onClearLog ? (\n <button type=\"button\" className=\"fd-soon-link\" onClick={onClearLog}>Clear</button>\n ) : null}\n </span>\n\n <span style={{ display: \"block\", padding: \"12px 14px\", borderBottom: \"1px solid var(--border)\" }}>\n <span className=\"fd-body-sm fd-secondary\" style={{ display: \"block\", textWrap: \"pretty\" }}>\n {test\n ? \"Every feature is usable and nothing is obstructed, but no response comes from a real service — nothing you do here persists. Use this to review and demo the design.\"\n : \"This is what a user would see today. \" + s.incomplete + \" of \" + s.total + \" features depend on backend work that is not wired yet, so they render under construction.\"}\n </span>\n <span className=\"fd-row\" style={{ gap: 8, marginTop: 10, flexWrap: \"wrap\" }}>\n <span className=\"fd-body-sm fd-muted fd-mono\">\n {s.endpointsWired} endpoint{s.endpointsWired === 1 ? \"\" : \"s\"} live · {s.complete}/{s.total} features complete\n </span>\n {onOpenSpec ? (\n <>\n <span style={{ flex: 1 }} />\n <button type=\"button\" className=\"fd-soon-link\" onClick={() => { setOpen(false); onOpenSpec(); }}>\n API spec <i className=\"ph ph-arrow-right\" aria-hidden=\"true\" />\n </button>\n </>\n ) : null}\n </span>\n </span>\n\n <span className=\"fd-mode-choice\">\n <button type=\"button\" className={\"fd-mode-opt\" + (!test ? \" is-on\" : \"\")} onClick={() => go(\"live\")}>\n <i className=\"ph ph-lightning\" aria-hidden=\"true\" />\n <span className=\"fd-mode-opt-text\">\n <span className=\"fd-mode-opt-title\">Live mode</span>\n <span className=\"fd-mode-opt-desc\">Incomplete features under construction</span>\n </span>\n {!test ? <i className=\"ph ph-check\" aria-hidden=\"true\" /> : null}\n </button>\n <button type=\"button\" className={\"fd-mode-opt\" + (test ? \" is-on\" : \"\")} onClick={() => go(\"test\")}>\n <i className=\"ph ph-flask\" aria-hidden=\"true\" />\n <span className=\"fd-mode-opt-text\">\n <span className=\"fd-mode-opt-title\">Test mode</span>\n <span className=\"fd-mode-opt-desc\">Everything usable, all data simulated</span>\n </span>\n {test ? <i className=\"ph ph-check\" aria-hidden=\"true\" /> : null}\n </button>\n </span>\n\n {test && renderLog ? (\n <span style={{ display: \"block\", maxHeight: 340, overflowY: \"auto\", borderTop: \"1px solid var(--border)\" }}>\n {renderLog()}\n </span>\n ) : null}\n </span>\n ) : null}\n </span>\n );\n}\n\n/* A persistent strip for test mode. The header icon is easy to stop noticing; a bar at the top of\n the app is not. Rendered by the shell, above everything. */\nexport interface TestModeBarProps { onExit?: () => void }\n/** Persistent strip shown only in test mode. Render at the top of the app frame. */\nexport function TestModeBar({ onExit }: TestModeBarProps): React.ReactNode {\n const mode = useRuntimeMode();\n if (mode !== \"test\") return null;\n return (\n <div className=\"fd-testbar\" role=\"status\">\n <span className=\"fd-badge fd-badge-warning\">\n <i className=\"ph ph-flask\" aria-hidden=\"true\" />\n Test mode\n </span>\n <span className=\"fd-testbar-detail\">\n Every feature is unlocked and every response is simulated — nothing here persists.\n </span>\n <button type=\"button\" className=\"fd-soon-link\" onClick={() => (onExit ? onExit() : RuntimeKit.setMode(\"live\"))}>\n <i className=\"ph ph-lightning\" aria-hidden=\"true\" /> Back to live mode\n </button>\n </div>\n );\n}\n","import * as React from \"react\";\n\n/**\n * The canonical channel taxonomy. One icon and one hue per medium, used\n * everywhere a channel is named — table cells, charts, legends, filters, the\n * client view. The colour is part of the label, not decoration.\n *\n * Hue families: blues = large format, violets = moving, ambers = paper,\n * roses = direct, slate = digital.\n *\n * `physical` is a descriptive family property, NOT a weight. The model spec\n * (v2026-07-21 §4) assigns each channel its own weight from four factor scores —\n * 23 to 50, with persistence separating the tiers. Read weights from\n * window.CHANNEL_WEIGHT / MODEL.weights, never from this flag.\n */\n/* Channel weights, spec v2026-07-21 §4: weight = (visual + invasiveness) x persistence\n x social + 20. Duplicated here (not read from window.MODEL) so the component works in\n any consuming project, with or without the planner kit loaded. */\nexport const CHANNEL_WEIGHTS: Record<string, number> = {\n \"OOH\": 50, \"DOOH\": 50, \"Transit\": 48, \"Posters\": 44, \"Mobile Billboards\": 34,\n \"Flyers\": 33, \"SMS\": 26, \"Email\": 25.5, \"Print\": 24.5,\n \"Website (takeover)\": 24.5, \"Website (CPM)\": 23,\n \"Street Team\": 33, \"Print-Ribbon\": 24.5 // aliases, spec §9\n};\nconst W = CHANNEL_WEIGHTS;\n\n/** Spec §4 weight for a channel name, resolving §9 aliases. 0 = unmodeled (contributes no CRP). */\nexport function channelWeightOf(channel: string): number {\n const k = String(channel || \"\").trim();\n return W[k] != null ? W[k] : 0;\n}\n/* Capital-initial alias: only names starting with a capital reach window.<Namespace>, so a\n consuming project destructuring the lowercase form off the bundle would get undefined. */\nexport const ChannelWeightOf = channelWeightOf;\n\nexport interface ChannelMetaRecord {\n label: string;\n /** Phosphor icon name, without the `ph-` prefix. */\n icon: string;\n /** CSS custom-property reference, e.g. \"var(--ch-ooh)\". */\n color: string;\n /** Hue family: Large format | Moving | Paper | Direct | Digital | Other. */\n family: string;\n /** Descriptive family property, not a weight. Channel weights live in MODEL.weights (spec §4). */\n physical: boolean;\n name?: string;\n}\n\n/**\n * The canonical channel taxonomy — one icon and one hue per medium. Every screen\n * that names a channel reads from this, so a colour always means the same thing.\n */\nexport const CHANNELS: Record<string, ChannelMetaRecord> = {\n \"OOH\": { label: \"OOH\", icon: \"flag-banner\", color: \"var(--ch-ooh)\", family: \"Large format\", physical: true },\n \"DOOH\": { label: \"DOOH\", icon: \"television-simple\", color: \"var(--ch-dooh)\", family: \"Large format\", physical: true },\n \"Transit\": { label: \"Transit\", icon: \"bus\", color: \"var(--ch-transit)\", family: \"Moving\", physical: true },\n \"Mobile Billboards\": { label: \"Mobile\", icon: \"truck\", color: \"var(--ch-mobile)\", family: \"Moving\", physical: true },\n \"Print\": { label: \"Print\", icon: \"newspaper\", color: \"var(--ch-print)\", family: \"Paper\", physical: true },\n \"Posters\": { label: \"Posters\", icon: \"push-pin\", color: \"var(--ch-posters)\", family: \"Paper\", physical: true },\n \"Flyers\": { label: \"Flyers\", icon: \"note\", color: \"var(--ch-flyers)\", family: \"Paper\", physical: true },\n \"Email\": { label: \"Email\", icon: \"envelope-simple\", color: \"var(--ch-email)\", family: \"Direct\", physical: false },\n \"SMS\": { label: \"SMS\", icon: \"chat-centered-text\", color: \"var(--ch-sms)\", family: \"Direct\", physical: false },\n \"Website (CPM)\": { label: \"Web · CPM\", icon: \"browser\", color: \"var(--ch-web)\", family: \"Digital\", physical: false },\n \"Website (takeover)\": { label: \"Web · takeover\", icon: \"browsers\", color: \"var(--ch-web)\", family: \"Digital\", physical: false },\n \"Web\": { label: \"Web\", icon: \"browser\", color: \"var(--ch-web)\", family: \"Digital\", physical: false }\n};\n\nconst FALLBACK: ChannelMetaRecord = { label: \"Other\", icon: \"tag\", color: \"var(--ch-other)\", family: \"Other\", physical: false };\n\n/** Resolve any channel spelling (exact, lowercase key, partial) to its record. */\nexport function ChannelMeta(name?: string | null): ChannelMetaRecord {\n if (!name) return FALLBACK;\n if (CHANNELS[name]) return { ...CHANNELS[name], name };\n const k = String(name).toLowerCase().trim();\n const hit = Object.keys(CHANNELS).find((key) => key.toLowerCase() === k);\n if (hit) return { ...CHANNELS[hit], name: hit };\n // partial: \"website\", \"outdoor\", \"poster\"\n const loose = Object.keys(CHANNELS).find((key) => key.toLowerCase().startsWith(k) || k.startsWith(key.toLowerCase()));\n if (loose) return { ...CHANNELS[loose], name: loose };\n if (/web|site|display|banner/.test(k)) return { ...CHANNELS[\"Web\"], name };\n return { ...FALLBACK, label: String(name), name };\n}\n\nexport interface ChannelTagProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Channel name — \"OOH\", \"Website (CPM)\", \"transit\"… */\n channel?: string | null;\n size?: \"sm\" | \"md\";\n /** Hide the text and show icon only (dense tables). */\n showLabel?: boolean;\n /** Render as a bare colour swatch, for chart legends. */\n dot?: boolean;\n /** Append the channel's spec §4 weight after the label. */\n weight?: boolean;\n className?: string;\n}\n\n/**\n * The standard way to render a channel name. Icon + hue + label, in a tinted\n * chip. Use `dot` for a bare colour swatch in dense legends.\n */\nexport function ChannelTag({ channel, size = \"md\", showLabel = true, dot = false, weight = false, className = \"\", ...rest }: ChannelTagProps) {\n const m = ChannelMeta(channel);\n const wt = channelWeightOf(channel || \"\");\n if (dot) {\n return (\n <span className={[\"fd-chan-dot\", className].filter(Boolean).join(\" \")} title={m.name} style={{ background: m.color }} {...rest} />\n );\n }\n return (\n <span className={[\"fd-chan\", size === \"sm\" ? \"fd-chan-sm\" : \"\", className].filter(Boolean).join(\" \")}\n title={m.name + \" · \" + m.family + (wt ? \" · weight \" + wt : \" · unmodeled, 0 CRP\")}\n style={{ \"--chan\": m.color } as React.CSSProperties} {...rest}>\n <i className={\"ph ph-\" + m.icon} aria-hidden=\"true\" />\n {showLabel ? <span className=\"fd-chan-label\">{m.label}</span> : null}\n {weight ? <span className=\"fd-chan-weight\">{wt || 0}</span> : null}\n </span>\n );\n}\n","\ninterface Band {\n key: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n label: string;\n n: number;\n range: string;\n}\n\nconst BANDS: Band[] = [\n { key: \"weak\", label: \"Weak\", n: 1, range: \"< 50\" },\n { key: \"adequate\", label: \"Adequate\", n: 2, range: \"50–100\" },\n { key: \"strong\", label: \"Strong\", n: 3, range: \"100–200\" },\n { key: \"dominant\", label: \"Dominant\", n: 4, range: \"200+\" }\n];\n\n/**\n * The plan's shape: how funded campuses spread across the four CSI bands.\n * Each campus is one labelled block stacked in its band's column, so the\n * distribution reads as a silhouette before any number is parsed. Columns are\n * clickable to filter the school mix by band.\n */\nexport interface SaturationDistributionCampus {\n name: string;\n /** Short label shown inside the block, e.g. \"Michigan State\" */\n short?: string;\n band: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n crp?: number;\n}\nexport interface SaturationDistributionProps {\n campuses: SaturationDistributionCampus[];\n /** Band of the plan-level floor score. Renders the floor explainer strip. */\n floorBand?: \"weak\" | \"adequate\" | \"strong\" | \"dominant\";\n /** The plan floor figure, e.g. 157.2 */\n floorScore?: number | string;\n onSelectBand?: (band: string | null) => void;\n selectedBand?: string | null;\n loading?: boolean;\n className?: string;\n}\n\nexport function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelectBand, selectedBand, loading = false, className = \"\" }: SaturationDistributionProps) {\n const grouped = BANDS.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));\n const tallest = Math.max(1, ...grouped.map((g) => g.items.length));\n const floor = BANDS.find((b) => b.key === floorBand) || BANDS[0];\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 16 }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(4,1fr)\", gap: 12, alignItems: \"end\" }}>\n {grouped.map((g) => {\n const mark = \"var(--csi-\" + g.n + \"-mark)\";\n const active = selectedBand === g.key;\n return (\n <button key={g.key} type=\"button\" onClick={onSelectBand ? () => onSelectBand(active ? null : g.key) : undefined}\n style={{ display: \"flex\", flexDirection: \"column\", justifyContent: \"flex-end\", gap: 10, padding: 12, border: \"1px solid \" + (active ? \"var(--border-strong)\" : \"var(--border)\"), borderRadius: \"var(--r-lg)\", background: active ? \"var(--surface-2)\" : \"var(--surface)\", cursor: onSelectBand ? \"pointer\" : \"default\", textAlign: \"left\", minHeight: 190, transition: \"background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)\" }}>\n <span style={{ display: \"flex\", flexDirection: \"column-reverse\", gap: 4, minHeight: tallest * 24 }}>\n {loading\n ? Array.from({ length: 3 }).map((_, i) => <span key={i} className=\"fd-skel\" style={{ height: 16, borderRadius: 4 }} />)\n : g.items.map((c) => (\n <span key={c.name} title={c.name + \" · \" + c.crp}\n style={{ height: 18, borderRadius: 4, background: \"var(--csi-\" + g.n + \"-fill)\", border: \"1px solid var(--csi-\" + g.n + \"-edge)\", color: \"var(--csi-\" + g.n + \"-text)\", display: \"flex\", alignItems: \"center\", padding: \"0 7px\", fontSize: 10, fontWeight: 700, overflow: \"hidden\", whiteSpace: \"nowrap\" }}>\n {c.short || c.name}\n </span>\n ))}\n </span>\n <span className=\"fd-row\" style={{ gap: 8, alignItems: \"baseline\" }}>\n <span className=\"fd-num-hero\" style={{ fontSize: 30, color: g.items.length ? \"var(--text)\" : \"var(--text-disabled)\" }}>\n {loading ? \"–\" : g.items.length}\n </span>\n <span className=\"fd-meter\" style={{ gap: 2, color: mark }} aria-hidden=\"true\">\n {[1, 2, 3, 4].map((i) => <span key={i} className={\"fd-meter-seg\" + (i <= g.n ? \" is-on\" : \"\")} style={{ width: 4, height: 9 }} />)}\n </span>\n </span>\n <span className=\"fd-stack\" style={{ gap: 1 }}>\n <span className=\"fd-label-lg\">{g.label}</span>\n <span className=\"fd-body-sm fd-muted\" style={{ fontSize: 11.5 }}>CRP {g.range}</span>\n </span>\n </button>\n );\n })}\n </div>\n {floorBand ? (\n <div className=\"fd-row\" style={{ gap: 10, padding: \"12px 14px\", borderRadius: \"var(--r-md)\", background: \"var(--surface-2)\", border: \"1px solid var(--border)\", flexWrap: \"wrap\" }}>\n <span className=\"fd-meter\" style={{ gap: 2, color: \"var(--csi-\" + floor.n + \"-mark)\" }} aria-hidden=\"true\">\n {[1, 2, 3, 4].map((i) => <span key={i} className={\"fd-meter-seg\" + (i <= floor.n ? \" is-on\" : \"\")} style={{ width: 5, height: 12 }} />)}\n </span>\n <span className=\"fd-body-sm fd-secondary\" style={{ flex: 1, minWidth: 240 }}>\n <strong style={{ color: \"var(--text)\" }}>Plan floor {floorScore}</strong> — the saturation about 70% of students in this plan reach or exceed. Enrollment-weighted 30th percentile, not an average.\n </span>\n </div>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { ChannelTag } from \"./ChannelMeta\";\n\n/**\n * Realized media mix against the strategic target, one row per channel.\n * Realized is a solid brand bar, target a neutral tick on the same row, and the\n * gap is labelled directly on the bar — the gap is the story, so it never hides\n * in a legend.\n */\nexport interface MixGapRow {\n channel: string;\n /** Target share, percent */\n target: number;\n /** Realized share, percent */\n realized: number;\n /** Why the gap exists, e.g. \"Limited inventory at target campuses\" — shown in the hover tooltip. */\n note?: string;\n}\nexport interface MixGapProps {\n rows: MixGapRow[];\n loading?: boolean;\n className?: string;\n}\n\nexport function MixGap({ rows = [], loading = false, className = \"\" }: MixGapProps) {\n const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));\n const [hover, setHover] = React.useState<string | null>(null);\n const toneOf = (gap: number) => gap >= -1 ? \"ok\" : gap >= -4 ? \"warn\" : \"danger\";\n const TONE: Record<string, string> = { ok: \"var(--ok-solid)\", warn: \"var(--warn-solid)\", danger: \"var(--danger-solid)\" };\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 4 }}>\n <div className=\"fd-row\" style={{ gap: 16, justifyContent: \"flex-end\", paddingBottom: 6, flexWrap: \"wrap\" }}>\n {[[\"On target\", TONE.ok], [\"Close\", TONE.warn], [\"Short\", TONE.danger]].map(([l, c]) => (\n <span key={l} className=\"fd-row fd-body-sm fd-muted\" style={{ gap: 6 }}>\n <span style={{ width: 14, height: 9, borderRadius: 2, background: c }} />{l}\n </span>\n ))}\n <span className=\"fd-row fd-body-sm fd-muted\" style={{ gap: 6 }}>\n <span style={{ width: 3, height: 14, background: \"var(--n-500)\" }} />Target\n </span>\n </div>\n {rows.map((r) => {\n const gap = r.realized - r.target;\n const tone = toneOf(gap);\n const tip = \"Realized \" + r.realized + \"% vs \" + r.target + \"% target\" +\n (gap < -1 ? \" · \" + Math.abs(gap).toFixed(0) + \" pts short\" : gap > 1 ? \" · \" + gap.toFixed(0) + \" pts over\" : \" · on target\") +\n (r.note ? \" — \" + r.note : \"\");\n return (\n <div key={r.channel} className=\"fd-row\" style={{ gap: 12, padding: \"7px 0\", borderBottom: \"1px solid var(--border)\" }}\n onMouseEnter={() => setHover(r.channel)} onMouseLeave={() => setHover(null)}>\n <span style={{ width: 128, flex: \"none\" }}><ChannelTag channel={r.channel} size=\"sm\" /></span>\n <span style={{ position: \"relative\", flex: 1, height: 22, minWidth: 120 }}>\n {loading ? <span className=\"fd-skel\" style={{ position: \"absolute\", inset: \"5px 0\", borderRadius: 3 }} /> : <>\n <span style={{ position: \"absolute\", left: 0, top: 5, height: 12, width: (r.realized / max * 100) + \"%\", background: TONE[tone], borderRadius: \"2px 3px 3px 2px\", transition: \"width var(--dur-slow) var(--ease), background var(--dur-base) var(--ease)\" }} />\n <span style={{ position: \"absolute\", left: (r.target / max * 100) + \"%\", top: 0, width: 3, height: 22, background: \"var(--n-500)\", borderRadius: 1 }} />\n <span className=\"fd-num\" style={{ position: \"absolute\", right: Math.max(r.realized, r.target) / max > 0.82 ? 0 : \"auto\", left: Math.max(r.realized, r.target) / max > 0.82 ? \"auto\" : \"calc(\" + (Math.max(r.realized, r.target) / max * 100) + \"% + 10px)\", top: 2, fontSize: 12, color: \"var(--text-muted)\", whiteSpace: \"nowrap\", background: Math.max(r.realized, r.target) / max > 0.82 ? \"var(--surface)\" : \"none\", paddingLeft: 3 }}>{r.realized}%</span>\n {hover === r.channel ? (\n <span className=\"fd-tooltip\" role=\"tooltip\" style={{ position: \"absolute\", left: 0, right: \"auto\", bottom: 26, maxWidth: \"min(340px, 100%)\", whiteSpace: \"normal\", textAlign: \"left\", width: \"max-content\" }}>{tip}</span>\n ) : null}\n </>}\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n","import { channelWeightOf, ChannelMeta, ChannelTag } from \"./ChannelMeta\";\n\nconst money = (n: number) => \"$\" + Math.round(n).toLocaleString();\n\n/**\n * How one campus's CRP was built, channel by channel, with the surround-sound\n * bonus as its own hatched segment. This is the most valuable visualization in\n * the planner: it answers why a campus scores what it scores and where the\n * headroom is.\n */\nexport interface ChannelContributionChannel {\n name: string;\n /** CRP contributed by this channel */\n crp: number;\n /** Formatted spend, e.g. \"$12,400\" */\n spend?: string;\n /** Physical formats (OOH, transit, posters) carry roughly 2x the weight of feed-based digital. */\n physical?: boolean;\n color?: string;\n}\nexport interface ChannelContributionProps {\n channels: ChannelContributionChannel[];\n /** Surround-sound bonus actually earned, as a percent of the channel base. */\n bonusPct?: number;\n /** The model's ceiling. Defaults to 40. */\n bonusMax?: number;\n /** Override the computed total when the engine's figure differs from base + bonus. */\n total?: number;\n loading?: boolean;\n showTable?: boolean;\n className?: string;\n}\n\nexport function ChannelContribution({\n channels = [], bonusPct = 0, bonusMax = 40, total, loading = false, showTable = true, className = \"\"\n}: ChannelContributionProps) {\n const base = channels.reduce((s, c) => s + c.crp, 0);\n const bonus = base * (bonusPct / 100);\n const grand = total !== undefined ? total : base + bonus;\n const pct = (v: number) => (grand ? (v / grand) * 100 : 0);\n const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, \"\")), 0);\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 16 }}>\n {loading ? <span className=\"fd-skel\" style={{ height: 34, borderRadius: \"var(--r-sm)\" }} /> : (\n <div className=\"fd-row\" style={{ height: 34, borderRadius: \"var(--r-sm)\", overflow: \"hidden\", gap: 2, background: \"var(--surface-3)\" }}>\n {channels.map((c) => (\n <span key={c.name} title={c.name + \" · \" + c.crp.toFixed(1) + \" CRP\"}\n style={{ width: pct(c.crp) + \"%\", background: c.color || ChannelMeta(c.name).color, display: \"grid\", placeItems: \"center\", fontSize: 10.5, fontWeight: 700, color: \"#fff\", overflow: \"hidden\", transition: \"width var(--dur-slow) var(--ease)\" }}>\n {pct(c.crp) > 9 ? c.crp.toFixed(0) : \"\"}\n </span>\n ))}\n {bonus > 0 ? (\n <span title={\"Surround-sound bonus +\" + bonusPct + \"%\"}\n style={{ width: pct(bonus) + \"%\", background: \"repeating-linear-gradient(135deg,var(--csi-3-mark) 0 6px,var(--csi-2-mark) 6px 12px)\", display: \"grid\", placeItems: \"center\", fontSize: 10.5, fontWeight: 700, color: \"#fff\" }}>\n {pct(bonus) > 9 ? \"+\" + bonus.toFixed(0) : \"\"}\n </span>\n ) : null}\n </div>\n )}\n\n {showTable ? (\n <table className=\"fd-table\" style={{ fontSize: \"var(--body-sm-size)\" }}>\n <thead><tr>\n <th style={{ width: \"34%\" }}>Channel</th>\n <th style={{ width: \"16%\" }}>Weight</th>\n <th className=\"is-num\" style={{ width: \"16%\" }}>Spend</th>\n <th className=\"is-num\" style={{ width: \"17%\" }}>CRP</th>\n <th className=\"is-num\" style={{ width: \"17%\" }}>Share</th>\n </tr></thead>\n <tbody>\n {channels.map((c) => (\n <tr key={c.name}>\n <td><ChannelTag channel={c.name} size=\"sm\" /></td>\n <td><span className=\"fd-badge fd-badge-neutral\" style={{ height: 20, fontSize: 11 }}\n title={\"Spec §4 channel weight\" + (c.physical ? \" · physical format\" : \"\")}>{\"weight \" + (channelWeightOf(c.name) || 0)}</span></td>\n <td className=\"is-num\">{c.spend}</td>\n <td className=\"is-num\">{c.crp.toFixed(1)}</td>\n <td className=\"is-num\">{pct(c.crp).toFixed(0)}%</td>\n </tr>\n ))}\n {bonus > 0 ? (\n <tr>\n <td><span className=\"fd-row\" style={{ gap: 9, fontWeight: 600 }}>\n <span style={{ width: 9, height: 9, borderRadius: 2, background: \"repeating-linear-gradient(135deg,var(--csi-3-mark) 0 3px,var(--csi-2-mark) 3px 6px)\", flex: \"none\" }} />\n Surround-sound bonus\n </span></td>\n <td><span className=\"fd-badge fd-badge-success\" style={{ height: 20, fontSize: 11 }}>+{bonusPct}% of +{bonusMax}%</span></td>\n <td className=\"is-num fd-muted\">—</td>\n <td className=\"is-num\">{bonus.toFixed(1)}</td>\n <td className=\"is-num\">{pct(bonus).toFixed(0)}%</td>\n </tr>\n ) : null}\n <tr style={{ background: \"var(--surface-2)\" }}>\n <td style={{ fontWeight: 700 }}>Campus total</td>\n <td />\n <td className=\"is-num\" style={{ fontWeight: 700 }}>{money(spendTotal)}</td>\n <td className=\"is-num\" style={{ fontWeight: 700 }}>{grand.toFixed(1)}</td>\n <td className=\"is-num\" style={{ fontWeight: 700 }}>100%</td>\n </tr>\n </tbody>\n </table>\n ) : null}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { CsiBadge } from \"../data/CsiBadge\";\n\nconst bandFor = (crp: number) => crp >= 200 ? \"dominant\" : crp >= 100 ? \"strong\" : crp >= 50 ? \"adequate\" : \"weak\";\n\n/**\n * The planner's signature interaction: move budget at one campus and watch its\n * saturation band re-score live. The previewed band renders at 70% opacity with\n * a dashed edge until the change is committed; Escape reverts.\n */\nexport interface BudgetReallocatorProps {\n campus: string;\n /** Committed spend. */\n spend: number;\n /** Committed CRP. */\n crp: number;\n min?: number;\n max: number;\n /** Defaults to 100 — the same increment as an arrow-key step. */\n step?: number;\n /** The engine's re-score for a candidate spend. Required for a live preview. */\n scoreFor?: (spend: number) => number;\n onPreview?: (spend: number, crp: number) => void;\n onCommit?: (spend: number, crp: number) => void;\n onCancel?: () => void;\n className?: string;\n}\n\nexport function BudgetReallocator({\n campus, spend, crp, min = 0, max, step = 100, scoreFor,\n onPreview, onCommit, onCancel, className = \"\"\n}: BudgetReallocatorProps) {\n const [draft, setDraft] = React.useState(spend);\n React.useEffect(() => setDraft(spend), [spend]);\n const dirty = draft !== spend;\n const nextCrp = scoreFor ? scoreFor(draft) : crp;\n const nextBand = bandFor(nextCrp);\n const nowBand = bandFor(crp);\n const delta = draft - spend;\n const set = (v: number) => { setDraft(v); if (onPreview) onPreview(v, scoreFor ? scoreFor(v) : crp); };\n const pct = max === min ? 0 : ((draft - min) / (max - min)) * 100;\n const revert = () => { setDraft(spend); if (onCancel) onCancel(); };\n\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")}\n style={{ gap: 14, padding: 18, border: \"1px solid \" + (dirty ? \"var(--border-brand)\" : \"var(--border)\"), borderRadius: \"var(--r-lg)\", background: dirty ? \"var(--surface-brand)\" : \"var(--surface)\", color: \"var(--text)\", transition: \"background var(--dur-base) var(--ease),border-color var(--dur-base) var(--ease)\" }}>\n <div className=\"fd-row\" style={{ gap: 12, flexWrap: \"wrap\" }}>\n <span className=\"fd-h4\" style={{ flex: 1, minWidth: 140 }}>{campus}</span>\n <CsiBadge band={nowBand} crp={crp} size=\"medium\" />\n {dirty ? <>\n <i className=\"ph ph-arrow-right fd-muted\" aria-hidden=\"true\" />\n <CsiBadge band={nextBand} crp={nextCrp} size=\"medium\" preview />\n </> : null}\n </div>\n\n <div className=\"fd-slider\">\n <span className=\"fd-slider-fill\" style={{ width: pct + \"%\" }} />\n {dirty ? (\n <span className=\"fd-slider-chip\" style={{ left: pct + \"%\", background: delta < 0 ? \"var(--danger-solid)\" : \"var(--ok-solid)\" }}>\n {(delta < 0 ? \"−$\" : \"+$\") + Math.abs(delta).toLocaleString()}\n </span>\n ) : null}\n <input type=\"range\" min={min} max={max} step={step} value={draft}\n onChange={(e) => set(Number(e.target.value))}\n onKeyDown={(e) => { if (e.key === \"Escape\") revert(); }}\n aria-label={\"Budget at \" + campus} />\n </div>\n\n <div className=\"fd-row\" style={{ gap: 12, flexWrap: \"wrap\" }}>\n <span className=\"fd-stack\" style={{ gap: 2, flex: 1, minWidth: 150 }}>\n <span className=\"fd-num\" style={{ fontSize: 19, fontWeight: 700 }}>{\"$\" + draft.toLocaleString()}</span>\n <span className=\"fd-body-sm fd-muted\">Arrow keys step $100, shift+arrow $1,000. Escape reverts.</span>\n </span>\n <button type=\"button\" className=\"fd-btn fd-btn-ghost\" disabled={!dirty} onClick={revert}>Cancel</button>\n <button type=\"button\" className=\"fd-btn fd-btn-primary\" disabled={!dirty}\n onClick={() => { if (onCommit) onCommit(draft, nextCrp); }}>Commit reallocation</button>\n </div>\n </div>\n );\n}\n","\n// Categories mirror the canonical channel taxonomy in ChannelMeta — same icon,\n// same hue, so a colour means the same medium here as in every table.\nconst CATEGORIES = [\n { key: \"ooh\", label: \"OOH\", icon: \"flag-banner\", color: \"var(--ch-ooh)\" },\n { key: \"transit\", label: \"Transit\", icon: \"bus\", color: \"var(--ch-transit)\" },\n { key: \"posters\", label: \"Posters\", icon: \"push-pin\", color: \"var(--ch-posters)\" },\n { key: \"print\", label: \"Print\", icon: \"newspaper\", color: \"var(--ch-print)\" },\n { key: \"email\", label: \"Email\", icon: \"envelope-simple\", color: \"var(--ch-email)\" },\n { key: \"web\", label: \"Web\", icon: \"browser\", color: \"var(--ch-web)\" }\n];\n\n/**\n * Channel-diversity breadth at one campus and the bonus it earned or forgave.\n * The engine rewards reaching a campus through multiple reinforcing categories\n * with up to +40% on its score; thin-breadth campuses forgo most of it.\n */\nexport interface SurroundSoundProps {\n /** Category keys present: \"ooh\" | \"transit\" | \"posters\" | \"print\" | \"email\" | \"web\" */\n present: string[];\n /** Bonus actually earned, in points of percent. */\n bonusPct?: number;\n /** Model ceiling. Defaults to 40. */\n bonusMax?: number;\n /** One sentence naming what the missed breadth costs, e.g. \"+$3,000 into OOH earns +12%.\" */\n missedCost?: string;\n className?: string;\n}\n\nexport function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = \"\" }: SurroundSoundProps) {\n const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));\n const single = present.length <= 2;\n return (\n <div className={[\"fd-stack\", className].filter(Boolean).join(\" \")} style={{ gap: 14 }}>\n <div className=\"fd-row\" style={{ gap: 8, flexWrap: \"wrap\" }}>\n {CATEGORIES.map((c) => {\n const on = present.includes(c.key);\n return (\n <span key={c.key} title={c.label + (on ? \" — present\" : \" — not bought\")}\n style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 5, width: 62, padding: \"10px 0\", borderRadius: \"var(--r-md)\", border: \"1px solid \" + (on ? \"var(--csi-2-edge)\" : \"var(--border)\"), background: on ? \"var(--csi-2-fill)\" : \"var(--surface-2)\", color: on ? \"var(--csi-2-text)\" : \"var(--text-disabled)\" }}>\n <i className={\"ph ph-\" + c.icon} style={{ fontSize: 19, color: on ? c.color : \"var(--text-muted)\" }} aria-hidden=\"true\" />\n <span style={{ fontSize: 10.5, fontWeight: 700 }}>{c.label}</span>\n </span>\n );\n })}\n </div>\n <div className=\"fd-stack\" style={{ gap: 8 }}>\n <div className=\"fd-row\" style={{ justifyContent: \"space-between\", gap: 12 }}>\n <span className=\"fd-label-lg\">Surround-sound bonus earned</span>\n <span className=\"fd-num\" style={{ color: single ? \"var(--warn-text)\" : \"var(--csi-3-mark)\", fontWeight: 700 }}>\n +{bonusPct}% of +{bonusMax}%\n </span>\n </div>\n <div style={{ height: 8, borderRadius: \"var(--r-xs)\", background: \"var(--surface-3)\", overflow: \"hidden\" }}>\n <div style={{ height: \"100%\", width: (earned * 100) + \"%\", background: \"var(--csi-3-mark)\", borderRadius: \"inherit\", transition: \"width var(--dur-slow) var(--ease)\" }} />\n </div>\n <span className=\"fd-body-sm fd-secondary\" style={{ textWrap: \"pretty\" }}>\n {present.length} of 6 channel categories present.{\" \"}\n {single\n ? \"Thin breadth forgoes most of the bonus — the same dollars spread across another category score higher.\"\n : \"Students pass the same spaces daily, so reinforcing channels compound.\"}\n {missedCost ? \" \" + missedCost : \"\"}\n </span>\n </div>\n </div>\n );\n}\n","export type ImportanceLevelId = \"nudge\" | \"lean\" | \"priority\" | \"driver\" | \"dealbreaker\";\n\nexport interface ImportanceLevel {\n id: ImportanceLevelId;\n /** 1-5, ascending. This is the number the --imp-N-* tokens are keyed by. */\n rank: 1 | 2 | 3 | 4 | 5;\n /** How the level is named in the UI. */\n label: string;\n /** Phosphor icon name. */\n icon: string;\n /** One line saying what choosing this level actually does to a plan. */\n description: string;\n}\n\n/**\n * How much a single criterion is allowed to matter, as five ordered steps. Ordered\n * ascending, and index-stable: the position in this array IS the `rank`, which is what\n * the --imp-N-* colour tokens are keyed by, so reordering it would silently re-colour\n * every criterion in the product.\n *\n * The ramp runs slate → blue → indigo → amber → red, i.e. from \"barely registers\" to\n * \"nothing else matters\". It deliberately crosses from the neutral/interaction end of\n * the palette into the warning end, because that IS the semantic gradient: a\n * Deal-breaker isn't a stronger preference, it's a veto, and it should look like one.\n */\nexport const IMPORTANCE_LEVELS: ImportanceLevel[] = [\n { id: \"nudge\", rank: 1, label: \"Nudge\", icon: \"feather\", description: \"Breaks a tie, nothing more.\" },\n { id: \"lean\", rank: 2, label: \"Lean\", icon: \"arrow-bend-up-right\", description: \"A mild preference between otherwise equal options.\" },\n { id: \"priority\", rank: 3, label: \"Priority\", icon: \"push-pin\", description: \"Weighed seriously against the other priorities.\" },\n { id: \"driver\", rank: 4, label: \"Driver\", icon: \"lightning\", description: \"Shapes the plan — outranks anything below it.\" },\n { id: \"dealbreaker\", rank: 5, label: \"Deal-breaker\", icon: \"prohibit\", description: \"Must be satisfied. Anything failing it is out.\" },\n];\n\nconst BY_ID: Record<string, ImportanceLevel> = IMPORTANCE_LEVELS.reduce(\n (acc, lvl) => {\n acc[lvl.id] = lvl;\n return acc;\n },\n {} as Record<string, ImportanceLevel>\n);\n\n/** The level record for an id, falling back to the lowest step for an unknown one — an\n * unrecognised level should read as \"barely matters\", never throw in a list row. */\nexport function importanceLevel(id: ImportanceLevelId | string): ImportanceLevel {\n return BY_ID[id] || IMPORTANCE_LEVELS[0];\n}\n\nexport interface ImportanceTokens {\n /** Background wash for a criterion card at this level. */\n fill: string;\n /** Border for that card. */\n edge: string;\n /** AA-safe text colour ON `fill`. */\n text: string;\n /** The solid — meter segments, glyphs, dots. Clears 3:1 on the meter rail. */\n mark: string;\n}\n\n/**\n * The four `var(--imp-N-*)` references for a level, as a plain object, so a criterion\n * card elsewhere in a consuming app tints itself from exactly the same tokens the meter\n * segments are drawn in rather than from a second hand-copied list of hexes. Returns the\n * var() references, not resolved colours — the whole point is that the theme resolves\n * them, and every one of these is defined for both light and dark ground.\n */\nexport function importanceTokens(id: ImportanceLevelId | string): ImportanceTokens {\n const n = importanceLevel(id).rank;\n return {\n fill: \"var(--imp-\" + n + \"-fill)\",\n edge: \"var(--imp-\" + n + \"-edge)\",\n text: \"var(--imp-\" + n + \"-text)\",\n mark: \"var(--imp-\" + n + \"-mark)\",\n };\n}\n\nexport interface ImportanceTagProps {\n level: ImportanceLevelId | string;\n /** Show the level's name next to its glyph. Off for a bare glyph in tight spots. */\n showLabel?: boolean;\n size?: \"sm\" | \"md\";\n className?: string;\n}\n\n/**\n * The level itself, as a small tinted tag — glyph plus name in that level's own fill,\n * edge and text tokens. Never colour alone: the name and the icon both carry the level,\n * so the five steps are still distinguishable without colour vision.\n */\nexport function ImportanceTag({ level, showLabel = true, size = \"sm\", className = \"\" }: ImportanceTagProps) {\n const lvl = importanceLevel(level);\n const t = importanceTokens(level);\n return (\n <span\n className={[\"fd-imp-tag\", size === \"md\" ? \"is-md\" : \"\", className].filter(Boolean).join(\" \")}\n style={{ background: t.fill, borderColor: t.edge, color: t.text }}\n title={lvl.label + \" — \" + lvl.description}\n >\n <i className={\"ph ph-\" + lvl.icon} aria-hidden=\"true\" />\n {showLabel ? lvl.label : <span className=\"fd-sr\">{lvl.label}</span>}\n </span>\n );\n}\n","import * as React from \"react\";\nimport { ScoreMeter } from \"../data/ScoreMeter\";\nimport type { MeterSegmentInput } from \"../data/SegmentedMeter\";\nimport type { Placement } from \"../actions/Popover\";\nimport { ImportanceTag, importanceLevel, importanceTokens, type ImportanceLevelId } from \"./Importance\";\n\nexport interface PreferenceCriterion {\n id: string;\n /** What the planner asked for — \"Within 50 miles\", \"Enrollment over 10,000\". */\n label: string;\n importance: ImportanceLevelId | string;\n /** The most this criterion could contribute to a 100-point score, i.e. what it is\n * worth given its importance relative to the other criteria. */\n weight: number;\n /** What it actually contributed for this option, 0..weight. A partially-satisfied\n * criterion is allowed — this is not a pass/fail flag. */\n earned: number;\n /** Optional plain-language reason shown under the criterion in the breakdown, e.g.\n * \"31 miles\" or \"no outdoor inventory\". */\n note?: React.ReactNode;\n}\n\n/** The score a set of criteria adds up to, rounded to a whole 0-100. Exported because a\n * consumer usually needs the same number for sorting the list as for drawing the meter,\n * and two implementations of that would drift. */\nexport function preferenceScore(criteria: PreferenceCriterion[]): number {\n const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);\n const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);\n if (weight <= 0) return 0;\n return Math.max(0, Math.min(100, Math.round((earned / weight) * 100)));\n}\n\n/** One meter segment per criterion, each sized by what that criterion actually earned\n * (as a share of 100) and coloured by its importance level's `mark` token. */\nexport function preferenceSegments(criteria: PreferenceCriterion[]): MeterSegmentInput[] {\n const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);\n if (weight <= 0) return [];\n return criteria.map((c) => ({\n id: c.id,\n label: c.label + \" · \" + importanceLevel(c.importance).label,\n value: ((Number(c.earned) || 0) / weight) * 100,\n color: importanceTokens(c.importance).mark,\n }));\n}\n\nexport interface PreferenceMeterProps {\n criteria: PreferenceCriterion[];\n /** Overrides the score derived from `criteria`. Pass it when the score is computed\n * server-side and the criteria are only the explanation of it. */\n score?: number;\n /** Accessible name. Defaults to \"Preference score\". */\n label?: string;\n width?: number;\n height?: number;\n showScore?: boolean;\n placement?: Placement;\n /** Heading shown above the breakdown list. */\n breakdownTitle?: string;\n className?: string;\n}\n\n/**\n * PreferenceMeter — how well one option matches the planner's stated priorities, drawn\n * as one segment per criterion coloured by that criterion's importance.\n *\n * The encoding is the point, and it is not \"how high did this score\". A plain 0-100 bar\n * says a school scored 72; this says WHICH of the planner's priorities it satisfies — a\n * bar that is mostly red-and-amber is meeting the deal-breakers and drivers, a bar of\n * the same length that is mostly slate is scraping the same number out of things the\n * planner said barely matter. Two schools with identical scores are visibly different\n * propositions, at a glance, in a list row.\n *\n * Segment width is what the criterion EARNED, not what it was worth, so the unfilled\n * remainder of the rail is exactly what the option is failing to deliver. Clicking opens\n * the breakdown: every criterion, its level, what it earned out of its weight, and the\n * caller's own note explaining why.\n */\nexport function PreferenceMeter({\n criteria,\n score,\n label = \"Preference score\",\n width,\n height,\n showScore,\n placement,\n breakdownTitle = \"Why this score\",\n className = \"\",\n}: PreferenceMeterProps) {\n const value = score == null ? preferenceScore(criteria) : score;\n const segments = React.useMemo(() => preferenceSegments(criteria), [criteria]);\n\n return (\n <ScoreMeter\n score={value}\n segments={segments}\n label={label}\n width={width}\n height={height}\n showScore={showScore}\n placement={placement}\n className={className}\n breakdownLabel={breakdownTitle}\n breakdown={\n <div className=\"fd-prefbreak\">\n <div className=\"fd-prefbreak-head\">\n <span className=\"fd-label-lg\">{breakdownTitle}</span>\n <span className=\"fd-prefbreak-score fd-tabular\">{Math.round(value)}</span>\n </div>\n <ul className=\"fd-prefbreak-list\">\n {criteria.map((c) => {\n const pct = c.weight > 0 ? Math.round(((Number(c.earned) || 0) / c.weight) * 100) : 0;\n return (\n <li key={c.id} className={pct === 0 ? \"fd-prefbreak-item is-unmet\" : \"fd-prefbreak-item\"}>\n <ImportanceTag level={c.importance} />\n <span className=\"fd-prefbreak-text\">\n <span className=\"fd-prefbreak-label\">{c.label}</span>\n {c.note ? <span className=\"fd-prefbreak-note\">{c.note}</span> : null}\n </span>\n <span className=\"fd-prefbreak-val fd-tabular\">\n {Math.round(Number(c.earned) || 0)}\n <span className=\"fd-prefbreak-sep\">/</span>\n {Math.round(c.weight)}\n </span>\n </li>\n );\n })}\n </ul>\n </div>\n }\n />\n );\n}\n","import * as React from \"react\";\nimport { useChatEngine } from \"./chatEngine\";\nimport type { ChatAdapter, ChatMessage, Packet, PacketSchema } from \"./chatEngine\";\nimport { ChatTranscript } from \"./ChatTranscript\";\nimport { ChatComposer } from \"./ChatComposer\";\nimport { ChatSessionBar, ModelControls } from \"./ChatSessionBar\";\nimport { MenuButton } from \"../actions/Popover\";\nimport type { MenuItem } from \"../actions/Popover\";\nimport { formatRelative } from \"../data/RelativeTime\";\nimport type { Attachment } from \"../../kits/files\";\nimport type { FileUploadHandler } from \"../forms/Dropzone\";\nimport type { MeterSegmentInput } from \"../data/SegmentedMeter\";\n\nconst SURFACES: Record<string, string> = { sidebar: \"is-sidebar\", inline: \"is-inline\", page: \"is-page\", modal: \"is-modal\", sheet: \"is-sheet\" };\n\nexport interface Suggestion { id?: string; label: string; text?: string; description?: string; icon?: string }\nexport interface SlashCommand { id: string; label: string; description?: string; icon?: string; shortcut?: string; /** Send immediately on pick. */ immediate?: boolean; run?: () => void }\nexport interface MentionSource { id?: string; label: string; value?: string; description?: string; icon?: string; meta?: React.ReactNode }\nexport interface Model { id: string; label: string; description?: string; /** Key HINT only. */ shortcut?: string; group?: string; meta?: React.ReactNode; disabled?: boolean }\nexport interface ContextUsage { total: number; segments: MeterSegmentInput[]; label?: string; format?: \"count\" | \"compact\" | \"bytes\" }\nexport interface UsageLimit { id: string; label: string; percent: number; resetsAt?: string; note?: string }\nexport interface SessionStats { elapsedMs?: number; tokens?: number; runningTasks?: number; costUsd?: number; turns?: number }\nexport interface ThreadSummary { id: string; title?: string; description?: string; updatedAt?: string }\n\nexport type VoiceHandler = (controls: { onText: (text: string, meta?: { replace?: boolean }) => void; onEnd?: () => void }) => (() => void) | void;\n\nexport interface AgentChatPanelProps {\n /* required */\n contextType: string;\n contextId: string;\n apiAdapter: ChatAdapter | null;\n /** Show this exact thread instead of resolving one from context. Set it from\n * onNewThread / onSelectThread to make history switching work. */\n threadId?: string | null;\n\n /* chrome */\n title?: string;\n subtitle?: React.ReactNode;\n showHeader?: boolean;\n headerActions?: React.ReactNode;\n onClose?: () => void;\n assistantName?: string;\n userName?: string;\n assistantAvatar?: string;\n userAvatar?: string;\n /** Phosphor name for the assistant mark. Default \"sparkle\". */\n assistantIcon?: string;\n showAvatars?: boolean;\n\n /* transcript */\n markdown?: boolean;\n /** Clamp threshold before Show more. Default 600; 0 disables. */\n maxVisibleChars?: number;\n messageActions?: boolean;\n showSteps?: boolean;\n showThinking?: boolean;\n emptyTitle?: string;\n emptyDescription?: string;\n emptyIcon?: string;\n suggestions?: Array<Suggestion | string>;\n renderEmpty?: () => React.ReactNode;\n packetSchemas?: Record<string, PacketSchema>;\n packetRenderers?: Record<string, (p: Packet) => React.ReactNode>;\n onApplyPacket?: (p: Packet) => void;\n onOpenAttachment?: (a: Attachment) => void;\n /** Map a backend error code to human copy. */\n errorCopy?: (code: string) => React.ReactNode;\n\n /* composer */\n placeholder?: string;\n maxLength?: number;\n hint?: React.ReactNode;\n /** Omit and there is no attach affordance — a pasted image falls through. */\n fileUploadHandler?: FileUploadHandler;\n acceptFiles?: string;\n maxFileSize?: number;\n /** Chars above which a paste becomes a .txt attachment. Default 4000. */\n largePasteThreshold?: number;\n slashCommands?: SlashCommand[];\n mentionSources?: MentionSource[] | ((query: string) => Promise<MentionSource[]>);\n voiceHandler?: VoiceHandler;\n initialMessage?: string | null;\n\n /* session bar — supply none of these and no bar renders */\n contextUsage?: ContextUsage;\n sessionStats?: SessionStats;\n usageLimits?: UsageLimit[];\n models?: Model[];\n moreModels?: Model[];\n model?: string;\n onModelChange?: (id: string) => void;\n effortLevels?: string[];\n effort?: string;\n onEffortChange?: (level: string) => void;\n fastMode?: boolean;\n onFastModeChange?: (on: boolean) => void;\n\n /* threads */\n threads?: ThreadSummary[];\n onSelectThread?: (t: ThreadSummary) => void;\n onNewThread?: () => void;\n /** Supply to put a delete affordance on each history row. Omit and none renders. */\n onDeleteThread?: (t: ThreadSummary) => void;\n\n /* layout — behaviour is identical across all five surfaces */\n surface?: \"sidebar\" | \"inline\" | \"page\" | \"modal\" | \"sheet\";\n width?: number;\n minWidth?: number;\n maxWidth?: number;\n resizable?: boolean;\n height?: number | string;\n className?: string;\n style?: React.CSSProperties;\n\n /* events */\n onPacket?: (p: Packet) => void;\n onThreadReady?: (id: string) => void;\n onError?: (e: unknown) => void;\n onSend?: (text: string) => void;\n onClear?: () => void;\n onFeedback?: (x: { message?: ChatMessage; feedback?: string | null }) => void;\n onEditMessage?: (m: ChatMessage) => void;\n}\n\n/**\n * Agent chat panel.\n *\n * Ships no backend: without `apiAdapter` it loads nothing and says so. Every\n * optional surface — usage meters, model picker, attachments, avatars, steps —\n * renders only when its input is supplied. A panel with no telemetry shows no\n * telemetry, not zeroes.\n */\nexport function AgentChatPanel({\n /* required */\n contextType, contextId, apiAdapter,\n threadId,\n /* identity + chrome */\n title = \"Assistant\", subtitle, showHeader = true, headerActions, onClose,\n assistantName = \"Assistant\", userName = \"You\", assistantAvatar, userAvatar,\n assistantIcon = \"sparkle\", showAvatars = true,\n /* transcript */\n markdown = true, maxVisibleChars = 600, messageActions = true,\n showSteps = true, showThinking = true,\n emptyTitle, emptyDescription, emptyIcon, suggestions = [], renderEmpty,\n packetSchemas, packetRenderers, onApplyPacket, onOpenAttachment, errorCopy,\n /* composer */\n placeholder = \"Ask a question…\", maxLength, hint,\n fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold = 4000,\n slashCommands, mentionSources, voiceHandler, initialMessage,\n /* session bar */\n contextUsage, sessionStats, usageLimits,\n models, model, onModelChange, effortLevels, effort, onEffortChange,\n fastMode, onFastModeChange, moreModels,\n /* threads */\n threads, onSelectThread, onNewThread, onDeleteThread,\n /* layout */\n surface = \"sidebar\", width = 420, minWidth = 340, maxWidth = 760, resizable = true,\n height, className = \"\", style,\n /* events */\n onPacket, onThreadReady, onError, onSend, onClear, onFeedback, onEditMessage,\n}: AgentChatPanelProps) {\n const [panelWidth, setPanelWidth] = React.useState(width);\n const [applied, setApplied] = React.useState<Record<string, boolean>>({});\n const [draft, setDraft] = React.useState(\"\");\n const dragging = React.useRef<{ x: number; w: number } | null>(null);\n React.useEffect(() => setPanelWidth(width), [width]);\n\n const engine = useChatEngine({\n contextType, contextId, apiAdapter, initialMessage, threadId,\n onPacket, onThreadReady, onError, onSend, onClear, onFeedback,\n });\n\n /* resize (sidebar only) — pointer events so it works with touch and pen */\n const startDrag = (e: React.PointerEvent) => {\n if (!resizable) return;\n e.preventDefault();\n dragging.current = { x: e.clientX, w: panelWidth };\n const move = (ev: PointerEvent) => {\n if (!dragging.current) return;\n const dx = dragging.current.x - ev.clientX;\n setPanelWidth(Math.max(minWidth, Math.min(maxWidth, dragging.current.w + dx)));\n };\n const up = () => {\n dragging.current = null;\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n document.body.style.userSelect = \"\";\n };\n document.body.style.userSelect = \"none\";\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n };\n\n const narrow = surface === \"sidebar\" ? panelWidth < 420 : surface === \"sheet\";\n\n const ctx = {\n assistantName, userName, assistantAvatar, userAvatar, assistantIcon, showAvatars,\n markdown, maxVisibleChars, messageActions, showSteps, showThinking,\n packetSchemas, packetRenderers, appliedPackets: applied, narrow,\n onOpenAttachment, errorCopy,\n onRetry: engine.retry,\n onFeedback: (id: string, v: \"up\" | \"down\") => engine.setFeedback(id, v),\n onEdit: (m: ChatMessage) => { setDraft(m.text || \"\"); onEditMessage && onEditMessage(m); },\n onApplyPacket: onApplyPacket ? (p: Packet) => {\n const carrier = [...engine.visible].reverse().find((m) => m.packet === p);\n if (carrier) setApplied((a) => Object.assign({}, a, { [carrier.id]: true }));\n onApplyPacket(p);\n } : undefined,\n onReconnect: engine.reload,\n deadTitle: \"The assistant isn’t reachable\",\n };\n\n const sessionBar = (\n <ChatSessionBar\n sessionStats={sessionStats} contextUsage={contextUsage} usageLimits={usageLimits}\n onClear={engine.visible.length ? engine.clear : undefined}\n />\n );\n\n const modelControls = (\n <ModelControls\n models={models} model={model} onModelChange={onModelChange}\n effortLevels={effortLevels} effort={effort} onEffortChange={onEffortChange}\n fastMode={fastMode} onFastModeChange={onFastModeChange} moreModels={moreModels}\n narrow={narrow}\n />\n );\n\n const threadMenu = threads && threads.length ? (\n <MenuButton\n variant=\"ghost\" icon=\"clock-counter-clockwise\" trailingIcon={null} placement=\"bottom-end\"\n ariaLabel=\"Conversation history\" title=\"History\" minWidth={300}\n items={([{ kind: \"section\", label: \"Recent\" }] as MenuItem[]).concat(threads.map((t) => ({\n id: t.id, label: t.title || \"Untitled\",\n description: t.updatedAt ? formatRelative(t.updatedAt) : t.description,\n checked: t.id === engine.threadId,\n onSelect: () => onSelectThread && onSelectThread(t),\n /* Delete sits on the row rather than behind a submenu, so removing a stale thread is\n one gesture. Only offered when the host can actually persist it. */\n trailingAction: onDeleteThread ? {\n icon: \"trash\", label: \"Delete “\" + (t.title || \"Untitled\") + \"”\", danger: true,\n onSelect: () => onDeleteThread(t)\n } : undefined,\n })))}\n />\n ) : null;\n\n return (\n <aside\n className={[\"fdc-panel\", SURFACES[surface] || SURFACES.sidebar, narrow ? \"is-narrow\" : \"\", className].filter(Boolean).join(\" \")}\n style={{\n ...(surface === \"sidebar\" ? { width: panelWidth } : {}),\n ...(height ? { height } : {}),\n ...style,\n }}\n aria-label={title}\n >\n {surface === \"sidebar\" && resizable ? (\n <div\n className=\"fdc-grip\" onPointerDown={startDrag} role=\"separator\"\n aria-orientation=\"vertical\" aria-label=\"Resize panel\" tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"ArrowLeft\") setPanelWidth((w) => Math.min(maxWidth, w + 24));\n if (e.key === \"ArrowRight\") setPanelWidth((w) => Math.max(minWidth, w - 24));\n }}\n />\n ) : null}\n\n {showHeader ? (\n <header className=\"fdc-head\">\n <span className=\"fdc-head-mark\" aria-hidden=\"true\"><i className={\"ph ph-\" + assistantIcon} /></span>\n <span className=\"fdc-head-titles\">\n <span className=\"fdc-head-title\">{title}</span>\n {subtitle ? <span className=\"fdc-head-sub\">{subtitle}</span> : null}\n </span>\n <span className=\"fdc-head-acts\">\n {headerActions}\n {threadMenu}\n {onNewThread ? (\n <button type=\"button\" className=\"fdc-iconbtn\" onClick={onNewThread} aria-label=\"New conversation\" title=\"New conversation\">\n <i className=\"ph ph-plus\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {onClose ? (\n <button type=\"button\" className=\"fdc-iconbtn\" onClick={onClose} aria-label=\"Close panel\" title=\"Close\">\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </span>\n </header>\n ) : null}\n\n <ChatTranscript\n messages={engine.visible} ctx={ctx} status={engine.status} fatal={engine.fatal}\n suggestions={suggestions} onPick={(t) => engine.send(t as string)}\n emptyTitle={emptyTitle} emptyDescription={emptyDescription} emptyIcon={emptyIcon}\n renderEmpty={renderEmpty}\n />\n\n <ChatComposer\n onSubmit={(text, atts) => engine.send(text, atts)}\n onStop={engine.stop}\n busy={engine.busy}\n disabled={engine.status === \"disconnected\" || engine.status === \"idle\"}\n placeholder={placeholder} maxLength={maxLength} hint={hint}\n fileUploadHandler={fileUploadHandler} acceptFiles={acceptFiles}\n maxFileSize={maxFileSize} largePasteThreshold={largePasteThreshold}\n slashCommands={slashCommands} mentionSources={mentionSources} voiceHandler={voiceHandler}\n queue={engine.queue} onRemoveQueued={engine.removeQueued}\n sessionBar={sessionBar} toolbarExtras={modelControls}\n onOpenAttachment={onOpenAttachment}\n draft={draft} onDraftChange={setDraft} narrow={narrow}\n />\n </aside>\n );\n}\n","import * as React from \"react\";\nimport type { Attachment } from \"../../kits/files\";\nimport type { Step } from \"../data/StepList\";\n\n/**\n * Chat state machine. Framework-shaped as a React hook, but the rules it encodes\n * are the portable part: thread resolution, serial sending, escalation polling,\n * recovery, abort semantics and retry truncation.\n *\n * It ships no HTTP client. Without an adapter it resolves nothing and renders\n * nothing — every app's proxy differs in auth, routing and host.\n */\n\n/* ── types ────────────────────────────────────────────────────────────────── */\n\n/** Tri-state `valid`: only an explicit false blocks Apply. */\nexport interface Citation { id?: string; marker?: string | number; title?: string; url?: string; detail?: string }\n\n/** Tri-state `valid`: only an explicit false blocks Apply. */\nexport interface Packet { type: string; payload: unknown; valid?: boolean; error?: string; repaired?: boolean }\nexport interface PacketSchema { heading?: string; icon?: string; applyLabel?: string }\n\nexport interface JobStatus {\n id?: string;\n /** queued | running keep polling · completed | recovered are success · anything else fails loudly. */\n status: string;\n detail?: string;\n error?: string;\n}\n\nexport interface ChatMessage {\n id: string;\n role: \"user\" | \"assistant\" | \"system\";\n text?: string | null;\n packet?: Packet | null;\n /** Escalation in flight. */\n working?: boolean;\n /** Tokens arriving — renders a live caret. */\n streaming?: boolean;\n /** Optimistic, not yet confirmed. */\n pending?: boolean;\n /** The turn was stopped by the user. */\n stopped?: boolean;\n jobId?: string;\n job?: JobStatus;\n error?: string;\n retryable?: boolean;\n timestamp?: string;\n author?: string;\n steps?: Step[];\n citations?: Citation[];\n attachments?: Attachment[];\n thinking?: string;\n thinkingMs?: number;\n feedback?: \"up\" | \"down\" | null;\n model?: string;\n usage?: unknown;\n resumed?: boolean;\n metadata?: { type?: string; [k: string]: unknown };\n}\n\nexport interface SendMessageResult {\n /** true = escalated to a background job. */\n dispatched?: boolean;\n job_id?: string;\n reply?: string | null;\n packet?: Packet;\n steps?: Step[];\n citations?: Citation[];\n usage?: unknown;\n model?: string;\n}\n\nexport interface StreamHandlers {\n /** Chunks APPEND, never replace. */\n onToken(chunk: string): void;\n onStep?(step: Step): void;\n onThinking?(chunk: string): void;\n}\n\n/**\n * The app-supplied backend. There is no default: every proxy differs in auth,\n * routing and host. Reject with the backend's stable error code as the message —\n * the panel matches codes by exact equality, never substring sniffing.\n */\nexport interface ChatAdapter {\n resolveThread(ctx: { contextType: string; contextId: string }): Promise<{ thread_id: string | null }>;\n getThread(threadId: string): Promise<{ messages: ChatMessage[] }>;\n sendMessage(threadId: string, text: string, signal?: AbortSignal, attachments?: Attachment[]): Promise<SendMessageResult>;\n getJob(jobId: string): Promise<JobStatus>;\n /** Preferred when present. */\n streamMessage?(threadId: string, text: string, handlers: StreamHandlers, signal: AbortSignal, attachments?: Attachment[]): Promise<SendMessageResult>;\n /** Cancels upstream only. It must not gate whether Stop appears. */\n cancelJob?(jobId: string): Promise<void>;\n}\n\nexport interface ChatEngineOptions {\n contextType: string;\n contextId: string;\n apiAdapter?: ChatAdapter | null;\n initialMessage?: string | null;\n threadId?: string | null;\n pollIntervalMs?: number;\n pollMaxAttempts?: number;\n store?: { get(k: string): string | null; set(k: string, v: string): void; del(k: string): void };\n onPacket?: (p: Packet) => void;\n onThreadReady?: (id: string) => void;\n onError?: (e: unknown) => void;\n onSend?: (text: string) => void;\n onClear?: () => void;\n onFeedback?: (x: { message?: ChatMessage; feedback?: string | null }) => void;\n}\n\nexport interface QueuedTurn { id: string; text: string; attachments?: Attachment[] }\n\nexport interface ChatEngine {\n status: \"idle\" | \"resolving\" | \"loading\" | \"ready\" | \"disconnected\";\n threadId: string | null;\n messages: ChatMessage[];\n visible: ChatMessage[];\n queue: QueuedTurn[];\n busy: boolean;\n fatal: string | null;\n turnStartedAt: number | null;\n send(text: string, attachments?: Attachment[]): void;\n stop(): void;\n retry(): void;\n clear(): void;\n removeQueued(id: string): void;\n setFeedback(id: string, value: \"up\" | \"down\"): void;\n reload(): Promise<void>;\n canSend: boolean;\n}\n\n/* ── constants / helpers ──────────────────────────────────────────────────── */\n\nexport const CHAT_UNAVAILABLE = \"chat_unavailable\";\nconst JOB_PENDING = [\"queued\", \"running\"];\nconst JOB_SUCCESS = [\"completed\", \"recovered\"]; // `recovered` IS success\nconst STORAGE_PREFIX = \"fdchat:job:\";\n\nlet seq = 0;\nconst uid = (p: string) => p + \"_\" + (++seq) + \"_\" + Date.now().toString(36);\nconst sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\ntype Store = { get(k: string): string | null; set(k: string, v: string): void; del(k: string): void };\n\n/** sessionStorage that cannot throw — private-mode browsers expose it and throw on use. */\nconst safeStore: Store = {\n get(k) { try { return window.sessionStorage.getItem(k); } catch (e) { return null; } },\n set(k, v) { try { window.sessionStorage.setItem(k, v); } catch (e) { /* noop */ } },\n del(k) { try { window.sessionStorage.removeItem(k); } catch (e) { /* noop */ } },\n};\n\nexport const isSystemMessage = (m: ChatMessage | null | undefined): boolean =>\n !!m && (m.role === \"system\" || (m.metadata != null && m.metadata.type === \"system\"));\nexport const visibleMessages = (list: ChatMessage[] | null | undefined): ChatMessage[] =>\n (list || []).filter((m) => !isSystemMessage(m));\n\nexport function jobBucket(status?: string): \"pending\" | \"success\" | \"failure\" {\n const s = String(status || \"\").toLowerCase();\n if (JOB_PENDING.indexOf(s) !== -1) return \"pending\";\n if (JOB_SUCCESS.indexOf(s) !== -1) return \"success\";\n return \"failure\"; // including anything unrecognised\n}\n\n/* An AbortController-shaped fallback for environments without one — its `signal`\n is deliberately undefined; callers that require a real AbortSignal cast it. */\ntype AbortLike = AbortController | { abort(): void; signal?: undefined };\n\nexport function useChatEngine(opts: ChatEngineOptions): ChatEngine {\n const {\n contextType, contextId, apiAdapter, initialMessage, threadId: threadIdProp,\n pollIntervalMs = 1500, pollMaxAttempts = 120, store = safeStore,\n onPacket, onThreadReady, onError, onSend, onClear, onFeedback,\n } = opts || ({} as ChatEngineOptions);\n\n const [status, setStatus] = React.useState<ChatEngine[\"status\"]>(\"idle\"); // idle|resolving|loading|ready|disconnected\n const [threadId, setThreadId] = React.useState<string | null>(null);\n const [messages, setMessages] = React.useState<ChatMessage[]>([]);\n const [queue, setQueue] = React.useState<QueuedTurn[]>([]);\n const [fatal, setFatal] = React.useState<string | null>(null);\n const [busy, setBusy] = React.useState(false);\n const [turnStartedAt, setTurnStartedAt] = React.useState<number | null>(null);\n\n const listRef = React.useRef<ChatMessage[]>([]);\n const queueRef = React.useRef<QueuedTurn[]>([]);\n const busyRef = React.useRef(false);\n const stoppedRef = React.useRef(false);\n const abortRef = React.useRef<AbortLike | null>(null);\n const serverCount = React.useRef(0);\n const threadRef = React.useRef<string | null>(null);\n const mounted = React.useRef(true);\n\n // React 18 Strict Mode double-invokes this effect in dev (mount, cleanup, remount)\n // without discarding the ref, so the cleanup alone leaves `mounted.current` stuck\n // false forever unless the body also resets it true — without this, every commit()\n // after the phantom unmount is silently dropped and the transcript never renders.\n React.useEffect(() => {\n mounted.current = true;\n return () => { mounted.current = false; };\n }, []);\n\n const commit = (next: ChatMessage[]) => { listRef.current = next; if (mounted.current) setMessages(next); };\n const patch = (id: string, p: Partial<ChatMessage> | ((m: ChatMessage) => Partial<ChatMessage>)) =>\n commit(listRef.current.map((m) => (m.id === id ? Object.assign({}, m, typeof p === \"function\" ? p(m) : p) : m)));\n const push = (...msgs: ChatMessage[]) => commit(listRef.current.concat(msgs));\n\n const fail = (err: unknown): boolean => {\n const code = ((err as { message?: string })?.message) || String(err || \"error\");\n onError && onError(err);\n if (code === CHAT_UNAVAILABLE) { setStatus(\"disconnected\"); setFatal(code); return true; }\n return false;\n };\n\n /* ── thread lifecycle ─────────────────────────────────────────────────── */\n\n const loadThread = React.useCallback(async (id: string): Promise<ChatMessage[]> => {\n const data = await apiAdapter!.getThread(id);\n // Copy: an adapter may hand back a live store array, and this panel pushes\n // optimistic messages onto its list. Aliasing it double-renders every turn.\n const list = [...((data && data.messages) || [])];\n serverCount.current = list.length;\n commit(list);\n return list;\n }, [apiAdapter]);\n\n React.useEffect(() => {\n if (!apiAdapter) {\n // No adapter: load nothing, show nothing. Drop anything a previous adapter left.\n setStatus(\"idle\"); setFatal(null);\n commit([]); queueRef.current = []; setQueue([]); serverCount.current = 0;\n return;\n }\n let dead = false;\n // Abandon anything in flight for the thread we are leaving.\n if (abortRef.current) { try { abortRef.current.abort(); } catch (e) { /* already settled */ } abortRef.current = null; }\n busyRef.current = false; setBusy(false); setTurnStartedAt(null);\n queueRef.current = []; setQueue([]);\n stoppedRef.current = false;\n setStatus(\"resolving\"); setFatal(null);\n (async () => {\n try {\n // An explicit id wins: the host has already created or picked the thread.\n const id = threadIdProp || await (async () => {\n const res = await apiAdapter.resolveThread({ contextType, contextId });\n return res && res.thread_id;\n })();\n if (dead) return;\n if (!id) { setStatus(\"disconnected\"); setFatal(CHAT_UNAVAILABLE); return; }\n threadRef.current = id; setThreadId(id);\n setStatus(\"loading\");\n await loadThread(id);\n if (dead) return;\n setStatus(\"ready\");\n onThreadReady && onThreadReady(id);\n const stored = store.get(STORAGE_PREFIX + id);\n if (stored) resumeJob(stored); // escalation survives remount\n else if (initialMessage) send(initialMessage);\n } catch (err) {\n if (dead) return;\n if (!fail(err)) { setStatus(\"disconnected\"); setFatal(((err as { message?: string })?.message) || \"load_failed\"); }\n }\n })();\n return () => { dead = true; };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [apiAdapter, contextType, contextId, threadIdProp]);\n\n /* ── job polling ──────────────────────────────────────────────────────── */\n\n async function pollJob(jobId: string, placeholderId: string): Promise<void> {\n store.set(STORAGE_PREFIX + threadRef.current, jobId);\n let attempts = 0;\n while (attempts++ < pollMaxAttempts) {\n if (stoppedRef.current) break;\n await sleep(pollIntervalMs);\n if (!mounted.current) return;\n let job: JobStatus | undefined;\n try {\n job = await apiAdapter!.getJob(jobId);\n } catch (err) {\n // A job can succeed, write its result, then age out of the registry — so\n // the next poll 404s even though the work landed. Check the thread first.\n const landed = await didResultLand();\n if (landed) { finishJob(jobId); return; }\n recordFailure(placeholderId, ((err as { message?: string })?.message) || \"job_unavailable\", true);\n return;\n }\n patch(placeholderId, { job });\n const bucket = jobBucket(job && job.status);\n if (bucket === \"pending\") continue;\n if (bucket === \"success\") {\n finishJob(jobId, job);\n return;\n }\n recordFailure(placeholderId, (job && (job.error || job.status)) || \"job_failed\", true, job);\n return;\n }\n if (!stoppedRef.current) recordFailure(placeholderId, \"timeout\", true);\n }\n\n async function didResultLand(): Promise<boolean> {\n const before = serverCount.current;\n try {\n const list = await loadThread(threadRef.current!);\n return list.length > before; // count, not object identity\n } catch (e) { return false; }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- signature mirrors both call sites (pollJob success, and the post-getJob-404 recovery path)\n async function finishJob(_jobId: string, _job?: JobStatus): Promise<void> {\n store.del(STORAGE_PREFIX + threadRef.current);\n try {\n const list = await loadThread(threadRef.current!);\n const withPacket = [...list].reverse().find((m) => m && m.packet);\n if (withPacket && onPacket && withPacket.packet) onPacket(withPacket.packet);\n } catch (err) { fail(err); }\n }\n\n function recordFailure(placeholderId: string, code: string, retryable: boolean, job?: JobStatus): void {\n store.del(STORAGE_PREFIX + threadRef.current);\n // A recovery reload replaces the whole list and can detach the placeholder.\n // Re-attach it by id, or the error lands on an object nothing renders.\n if (!listRef.current.some((m) => m.id === placeholderId)) {\n push({ id: placeholderId, role: \"assistant\", text: null });\n }\n patch(placeholderId, { working: false, streaming: false, error: code, retryable: !!retryable, job: job || undefined });\n onError && onError(new Error(code));\n }\n\n function resumeJob(jobId: string): void {\n const id = uid(\"a\");\n push({ id, role: \"assistant\", working: true, jobId, resumed: true });\n setBusy(true); busyRef.current = true; setTurnStartedAt(Date.now());\n pollJob(jobId, id).finally(() => { busyRef.current = false; setBusy(false); setTurnStartedAt(null); });\n }\n\n /* ── sending ──────────────────────────────────────────────────────────── */\n\n async function dispatchTurn(turn: QueuedTurn): Promise<void> {\n const id = threadRef.current;\n if (!id) return;\n busyRef.current = true; setBusy(true); setTurnStartedAt(Date.now());\n const userId = uid(\"u\");\n const holderId = uid(\"a\");\n push(\n { id: userId, role: \"user\", text: turn.text || null, attachments: turn.attachments, pending: true, timestamp: new Date().toISOString() },\n { id: holderId, role: \"assistant\", text: \"\", streaming: !!apiAdapter!.streamMessage, working: !apiAdapter!.streamMessage, timestamp: new Date().toISOString() },\n );\n const ac: AbortLike = typeof AbortController !== \"undefined\" ? new AbortController() : { abort() {}, signal: undefined };\n abortRef.current = ac;\n onSend && onSend(turn.text);\n\n try {\n let res: SendMessageResult | undefined;\n if (apiAdapter!.streamMessage) {\n res = await apiAdapter!.streamMessage(id, turn.text, {\n onToken: (chunk: string) => patch(holderId, (m) => ({ text: (m.text || \"\") + chunk, streaming: true })), // chunks append\n onStep: (step) => patch(holderId, (m) => {\n const steps = (m.steps || []).slice();\n const at = steps.findIndex((s) => s.id === step.id);\n if (at === -1) steps.push(step); else steps[at] = Object.assign({}, steps[at], step);\n return { steps };\n }),\n onThinking: (chunk: string) => patch(holderId, (m) => ({ thinking: (m.thinking || \"\") + chunk })),\n }, ac.signal as AbortSignal, turn.attachments && turn.attachments.length ? turn.attachments : undefined);\n } else if (turn.attachments && turn.attachments.length) {\n res = await apiAdapter!.sendMessage(id, turn.text, ac.signal, turn.attachments);\n } else {\n res = await apiAdapter!.sendMessage(id, turn.text, ac.signal); // same three args as always\n }\n\n patch(userId, { pending: false });\n const r: SendMessageResult = res || {};\n if (r.dispatched && r.job_id) {\n patch(holderId, { streaming: false, working: true, jobId: r.job_id, text: r.reply || \"\" });\n await pollJob(r.job_id, holderId);\n } else {\n patch(holderId, {\n streaming: false, working: false,\n text: r.reply != null ? r.reply : listRef.current.find((m) => m.id === holderId)?.text || \"\",\n packet: r.packet, steps: r.steps || listRef.current.find((m) => m.id === holderId)?.steps,\n citations: r.citations, usage: r.usage, model: r.model,\n timestamp: new Date().toISOString(),\n });\n serverCount.current += 2;\n if (r.packet && onPacket) onPacket(r.packet);\n }\n } catch (err) {\n const aborted = (err && ((err as { name?: string }).name === \"AbortError\" || (err as { message?: string }).message === \"aborted\")) || stoppedRef.current;\n patch(userId, { pending: false });\n if (aborted) {\n patch(holderId, (m) => ({ streaming: false, working: false, stopped: true, retryable: true, text: m.text || null }));\n } else if (!fail(err)) {\n patch(holderId, { streaming: false, working: false, error: ((err as { message?: string })?.message) || \"send_failed\", retryable: true });\n } else {\n commit(listRef.current.filter((m) => m.id !== holderId));\n }\n } finally {\n abortRef.current = null;\n busyRef.current = false; setBusy(false); setTurnStartedAt(null);\n }\n }\n\n async function drain(): Promise<void> {\n if (busyRef.current) return;\n while (queueRef.current.length) {\n if (stoppedRef.current) return; // Stop halts the pipeline, not just the request\n const turn = queueRef.current[0];\n queueRef.current = queueRef.current.slice(1);\n setQueue(queueRef.current.slice());\n await dispatchTurn(turn);\n }\n }\n\n const send = React.useCallback((text: string, attachments?: Attachment[]) => {\n const body = (text || \"\").trim();\n if (!body && !(attachments && attachments.length)) return; // nothing to send\n if (status === \"disconnected\") return;\n const turn: QueuedTurn = { id: uid(\"q\"), text: body, attachments: attachments && attachments.length ? attachments.slice() : undefined };\n queueRef.current = queueRef.current.concat(turn);\n setQueue(queueRef.current.slice());\n stoppedRef.current = false; // a fresh send always resets the flag\n drain();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n const stop = React.useCallback(() => {\n stoppedRef.current = true;\n const ac = abortRef.current;\n if (ac) { try { ac.abort(); } catch (e) { /* noop */ } }\n const holder = [...listRef.current].reverse().find((m) => m.working || m.streaming);\n if (holder) {\n patch(holder.id, (m) => ({ working: false, streaming: false, stopped: true, retryable: true, text: m.text || null }));\n if (holder.jobId && apiAdapter && apiAdapter.cancelJob) {\n // cancelJob gates only the upstream cancel — never the Stop button itself.\n Promise.resolve(apiAdapter.cancelJob(holder.jobId)).catch(() => {});\n }\n store.del(STORAGE_PREFIX + threadRef.current);\n }\n // The queue is text the user typed: leave it standing, visible and removable.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [apiAdapter]);\n\n const removeQueued = React.useCallback((id: string) => {\n queueRef.current = queueRef.current.filter((t) => t.id !== id);\n setQueue(queueRef.current.slice());\n }, []);\n\n const retry = React.useCallback(() => {\n const list = listRef.current;\n let at = -1;\n for (let i = list.length - 1; i >= 0; i--) if (list[i].role === \"user\") { at = i; break; }\n if (at === -1) return;\n const turn = list[at];\n commit(list.slice(0, at)); // a retry reads as one attempt, not a pile\n serverCount.current = Math.max(0, serverCount.current - 1);\n stoppedRef.current = false;\n queueRef.current = ([{ id: uid(\"q\"), text: turn.text || \"\", attachments: turn.attachments }] as QueuedTurn[]).concat(queueRef.current);\n setQueue(queueRef.current.slice());\n drain();\n }, []);\n\n const clear = React.useCallback(() => {\n commit([]); serverCount.current = 0;\n queueRef.current = []; setQueue([]);\n onClear && onClear();\n }, [onClear]);\n\n const setFeedback = React.useCallback((id: string, value: \"up\" | \"down\") => {\n patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));\n const msg = listRef.current.find((m) => m.id === id);\n onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [onFeedback]);\n\n const reload = React.useCallback(async () => {\n if (!threadRef.current) return;\n setStatus(\"loading\");\n try { await loadThread(threadRef.current!); setStatus(\"ready\"); }\n catch (err) { if (!fail(err)) setStatus(\"ready\"); }\n }, [loadThread]);\n\n return {\n status, threadId, messages, visible: visibleMessages(messages), queue,\n busy, fatal, turnStartedAt,\n send, stop, retry, clear, removeQueued, setFeedback, reload,\n canSend: status === \"ready\",\n };\n}\n\n/**\n * Namespace export. The bundle exposes only capital-initial names, so this is how a\n * consuming project reaches the state machine to build its own shell:\n *\n * const { useChatEngine } = window.<Namespace>.ChatKit;\n * const chat = useChatEngine({ contextType, contextId, apiAdapter });\n */\nexport const ChatKit = {\n useChatEngine,\n visibleMessages,\n isSystemMessage,\n jobBucket,\n CHAT_UNAVAILABLE,\n};\n","import * as React from \"react\";\nimport { ChatTurn } from \"./ChatTurn\";\nimport type { ChatRenderContext, MessageGroup } from \"./ChatTurn\";\nimport type { ChatMessage } from \"./chatEngine\";\nimport type { Suggestion } from \"./AgentChatPanel\";\n\nconst GROUP_WINDOW = 60e3;\nconst STICK_PX = 100;\n\n/** Consecutive messages from one sender inside 60s share a head. Anything\n * carrying a packet, steps or an error always starts its own group. */\nexport function groupMessages(list: ChatMessage[]): MessageGroup[] {\n const groups: Array<MessageGroup & { t: number | null }> = [];\n (list || []).forEach((m) => {\n const solo = !!(m.packet || (m.steps && m.steps.length) || m.error || m.working || m.stopped);\n const prev = groups[groups.length - 1];\n const t = m.timestamp ? Date.parse(m.timestamp) : null;\n const close = prev && prev.t != null && t != null ? Math.abs(t - prev.t) < GROUP_WINDOW : !!prev;\n if (prev && !prev.solo && !solo && prev.role === m.role && (prev.author || \"\") === (m.author || \"\") && close) {\n prev.messages.push(m);\n prev.t = t == null ? prev.t : t;\n return;\n }\n groups.push({ role: m.role, author: m.author, messages: [m], t, solo, key: m.id });\n });\n return groups;\n}\n\nconst dayKey = (iso: string | undefined): string | null => {\n const d = iso ? new Date(iso) : null;\n return d && !isNaN(d.getTime()) ? d.toDateString() : null;\n};\n\nfunction dayLabel(key: string): string {\n const d = new Date(key);\n const today = new Date().toDateString();\n const yest = new Date(Date.now() - 864e5).toDateString();\n if (key === today) return \"Today\";\n if (key === yest) return \"Yesterday\";\n return d.toLocaleDateString([], { weekday: \"long\", day: \"numeric\", month: \"long\" });\n}\n\nfunction Suggestions({ items = [], onPick }: { items?: Array<Suggestion | string>; onPick?: (s: Suggestion | string) => void }) {\n if (!items.length) return null;\n return (\n <div className=\"fdc-suggest\">\n {items.map((s, i) => {\n const it: Suggestion = typeof s === \"string\" ? { label: s, text: s } : s;\n return (\n <button type=\"button\" key={it.id || i} className=\"fdc-suggest-item\" onClick={() => onPick && onPick(it.text || it.label)}>\n {it.icon ? <i className={\"ph ph-\" + it.icon} aria-hidden=\"true\" /> : null}\n <span className=\"fdc-suggest-text\">\n <span className=\"fdc-suggest-label\">{it.label}</span>\n {it.description ? <span className=\"fdc-suggest-desc\">{it.description}</span> : null}\n </span>\n <i className=\"ph ph-arrow-up-right fdc-suggest-go\" aria-hidden=\"true\" />\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction LoadingTurns() {\n return (\n <div className=\"fdc-skel\" aria-hidden=\"true\">\n {[0, 1].map((i) => (\n <div key={i} className=\"fdc-skel-turn\">\n <div className=\"fd-skel fd-skel-circle\" style={{ width: 22, height: 22 }} />\n <div className=\"fdc-skel-lines\">\n <div className=\"fd-skel\" style={{ width: i ? \"62%\" : \"44%\", height: 11 }} />\n <div className=\"fd-skel\" style={{ width: i ? \"94%\" : \"78%\", height: 11 }} />\n <div className=\"fd-skel\" style={{ width: i ? \"71%\" : \"56%\", height: 11 }} />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\n/**\n * Runs of consecutive messages from one sender, for run-vs-turn spacing.\n * `role=\"log\"` and deliberately NOT also aria-live — a live region on a\n * transcript makes a screen reader announce every token of a streaming reply.\n */\nexport interface ChatTranscriptProps {\n messages?: ChatMessage[];\n ctx: ChatRenderContext;\n status?: \"idle\" | \"resolving\" | \"loading\" | \"ready\" | \"disconnected\";\n /** Terminal error code; renders the disconnected state. */\n fatal?: string | null;\n suggestions?: Array<Suggestion | string>;\n onPick?: (s: Suggestion | string) => void;\n emptyTitle?: string;\n emptyDescription?: string;\n emptyIcon?: string;\n renderEmpty?: () => React.ReactNode;\n className?: string;\n}\n\n/**\n * The transcript: a role=\"log\" region (and deliberately not aria-live too —\n * that doubles announcements). Grouping, day dividers, and an auto-scroll that\n * follows only while the reader is already at the bottom.\n */\nexport function ChatTranscript({\n messages = [], ctx, status, fatal, suggestions = [], onPick,\n emptyTitle = \"How can I help?\", emptyDescription, emptyIcon = \"chat-teardrop-dots\",\n renderEmpty, className = \"\",\n}: ChatTranscriptProps) {\n const scroller = React.useRef<HTMLDivElement | null>(null);\n const stick = React.useRef(true);\n const [pill, setPill] = React.useState(0);\n const seen = React.useRef(0);\n\n const toBottom = (smooth?: boolean) => {\n const el = scroller.current;\n if (!el) return;\n // Scroll the container, never the page.\n el.scrollTo({ top: el.scrollHeight, behavior: smooth ? \"smooth\" : \"auto\" });\n stick.current = true;\n setPill(0);\n seen.current = messages.length;\n };\n\n const onScroll = () => {\n const el = scroller.current;\n if (!el) return;\n const gap = el.scrollHeight - el.scrollTop - el.clientHeight;\n stick.current = gap <= STICK_PX;\n if (stick.current && pill) { setPill(0); seen.current = messages.length; }\n };\n\n React.useLayoutEffect(() => {\n const el = scroller.current;\n if (!el) return;\n if (stick.current) { el.scrollTop = el.scrollHeight; seen.current = messages.length; }\n else setPill(Math.max(0, messages.length - seen.current));\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n // Content that settles late — webfonts, images, a code block unfolding — must\n // not leave a \"stuck to bottom\" reader stranded mid-transcript.\n React.useEffect(() => {\n const el = scroller.current;\n const inner = el && (el.firstChild as Element | null);\n if (!el || !inner || typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver(() => { if (stick.current) el.scrollTop = el.scrollHeight; });\n ro.observe(inner);\n return () => ro.disconnect();\n }, []);\n\n const groups = React.useMemo(() => groupMessages(messages), [messages]);\n const empty = !messages.length && status === \"ready\";\n\n return (\n <div className={[\"fdc-scroll\", className].filter(Boolean).join(\" \")} ref={scroller} onScroll={onScroll}>\n <div className=\"fdc-log\" role=\"log\" aria-label=\"Conversation\">\n {status === \"loading\" || status === \"resolving\" ? <LoadingTurns /> : null}\n\n {status === \"disconnected\" ? (\n <div className=\"fdc-dead\">\n <span className=\"fdc-dead-icon\"><i className=\"ph ph-plugs\" aria-hidden=\"true\" /></span>\n <h3 className=\"fdc-dead-title\">{ctx.deadTitle || \"The assistant isn’t reachable\"}</h3>\n <p className=\"fdc-dead-body\">\n {fatal === \"chat_unavailable\"\n ? \"The service reported chat_unavailable. Nothing you type will be lost — reopen the panel once it’s back.\"\n : \"The thread couldn’t be resolved\" + (fatal ? \" (\" + fatal + \")\" : \"\") + \". The composer stays disabled until it resolves.\"}\n </p>\n {ctx.onReconnect ? (\n <button type=\"button\" className=\"fd-btn fd-btn-secondary fd-btn-sm\" onClick={ctx.onReconnect}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />Try again\n </button>\n ) : null}\n </div>\n ) : null}\n\n {empty ? (\n renderEmpty ? renderEmpty() : (\n <div className=\"fdc-empty\">\n <span className=\"fdc-empty-icon\"><i className={\"ph ph-\" + emptyIcon} aria-hidden=\"true\" /></span>\n <h3 className=\"fdc-empty-title\">{emptyTitle}</h3>\n {emptyDescription ? <p className=\"fdc-empty-body\">{emptyDescription}</p> : null}\n <Suggestions items={suggestions} onPick={onPick} />\n </div>\n )\n ) : null}\n\n {groups.map((g, i) => {\n const prev = groups[i - 1];\n const k = dayKey(g.messages[0].timestamp);\n const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);\n return (\n <React.Fragment key={g.key || i}>\n {showDay ? <div className=\"fdc-day\"><span>{dayLabel(k!)}</span></div> : null}\n <ChatTurn group={g} ctx={ctx} />\n </React.Fragment>\n );\n })}\n </div>\n\n {pill ? (\n <button type=\"button\" className=\"fdc-pill\" onClick={() => toBottom(true)}>\n <i className=\"ph ph-arrow-down\" aria-hidden=\"true\" />\n {pill} new message{pill === 1 ? \"\" : \"s\"}\n </button>\n ) : null}\n </div>\n );\n}\n\n/** Namespace export — grouping helper, for consumers rendering their own transcript. */\nexport const TranscriptKit = { groupMessages };\n","import * as React from \"react\";\nimport type { Attachment } from \"../../kits/files\";\nimport { Markdown, markdownToText } from \"../data/Markdown\";\nimport { CodeBlock } from \"../data/CodeBlock\";\nimport { StepList } from \"../data/StepList\";\nimport { FileGrid } from \"../forms/FileGrid\";\nimport { formatClock, formatDuration, RelativeTime } from \"../data/RelativeTime\";\nimport type { Citation, ChatMessage, Packet, PacketSchema } from \"./chatEngine\";\n\n/**\n * Render context, built once by AgentChatPanel and threaded into every part.\n * Assembling your own shell means supplying this yourself.\n */\nexport interface ChatRenderContext {\n assistantName?: string;\n userName?: string;\n assistantAvatar?: string;\n userAvatar?: string;\n /** Phosphor name for the assistant mark. Default \"sparkle\". */\n assistantIcon?: string;\n showAvatars?: boolean;\n markdown?: boolean;\n /** Clamp threshold before Show more. 0 disables. */\n maxVisibleChars?: number;\n messageActions?: boolean;\n showSteps?: boolean;\n showThinking?: boolean;\n packetSchemas?: Record<string, PacketSchema>;\n packetRenderers?: Record<string, (p: Packet) => React.ReactNode>;\n appliedPackets?: Record<string, boolean>;\n /** Sidebar-width layout: tighter padding, stacked controls. */\n narrow?: boolean;\n onOpenAttachment?: (a: Attachment) => void;\n /** Max height (px) of the attachment grid before it scrolls. Default 220. */\n attachmentHeight?: number;\n /** Renderer for `[^n]` citation markers inside markdown bodies. */\n renderCitation?: (marker: string) => React.ReactNode;\n /** Map a backend error code to human copy. */\n errorCopy?: (code: string) => React.ReactNode;\n onRetry?: () => void;\n onFeedback?: (id: string, value: \"up\" | \"down\") => void;\n onEdit?: (m: ChatMessage) => void;\n onApplyPacket?: (p: Packet) => void;\n onOpenCitation?: (c: Citation, e: React.MouseEvent) => void;\n extraActions?: (group: MessageGroup) => React.ReactNode;\n /** Disconnected-state heading. Default \"The assistant isn't reachable\". */\n deadTitle?: string;\n onReconnect?: () => void;\n}\n\n/** A run of consecutive messages from one sender — see groupMessages. */\nexport interface MessageGroup {\n role: string;\n author?: string;\n messages: ChatMessage[];\n /** A single-message run; affects spacing and the author label. */\n solo: boolean;\n key: string;\n}\n\n/* ── packets ──────────────────────────────────────────────────────────────── */\n\nfunction JsonView({ value }: { value: unknown }) {\n let text: string | undefined;\n try { text = JSON.stringify(value, null, 2); } catch (e) { text = String(value); }\n return <CodeBlock code={text as string} language=\"json\" collapseAfter={18} />;\n}\n\n/** A structured result. `valid: false` blocks Apply; undefined does not. */\nexport interface PacketCardProps { packet: Packet; schema?: PacketSchema; render?: (p: Packet) => React.ReactNode; onApply?: (p: Packet) => void; applied?: boolean }\n\n/**\n * A structured result carried by a message. `valid` is tri-state: only an\n * explicit `false` blocks Apply — an unvalidated packet is a legitimate result.\n */\nexport function PacketCard({ packet, schema, render, onApply, applied }: PacketCardProps) {\n if (!packet) return null;\n const s = schema || {};\n const invalid = packet.valid === false;\n const title = s.heading || packet.type;\n return (\n <section className={\"fdc-packet\" + (invalid ? \" is-invalid\" : \"\")} aria-label={title}>\n <header className=\"fdc-packet-head\">\n <i className={\"ph ph-\" + (s.icon || \"package\")} aria-hidden=\"true\" />\n <span className=\"fdc-packet-title\">{title}</span>\n {packet.repaired ? <span className=\"fdc-packet-badge\">Repaired</span> : null}\n {invalid ? <span className=\"fdc-packet-badge is-danger\">Invalid</span> : null}\n </header>\n {invalid ? (\n <div className=\"fdc-packet-alert\" role=\"alert\">\n <i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />\n <span>{packet.error || \"This result failed validation and can’t be applied.\"}</span>\n </div>\n ) : (\n <div className=\"fdc-packet-body\">\n {render ? render(packet) : <JsonView value={packet.payload} />}\n </div>\n )}\n {!invalid && onApply ? (\n <footer className=\"fdc-packet-foot\">\n {packet.repaired ? <span className=\"fdc-packet-note\">Corrected by the backend after a first attempt.</span> : <span />}\n <button type=\"button\" className=\"fd-btn fd-btn-primary fd-btn-sm\" disabled={applied} onClick={() => onApply(packet)}>\n <i className={\"ph ph-\" + (applied ? \"check\" : \"arrow-square-in\")} aria-hidden=\"true\" />\n {applied ? \"Applied\" : (s.applyLabel || \"Apply\")}\n </button>\n </footer>\n ) : null}\n </section>\n );\n}\n\n/* ── thinking ─────────────────────────────────────────────────────────────── */\n\nexport interface ThinkingBlockProps { text?: string; durationMs?: number; streaming?: boolean; defaultOpen?: boolean }\n\nexport function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }: ThinkingBlockProps) {\n const [open, setOpen] = React.useState(defaultOpen);\n if (!text) return null;\n return (\n <div className={\"fdc-think\" + (open ? \" is-open\" : \"\")}>\n <button type=\"button\" className=\"fdc-think-head\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className=\"ph ph-brain\" aria-hidden=\"true\" />\n <span>{streaming ? \"Thinking\" : durationMs ? \"Thought for \" + formatDuration(durationMs) : \"Thought process\"}</span>\n {streaming ? <span className=\"fdc-dots\" aria-hidden=\"true\"><span /><span /><span /></span> : null}\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n </button>\n {open ? <div className=\"fdc-think-body\">{text}</div> : null}\n </div>\n );\n}\n\n/* ── citations ────────────────────────────────────────────────────────────── */\n\nexport interface CitationsProps { items?: Citation[]; onOpen?: (c: Citation, e: React.MouseEvent) => void }\n\nexport function Citations({ items = [], onOpen }: CitationsProps) {\n const [open, setOpen] = React.useState(false);\n if (!items.length) return null;\n return (\n <div className=\"fdc-cites\">\n <button type=\"button\" className=\"fdc-cites-head\" onClick={() => setOpen((v) => !v)} aria-expanded={open}>\n <i className=\"ph ph-quotes\" aria-hidden=\"true\" />\n <span>{items.length} source{items.length === 1 ? \"\" : \"s\"}</span>\n <i className={\"ph ph-caret-\" + (open ? \"up\" : \"down\")} aria-hidden=\"true\" />\n </button>\n {open ? (\n <ol className=\"fdc-cites-list\">\n {items.map((c, i) => (\n <li key={c.id || i}>\n <span className=\"fdc-cite-n fd-tabular\">{c.marker || i + 1}</span>\n {c.url ? (\n <a href={c.url} target=\"_blank\" rel=\"noopener noreferrer\" onClick={onOpen ? (e) => onOpen(c, e) : undefined}>{c.title || c.url}</a>\n ) : <span>{c.title || \"Source\"}</span>}\n {c.detail ? <span className=\"fdc-cite-detail\">{c.detail}</span> : null}\n </li>\n ))}\n </ol>\n ) : null}\n </div>\n );\n}\n\n/* ── message body ─────────────────────────────────────────────────────────── */\n\nfunction clampText(text: string, max?: number): string | null {\n if (!max || !text || text.length <= max) return null;\n const cut = text.slice(0, max);\n const at = cut.lastIndexOf(\" \");\n return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + \"…\";\n}\n\n/** Message content only — markdown, code blocks, clamping. No chrome. */\nexport interface MessageBodyProps { message: ChatMessage; ctx: ChatRenderContext }\n\nexport function MessageBody({ message: m, ctx }: MessageBodyProps) {\n const [expanded, setExpanded] = React.useState(false);\n const isUser = m.role === \"user\";\n const raw = m.text || \"\";\n const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;\n const body = clamped != null ? clamped : raw;\n const showMd = ctx.markdown && !isUser;\n\n return (\n <div className=\"fdc-body\">\n {m.thinking && ctx.showThinking ? (\n <ThinkingBlock text={m.thinking} durationMs={m.thinkingMs} streaming={m.streaming && !m.text} />\n ) : null}\n\n {m.steps && m.steps.length && ctx.showSteps ? (\n <StepList steps={m.steps} defaultOpen={m.steps.some((s) => s.status === \"running\")} dense />\n ) : null}\n\n {body ? (\n <div className={\"fdc-text\" + (isUser ? \" is-user\" : \"\")}>\n {showMd\n ? <Markdown source={body} headingOffset={2} codeProps={{ collapseAfter: 22 }} renderCitation={ctx.renderCitation} />\n : <div className=\"fdc-plain\">{body}</div>}\n {m.streaming ? <span className=\"fdc-caret\" aria-hidden=\"true\" /> : null}\n </div>\n ) : null}\n\n {clamped != null ? (\n <button type=\"button\" className=\"fdc-more\" onClick={() => setExpanded(true)}>\n <i className=\"ph ph-caret-down\" aria-hidden=\"true\" />Show more\n <span className=\"fdc-more-len fd-tabular\">{raw.length < 2000 ? raw.length.toLocaleString() + \" characters\" : (Math.round(raw.length / 100) / 10) + \"k characters\"}</span>\n </button>\n ) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? (\n <button type=\"button\" className=\"fdc-more\" onClick={() => setExpanded(false)}>\n <i className=\"ph ph-caret-up\" aria-hidden=\"true\" />Show less\n </button>\n ) : null}\n\n {m.attachments && m.attachments.length ? (\n <FileGrid files={m.attachments} onOpen={ctx.onOpenAttachment} tiles maxHeight={ctx.attachmentHeight || 220} compact={ctx.narrow} />\n ) : null}\n\n {m.packet ? (\n <PacketCard\n packet={m.packet}\n schema={(ctx.packetSchemas || {})[m.packet.type]}\n render={(ctx.packetRenderers || {})[m.packet.type]}\n onApply={ctx.onApplyPacket}\n applied={ctx.appliedPackets && ctx.appliedPackets[m.id]}\n />\n ) : null}\n\n {m.citations && m.citations.length ? <Citations items={m.citations} onOpen={ctx.onOpenCitation} /> : null}\n\n {m.working ? (\n <div className=\"fdc-working\" role=\"status\">\n <span className=\"fdc-dots\" aria-hidden=\"true\"><span /><span /><span /></span>\n <span className=\"fdc-working-label\">\n {m.resumed ? \"Resuming\" : \"Working\"}\n {m.job && m.job.status ? <span className=\"fdc-working-job\"> · {m.job.status}</span> : null}\n {m.job && m.job.detail ? <span className=\"fdc-working-job\"> · {m.job.detail}</span> : null}\n </span>\n {m.jobId ? <span className=\"fdc-working-id fd-mono\">{String(m.jobId).slice(0, 12)}</span> : null}\n </div>\n ) : null}\n\n {m.stopped ? <div className=\"fdc-stopped\"><i className=\"ph ph-stop-circle\" aria-hidden=\"true\" />Stopped</div> : null}\n\n {m.error ? (\n <div className=\"fdc-error\" role=\"alert\">\n <i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />\n <span className=\"fdc-error-text\">{ctx.errorCopy ? ctx.errorCopy(m.error) : m.error}</span>\n {m.retryable && ctx.onRetry ? (\n <button type=\"button\" className=\"fdc-error-retry\" onClick={ctx.onRetry}>\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />Retry\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n/* ── run actions ──────────────────────────────────────────────────────────── */\n\nfunction useCopyRun(): [boolean, (text: string) => void] {\n const [done, setDone] = React.useState(false);\n const t = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n React.useEffect(() => () => { if (t.current) clearTimeout(t.current); }, []);\n return [done, (text: string) => {\n const p = navigator.clipboard && navigator.clipboard.writeText ? navigator.clipboard.writeText(text) : Promise.reject();\n p.catch(() => {}).finally(() => {\n setDone(true);\n if (t.current) clearTimeout(t.current);\n t.current = setTimeout(() => setDone(false), 1600);\n });\n }];\n}\n\n/** Copy / retry / feedback / edit. Real buttons; the hover reveal is CSS only. */\nexport interface RunActionsProps { group: MessageGroup; ctx: ChatRenderContext }\n\n/**\n * One toolbar per run — copying the whole run, not one message. Buttons stay in\n * the DOM (the reveal is CSS only), so keyboard and screen-reader users, who\n * never produce a hover, can still reach them.\n */\nexport function RunActions({ group, ctx }: RunActionsProps) {\n const [copied, copy] = useCopyRun();\n const last = group.messages[group.messages.length - 1];\n const text = group.messages.map((m) => m.text || \"\").filter(Boolean).join(\"\\n\\n\");\n const isAssistant = group.role === \"assistant\";\n const fb = last.feedback;\n if (!ctx.messageActions) return null;\n return (\n <div className=\"fdc-actions\" role=\"group\" aria-label=\"Message actions\">\n <button type=\"button\" className={\"fdc-act\" + (copied ? \" is-done\" : \"\")} onClick={() => copy(markdownToText(text))} aria-label=\"Copy message\">\n <i className={\"ph ph-\" + (copied ? \"check\" : \"copy\")} aria-hidden=\"true\" />\n <span className=\"fdc-act-label\">{copied ? \"Copied\" : \"Copy\"}</span>\n </button>\n {isAssistant && ctx.onRetry ? (\n <button type=\"button\" className=\"fdc-act\" onClick={ctx.onRetry} aria-label=\"Retry this turn\">\n <i className=\"ph ph-arrow-clockwise\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {group.role === \"user\" && ctx.onEdit ? (\n <button type=\"button\" className=\"fdc-act\" onClick={() => ctx.onEdit!(last)} aria-label=\"Edit and resend\">\n <i className=\"ph ph-pencil-simple\" aria-hidden=\"true\" />\n </button>\n ) : null}\n {isAssistant && ctx.onFeedback ? (\n <React.Fragment>\n <button type=\"button\" className={\"fdc-act\" + (fb === \"up\" ? \" is-on\" : \"\")} onClick={() => ctx.onFeedback!(last.id, \"up\")} aria-pressed={fb === \"up\"} aria-label=\"Good response\">\n <i className=\"ph ph-thumbs-up\" aria-hidden=\"true\" />\n </button>\n <button type=\"button\" className={\"fdc-act\" + (fb === \"down\" ? \" is-on\" : \"\")} onClick={() => ctx.onFeedback!(last.id, \"down\")} aria-pressed={fb === \"down\"} aria-label=\"Bad response\">\n <i className=\"ph ph-thumbs-down\" aria-hidden=\"true\" />\n </button>\n </React.Fragment>\n ) : null}\n {ctx.extraActions ? ctx.extraActions(group) : null}\n </div>\n );\n}\n\n/* ── the turn ─────────────────────────────────────────────────────────────── */\n\n/** One turn: author label, body, attachments, packet, thinking, citations, actions. */\nexport interface ChatTurnProps { group: MessageGroup; ctx: ChatRenderContext }\n\nexport function ChatTurn({ group, ctx }: ChatTurnProps) {\n const isUser = group.role === \"user\";\n const name = isUser ? ctx.userName : (group.author || ctx.assistantName);\n const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;\n const stamp = group.messages[0].timestamp;\n\n return (\n <article className={\"fdc-turn is-\" + group.role} aria-label={String(name) + (stamp ? \" at \" + formatClock(stamp) : \"\")}>\n <div className=\"fdc-turn-head\">\n {ctx.showAvatars ? (\n <span className={\"fdc-avatar is-\" + group.role} aria-hidden=\"true\">\n {avatar ? <img src={avatar} alt=\"\" /> : isUser\n ? <span className=\"fdc-avatar-txt\">{(name || \"You\").slice(0, 1).toUpperCase()}</span>\n : <i className={\"ph ph-\" + (ctx.assistantIcon || \"sparkle\")} />}\n </span>\n ) : null}\n <span className=\"fdc-who\">{name}</span>\n {stamp ? <RelativeTime className=\"fdc-when\" value={stamp} /> : null}\n {group.messages.some((m) => m.model) ? <span className=\"fdc-turn-model\">{group.messages.find((m) => m.model)!.model}</span> : null}\n </div>\n <div className=\"fdc-turn-body\">\n {group.messages.map((m) => (\n <div key={m.id} className={\"fdc-msg\" + (m.pending ? \" is-pending\" : \"\")}>\n <MessageBody message={m} ctx={ctx} />\n </div>\n ))}\n <RunActions group={group} ctx={ctx} />\n </div>\n </article>\n );\n}\n","import * as React from \"react\";\nimport { MarkdownEditor } from \"../forms/MarkdownEditor\";\nimport type { MarkdownEditorHandle, EditorTrigger } from \"../forms/MarkdownEditor\";\nimport { Dropzone, FilePickButton, useStagedFiles } from \"../forms/Dropzone\";\nimport type { FileUploadHandler } from \"../forms/Dropzone\";\nimport { FileStrip } from \"../forms/FileGrid\";\nimport { Popover, Menu } from \"../actions/Popover\";\nimport type { MenuItem } from \"../actions/Popover\";\nimport { extractClipboardFiles } from \"../../kits/files\";\nimport type { Attachment, FileRejection } from \"../../kits/files\";\nimport { KeyHint } from \"../feedback/KeyHint\";\nimport type { SlashCommand, MentionSource, VoiceHandler } from \"./AgentChatPanel\";\n\n/**\n * Staged files, the queue strip, the markdown editor, slash/mention triggers, send + stop.\n * Enter sends, Shift+Enter continues the list or quote you are in, IME composition never\n * sends. Omit `fileUploadHandler` and there is no attach affordance at all — a pasted\n * image then falls through to the editor rather than stranding on a message that cannot\n * carry it.\n */\nexport interface ChatComposerProps {\n onSubmit: (text: string, attachments?: Attachment[]) => void;\n /** Offered whenever a turn is in flight, even with no upstream cancel. */\n onStop?: () => void;\n busy?: boolean;\n disabled?: boolean;\n placeholder?: string;\n maxLength?: number;\n fileUploadHandler?: FileUploadHandler;\n acceptFiles?: string;\n maxFileSize?: number;\n /** Chars above which a paste becomes a .txt attachment. Default 4000. */\n largePasteThreshold?: number;\n slashCommands?: SlashCommand[];\n mentionSources?: MentionSource[] | ((query: string) => Promise<MentionSource[]>);\n voiceHandler?: VoiceHandler;\n /** Messages waiting behind the turn in flight. Each row is removable. */\n queue?: Array<{ id: string; text: string; attachments?: Attachment[] }>;\n onRemoveQueued?: (id: string) => void;\n /** Rendered above the field — where AgentChatPanel puts the session bar. */\n sessionBar?: React.ReactNode;\n toolbarExtras?: React.ReactNode;\n /** Controlled draft, so a host can prefill (edit-a-message does this). */\n draft?: string;\n onDraftChange?: (text: string) => void;\n hint?: React.ReactNode;\n narrow?: boolean;\n autoFocus?: boolean;\n onReject?: (rejections: FileRejection[]) => void;\n onOpenAttachment?: (a: Attachment) => void;\n}\n\n/**\n * The composer: staged attachments, the visible send queue, the editor, and the\n * send/stop control. Every optional affordance appears only when its input is\n * supplied — no upload handler means no attach button at all.\n */\nexport function ChatComposer({\n onSubmit, onStop, busy, disabled, placeholder = \"Ask a question…\", maxLength,\n fileUploadHandler, acceptFiles, maxFileSize, largePasteThreshold = 4000,\n slashCommands, mentionSources, voiceHandler,\n queue = [], onRemoveQueued, sessionBar, toolbarExtras,\n draft, onDraftChange, hint, narrow, autoFocus,\n onReject, onOpenAttachment,\n}: ChatComposerProps) {\n const [text, setText] = React.useState(draft || \"\");\n const [trigger, setTrigger] = React.useState<EditorTrigger | null>(null);\n const [mentionItems, setMentionItems] = React.useState<MentionSource[]>([]);\n const [listening, setListening] = React.useState(false);\n const [notice, setNotice] = React.useState<string | null>(null);\n const editor = React.useRef<MarkdownEditorHandle>(null);\n const wrap = React.useRef<HTMLDivElement>(null);\n const stopVoice = React.useRef<(() => void) | null>(null);\n const staged = useStagedFiles(fileUploadHandler, { onError: () => {} });\n\n React.useEffect(() => { if (draft != null && draft !== text) setText(draft); }, [draft]);\n const change = (v: string) => { setText(v); onDraftChange && onDraftChange(v); };\n\n const uploading = staged.busy;\n const canSend = !disabled && !uploading && (text.trim().length > 0 || staged.items.length > 0);\n\n const flash = (msg: string) => { setNotice(msg); setTimeout(() => setNotice(null), 4000); };\n\n const submit = () => {\n if (!canSend) return;\n onSubmit(text.trim(), staged.items.map((f) => {\n const { file: _file, ...rest } = f; // drop the raw File from the wire shape\n return rest;\n }));\n change(\"\");\n staged.clear();\n setTrigger(null);\n };\n\n /* paste → attachment. The extractor reports; this host decides whether to consume. */\n const onPaste = (e: React.ClipboardEvent) => {\n if (!fileUploadHandler) return; // nowhere to put it: fall through\n const found = extractClipboardFiles(e.nativeEvent, { largePasteThreshold, accept: acceptFiles, maxFileSize });\n if (found.rejected && found.rejected.length) { flash(found.rejected[0].message); onReject && onReject(found.rejected); }\n if (!found.source || !found.files.length) return; // ordinary paste: leave the event alone\n e.preventDefault();\n staged.add(found.files);\n };\n\n /* trigger menus */\n React.useEffect(() => {\n if (!trigger || trigger.type !== \"mention\" || !mentionSources) { setMentionItems([]); return; }\n if (typeof mentionSources === \"function\") {\n let dead = false;\n Promise.resolve(mentionSources(trigger.query)).then((r) => { if (!dead) setMentionItems(r || []); }).catch(() => {});\n return () => { dead = true; };\n }\n const q = (trigger.query || \"\").toLowerCase();\n setMentionItems(mentionSources.filter((m) => !q || (m.label + \" \" + (m.description || \"\")).toLowerCase().includes(q)));\n }, [trigger, mentionSources]);\n\n const slashItems = React.useMemo(() => {\n if (!trigger || trigger.type !== \"slash\" || !slashCommands) return [] as SlashCommand[];\n const q = (trigger.query || \"\").toLowerCase();\n return slashCommands.filter((c) => !q || (c.id + \" \" + c.label + \" \" + (c.description || \"\")).toLowerCase().includes(q));\n }, [trigger, slashCommands]);\n\n const menuItems: MenuItem[] = trigger\n ? (trigger.type === \"slash\" ? slashItems : mentionItems).slice(0, 40).map((it) => {\n const slash = it as SlashCommand;\n const mention = it as MentionSource;\n return {\n id: it.id, label: trigger.type === \"slash\" ? \"/\" + slash.id : mention.label,\n description: it.description, icon: it.icon, meta: mention.meta,\n shortcut: slash.shortcut ? <KeyHint keys={slash.shortcut} size=\"sm\" /> : undefined,\n onSelect: () => {\n const insert = trigger.type === \"slash\"\n ? (slash.immediate ? \"/\" + slash.id : \"/\" + slash.id + \" \")\n : \"@\" + (mention.value || mention.label) + \" \";\n editor.current && editor.current.replaceRange(trigger.from, trigger.to, insert);\n setTrigger(null);\n if (slash.immediate) setTimeout(() => { onSubmit(\"/\" + slash.id, []); change(\"\"); }, 0);\n if (slash.run) slash.run();\n },\n };\n })\n : [];\n const menuOpen = !!trigger && menuItems.length > 0;\n\n const keydown = (e: React.KeyboardEvent) => {\n if (menuOpen) {\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n e.preventDefault();\n const active = document.querySelector<HTMLElement>(\".fdc-trigger .fd-menu-item.is-active\") || document.querySelector<HTMLElement>(\".fdc-trigger .fd-menu-item\");\n if (active) active.click(); else setTrigger(null);\n return;\n }\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n // the open menu owns vertical movement\n e.preventDefault();\n const list = document.querySelector(\".fdc-trigger .fd-menu\");\n if (list) list.dispatchEvent(new KeyboardEvent(\"keydown\", { key: e.key, bubbles: true }));\n return;\n }\n if (e.key === \"Escape\") { e.preventDefault(); setTrigger(null); return; }\n }\n const mod = e.metaKey || e.ctrlKey;\n if (mod && e.key === \"Enter\") { e.preventDefault(); submit(); return; }\n if (e.key === \"Escape\" && busy && onStop) { e.preventDefault(); onStop(); }\n };\n\n const voice = () => {\n if (!voiceHandler) return;\n if (listening) { if (stopVoice.current) stopVoice.current(); setListening(false); return; }\n setListening(true);\n const res = voiceHandler({\n onText: (t: string, meta?: { replace?: boolean }) => { change(((meta && meta.replace) ? \"\" : text ? text + \" \" : \"\") + t); },\n onEnd: () => setListening(false),\n });\n stopVoice.current = typeof res === \"function\" ? res : () => {};\n };\n\n return (\n <div className={\"fdc-composer\" + (disabled ? \" is-disabled\" : \"\") + (narrow ? \" is-narrow\" : \"\")}>\n {queue.length ? (\n <div className=\"fdc-queue\" aria-label=\"Queued messages\">\n {queue.map((q) => (\n <div className=\"fdc-queue-row\" key={q.id}>\n <i className=\"ph ph-clock-countdown\" aria-hidden=\"true\" />\n <span className=\"fdc-queue-text\">{q.text || (q.attachments ? q.attachments.length + \" file(s)\" : \"\")}</span>\n {onRemoveQueued ? (\n <button type=\"button\" className=\"fdc-queue-x\" onClick={() => onRemoveQueued(q.id)} aria-label=\"Remove queued message\">\n <i className=\"ph ph-x\" aria-hidden=\"true\" />\n </button>\n ) : null}\n </div>\n ))}\n </div>\n ) : null}\n\n {sessionBar}\n\n <Dropzone\n className=\"fdc-field\"\n onFiles={fileUploadHandler ? (files) => staged.add(files) : undefined}\n onReject={(r) => { flash(r[0].message); onReject && onReject(r); }}\n accept={acceptFiles} maxFileSize={maxFileSize}\n disabled={!fileUploadHandler || disabled}\n label=\"Drop to attach\"\n hint={acceptFiles ? acceptFiles.replace(/,/g, \" · \") : undefined}\n >\n <div ref={wrap} className=\"fdc-field-inner\">\n {staged.items.length ? (\n <div className=\"fdc-staged\">\n <FileStrip files={staged.items} size={narrow ? 60 : 68} onRemove={staged.remove} onRetry={staged.retry} onOpen={onOpenAttachment} />\n </div>\n ) : null}\n\n <MarkdownEditor\n ref={editor} value={text} onChange={change} onSubmit={submit}\n onKeyDown={keydown} onPaste={onPaste} onTrigger={setTrigger}\n placeholder={disabled ? \"The assistant is unavailable\" : placeholder}\n disabled={disabled} maxLength={maxLength} autoFocus={autoFocus}\n minRows={narrow ? 1 : 2} maxRows={12} ariaLabel=\"Message\"\n />\n\n <div className=\"fdc-tools\">\n {fileUploadHandler ? (\n <FilePickButton onFiles={staged.add} onReject={(r) => flash(r[0].message)} accept={acceptFiles} maxFileSize={maxFileSize} label=\"Attach files\" icon=\"plus\" />\n ) : null}\n {voiceHandler ? (\n <button type=\"button\" className={\"fd-attachbtn\" + (listening ? \" is-live\" : \"\")} onClick={voice} aria-pressed={listening} aria-label={listening ? \"Stop dictation\" : \"Dictate\"}>\n <i className={\"ph ph-\" + (listening ? \"waveform\" : \"microphone\")} aria-hidden=\"true\" />\n </button>\n ) : null}\n {toolbarExtras}\n <span className=\"fdc-tools-gap\" />\n {maxLength && text.length > maxLength * 0.6 ? (\n <span className={\"fdc-count fd-tabular\" + (text.length > maxLength * 0.95 ? \" is-hot\" : \"\")}>{text.length}/{maxLength}</span>\n ) : null}\n {busy ? (\n <button type=\"button\" className=\"fdc-stop\" onClick={onStop} aria-label=\"Stop generating\">\n <i className=\"ph ph-stop-circle\" aria-hidden=\"true\" />\n <span>Stop</span>\n </button>\n ) : (\n <button type=\"button\" className=\"fdc-send\" onClick={submit} disabled={!canSend} aria-label=\"Send message\">\n <i className=\"ph ph-paper-plane-right\" aria-hidden=\"true\" />\n <span className=\"fdc-send-label\">Send</span>\n </button>\n )}\n </div>\n </div>\n </Dropzone>\n\n {notice ? <div className=\"fdc-notice\" role=\"status\"><i className=\"ph ph-warning-circle\" aria-hidden=\"true\" />{notice}</div> : null}\n {hint && !notice ? <div className=\"fdc-hint\">{hint}</div> : null}\n\n <Popover\n open={menuOpen} anchorRef={wrap} placement=\"top-start\" offset={10}\n minWidth={narrow ? 260 : 320} maxHeight={300} className=\"fdc-trigger\"\n onClose={() => setTrigger(null)} returnFocus={false} closeOnOutside\n label={trigger && trigger.type === \"slash\" ? \"Commands\" : \"Mentions\"}\n >\n <Menu\n items={menuItems} autoFocus={false}\n header={<div className=\"fd-pop-group\">{trigger && trigger.type === \"slash\" ? \"Commands\" : \"Attach context\"}</div>}\n onClose={() => setTrigger(null)}\n />\n </Popover>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { SegmentedMeter, QuotaRow, meterFormats } from \"../data/SegmentedMeter\";\nimport { Popover, MenuButton } from \"../actions/Popover\";\nimport type { MenuItem } from \"../actions/Popover\";\nimport { formatDuration, formatRelative } from \"../data/RelativeTime\";\nimport { KeyHint } from \"../feedback/KeyHint\";\nimport type { SessionStats, ContextUsage, UsageLimit, Model } from \"./AgentChatPanel\";\n\nconst compact = meterFormats.compact;\n\n/**\n * Elapsed time, token spend, context window and quota rows. Renders `null` unless at\n * least one input is supplied — the bar is never an empty frame.\n */\nexport interface ChatSessionBarProps {\n sessionStats?: SessionStats;\n contextUsage?: ContextUsage;\n usageLimits?: UsageLimit[];\n onClear?: () => void;\n extras?: React.ReactNode;\n}\n\n/**\n * The strip above the composer. Every part is prop-fed: supply none of\n * sessionStats / contextUsage / usageLimits and no bar renders at all.\n */\nexport function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }: ChatSessionBarProps) {\n const [open, setOpen] = React.useState(false);\n const anchor = React.useRef<HTMLButtonElement>(null);\n const stats = sessionStats || null;\n const cu = contextUsage || null;\n const limits = usageLimits || null;\n if (!stats && !cu && !limits && !extras) return null;\n\n const total = cu && Number(cu.total) > 0 ? Number(cu.total) : 0;\n const used = cu ? (cu.segments || []).reduce((n, s) => n + (Number(s.value) || 0), 0) : 0;\n const pct = total ? Math.min(100, Math.round((used / total) * 100)) : 0;\n\n const bits: string[] = [];\n if (stats && stats.elapsedMs) bits.push(formatDuration(stats.elapsedMs));\n if (stats && stats.tokens) bits.push(compact(stats.tokens) + \" tokens\");\n if (stats && stats.costUsd != null) bits.push(\"$\" + Number(stats.costUsd).toFixed(stats.costUsd < 1 ? 3 : 2));\n if (stats && stats.runningTasks) bits.push(stats.runningTasks + \" running task\" + (stats.runningTasks === 1 ? \"\" : \"s\"));\n if (cu) bits.push(pct + \"% context\");\n\n const expandable = !!(cu || limits);\n\n return (\n <React.Fragment>\n <div className=\"fdc-bar\">\n <button\n type=\"button\" ref={anchor} className=\"fdc-bar-btn\" disabled={!expandable}\n onClick={() => setOpen((v) => !v)} aria-expanded={expandable ? open : undefined}\n aria-label={expandable ? \"Usage details\" : undefined}\n >\n {cu ? (\n <span className=\"fdc-bar-mini\" aria-hidden=\"true\">\n <SegmentedMeter total={total} segments={cu.segments} height={4} showTotal={false} />\n </span>\n ) : null}\n <span className=\"fdc-bar-text\">{bits.join(\" · \")}</span>\n {expandable ? <i className=\"ph ph-caret-right fdc-bar-caret\" aria-hidden=\"true\" /> : null}\n </button>\n {extras}\n </div>\n\n <Popover open={open} anchorRef={anchor} placement=\"top-start\" onClose={() => setOpen(false)} minWidth={330} maxHeight={460} padded label=\"Usage\">\n <div className=\"fdc-usage\">\n {cu ? (\n <section className=\"fdc-usage-sec\">\n <SegmentedMeter\n total={total} segments={cu.segments} label={cu.label || \"Context window\"}\n format={cu.format === \"bytes\" ? meterFormats.bytes : compact} height={8} legend\n remainderLabel=\"Free\"\n />\n </section>\n ) : null}\n {limits && limits.length ? (\n <section className=\"fdc-usage-sec\">\n <h4 className=\"fdc-usage-h\">{\"Usage limits\"}</h4>\n <div className=\"fdc-usage-rows\">\n {limits.map((l) => (\n <QuotaRow key={l.id} label={l.label} percent={l.percent}\n note={l.resetsAt ? \"Resets \" + formatRelative(l.resetsAt) : l.note} />\n ))}\n </div>\n </section>\n ) : null}\n {stats ? (\n <section className=\"fdc-usage-sec fdc-usage-stats\">\n {stats.elapsedMs ? <div><span>Session</span><b className=\"fd-tabular\">{formatDuration(stats.elapsedMs)}</b></div> : null}\n {stats.tokens ? <div><span>Tokens</span><b className=\"fd-tabular\">{stats.tokens.toLocaleString()}</b></div> : null}\n {stats.costUsd != null ? <div><span>Cost</span><b className=\"fd-tabular\">${Number(stats.costUsd).toFixed(3)}</b></div> : null}\n {stats.turns ? <div><span>Turns</span><b className=\"fd-tabular\">{stats.turns}</b></div> : null}\n </section>\n ) : null}\n {onClear ? (\n <footer className=\"fdc-usage-foot\">\n <button type=\"button\" className=\"fdc-usage-clear\" onClick={() => { setOpen(false); onClear(); }}>\n <i className=\"ph ph-trash\" aria-hidden=\"true\" />Clear conversation\n </button>\n </footer>\n ) : null}\n </div>\n </Popover>\n </React.Fragment>\n );\n}\n\n/**\n * Model picker, effort level and fast mode. `null` when no models are given.\n * A model's `shortcut` renders a key cap and binds nothing.\n */\nexport interface ModelControlsProps {\n models?: Model[];\n model?: string;\n onModelChange?: (id: string) => void;\n effortLevels?: string[];\n effort?: string;\n onEffortChange?: (level: string) => void;\n fastMode?: boolean;\n onFastModeChange?: (on: boolean) => void;\n fastModeLabel?: string;\n /** Collapsed into a submenu. */\n moreModels?: Model[];\n narrow?: boolean;\n}\n\n/**\n * Model picker (+ optional effort and fast-mode). Renders only when `models` is\n * supplied. Shortcuts are hints; the app registers the real keys.\n */\nexport function ModelControls({\n models, model, onModelChange,\n effortLevels, effort, onEffortChange,\n fastMode, onFastModeChange, fastModeLabel = \"Enable fast mode\",\n moreModels, narrow: _narrow,\n}: ModelControlsProps) {\n if (!models || !models.length) return null;\n const current = models.find((m) => m.id === model) || models[0];\n const grouped: Record<string, Model[]> = {};\n const flat: Model[] = [];\n models.forEach((m) => {\n if (m.group) { (grouped[m.group] = grouped[m.group] || []).push(m); return; }\n flat.push(m);\n });\n\n const item = (m: Model): MenuItem => ({\n id: m.id, label: m.label, description: m.description, disabled: m.disabled,\n checked: m.id === (current && current.id),\n meta: m.meta,\n shortcut: m.shortcut ? <KeyHint keys={m.shortcut} size=\"sm\" /> : undefined,\n onSelect: () => onModelChange && onModelChange(m.id),\n });\n\n const items: MenuItem[] = ([{ kind: \"section\", label: \"Models\" }] as MenuItem[]).concat(flat.map(item));\n Object.keys(grouped).forEach((g) => {\n items.push({ id: \"grp_\" + g, label: g, icon: \"stack\", submenu: grouped[g].map(item) });\n });\n if (moreModels && moreModels.length) items.push({ id: \"more\", label: \"More models\", submenu: moreModels.map(item) });\n if (onFastModeChange) {\n items.push({ kind: \"separator\" });\n items.push({ kind: \"section\", label: \"Fast mode\" });\n items.push({\n kind: \"custom\",\n render: () => (\n <label className=\"fdc-switchrow\">\n <span>{fastModeLabel}</span>\n <input type=\"checkbox\" className=\"fd-sr\" checked={!!fastMode} onChange={(e) => onFastModeChange(e.target.checked)} />\n <span className={\"fd-switch-track\" + (fastMode ? \" is-on\" : \"\")} aria-hidden=\"true\"><span className=\"fd-switch-thumb\" /></span>\n </label>\n ),\n });\n }\n\n return (\n <React.Fragment>\n <MenuButton\n items={items} placement=\"top-end\" minWidth={252} ariaLabel=\"Model\"\n label={current ? current.label : \"Model\"} title=\"Choose a model\"\n />\n {effortLevels && effortLevels.length ? (\n <MenuButton\n placement=\"top-end\" minWidth={180} ariaLabel=\"Reasoning effort\" trailingIcon={null}\n label={effort || effortLevels[0]} title=\"Reasoning effort\"\n items={effortLevels.map((lv) => ({\n id: lv, label: lv, checked: lv === effort,\n onSelect: () => onEffortChange && onEffortChange(lv),\n }))}\n />\n ) : null}\n </React.Fragment>\n );\n}\n","import * as React from \"react\";\n\n/* =============================================================================\n QueryKit — the one way this app asks a server for a list.\n\n Two halves:\n\n 1. QueryKit.run(rows, query, cfg)\n The SERVER side, simulated. Applies search → filters → sort → page in that\n order and returns the one envelope every list endpoint must return:\n\n {\n rows, the current page only\n pager: { page, pageSize, total, totalPages, from, to, hasPrev, hasNext },\n sort: { key, dir },\n filter: { applied, q, facets }\n }\n\n When the real API lands, this function is deleted — the endpoint returns\n the same envelope and nothing else changes.\n\n 2. useServerTable({ endpoint, params, defaults, deps })\n The CLIENT side. Owns one query object, refetches on any change, debounces\n typing, drops stale responses, and resets to page 1 whenever the result set\n changes shape (search, filter or sort). Every table in the app uses it, so\n paging/sorting/filtering behave identically everywhere.\n\n Query contract (identical for every list endpoint):\n page 1-indexed\n pageSize 10 | 25 | 50 | 100\n sort column key\n dir \"asc\" | \"desc\"\n q free-text search across the endpoint's searchable columns\n filters { [filterId]: value } — endpoint-specific, documented per endpoint\n============================================================================= */\n\nexport interface TableQuery {\n /** 1-indexed. */\n page: number;\n pageSize: number;\n sort: string | null;\n dir: \"asc\" | \"desc\";\n /** Free-text search across the endpoint's searchable columns. */\n q: string;\n filters: Record<string, unknown>;\n}\nexport interface Pager {\n page: number; pageSize: number; total: number; totalPages: number;\n from: number; to: number; hasPrev: boolean; hasNext: boolean;\n}\n/** The envelope EVERY paged list endpoint returns. */\nexport interface ListEnvelope<Row = unknown> {\n rows: Row[];\n pager: Pager;\n sort: { key: string; dir: \"asc\" | \"desc\" } | null;\n filter: { applied: Record<string, unknown>; q: string; facets: Record<string, Record<string, number>> };\n aggregate?: Record<string, unknown>;\n}\nexport interface RunConfig<Row = unknown> {\n searchKeys?: string[];\n filters?: Record<string, (row: Row, value: any) => boolean>;\n /** Sort value for a column whose key isn't a plain field. */\n accessors?: Record<string, (row: Row) => unknown>;\n /** Option counts, computed over the SEARCHED set so a filter never erases its own alternatives. */\n facets?: Record<string, (row: Row) => string | number | null>;\n defaultSort?: { key: string; dir: \"asc\" | \"desc\" };\n defaultPageSize?: number;\n}\nexport interface ServerTable<Row = unknown> {\n rows: Row[]; pager: Pager; total: number; page: number; pageSize: number;\n totalPages: number; from: number; to: number;\n facets: Record<string, Record<string, number>>;\n aggregate: Record<string, unknown>;\n query: TableQuery;\n sort?: { key: string; dir: \"asc\" | \"desc\" };\n q: string; filters: Record<string, unknown>;\n loading: boolean;\n /** True only on the FIRST load — later loads keep showing stale rows. */\n initialLoading: boolean;\n /** True while re-querying with previous rows still on screen. Pass straight to\n * DataTable's `refreshing`, or to LoadingRegion as state=\"refreshing\". */\n refreshing: boolean;\n activeFilterCount: number;\n setPage(p: number): void;\n setPageSize(n: number): void;\n setQ(q: string): void;\n toggleSort(key: string): void;\n setSortKey(key: string, dir?: \"asc\" | \"desc\"): void;\n /** Same query, unpaged — for CSV export and select-all-matching. */\n fetchAll(): Promise<Row[]>;\n /** value may be an updater fn — REQUIRED for toggles, or two fast clicks read the same\n * stale array and the first is lost. */\n setFilter(id: string, value: unknown | ((prev: unknown) => unknown)): void;\n clearFilter(id: string): void;\n setFilters(filters: Record<string, unknown>): void;\n clearFilters(): void;\n refresh(): void;\n queryString: string;\n}\nexport interface UseServerTableOptions {\n endpoint: string;\n params?: Record<string, unknown>;\n defaults?: Partial<TableQuery>;\n /** Extra values that should trigger a refetch. */\n deps?: unknown[];\n /** Opts into durable rows-per-page and default sort. Page/search/filters are deliberately\n * NOT persisted — they describe one task, and restoring them hides rows the user expects. */\n prefsKey?: string;\n}\n\n/* Filter-predicate builders for RunConfig.filters — covers the three shapes that come\n up in almost every table: equality/multi-select, tag/array membership, numeric range.\n A filter is free to skip these and write its own (row, value) => boolean instead. */\nexport function eqFilter<Row>(get: (row: Row) => unknown) {\n return (row: Row, value: unknown): boolean =>\n Array.isArray(value) ? value.includes(get(row)) : get(row) === value;\n}\nexport function anyOfFilter<Row>(get: (row: Row) => string[]) {\n return (row: Row, value: unknown): boolean => {\n const xs = get(row) ?? [];\n return Array.isArray(value)\n ? value.some((x) => xs.includes(String(x)))\n : xs.includes(String(value));\n };\n}\nexport function rangeFilter<Row>(get: (row: Row) => number) {\n return (row: Row, value: unknown): boolean => {\n const n = get(row);\n const bounds = Array.isArray(value) ? value : [0, Number.POSITIVE_INFINITY];\n const lo = Number(bounds[0] ?? 0);\n const hiRaw = bounds[1];\n const hi = hiRaw == null ? Number.POSITIVE_INFINITY : Number(hiRaw);\n return n >= lo && (hi === Number.POSITIVE_INFINITY || n <= hi);\n };\n}\n\nconst DEFAULTS: TableQuery = { page: 1, pageSize: 25, sort: null, dir: \"desc\", q: \"\", filters: {} };\n\nfunction compare(a: unknown, b: unknown, dir: \"asc\" | \"desc\"): number {\n const empty = (v: unknown) => v == null || v === \"\";\n if (empty(a) && empty(b)) return 0;\n if (empty(a)) return 1; // nulls always last, both directions\n if (empty(b)) return -1;\n const n = typeof a === \"number\" && typeof b === \"number\"\n ? a - b\n : String(a).localeCompare(String(b), undefined, { numeric: true, sensitivity: \"base\" });\n return dir === \"asc\" ? n : -n;\n}\n\n/* Transport and prefs are injected: setApi() once per app. Without this the kit would\n have to know an app-specific global, which is exactly what makes a shared kit unshareable. */\ntype Api = { request(id: string, params?: unknown): Promise<unknown> };\ntype PrefsStore = { getTable(key: string): any; setTable(key: string, patch: any): void };\n\nlet API: Api | null = null;\nlet PREFS: PrefsStore | null = null;\n\ndeclare global {\n interface Window {\n /* Legacy global fallback for QueryKit.setPrefs() — this is the name of the prefs store\n in the app query.js was extracted from. Harmless: `PREFS || window.PlannerPrefs` already\n short-circuits on PREFS first, so a consuming app that never defines this global (as most\n won't) simply falls through to \"no prefs store\" behaviour. Ported as-is, not renamed. */\n PlannerPrefs?: PrefsStore;\n }\n}\n\n/** React hook — the only way a screen should talk to a list endpoint. */\nfunction useServerTable<Row = unknown>({ endpoint, params, defaults, deps, prefsKey }: UseServerTableOptions): ServerTable<Row> {\n /* prefsKey opts a table into durable rows-per-page and default sort (prefs.js).\n Page number, search text and filters are deliberately NOT persisted: they\n describe one task, and restoring them would hide rows the user expects. */\n const [query, setQuery] = React.useState<TableQuery>(() => {\n const store = PREFS || window.PlannerPrefs;\n const saved = prefsKey && store ? store.getTable(prefsKey) : {};\n return { ...DEFAULTS, ...(defaults || {}), ...(saved.pageSize ? { pageSize: saved.pageSize } : {}), ...(saved.sort ? { sort: saved.sort, dir: saved.dir || \"desc\" } : {}) };\n });\n const savePref = React.useCallback((patch: { pageSize?: number; sort?: string; dir?: \"asc\" | \"desc\" }) => {\n const store = PREFS || window.PlannerPrefs;\n if (prefsKey && store) store.setTable(prefsKey, patch);\n }, [prefsKey]);\n const [res, setRes] = React.useState<ListEnvelope<Row> | null>(null);\n const [loading, setLoading] = React.useState(true);\n const seq = React.useRef(0);\n const depKey = (deps || []).join(\"|\");\n const paramKey = JSON.stringify(params || {});\n const queryKey = JSON.stringify(query);\n\n React.useEffect(() => {\n const id = ++seq.current;\n setLoading(true);\n // Debounced so typing in a search box is one request, not one per keystroke —\n // exactly what we want against the real endpoint.\n const t = setTimeout(() => {\n QueryKit.getApi().request(endpoint, { ...(params || {}), ...query }).then((r) => {\n if (id !== seq.current) return; // stale response, drop it\n setRes(r as ListEnvelope<Row>);\n setLoading(false);\n });\n }, query.q ? 220 : 60);\n return () => clearTimeout(t);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [endpoint, queryKey, paramKey, depKey]);\n\n const patch = (p: Partial<TableQuery>, resetPage = true) =>\n setQuery((s) => ({ ...s, ...p, page: resetPage ? 1 : (p.page != null ? p.page : s.page) }));\n const defaultPager: Pager = { page: query.page, pageSize: query.pageSize, total: 0, totalPages: 1, from: 0, to: 0, hasPrev: false, hasNext: false };\n const pager: Pager = (res && res.pager) || defaultPager;\n const api: ServerTable<Row> = {\n rows: res ? res.rows : [],\n /** The response's pager block, verbatim. */\n pager,\n total: pager.total || 0,\n page: pager.page || query.page,\n pageSize: query.pageSize,\n totalPages: pager.totalPages || 1,\n from: pager.from || 0,\n to: pager.to || 0,\n facets: (res && res.filter && res.filter.facets) || {},\n /** Server-computed totals over the whole match, never the current page. */\n aggregate: (res && res.aggregate) || {},\n /** The live query object — pass to fetchAll-style calls that need the full match. */\n query,\n sort: query.sort ? { key: query.sort, dir: query.dir } : undefined,\n q: query.q,\n filters: query.filters,\n loading,\n /** True only on the very first load — later loads keep showing stale rows. */\n initialLoading: loading && !res,\n activeFilterCount: Object.values(query.filters).filter((v) => !(v == null || v === \"\" || v === false)).length,\n setPage: (page: number) => patch({ page }, false),\n setPageSize: (pageSize: number) => { savePref({ pageSize }); patch({ pageSize }); },\n setQ: (q: string) => patch({ q }),\n toggleSort: (key: string) => setQuery((s) => {\n const dir: \"asc\" | \"desc\" = s.sort === key && s.dir === \"desc\" ? \"asc\" : \"desc\";\n savePref({ sort: key, dir });\n return { ...s, page: 1, sort: key, dir };\n }),\n setSortKey: (key: string, dir?: \"asc\" | \"desc\") => { savePref({ sort: key, dir: dir || \"desc\" }); setQuery((s) => ({ ...s, page: 1, sort: key, dir: dir || \"desc\" })); },\n /** Same query, unpaged — for CSV export and select-all-matching. */\n fetchAll: () => QueryKit.getApi().request(endpoint, { ...(params || {}), ...query, page: 1, pageSize: 100000 }).then((r) => (r as ListEnvelope<Row>).rows),\n /** value may be an updater fn — required for toggles, or two fast clicks\n both read the same stale array and the first one is lost. */\n setFilter: (id: string, value: unknown | ((prev: unknown) => unknown)) => setQuery((s) => ({ ...s, page: 1, filters: { ...s.filters, [id]: typeof value === \"function\" ? (value as (prev: unknown) => unknown)(s.filters[id]) : value } })),\n clearFilter: (id: string) => setQuery((s) => { const f = { ...s.filters }; delete f[id]; return { ...s, page: 1, filters: f }; }),\n setFilters: (filters: Record<string, unknown>) => patch({ filters }),\n clearFilters: () => patch({ filters: {}, q: \"\" }),\n refresh: () => setQuery((s) => ({ ...s })),\n /* True on a re-query while the PREVIOUS rows are still rendered — sort, filter, page.\n Distinct from `loading` (first load, nothing on screen) because the two need different\n treatments: skeletons versus a stale overlay on real content. */\n refreshing: loading && !!res,\n queryString: QueryKit.toQueryString(query)\n };\n return api;\n}\n\nconst QueryKit = {\n DEFAULTS,\n /** Register the app's simulated (or real) transport: an object with .request(id, params). */\n setApi<T extends Api>(api: T): T { API = api; return api; },\n getApi(): Api {\n if (!API) throw new Error(\"QueryKit: call QueryKit.setApi(yourApi) once at app boot — the kit must not guess at app globals.\");\n return API;\n },\n /** Optional durable table preferences store: { getTable(key), setTable(key, patch) }. */\n setPrefs(p: PrefsStore): void { PREFS = p; },\n\n /**\n * @param rows the full static dataset (stands in for the table)\n * @param query { page, pageSize, sort, dir, q, filters }\n * @param cfg { searchKeys[], filters: {id: (row, value) => boolean},\n * accessors: {colKey: (row) => sortableValue},\n * facets: {id: (row) => facetValue} }\n */\n run<Row>(rows: Row[], query: Partial<TableQuery>, cfg: RunConfig<Row>): ListEnvelope<Row> {\n const Q: TableQuery = { ...DEFAULTS, ...(query || {}) };\n const c = cfg;\n const filters = Q.filters || {};\n const active = (v: unknown) => !(v == null || v === \"\" || v === false || (Array.isArray(v) && !v.length));\n\n // search\n let out: Row[] = rows;\n const term = (Q.q || \"\").trim().toLowerCase();\n if (term && c.searchKeys) {\n const keys = c.searchKeys;\n out = out.filter((r) => keys.some((k) => String((r as Record<string, unknown>)[k] ?? \"\").toLowerCase().includes(term)));\n }\n const searched = out;\n\n // filters\n Object.entries(filters).forEach(([id, val]) => {\n const fn = c.filters && c.filters[id];\n if (!active(val) || !fn) return;\n out = out.filter((r) => fn(r, val));\n });\n const matched = out;\n\n // facets — option counts computed over the searched set, so a filter never\n // erases its own alternatives from the UI.\n const facets: Record<string, Record<string, number>> = {};\n if (c.facets) Object.entries(c.facets).forEach(([id, get]) => {\n const counts: Record<string, number> = {};\n searched.forEach((r) => { const v = get(r); if (v != null) counts[v] = (counts[v] || 0) + 1; });\n facets[id] = counts;\n });\n\n // sort\n if (Q.sort) {\n const get = (c.accessors && c.accessors[Q.sort]) || ((r: Row) => (r as Record<string, unknown>)[Q.sort as string]);\n out = [...out].sort((a, b) => compare(get(a), get(b), Q.dir));\n }\n\n // page\n const total = matched.length;\n const pageSize = Math.max(1, Q.pageSize);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const page = Math.min(Math.max(1, Q.page), totalPages);\n const paged = out.slice((page - 1) * pageSize, page * pageSize);\n return {\n rows: paged,\n pager: {\n page, pageSize, total, totalPages,\n from: total === 0 ? 0 : (page - 1) * pageSize + 1,\n to: Math.min(total, page * pageSize),\n hasPrev: page > 1,\n hasNext: page < totalPages\n },\n sort: Q.sort ? { key: Q.sort, dir: Q.dir } : null,\n filter: { applied: filters, q: Q.q || \"\", facets }\n };\n },\n\n /** Display form of a query, for the request log and the API spec screen. */\n toQueryString(query: Partial<TableQuery>): string {\n const Q: TableQuery = { ...DEFAULTS, ...(query || {}) };\n const parts: string[] = [];\n if (Q.page !== 1) parts.push(\"page=\" + Q.page);\n if (Q.pageSize !== DEFAULTS.pageSize) parts.push(\"pageSize=\" + Q.pageSize);\n if (Q.sort) parts.push(\"sort=\" + Q.sort + \"&dir=\" + Q.dir);\n if (Q.q) parts.push(\"q=\" + encodeURIComponent(Q.q));\n Object.entries(Q.filters || {}).forEach(([k, v]) => {\n if (v == null || v === \"\" || v === false || (Array.isArray(v) && !v.length)) return;\n // Arrays serialize as repeated params — ?state=OH&state=MI — the convention\n // the real endpoints read for multi-select filters.\n if (Array.isArray(v)) v.forEach((x) => parts.push(k + \"=\" + encodeURIComponent((x === Infinity ? \"*\" : x) as string | number | boolean)));\n else parts.push(k + \"=\" + encodeURIComponent(v as string | number | boolean));\n });\n return parts.join(\"&\");\n },\n\n useServerTable\n};\n\nexport { QueryKit, useServerTable };\n","/* =============================================================================\n MockJobKit — simulates a long-running backend job so a mock/demo transport can\n answer the `{ jobId }` → poll pattern the same way a real async endpoint would:\n the initiating call returns immediately with an id, and the caller polls a\n status endpoint until the work is done.\n\n Two halves:\n\n 1. MockJobKit.schedule(prefix, latency, stages, compute)\n The SERVER side, simulated. Registers a job and advances it through `stages`\n on a jittered timer within `latency`, calling `compute()` on the final tick\n to produce the result. Returns the job id at once — exactly what a real\n endpoint returns before doing the work off the request/response cycle.\n\n 2. MockJobKit.get(jobId) / MockJobKit.poll(jobId, opts)\n The CLIENT side. `get` is the plain status lookup a jobs.get-style endpoint\n wraps. `poll` is the loop every screen that watches a job actually needs:\n re-check on an interval, report progress via onTick, resolve with the\n result once done, throw once failed. Pulled out here because two unrelated\n screens had each hand-written the identical loop.\n\n Failure: `compute` may throw. A throw is caught and turned into a \"failed\"\n status with `error` set to the thrown value's message — the honest way to make\n MockJobStatus's \"failed\" state one that can actually occur, rather than a value\n the type claims is reachable but no scheduler ever produces.\n============================================================================= */\n\nexport interface MockJobStatus<TResult = unknown> {\n id: string;\n status: \"queued\" | \"running\" | \"done\" | \"failed\";\n progress?: number;\n stage?: string;\n result?: TResult;\n /** Set only when status is \"failed\" — the thrown value's message. */\n error?: string;\n}\nexport interface PollOptions<TResult = unknown> {\n /** Delay between polls, ms. Default 400 — the rate every hand-written poller used. */\n intervalMs?: number;\n onTick?: (status: MockJobStatus<TResult>) => void;\n}\n\nlet ridSeq = 0;\nconst rid = (prefix: string) =>\n `${prefix}_${(++ridSeq).toString(36)}${Math.random().toString(36).slice(2, 6)}`;\nconst jitter = ([lo, hi]: [number, number]) => lo + Math.random() * (hi - lo);\nconst sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\nconst jobs = new Map<string, MockJobStatus>();\n\n/**\n * @param prefix id prefix, e.g. \"imp\" → \"imp_1a2b3c\"\n * @param latency [lo, hi] ms — total time across every stage, jittered within the range\n * @param stages progress labels in order, e.g. [\"Uploading\", \"Parsing\", \"Validating\"]\n * @param compute runs once, on the final stage, to produce the result — or throws to fail the job\n */\nfunction schedule<TResult>(\n prefix: string,\n latency: [number, number],\n stages: string[],\n compute: () => TResult,\n): string {\n const id = rid(prefix);\n const list = stages.length ? stages : [\"Working\"];\n const total = jitter(latency);\n jobs.set(id, { id, status: \"queued\", progress: 0, stage: list[0] });\n list.forEach((stage, i) => {\n const at = (total * (i + 1)) / list.length;\n setTimeout(() => {\n if (!jobs.has(id)) return; // job was cleared out from under this tick\n if (i === list.length - 1) {\n try {\n jobs.set(id, { id, status: \"done\", progress: 1, stage, result: compute() });\n } catch (err) {\n jobs.set(id, {\n id, status: \"failed\", progress: 1, stage,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n } else {\n jobs.set(id, { id, status: \"running\", progress: (i + 1) / list.length, stage });\n }\n }, at);\n });\n return id;\n}\n\n/** Plain status lookup — what a jobs.get-style mock endpoint wraps. Throws if the id is unknown. */\nfunction get<TResult = unknown>(jobId: string): MockJobStatus<TResult> {\n const job = jobs.get(jobId);\n if (!job) throw new Error(`MockJobKit: job \"${jobId}\" not found`);\n // The store is untyped (one Map holds every job in the app) — the caller's TResult\n // is trusted the same way a real jobs.get response's shape would be.\n return { ...job } as unknown as MockJobStatus<TResult>;\n}\n\n/** Polls until the job resolves. Resolves with the result on \"done\", throws on \"failed\". */\nasync function poll<TResult = unknown>(jobId: string, opts?: PollOptions<TResult>): Promise<TResult> {\n const intervalMs = opts?.intervalMs ?? 400;\n for (;;) {\n const status = get<TResult>(jobId);\n opts?.onTick?.(status);\n if (status.status === \"done\") return status.result as TResult;\n if (status.status === \"failed\") throw new Error(status.error || `Job failed: ${jobId}`);\n await sleep(intervalMs);\n }\n}\n\nexport const MockJobKit = { schedule, get, poll };\n","/* =============================================================================\n VersionKit — append-only version history with a full-state snapshot per\n version, so any version can be jumped back to without replaying mutations.\n\n Extracted from media-planner's plan-version pattern (commitVersion / plan.undo /\n versions.restore) and generalized: this file has no idea what TState is. A\n consuming app supplies the whole state shape it wants versioned — a plan, a\n document, a form draft, whatever — plus an optional `diff` function for\n describing what changed between two states in whatever shape it cares about.\n\n Factory, not a namespace: an app can have more than one independently-versioned\n thing open at once (two plans, a plan and a separate document), and each needs\n its own version array, its own snapshot map and its own \"current\" pointer.\n createVersionStore() returns one such instance; SessionKit/RuntimeKit's\n single-shared-store shape would make the second instance clobber the first.\n\n History is append-only on purpose: undo() and restoreTo() never delete or\n rewrite a version, they COMMIT a new one whose state happens to match an\n earlier snapshot. That is what makes \"undo the undo\" possible and what keeps\n the version list a true audit trail instead of a mutable pointer. ---------- */\n\n/** One entry in the append-only history. Never mutated after it's appended,\n * except for `current` flipping to false when a later version is committed. */\nexport interface VersionRecord<TDiff = unknown> {\n v: number;\n current: boolean;\n who: string;\n when: string;\n action: string;\n /** Human-readable change descriptions, as returned by the mutator passed to commit(). */\n changes: string[];\n /** Present only when the store was created with a `diff` option. */\n diff?: TDiff;\n /** Open bag for caller-specific before/after figures (e.g. a computed total) that\n * don't belong in `diff` because they aren't part of the state comparison itself. */\n meta?: Record<string, unknown>;\n}\n\nexport interface CreateVersionStoreOptions<TState, TDiff = unknown> {\n /** Defaults to structuredClone. Override if TState holds something it can't clone\n * (a class instance, a function) — must still produce a deep, independent copy. */\n clone?: (state: TState) => TState;\n /** Computes what a version's `diff` field holds by comparing the state before and\n * after the mutation. Omit if the caller has no use for a structured diff — the\n * `changes` string list on every record still describes what happened. */\n diff?: (before: TState, after: TState) => TDiff;\n /** Timestamp/attribution stamp for `when`. Defaults to `new Date().toISOString()`. */\n now?: () => string;\n /** Version number the initial state is recorded under. Defaults to 0. */\n initialVersion?: number;\n who?: string;\n action?: string;\n}\n\nexport interface VersionStore<TState, TDiff = unknown> {\n /** The live state. Mutating it directly bypasses versioning — always go through commit(). */\n getState(): TState;\n /** Newest first, matching the order a version-history panel reads top to bottom. */\n getVersions(): VersionRecord<TDiff>[];\n getVersion(v: number): VersionRecord<TDiff> | undefined;\n /**\n * Snapshots the state before mutation, runs `mutate` against the live state, then\n * appends a new version recording what changed and keeps a full-state snapshot of\n * the result so this version can be restored to or undone past later.\n */\n commit(who: string, action: string, mutate: (state: TState) => string[], meta?: Record<string, unknown>): VersionRecord<TDiff>;\n /** Makes version `v` current by committing its snapshot as a NEW head version —\n * history is append-only, so this never rewrites or truncates the list. */\n restoreTo(v: number, who?: string): VersionRecord<TDiff>;\n /** Restores the state one version behind the current head, committed as a new head\n * version (the inverse of the head's change, recorded rather than erased). Throws\n * if the head is already the oldest recorded version. */\n undo(who?: string): VersionRecord<TDiff>;\n}\n\nexport function createVersionStore<TState, TDiff = unknown>(\n initialState: TState,\n options?: CreateVersionStoreOptions<TState, TDiff>,\n): VersionStore<TState, TDiff> {\n const cloneFn = options?.clone ?? ((value: TState) => structuredClone(value));\n const diffFn = options?.diff;\n const now = options?.now ?? (() => new Date().toISOString());\n\n let headVersion = options?.initialVersion ?? 0;\n let state = cloneFn(initialState);\n\n let versions: VersionRecord<TDiff>[] = [\n {\n v: headVersion,\n current: true,\n who: options?.who ?? \"system\",\n when: now(),\n action: options?.action ?? \"Initial state\",\n changes: [],\n },\n ];\n const snapshots = new Map<number, TState>();\n snapshots.set(headVersion, cloneFn(state));\n\n function append(record: Omit<VersionRecord<TDiff>, \"v\" | \"current\">): VersionRecord<TDiff> {\n headVersion += 1;\n versions.forEach((v) => { v.current = false; });\n const version: VersionRecord<TDiff> = { ...record, v: headVersion, current: true };\n versions = [version, ...versions];\n snapshots.set(headVersion, cloneFn(state));\n return version;\n }\n\n return {\n getState(): TState { return state; },\n getVersions(): VersionRecord<TDiff>[] { return [...versions]; },\n getVersion(v: number): VersionRecord<TDiff> | undefined { return versions.find((x) => x.v === v); },\n\n commit(who, action, mutate, meta) {\n const before = cloneFn(state);\n const changes = mutate(state);\n return append({\n who, when: now(), action, changes, meta,\n diff: diffFn ? diffFn(before, state) : undefined,\n });\n },\n\n restoreTo(v, who = \"system\") {\n const snapshot = snapshots.get(v);\n const original = versions.find((x) => x.v === v);\n if (!snapshot || !original) throw new Error(`createVersionStore: version ${v} not found`);\n const before = cloneFn(state);\n state = cloneFn(snapshot);\n return append({\n who, when: now(),\n action: `Restored v${v}`,\n changes: [`Restored to v${v} (${original.action})`],\n diff: diffFn ? diffFn(before, state) : undefined,\n });\n },\n\n undo(who = \"system\") {\n const head = versions[0];\n const prevSnapshot = head ? snapshots.get(head.v - 1) : undefined;\n if (!head || !prevSnapshot) throw new Error(\"createVersionStore: nothing to undo\");\n const before = cloneFn(state);\n state = cloneFn(prevSnapshot);\n return append({\n who, when: now(),\n action: `Undid: ${head.action}`,\n changes: head.changes.map((c) => `↩ ${c}`),\n diff: diffFn ? diffFn(before, state) : undefined,\n });\n },\n };\n}\n"],"mappings":"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","names":["Tag","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","current","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","TONES","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","compact","React","import_jsx_runtime","import_jsx_runtime","compact","React","import_jsx_runtime","React","import_jsx_runtime","kind","m","buf","Tag","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","s","refresh","React","React","import_jsx_runtime","uid","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","current","React","import_jsx_runtime","bucket","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","React","import_react_dom","import_jsx_runtime","usePopPos","popStyle","mode","React","import_react_dom","import_jsx_runtime","usePopPos","popStyle","mode","React","import_jsx_runtime","React","import_jsx_runtime","fmt","React","import_jsx_runtime","import_jsx_runtime","compact","React","import_jsx_runtime","MarkdownEditor","read","next","React","React","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","React","React","listeners","import_jsx_runtime","iso","React","import_react_dom","import_jsx_runtime","W","iso","import_jsx_runtime","compact","React","import_jsx_runtime","mode","import_jsx_runtime","import_jsx_runtime","BANDS","React","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","React","bucket","React","React","import_jsx_runtime","import_jsx_runtime","iso","React","import_jsx_runtime","React","import_jsx_runtime","compact","current","import_jsx_runtime","React","get","patch","seq","sleep"]}