@ai-matrx/summon 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/window/WindowPanel.tsx","../src/window/icons.tsx","../src/window/LayoutIcon.tsx","../src/window/useWindowPanel.ts","../src/window/popout/popoutDragDetector.ts","../src/window/utils/autoOpenPlacement.ts","../src/window/utils/useIsClient.ts","../src/window/utils/useDebugFlag.ts","../src/window/utils/urlSyncIdentity.ts","../src/window/utils/sanitizeWindowData.ts","../src/window/mobile/MobileDrawerSurface.tsx","../src/window/chrome/MobileTitleRow.tsx","../src/window/mobile/MobileCardSurface.tsx","../src/window/chrome/DebugStrip.tsx","../src/window/chrome/chromeClasses.ts","../src/window/chrome/MobileHeader.tsx","../src/window/chrome/DeprecationBanner.tsx","../src/window/chrome/PopoutTopBar.tsx","../src/window/popout/featureDetection.ts","../src/window/popout/usePopoutWindow.ts","../src/window/popout/popoutWindowMap.ts","../src/window/popout/cloneStyles.ts","../src/window/popout/popoutPendingStorage.ts","../src/window/popout/usePopoutControl.ts","../src/window/popout/PopoutPortal.tsx","../src/window/popout/PopoutShell.tsx","../src/window/popout/PopoutContext.tsx","../src/window/tray/traySnapshotMap.ts","../src/window/tray/defaultTraySnapshotCapture.ts","../src/window/tray/MinimizedWindowContent.tsx","../src/window/tray/TrayChipPreview.tsx","../src/window.ts","../src/window/WindowSidebar.tsx","../src/window/useOverlaySurfaceRenderAck.ts","../src/window/tray/TrayStatusChip.tsx","../src/window/popout/usePopoutContainer.ts","../src/window/utils/mayRaiseUnbidden.ts","../src/window/utils/lazy-bundle-guard.ts"],"sourcesContent":["\"use client\";\n\n/**\n * WindowPanel — a floating, draggable, resizable, maximizable, minimizable OS-style window, with\n * snap/arrange, a minimized tile with a captured preview, pop-out to a real browser window, and\n * three phone presentations. Ported from matrx-frontend `features/window-panels/WindowPanel.tsx`.\n *\n * Body identity: the body subtree renders into ONE stable detached container through a portal at a\n * fixed position in this component's tree; each presentation (windowed, maximized, minimized,\n * popped out) only decides WHERE that container is attached. So maximize, minimize, pop-out and\n * dock never remount the body — its state, refs, effects and subscriptions survive every move.\n */\n\nimport React, { useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\";\nimport { announceLayerFront, FloatingLayer, useFloatingLayerZIndex, usePortalContainer, PortalContainerProvider } from \"@ai-matrx/design-system\";\nimport { ResizablePanelGroup, ResizablePanel, ResizableHandle } from \"@ai-matrx/design-system\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { useIsMobile } from \"@ai-matrx/kit/media-query\";\nimport { createPortal } from \"react-dom\";\nimport {\n arrangeActiveWindows,\n clampWindowRect,\n overlaysRawActions,\n DEFAULT_INSTANCE_ID,\n dockWindow,\n buildDockWindowPayload,\n getOverlayMeta,\n safeViewportDims,\n selectAllWindows,\n selectOverlayData,\n selectPopoutCandidateId,\n selectPopoutMode,\n selectWindowPersistence,\n selectWindowsHidden,\n updateWindowPersistence,\n updateWindowRect,\n ackOverlayRender,\n clearOverlayRender,\n type GlobalLayoutType,\n type MobilePresentation,\n type WindowRect,\n} from \"@ai-matrx/summon\";\nimport { useOptionalOverlayInstance, useSummonDispatch, useSummonPorts, useSummonSelector, useSummonStore } from \"@ai-matrx/summon/react\";\nimport {\n AppWindowIcon as AppWindow,\n Maximize2Icon as Maximize2,\n Minimize2Icon as Minimize2,\n MinusIcon as Minus,\n PanelLeftCloseIcon as PanelLeftClose,\n PanelLeftIcon as PanelLeft,\n RectangleVerticalIcon as RectangleVertical,\n SaveIcon as Save,\n XIcon as X,\n} from \"./icons\";\nimport { LayoutIconButton } from \"./LayoutIcon\";\nimport { resolvePosition, useWindowPanel, type UseWindowPanelOptions, type ResizeEdge } from \"./useWindowPanel\";\nimport { AUTO_OPEN_NO_ROOM_EVENT, clearAutoOpened, isAutoOpened } from \"./utils/autoOpenPlacement\";\nimport { useIsClient } from \"./utils/useIsClient\";\nimport { useDebugFlag } from \"./utils/useDebugFlag\";\nimport { useOverlayLink } from \"@ai-matrx/summon/url\";\nimport { resolveWindowUrlSyncKey } from \"./utils/urlSyncIdentity\";\nimport { sanitizeWindowData } from \"./utils/sanitizeWindowData\";\nimport { useWindowConfig, WindowSelectionSurface } from \"@ai-matrx/summon/window-host\";\nimport MobileDrawerSurface from \"./mobile/MobileDrawerSurface\";\nimport MobileCardSurface from \"./mobile/MobileCardSurface\";\nimport { DebugStrip } from \"./chrome/DebugStrip\";\nimport { MobileWindowHeader } from \"./chrome/MobileHeader\";\nimport { WINDOW_CHROME_ACTIONS, WINDOW_CHROME_INTERACTIVE } from \"./chrome/chromeClasses\";\nimport { DeprecationBanner } from \"./chrome/DeprecationBanner\";\nimport { PopoutTopBar } from \"./chrome/PopoutTopBar\";\nimport { detectPopoutCapability } from \"./popout/featureDetection\";\nimport { usePopoutWindow } from \"./popout/usePopoutWindow\";\nimport { registerPopoutOpener } from \"./popout/usePopoutControl\";\nimport { PopoutPortal } from \"./popout/PopoutPortal\";\nimport { PopoutContext, usePopout, type PopoutContextValue } from \"./popout/PopoutContext\";\nimport { usePopoutWindowRef } from \"./popout/popoutWindowMap\";\nimport { setTraySnapshot, clearTraySnapshot } from \"./tray/traySnapshotMap\";\nimport { defaultTraySnapshotCapture } from \"./tray/defaultTraySnapshotCapture\";\nimport { MinimizedWindowContent } from \"./tray/MinimizedWindowContent\";\nimport { getTrayPreviewEntry, type TraySnapshotCapture } from \"@ai-matrx/summon/window-host\";\n\n/** The imperative handle of a ResizablePanel (react-resizable-panels v4), via the design-system component. */\ntype SidebarPanelHandle = NonNullable<Extract<React.ComponentProps<typeof ResizablePanel>[\"panelRef\"], { current: unknown }>[\"current\"]>;\n\n// ─── Resize handle descriptors ───────────────────────────────────────────────\n\ninterface HandleDef {\n edge: ResizeEdge;\n className: string;\n}\n\n/** How long after opening a window places itself without gliding (the entrance is 400ms). */\nconst GLIDE_SETTLE_MS = 800;\n\nconst HANDLES: HandleDef[] = [\n {\n edge: \"e\",\n className:\n \"absolute right-0 top-2 bottom-2 w-2.5 translate-x-1/2 cursor-ew-resize\",\n },\n {\n edge: \"w\",\n className:\n \"absolute left-0 top-2 bottom-2 w-2.5 -translate-x-1/2 cursor-ew-resize\",\n },\n {\n edge: \"s\",\n className:\n \"absolute bottom-0 left-2 right-2 h-2.5 translate-y-1/2 cursor-ns-resize\",\n },\n {\n // Start after the traffic-light hot zone (w-28) — top-left is close/minimize/maximize.\n edge: \"n\",\n className:\n \"absolute top-0 left-2 right-2 h-2.5 -translate-y-1/2 cursor-ns-resize\",\n },\n {\n edge: \"se\",\n className:\n \"absolute bottom-0 right-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nwse-resize\",\n },\n {\n edge: \"sw\",\n className:\n \"absolute bottom-0 left-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nesw-resize\",\n },\n {\n edge: \"ne\",\n className:\n \"absolute top-0 right-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nesw-resize\",\n },\n {\n edge: \"nw\",\n className:\n \"absolute top-0 left-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nwse-resize\",\n },\n];\n\n/**\n * Desktop body shell — consumers style the inner slot via `bodyClassName`\n * only. The outer guard ring is structural: it keeps full-bleed children off the\n * resize-handle hit zones and uses pointer-events-none so bare edge clicks reach\n * the handle layer (z-50) even when inner content is `absolute inset-0`.\n */\nfunction WindowPanelBodyShell({\n bodyRef,\n fitContent,\n isMaximized,\n bodyClassName,\n captureDimensions,\n children,\n}: {\n bodyRef: React.RefObject<HTMLDivElement | null>;\n fitContent?: boolean | undefined;\n isMaximized?: boolean | undefined;\n bodyClassName?: string | undefined;\n captureDimensions?: { width: number; height: number } | null | undefined;\n children: React.ReactNode;\n}) {\n return (\n <div\n ref={bodyRef}\n className={cn(\n // The structural guard ring is part of the body surface, not window\n // chrome. Painting it with the canonical page background keeps the\n // 2px resize-handle gutter visually continuous with full-bleed bodies\n // such as Chat instead of exposing the card-coloured window shell.\n \"relative z-0 min-h-0 flex-1 overflow-hidden bg-background pointer-events-none\",\n !isMaximized && \"p-0.5\",\n fitContent && \"overflow-visible\",\n captureDimensions && \"matrx-window-body-offscreen\",\n )}\n data-window-panel-body-shell\n style={captureDimensions ?? undefined}\n >\n <div\n className={cn(\n \"h-full min-h-0 overflow-auto pointer-events-auto\",\n !isMaximized && \"matrx-window-body-inner\",\n bodyClassName,\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\n/**\n * Props that don't participate in the close-binding discrimination.\n * Kept as an intersection base so the discriminated union below can layer\n * the close-binding contract on top without losing intellisense on the\n * common props.\n */\nexport interface WindowPanelBaseProps extends UseWindowPanelOptions {\n children: React.ReactNode;\n title?: string | undefined;\n /** Rich title rendered in the header. Falls back to `title` (string) when omitted. */\n titleNode?: React.ReactNode | undefined;\n /** @deprecated Use `actionsLeft` and `actionsRight` instead */\n actions?: React.ReactNode | undefined;\n actionsLeft?: React.ReactNode | undefined;\n actionsRight?: React.ReactNode | undefined;\n bodyClassName?: string | undefined;\n className?: string | undefined;\n /**\n * Rare escape hatch for page-local windows that have no overlay definition\n * but still need an explicit mobile surface. Registered overlays keep their\n * presentation in their definition (`window.mobile`).\n */\n mobilePresentationOverride?: MobilePresentation | undefined;\n /**\n * The surface this window REGISTERS (its own `SurfaceRuntimeProvider`).\n * Marks every root with `data-surface-layer`, so the unregistered-window\n * reader (`features/surfaces/runtime/window-forms.ts`) leaves it alone —\n * one way for an agent to write a field, never two.\n */\n surfaceLayer?: string | undefined;\n /** Phone drawer presentation: size the sheet to the content (max 85dvh). */\n mobileSizeToContent?: boolean | undefined;\n /**\n * Escape closes this window when it is the TOPMOST window and nothing above\n * it (a menu, popover, dialog, the workspace picker) is open to take the\n * key. Opt in for windows whose close is safe (their draft is kept, or\n * there is nothing to lose). Desktop only — a phone sheet has its own.\n */\n closeOnEscape?: boolean | undefined;\n /** Phone drawer presentation: no title-row ✕ (the handle and the window's own Cancel dismiss it). */\n mobileHideClose?: boolean | undefined;\n minWidth?: number | undefined;\n minHeight?: number | undefined;\n urlSyncKey?: string | undefined;\n urlSyncId?: string | undefined;\n urlSyncArgs?: Record<string, string> | undefined;\n /** Content to render in a collapsible left sidebar panel */\n sidebar?: React.ReactNode | undefined;\n /** Default width for the sidebar in pixels (default: 200) */\n sidebarDefaultSize?: number | undefined;\n /** Minimum width in pixels before the sidebar collapses (default: 150) */\n sidebarMinSize?: number | undefined;\n /** Whether the sidebar starts open (default: true) */\n defaultSidebarOpen?: boolean | undefined;\n /** Class name applied to the sidebar panel content wrapper */\n sidebarClassName?: string | undefined;\n /**\n * When true, opening the sidebar grows the window width by sidebarDefaultSize\n * and closing it shrinks it back, keeping the body content width constant.\n */\n sidebarExpandsWindow?: boolean | undefined;\n /**\n * Content for a collapsible RIGHT secondary panel — the canonical home for a\n * history / inspector / details pane that belongs to the window, not the body.\n * Resizable, mirrors the left `sidebar`. Desktop only; handle mobile in the\n * consumer (e.g. a Drawer) — see `features/notes` for the reference pattern.\n */\n secondaryPanel?: React.ReactNode | undefined;\n /** Whether the secondary panel is open (default: true when `secondaryPanel` is provided). */\n secondaryPanelOpen?: boolean | undefined;\n /** Default width for the secondary panel in pixels (default: 360) */\n secondaryPanelDefaultSize?: number | undefined;\n /** Minimum width in pixels for the secondary panel (default: 240) */\n secondaryPanelMinSize?: number | undefined;\n /** Class name applied to the secondary panel content wrapper */\n secondaryPanelClassName?: string | undefined;\n /**\n * When true, hides the header pop-out affordance (icon + green-dropdown entry).\n * Pop-out is shown by default on desktop when the browser supports it.\n */\n hidePopOutButton?: boolean | undefined;\n /** Content rendered in a full-width footer bar below the body. Renders as a single flex row. For zoned layout, use footerLeft/footerCenter/footerRight instead. */\n footer?: React.ReactNode | undefined;\n /** Left-aligned footer content (use instead of `footer` for zoned layout) */\n footerLeft?: React.ReactNode | undefined;\n /** Center-aligned footer content */\n footerCenter?: React.ReactNode | undefined;\n /** Right-aligned footer content */\n footerRight?: React.ReactNode | undefined;\n /**\n * Styling posture for the footer wrapper. Default `\"bar\"` applies the compact\n * metadata-bar chrome (thin chips, `text-xs`, tiny buttons/icons via descendant\n * selectors) tuned for status rows like `NoteMetadataBar`. That chrome CRUSHES\n * rich content — use `\"rich\"` when the footer hosts a composer / input bar /\n * anything with full-size buttons or a multi-row textarea (e.g. `SmartAgentInput`).\n * `\"rich\"` drops the compact descendant selectors and the `bg-muted/40` chrome,\n * leaving just `shrink-0 border-t` so the slot's own content owns its layout.\n */\n footerVariant?: \"bar\" | \"rich\" | undefined;\n /**\n * When true, the windowed panel sizes itself to fit its content rather than\n * using the explicit width/height from Redux. A ResizeObserver syncs the\n * measured dimensions back into Redux so drag/snap operations still work.\n * The panel will still respect minWidth/minHeight constraints.\n */\n fitContent?: boolean | undefined;\n\n /**\n * Called by WindowPanel before a save so the child component can return\n * its current content state for the local refresh-preservation cache.\n * Return value must be a plain object (JSON-serializable).\n */\n onCollectData?: (() => Record<string, unknown>) | undefined;\n /**\n * Optional snapshot capture function for the minimized tray chip.\n * WindowPanel invokes it after minimizing against a briefly retained,\n * offscreen body and stores the resulting Blob in a bounded local cache.\n * Pass this from the window component if it implements custom capture logic.\n */\n captureTraySnapshot?: TraySnapshotCapture | undefined;\n /** Overlay instance used by semantic minimized previews. Defaults to `default`. */\n overlayInstanceId?: string | undefined;\n}\n\n/**\n * The close-binding contract — enforced by the type system.\n *\n * Every WindowPanel declares HOW it closes. Exactly three shapes are valid:\n *\n * 1. Overlay-managed: `overlayId`. Close dispatches `closeOverlay` for that overlay (and the\n * instance this window renders, when it renders inside an SummonHost instance or passes\n * `overlayInstanceId`). The close-lifecycle middleware tombstones preservation, disposes the\n * instance's handles and runs persistence flushers; the host then unmounts the body. `onClose`\n * is an OPTIONAL hook for extra work.\n * 2. Instance-bound: `boundToOverlay` — the window renders inside an SummonHost-rendered overlay\n * and closes through that instance (`useOptionalOverlayInstance().close`). Rendering it outside\n * an overlay reports an error through the error port and the close button closes nothing.\n * 3. Page-local: `onClose`, REQUIRED, because nothing else will close the window.\n *\n * Passing none of them is a compile error: the silent-failure mode where the X rendered as a dead\n * button (matrx-frontend, Notes incident 2026-05-26). Do NOT make these all optional.\n */\nexport type WindowPanelCloseBinding =\n | {\n overlayId: string;\n boundToOverlay?: never | undefined;\n /** Optional extra cleanup hook (cancel uploads, save drafts, etc.). */\n onClose?: (() => void) | undefined;\n }\n | {\n overlayId?: never | undefined;\n /** Close through the enclosing SummonHost instance. */\n boundToOverlay: true;\n onClose?: (() => void) | undefined;\n }\n | {\n overlayId?: never | undefined;\n boundToOverlay?: never | undefined;\n /** Required when the panel is rendered page-locally (no overlay). */\n onClose: () => void;\n };\n\n/** Minimized tiles paint above any open window (managerZIndex counts up from 1000). */\nconst MINIMIZED_TILE_Z_FLOOR = 5000;\n\nexport type WindowPanelProps = WindowPanelBaseProps & WindowPanelCloseBinding;\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\nexport function WindowPanel({\n children,\n title,\n titleNode,\n actions,\n actionsLeft,\n actionsRight,\n onClose,\n bodyClassName,\n className,\n mobilePresentationOverride,\n surfaceLayer,\n mobileSizeToContent,\n closeOnEscape = false,\n mobileHideClose = false,\n minWidth,\n minHeight,\n urlSyncKey,\n urlSyncId,\n urlSyncArgs,\n sidebar,\n sidebarDefaultSize = 200,\n sidebarMinSize = 100,\n defaultSidebarOpen = true,\n sidebarClassName,\n sidebarExpandsWindow = false,\n secondaryPanel,\n secondaryPanelOpen,\n secondaryPanelDefaultSize = 360,\n secondaryPanelMinSize = 240,\n secondaryPanelClassName,\n footer,\n footerLeft,\n footerCenter,\n footerRight,\n footerVariant = \"bar\",\n fitContent = false,\n overlayId: overlayIdProp,\n boundToOverlay,\n onCollectData,\n captureTraySnapshot,\n overlayInstanceId: overlayInstanceIdProp,\n hidePopOutButton = false,\n ...hookOpts\n}: WindowPanelProps) {\n // Inside an SummonHost-rendered overlay the instance supplies identity and close; explicit\n // props win. A page-local window has no instance and closes through `onClose`.\n const instance = useOptionalOverlayInstance();\n const instanceMatches = instance !== null && (boundToOverlay === true || instance.overlayId === overlayIdProp);\n const overlayId: string | undefined = overlayIdProp ?? (boundToOverlay && instance ? instance.overlayId : undefined);\n const overlayInstanceId = overlayInstanceIdProp ?? (instanceMatches ? instance.instanceId : undefined);\n const ports = useSummonPorts();\n const windowConfig = useWindowConfig();\n // ── Pre-compute id and popout capabilities BEFORE useWindowPanel so we\n // can pass `onTriggerPopout` to the drag-detection logic. The id is\n // derived the same way useWindowPanel does internally (`opts.id ?? useId()`).\n const reactId = useId();\n const id = hookOpts.id ?? reactId;\n const trayRegistryKey = overlayId ?? id;\n const isMobile = useIsMobile();\n // `data-surface-layer` (literal: importing window-forms would pull the\n // surface writeback into every window's chunk).\n const surfaceLayerAttrs = surfaceLayer\n ? { \"data-surface-layer\": surfaceLayer }\n : undefined;\n const isMounted = useIsClient();\n const registryMeta = overlayId ? getOverlayMeta(overlayId) : undefined;\n const registryEntry = registryMeta?.window;\n const effectiveInstanceId = overlayInstanceId ?? DEFAULT_INSTANCE_ID;\n // MKT-104: a window the system opened (debug auto-open) docks beside the page, never over it.\n const [autoOpened] = useState(\n () => Boolean(overlayId) && isAutoOpened(overlayId as string, effectiveInstanceId),\n );\n useEffect(() => {\n if (!overlayId) return undefined;\n let timer: number | undefined;\n return () => {\n timer = window.setTimeout(\n () => clearAutoOpened(overlayId, effectiveInstanceId),\n 100,\n );\n void timer;\n };\n }, [overlayId, effectiveInstanceId]);\n const preservationEnabled = Boolean(\n overlayId &&\n registryEntry?.preservation &&\n !registryEntry.ephemeral &&\n (registryMeta?.instance !== \"multi\" || overlayInstanceId),\n );\n const overlayLaunchData = useSummonSelector((state) =>\n overlayId ? selectOverlayData(state, overlayId, effectiveInstanceId) : null,\n );\n const initialPreservationData = registryEntry?.preservation\n ? sanitizeWindowData(overlayLaunchData, registryEntry.preservation.dataKeys)\n : {};\n\n const popoutCapability = isMounted ? detectPopoutCapability() : null;\n\n // popout lifecycle hook — owns the actual browser popout window and its\n // open/close lifecycle. Always called (id is stable) but its `openPopout`\n // is only invoked when the user actually triggers a popout.\n const popout = usePopoutWindow(id);\n\n // Register the live openPopout in the module-level opener map so external\n // callers (`usePopoutControl`) can trigger popout for this window. Cleanup\n // on unmount is handled by the returned unregister function.\n useEffect(() => {\n return registerPopoutOpener(id, popout.openPopout);\n }, [id, popout.openPopout]);\n\n // Drag-out callback fired by useWindowPanel when the user drags this\n // window outside the viewport beyond the dwell threshold. Receives the\n // dragged rect at release time so popout sizing matches user intent.\n // The popout opener internally enforces single-PiP slot and surfaces\n // toasts on failure, so we don't double-check here.\n const handleDragOutPopout = useCallback(\n (draggedRect: WindowRect) => {\n void popout.openPopout({\n width: draggedRect.width,\n height: draggedRect.height,\n title: typeof title === \"string\" ? title : \"Window\",\n });\n },\n [popout, title],\n );\n\n // Hand drag-out detection a callback ONLY when popout is meaningful here:\n // - desktop only (mobile path is fully separate)\n // - browser must support some form of popout\n const onTriggerPopout =\n !isMobile && popoutCapability !== \"none\" ? handleDragOutPopout : undefined;\n\n const autoDispatch = useSummonDispatch();\n // Pass title and our pre-computed id+trigger into the hook\n const {\n windowState,\n rect,\n zIndex: managerZIndex,\n onDragStart,\n onResizeStart,\n onFocus,\n onRestore,\n onMaximize,\n onMinimize,\n onToggleMaximize,\n isInteracting,\n } = useWindowPanel({\n ...hookOpts,\n id,\n title,\n autoOpened,\n onAutoNoRoom: autoOpened\n ? () => {\n window.dispatchEvent(\n new CustomEvent(AUTO_OPEN_NO_ROOM_EVENT, { detail: { overlayId, instanceId: effectiveInstanceId } }),\n );\n if (overlayId) autoDispatch(overlaysRawActions.closeOverlay({ overlayId, instanceId: effectiveInstanceId }));\n }\n : undefined,\n minWidth,\n minHeight,\n onTriggerPopout,\n ...(preservationEnabled && overlayId\n ? {\n persistence: {\n overlayId,\n instanceId: effectiveInstanceId,\n data: initialPreservationData,\n sidebarOpen: defaultSidebarOpen,\n sidebarSize: sidebarDefaultSize,\n },\n }\n : {}),\n });\n\n // A window opened from inside a blocking Dialog/Sheet/Drawer is lifted to\n // the modal tier so it paints above that surface's scrim — otherwise the\n // click that picks an option lands on the scrim and closes the modal\n // (design-system floating-layer; the Source screen's association picker).\n const liftedZIndex = useFloatingLayerZIndex(managerZIndex);\n // A minimized tile is dock chrome: it rides above every open window, so a focused window can\n // never bury it (MKT-077 — the tile sat 2 below the front window and only a strip showed).\n // Stays below the tray (9999) and the modal tier.\n const zIndex = windowState === \"minimized\" ? Math.max(liftedZIndex, MINIMIZED_TILE_Z_FLOOR + managerZIndex) : liftedZIndex;\n\n const dispatch = useSummonDispatch();\n const windowsHidden = useSummonSelector(selectWindowsHidden);\n const isDebugMode = useDebugFlag(ports.debug);\n\n // THE FRONT-MOST LAYER (design-system `announceLayerFront`): a window that\n // opens or comes to the front tells every windowed Dialog, which steps\n // behind it — so an agent window opened from the Agents menu over Table\n // settings is usable (register ai-reachable-everywhere, ARE-010). The\n // manager raises `zIndex` exactly when this window becomes the top one.\n // Keyed on the MANAGER's z, never the lifted one: a modal opening or\n // closing lifts every window, and must not make each of them announce\n // itself front-most (which would bury every windowed Dialog behind them).\n useEffect(() => {\n announceLayerFront(\n document.querySelector(`[data-window-id=\"${CSS.escape(id)}\"]`),\n );\n }, [id, managerZIndex]);\n\n // A PRESS OR FOCUS IN THIS WINDOW CLAIMS THE FRONT AGAIN. The mount-time\n // announce above is not enough when the window is RENDERED from inside a\n // windowed Dialog's React tree (the reference picker's \"Browse files\" opens\n // the file picker window that way): React bubbles a portaled child's\n // synthetic focus / pointer events to its React ancestors, so the window's\n // own autofocus reached the Dialog's `onFocusCapture`, which brought the\n // Dialog back to z 10000 OVER the window it had just stepped behind (live\n // 2026-10-02: window 1000, Dialog 10000 — \"nothing happens\"). Capture\n // handlers run ancestors first, so this one fires AFTER the Dialog's and has\n // the last word. Guard: __tests__/aWindowOpenedFromADialogStaysInFront.test.tsx\n // The body renders through its own portal (stable identity across pop-out), so its wrapper\n // claims too; it announces the window shell it is attached to.\n const claimFront = (event: React.SyntheticEvent<HTMLElement>) => {\n announceLayerFront(event.currentTarget.closest(\"[data-window-id]\") ?? event.currentTarget);\n };\n\n // On mobile, only the topmost non-minimized window is rendered visible.\n const allWindows = useSummonSelector(selectAllWindows);\n const isTopWindow = !isMobile\n ? true\n : allWindows.find((w) => w.state !== \"minimized\")?.id === id;\n\n // Mobile sidebar/content toggle (not stored in Redux — purely a view concern)\n const [activePaneMobile, setActivePaneMobile] = useState<\"main\" | \"sidebar\">(\n \"main\",\n );\n\n // Address-bar link: the definition's `link.key` is canonical for overlay-managed windows;\n // page-local windows without a definition may pass explicit props. This keeps a stale caller\n // prop from publishing a token the link hydrator cannot reopen.\n const effectiveUrlSyncKey = resolveWindowUrlSyncKey(registryMeta?.link?.key, urlSyncKey);\n const effectiveUrlSyncId = urlSyncId ?? (effectiveUrlSyncKey ? overlayId : undefined);\n useOverlayLink(effectiveUrlSyncKey, effectiveUrlSyncId, urlSyncArgs);\n\n // Deprecation marker — when set on the registry entry, the shell renders a\n // red ring + dismissible banner so users can see at a glance that this\n // window is on its way out. Used during consolidation while the old window\n // is kept around for side-by-side parity verification with its replacement.\n const deprecation = registryEntry?.deprecated;\n const isDeprecated = !!deprecation;\n const deprecatedRingClass = isDeprecated\n ? \"ring-2 ring-destructive ring-offset-2 ring-offset-background\"\n : \"\";\n\n // ── Sidebar state ─────────────────────────────────────────────────────────\n const hasSidebar = !!sidebar;\n const [sidebarOpen, setSidebarOpen] = useState(defaultSidebarOpen);\n const [sidebarSize, setSidebarSize] = useState<number | null>(\n sidebarDefaultSize,\n );\n const restoredPersistence = useSummonSelector(selectWindowPersistence(id));\n const sidebarPanelRef = useRef<SidebarPanelHandle>(null);\n const restoredChromeAppliedRef = useRef(false);\n\n // ── Persistence ───────────────────────────────────────────────────────────\n /**\n * Stage the window's chrome + allowlisted semantic data (open data merged with what\n * `onCollectData()` returns) in its window-manager entry. The persistence section (when on)\n * writes the workspace from the store; this never touches storage itself.\n */\n const handleSaveWindowState = useCallback(() => {\n if (!overlayId || !preservationEnabled || !registryEntry?.preservation) {\n return;\n }\n let collected: Record<string, unknown> = {};\n try {\n collected = onCollectData?.() ?? {};\n } catch (error) {\n ports.errors.capture(error, { where: \"window-preservation collector\", overlayId, instanceId: effectiveInstanceId });\n }\n const base = sanitizeWindowData({ ...initialPreservationData, ...collected }, registryEntry.preservation.dataKeys);\n dispatch(\n updateWindowPersistence({\n id,\n data: base,\n sidebarOpen,\n ...(sidebarSize === null ? {} : { sidebarSize }),\n }),\n );\n }, [\n overlayId,\n preservationEnabled,\n registryEntry,\n effectiveInstanceId,\n initialPreservationData,\n id,\n sidebarOpen,\n sidebarSize,\n onCollectData,\n ports,\n dispatch,\n ]);\n\n /**\n * Keep semantic data current while the child changes. This never writes to\n * storage directly and deliberately has no unmount flush; explicit close\n * tombstones must always win over late cleanup.\n */\n const saveRef = useRef(handleSaveWindowState);\n useEffect(() => {\n saveRef.current = handleSaveWindowState;\n }, [handleSaveWindowState]);\n\n useEffect(() => {\n if (!preservationEnabled) return;\n saveRef.current();\n }, [preservationEnabled, overlayLaunchData, onCollectData]);\n\n /**\n * Route every close through the overlay slice: the close-lifecycle middleware tombstones the\n * window's preservation identity before the host unmounts it. Inside an SummonHost instance of\n * this overlay, close goes through the instance (exact instance id).\n */\n const handleClose = useCallback(() => {\n if (instanceMatches && instance && instance.overlayId === overlayId) {\n instance.close();\n } else if (boundToOverlay) {\n ports.errors.capture(new Error(\"[summon] WindowPanel boundToOverlay rendered outside an overlay instance\"), { windowId: id });\n } else if (overlayId) {\n const hasExactOverlayIdentity = registryMeta?.instance !== \"multi\" || Boolean(overlayInstanceId);\n if (hasExactOverlayIdentity) {\n // Erased-id action: a package-internal id is a plain string (the host owns OverlayId).\n dispatch(overlaysRawActions.closeOverlay({ overlayId, instanceId: effectiveInstanceId }));\n } else if (!onClose) {\n ports.errors.capture(new Error(`[summon] Cannot close multi-instance ${overlayId} without overlayInstanceId or onClose.`), { overlayId });\n }\n }\n onClose?.();\n }, [boundToOverlay, dispatch, effectiveInstanceId, id, instance, instanceMatches, onClose, overlayId, overlayInstanceId, ports, registryMeta?.instance]);\n\n // Escape → close, only for the topmost window with nothing layered above.\n useEffect(() => {\n if (!closeOnEscape || isMobile) return undefined;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented) return;\n // A menu, popover, select, dialog or the workspace picker owns Escape.\n // Only a VISIBLE one: the header keeps a hidden \"Organizations\" listbox\n // mounted, which swallowed every Escape (found live, 2026-09-27).\n const layered = Array.from(\n document.querySelectorAll<HTMLElement>(\n `[data-radix-popper-content-wrapper], [role=\"menu\"], [role=\"listbox\"], [role=\"dialog\"][data-state=\"open\"], [role=\"alertdialog\"], ${windowConfig.escapeYieldSelector}`,\n ),\n ).some(\n (el) =>\n el.getClientRects().length > 0 &&\n getComputedStyle(el).visibility !== \"hidden\" &&\n !el.closest(`[data-window-id=\"${CSS.escape(id)}\"]`),\n );\n if (layered) return;\n const mine = document.querySelector<HTMLElement>(\n `[data-window-panel][data-window-id=\"${CSS.escape(id)}\"]`,\n );\n if (!mine) return;\n const z = (el: Element) => Number(getComputedStyle(el).zIndex) || 0;\n const top = Array.from(\n document.querySelectorAll(\"[data-window-panel][data-window-id]\"),\n ).reduce<Element | null>((best, el) => (!best || z(el) > z(best) ? el : best), null);\n if (top !== mine) return;\n e.preventDefault();\n handleClose();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [closeOnEscape, isMobile, id, handleClose, windowConfig.escapeYieldSelector]);\n\n useEffect(() => {\n if (!restoredPersistence || restoredChromeAppliedRef.current) return;\n restoredChromeAppliedRef.current = true;\n setSidebarOpen(restoredPersistence.sidebarOpen);\n setSidebarSize(restoredPersistence.sidebarSize);\n if (!restoredPersistence.sidebarOpen) {\n sidebarPanelRef.current?.collapse();\n } else if (restoredPersistence.sidebarSize) {\n sidebarPanelRef.current?.resize(restoredPersistence.sidebarSize);\n }\n }, [restoredPersistence]);\n\n // ── fitContent: sync measured shell size back into Redux ─────────────────\n // A STATE-backed ref, not useRef: the shell renders through a portal that\n // exists only after mount, so on the first effect a plain ref was still null\n // and the measurer never attached — no fitContent window ever synced its\n // measured size (or its preset position). The effect re-runs when the\n // element actually appears.\n const [fitContentEl, fitContentRef] = useState<HTMLDivElement | null>(null);\n const fitContentStore = useSummonStore();\n // A preset position (\"center\", a corner) was resolved from the DEFAULT size\n // before anything was measured, so a window that fits its content grew away\n // from where it was placed — a centered 694px picker opened with its left\n // edge at the viewport's middle and its right side off-screen. So the preset\n // FOLLOWS the measured size — a lazy body measures small first, then its\n // real size — until the person first drags or resizes the window; from then\n // on it stays where they put it. Same choice `useWindowPanel` made at\n // registration: only when the window was NOT opened at a saved\n // `initialRect` place, and only for an explicit preset (the cascade default\n // is never re-run; it advances a shared counter).\n const fitPlacedRef = useRef(false);\n // NO GLIDE WHILE THE WINDOW IS STILL BEING PLACED (2026-10-08, owner: windows \"appear, then\n // slide into place\"). Opening a window measures its content and re-places it in the frames\n // after the first paint; with `glide` on, each correction animated across the screen. Glide\n // only programmatic moves made after the opening settles (snap, arrange, tray, restore).\n const [glideReady, setGlideReady] = useState(false);\n useEffect(() => {\n const timer = window.setTimeout(() => setGlideReady(true), GLIDE_SETTLE_MS);\n return () => window.clearTimeout(timer);\n }, []);\n useEffect(() => {\n if (isInteracting) fitPlacedRef.current = true;\n }, [isInteracting]);\n const fitPresetPosition = hookOpts.position;\n const fitMayReplace =\n hookOpts.initialRect?.x === undefined &&\n hookOpts.initialRect?.y === undefined;\n\n useEffect(() => {\n if (!fitContent || isMobile || windowState !== \"windowed\") return undefined;\n const el = fitContentEl;\n if (!el) return undefined;\n let active = true;\n const ro = new ResizeObserver((entries) => {\n // Disconnect does not cancel a callback already queued by the browser.\n // Read the current store state as well as the effect lifetime so a\n // maximize dispatched before React cleans up cannot save fullscreen size.\n if (!active || fitContentStore.getState().windowManager.windows[id]?.state !== \"windowed\") return;\n const entry = entries[0];\n if (!entry) return;\n const { width, height } = entry.contentRect;\n // Include border (2px each side) to match the element's full box size\n const borderH = el.offsetHeight - el.clientHeight;\n const borderW = el.offsetWidth - el.clientWidth;\n const fitWidth = Math.ceil(width + borderW);\n const fitHeight = Math.ceil(height + borderH);\n const placeNow =\n !fitPlacedRef.current &&\n fitMayReplace &&\n fitPresetPosition !== undefined;\n dispatch(\n updateWindowRect({\n id,\n rect: {\n width: fitWidth,\n height: fitHeight,\n ...(placeNow\n ? resolvePosition(fitPresetPosition, fitWidth, fitHeight)\n : {}),\n },\n }),\n );\n });\n ro.observe(el);\n return () => {\n active = false;\n ro.disconnect();\n };\n }, [fitContent, fitContentEl, isMobile, windowState, id, dispatch, fitContentStore, fitPresetPosition, fitMayReplace]);\n\n const toggleSidebar = useCallback(() => {\n const panel = sidebarPanelRef.current;\n if (!panel) return;\n if (sidebarOpen) {\n if (sidebarExpandsWindow) {\n dispatch(\n updateWindowRect({\n id,\n rect: { width: rect.width - sidebarDefaultSize },\n }),\n );\n requestAnimationFrame(() => panel.collapse());\n } else {\n panel.collapse();\n }\n } else {\n if (sidebarExpandsWindow) {\n dispatch(\n updateWindowRect({\n id,\n rect: { width: rect.width + sidebarDefaultSize },\n }),\n );\n requestAnimationFrame(() => panel.resize(sidebarDefaultSize));\n } else {\n panel.resize(sidebarDefaultSize);\n }\n }\n }, [\n sidebarOpen,\n sidebarDefaultSize,\n sidebarExpandsWindow,\n dispatch,\n id,\n rect.width,\n ]);\n\n const handleSidebarResize = useCallback(\n (panelSize: { asPercentage: number; inPixels: number }) => {\n setSidebarOpen(panelSize.asPercentage > 0);\n if (panelSize.inPixels > 0) setSidebarSize(panelSize.inPixels);\n if (preservationEnabled) {\n dispatch(\n updateWindowPersistence({\n id,\n sidebarOpen: panelSize.asPercentage > 0,\n sidebarSize:\n panelSize.inPixels > 0 ? panelSize.inPixels : sidebarSize,\n }),\n );\n }\n },\n [dispatch, id, preservationEnabled, sidebarSize],\n );\n\n // ── Portal target (client-only) ──────────────────────────────────────────\n const portalTarget = isMounted ? document.body : null;\n // The one container the body always renders into (see \"Body identity\" below).\n const [bodyHost] = useState<HTMLDivElement | null>(() => {\n if (typeof document === \"undefined\") return null;\n const host = document.createElement(\"div\");\n host.className = \"matrx-window-body-host\";\n host.setAttribute(\"data-window-body-host\", \"\");\n return host;\n });\n\n // ── Render acknowledgement ────────────────────────────────────────────────\n // Tell the render watchdog which window-manager id actually rendered this\n // overlay, so it can verify the panel became visible (and never false-flag a\n // window whose `id` differs from its registry slug). See overlayRenderWatchdog.\n useEffect(() => {\n if (!overlayId) return undefined;\n ackOverlayRender(overlayId, id);\n return () => clearOverlayRender(overlayId, id);\n }, [overlayId, id]);\n\n // Backward compat: legacy `actions` maps to actionsRight\n const resolvedActionsRight = actionsRight ?? actions ?? null;\n\n // ── Snap helpers (Move & Resize menu) ───────────────────────────────────\n const snapLeft = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n updateWindowRect({\n id,\n rect: { x: 0, y: 0, width: Math.round(vw / 2), height: vh },\n }),\n );\n }, [dispatch, id]);\n\n const snapRight = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n const half = Math.round(vw / 2);\n dispatch(\n updateWindowRect({\n id,\n rect: { x: half, y: 0, width: vw - half, height: vh },\n }),\n );\n }, [dispatch, id]);\n\n const snapTop = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n updateWindowRect({\n id,\n rect: { x: 0, y: 0, width: vw, height: Math.round(vh / 2) },\n }),\n );\n }, [dispatch, id]);\n\n const snapBottom = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n const half = Math.round(vh / 2);\n dispatch(\n updateWindowRect({\n id,\n rect: { x: 0, y: half, width: vw, height: vh - half },\n }),\n );\n }, [dispatch, id]);\n\n const snapCentre = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n const w = Math.min(rect.width, vw);\n const h = Math.min(rect.height, vh);\n dispatch(\n updateWindowRect({\n id,\n rect: {\n x: Math.round((vw - w) / 2),\n y: Math.round((vh - h) / 2),\n width: w,\n height: h,\n },\n }),\n );\n }, [dispatch, id, rect.width, rect.height]);\n\n const arrangeAll = useCallback(\n (layout: GlobalLayoutType) => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n arrangeActiveWindows({\n layout,\n viewportWidth: vw,\n viewportHeight: vh,\n }),\n );\n },\n [dispatch],\n );\n\n // ── Pop-out menu-click wiring ─────────────────────────────────────────────\n // (popout, popoutCapability, isMobile already set up at top of component)\n const popoutMode = useSummonSelector(selectPopoutMode(id));\n // The body's popout context: this window's own popped-out document when it is out, else\n // whatever surrounds the window (a window rendered inside another popout keeps that one).\n const outerPopout = usePopout();\n const outerPortalContainer = usePortalContainer();\n const popoutWin = usePopoutWindowRef(id);\n const ownPopout = popoutMode !== null && popoutWin !== null;\n const bodyPopoutValue = React.useMemo<PopoutContextValue>(\n () =>\n ownPopout && popoutWin\n ? { popoutDocument: popoutWin.document, popoutWindow: popoutWin, popoutContainer: popoutWin.document.body, mode: popoutMode }\n : outerPopout,\n [ownPopout, popoutWin, popoutMode, outerPopout],\n );\n const bodyPortalContainer = ownPopout && popoutWin ? popoutWin.document.body : outerPortalContainer;\n const popoutCandidateId = useSummonSelector(selectPopoutCandidateId);\n\n // Menu affordance is shown only when:\n // - desktop (mobile path is fully separate)\n // - browser supports popout (DPiP or window.open)\n // - the window isn't minimized (popout from the tray is awkward UX)\n // - the window isn't already popped out\n //\n // The menu is NEVER disabled on PiP-slot-taken grounds: the popout hook\n // transparently falls back to `window.open()` for second+ popouts so the\n // user gets a working window without us blocking the action.\n const canShowPopOut =\n !hidePopOutButton &&\n !isMobile &&\n popoutCapability !== \"none\" &&\n windowState !== \"minimized\" &&\n popoutMode === null;\n\n // Menu-click handler — uses the live windowed rect (different from the\n // drag-out path which gets the rect from the gesture).\n const handlePopOut = useCallback(() => {\n void popout.openPopout({\n width: rect.width,\n height: rect.height,\n title: typeof title === \"string\" ? title : \"Window\",\n });\n }, [popout, rect.width, rect.height, title]);\n\n const handleDockBack = useCallback(() => {\n dispatch(dockWindow(buildDockWindowPayload(id)));\n }, [dispatch, id]);\n\n // ── Minimized thumbnail lifecycle ───────────────────────────────────────\n // Minimize dispatches immediately. The body ALWAYS stays mounted, offscreen, while minimized\n // (C38 R3: minimize keeps the component alive); one low-resolution local capture is taken for\n // the tile. No network, persistent storage, polling, or full-size image is involved.\n const bodyRef = useRef<HTMLDivElement | null>(null);\n const retainedBodyDimensionsRef = useRef<{\n width: number;\n height: number;\n } | null>(null);\n const captureGenerationRef = useRef(0);\n // Capture precedence: explicit prop → registered capture → the default capture for any window\n // WITHOUT a registered preview component. A window with a preview component skips capture\n // entirely — its preview is cheaper and higher-fidelity than a screenshot.\n const trayPreviewEntry = getTrayPreviewEntry(trayRegistryKey);\n const effectiveTrayCapture =\n captureTraySnapshot ??\n trayPreviewEntry.captureTraySnapshot ??\n (trayPreviewEntry.Preview ? undefined : defaultTraySnapshotCapture);\n const [pendingTrayCapture, setPendingTrayCapture] = useState<{\n capture: TraySnapshotCapture;\n width: number;\n height: number;\n generation: number;\n } | null>(null);\n const [trayPreviewData, setTrayPreviewData] = useState<\n Record<string, unknown> | undefined\n >(undefined);\n\n const handleMinimize = useCallback(() => {\n let collected: Record<string, unknown> | undefined;\n try {\n collected = onCollectData?.();\n } catch (error) {\n ports.errors.capture(error, { where: \"window preview collector\", windowId: trayRegistryKey });\n }\n if (collected && typeof collected === \"object\") {\n setTrayPreviewData(collected);\n }\n if (preservationEnabled) saveRef.current();\n const bodyEl = bodyRef.current;\n const generation = ++captureGenerationRef.current;\n if (bodyEl) {\n const bounds = bodyEl.getBoundingClientRect();\n retainedBodyDimensionsRef.current = {\n width: Math.max(1, Math.round(bounds.width)),\n height: Math.max(1, Math.round(bounds.height)),\n };\n }\n if (effectiveTrayCapture && bodyEl) {\n const bounds = bodyEl.getBoundingClientRect();\n setPendingTrayCapture({\n capture: effectiveTrayCapture,\n width: Math.max(1, Math.round(bounds.width)),\n height: Math.max(1, Math.round(bounds.height)),\n generation,\n });\n } else {\n setPendingTrayCapture(null);\n }\n onMinimize();\n }, [\n effectiveTrayCapture,\n onCollectData,\n onMinimize,\n ports,\n preservationEnabled,\n trayRegistryKey,\n ]);\n\n useEffect(() => {\n if (windowState !== \"minimized\" || !pendingTrayCapture) return undefined;\n const bodyEl = bodyRef.current;\n if (!bodyEl) {\n setPendingTrayCapture(null);\n return undefined;\n }\n\n let cancelled = false;\n const { capture, generation } = pendingTrayCapture;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<null>((resolve) => {\n timeoutId = setTimeout(() => resolve(null), 800);\n });\n void Promise.race([capture(bodyEl), timeout])\n .then((blob) => {\n if (blob && !cancelled && captureGenerationRef.current === generation) {\n setTraySnapshot(id, blob);\n }\n })\n .catch((err: unknown) => {\n if (!cancelled) ports.errors.capture(err, { where: \"captureTraySnapshot\", windowId: id });\n })\n .finally(() => {\n if (timeoutId) clearTimeout(timeoutId);\n if (!cancelled && captureGenerationRef.current === generation) {\n setPendingTrayCapture((current) =>\n current?.generation === generation ? null : current,\n );\n }\n });\n\n return () => {\n cancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n };\n }, [id, pendingTrayCapture, ports, windowState]);\n\n const handleRestoreClearingSnapshot = useCallback(() => {\n captureGenerationRef.current += 1;\n setPendingTrayCapture(null);\n clearTraySnapshot(id);\n onRestore();\n }, [id, onRestore]);\n\n // Clear any lingering snapshot on unmount.\n useEffect(() => {\n return () => {\n captureGenerationRef.current += 1;\n clearTraySnapshot(id);\n };\n }, [id]);\n\n // External exits (reveal, maximize, pop-out) do not pass through the\n // click-to-restore handler. Invalidate their pending capture and local image\n // too, so every way out of minimized state has the same cleanup contract.\n const previousTrayStateRef = useRef(windowState);\n useEffect(() => {\n const wasMinimized = previousTrayStateRef.current === \"minimized\";\n previousTrayStateRef.current = windowState;\n if (!wasMinimized || windowState === \"minimized\") return;\n\n const invalidGeneration = ++captureGenerationRef.current;\n clearTraySnapshot(id);\n queueMicrotask(() => {\n setPendingTrayCapture((current) =>\n current && current.generation < invalidGeneration ? null : current,\n );\n });\n }, [id, windowState]);\n\n // ── Off-screen rescue ────────────────────────────────────────────────────\n // If the windowed rect is fully out of reach (drag-released outside the\n // viewport without popout firing, restored from a stale preMinimizedRect,\n // or docked back from a popped-out state where the docked rect was\n // off-screen), nudge it back into a position where the user can grab it.\n // Runs whenever the window transitions INTO `windowed` from min/max/popout.\n const prevStateRef = useRef<typeof windowState>(windowState);\n const prevPopoutModeRef = useRef<typeof popoutMode>(popoutMode);\n useEffect(() => {\n const wasNonWindowed =\n prevStateRef.current !== \"windowed\" || prevPopoutModeRef.current !== null;\n const isNowWindowed = windowState === \"windowed\" && popoutMode === null;\n prevStateRef.current = windowState;\n prevPopoutModeRef.current = popoutMode;\n if (wasNonWindowed && isNowWindowed) {\n // Never rescue against an invented viewport: on a hidden tab or a\n // display:none ancestor the measurement is 0×0, and clamping to the\n // 1280×800 fallback would rewrite the user's real geometry from a\n // number no screen ever had. Skip — the next real measurement clamps.\n const { vw, vh, degenerate } = safeViewportDims();\n if (degenerate) return;\n dispatch(clampWindowRect({ id, viewportWidth: vw, viewportHeight: vh }));\n }\n }, [dispatch, id, windowState, popoutMode]);\n\n const isMinimized = windowState === \"minimized\";\n const isMaximized = windowState === \"maximized\";\n const isPopoutCandidate = popoutCandidateId === id;\n\n useEffect(() => {\n if (!isMobile || !isMinimized) return;\n let cancelled = false;\n queueMicrotask(() => {\n if (!cancelled) handleRestoreClearingSnapshot();\n });\n return () => {\n cancelled = true;\n };\n }, [handleRestoreClearingSnapshot, isMinimized, isMobile]);\n const minimizedTitle =\n title?.trim() ||\n getOverlayMeta(trayRegistryKey)?.label ||\n \"Window\";\n\n // ── Header (shared across all states) ───────────────────────────────────\n const header = (\n <WindowHeader\n title={titleNode ?? title}\n minimizedTitle={minimizedTitle}\n actionsLeft={actionsLeft}\n actionsRight={resolvedActionsRight}\n onDragStart={onDragStart}\n onMinimize={handleMinimize}\n onToggleMaximize={onToggleMaximize}\n onClose={handleClose}\n onRestore={handleRestoreClearingSnapshot}\n isMaximized={isMaximized}\n isMinimized={isMinimized}\n snapLeft={snapLeft}\n snapRight={snapRight}\n snapTop={snapTop}\n snapBottom={snapBottom}\n snapCentre={snapCentre}\n arrangeAll={arrangeAll}\n hasSidebar={hasSidebar}\n sidebarOpen={sidebarOpen}\n onToggleSidebar={toggleSidebar}\n onSaveWindowState={overlayId ? handleSaveWindowState : undefined}\n onPopOut={canShowPopOut ? handlePopOut : undefined}\n />\n );\n\n // ────────────────────────────────────────────────────────────────────────\n // Desktop body shared by windowed, maximized, and minimized states.\n // ────────────────────────────────────────────────────────────────────────\n // A secondary (right) panel is shown when content is provided and it's open.\n // Stable `id` props (sidebar/body/secondary) keep panel identity so toggling\n // the secondary panel doesn't tear down the body (and the live editor inside).\n const hasSecondaryPanel =\n secondaryPanel != null && (secondaryPanelOpen ?? true);\n\n const innerBody =\n hasSidebar || hasSecondaryPanel ? (\n <ResizablePanelGroup orientation=\"horizontal\" className=\"h-full min-h-0\">\n {hasSidebar && (\n <>\n <ResizablePanel\n id=\"sidebar\"\n panelRef={sidebarPanelRef}\n defaultSize={sidebarOpen ? sidebarDefaultSize : 0}\n minSize={sidebarMinSize}\n collapsible\n collapsedSize={0}\n groupResizeBehavior=\"preserve-pixel-size\"\n onResize={handleSidebarResize}\n style={{ overflow: \"hidden\" }}\n >\n <div\n className={cn(\n \"h-full flex flex-col min-h-0 overflow-y-auto scrollbar-thin\",\n sidebarClassName,\n )}\n >\n {sidebar}\n </div>\n </ResizablePanel>\n {/* A collapsed sidebar is 0px wide, so its handle would draw a\n stray line down the window's left edge. Keep it in the panel\n group (the library measures it) but make it invisible. */}\n <ResizableHandle\n className={\n sidebarOpen ? undefined : \"w-0 opacity-0 pointer-events-none\"\n }\n />\n </>\n )}\n <ResizablePanel id=\"body\" minSize={200} className=\"min-h-0\">\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n {children}\n </div>\n </ResizablePanel>\n {hasSecondaryPanel && (\n <>\n <ResizableHandle />\n <ResizablePanel\n id=\"secondary\"\n defaultSize={secondaryPanelDefaultSize}\n minSize={secondaryPanelMinSize}\n groupResizeBehavior=\"preserve-pixel-size\"\n style={{ overflow: \"hidden\" }}\n >\n <div\n className={cn(\n \"h-full flex flex-col min-h-0\",\n secondaryPanelClassName,\n )}\n >\n {secondaryPanel}\n </div>\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n ) : (\n children\n );\n\n // Every desktop body path (windowed, maximized, popped out, with a sidebar) is\n // one selection surface: the ONE selection toolbar and the menu work in every window.\n const bodyContent = (\n <WindowSelectionSurface>\n {isDeprecated ? (\n <div className=\"h-full flex flex-col min-h-0\">\n <DeprecationBanner\n replacedBy={deprecation?.replacement}\n note={deprecation?.reason}\n />\n <div className=\"flex-1 min-h-0\">{innerBody}</div>\n </div>\n ) : (\n innerBody\n )}\n </WindowSelectionSurface>\n );\n\n const hasZonedFooter = footerLeft || footerCenter || footerRight;\n const hasFooter = footer || hasZonedFooter;\n\n // Zoned trio — reused by both variants. In \"bar\" the wrapper is itself a flex\n // row so the trio drops in as direct children; in \"rich\" the wrapper is a\n // plain block, so the trio gets its own flex row to keep the left/center/right\n // layout (rich is normally used with a single `footer` node, though).\n const zonedFooter = (\n <>\n <div className=\"flex items-center gap-1 shrink-0\">{footerLeft}</div>\n <div className=\"flex-1 flex items-center justify-center gap-1\">\n {footerCenter}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">{footerRight}</div>\n </>\n );\n\n const footerBar = hasFooter ? (\n <div\n className={cn(\n // Always: detach from scroll + separate from the body with a top border.\n \"shrink-0 border-t border-border/50\",\n WINDOW_CHROME_INTERACTIVE,\n footerVariant === \"bar\" &&\n // Compact metadata-bar chrome — thin chips, tiny buttons/icons. Crushes\n // rich content; consumers with a composer/input bar pass footerVariant=\"rich\".\n \"flex items-center gap-1 px-2 py-1 rounded-b-xl bg-muted/40 select-none text-xs [&_svg]:h-3 [&_svg]:w-3 [&_button]:h-5 [&_button]:text-xs\",\n )}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {footer ??\n (footerVariant === \"bar\" ? (\n zonedFooter\n ) : (\n <div className=\"flex items-center gap-1\">{zonedFooter}</div>\n ))}\n </div>\n ) : null;\n\n // ────────────────────────────────────────────────────────────────────────\n // MOBILE — presentation comes from the definition (`window.mobile`):\n // \"drawer\" → bottom-sheet (vaul) with optional nested sidebar drawer\n // \"card\" → small z-stacked floating card (utility windows)\n // \"hidden\" → do not mount on mobile at all\n // \"fullscreen\" → one window at a time, fullscreen takeover (default)\n // ────────────────────────────────────────────────────────────────────────\n // ── Body identity ──────────────────────────────────────────────────────────\n // The body renders through ONE portal into ONE detached container, at a fixed position in this\n // component's output; each presentation only attaches that container (BodyMount). Maximize,\n // minimize, pop-out and dock therefore never remount the body. Proven by\n // __tests__/popoutBodyIdentity.test.tsx (it failed with a remount before this).\n const bodyPortal =\n isMounted && bodyHost && !isMobile\n ? createPortal(\n <PopoutContext.Provider value={bodyPopoutValue}>\n <PortalContainerProvider container={bodyPortalContainer}>\n {/* React bubbles synthetic events along the React tree, so the body (no longer a\n React child of the shell) carries the shell's focus / front-claim handlers. */}\n <div className=\"contents\" onPointerDown={onFocus} onPointerDownCapture={claimFront} onFocusCapture={claimFront}>\n {bodyContent}\n </div>\n </PortalContainerProvider>\n </PopoutContext.Provider>,\n bodyHost,\n )\n : null;\n\n if (isMobile) {\n const mobilePresentation: MobilePresentation =\n mobilePresentationOverride ?? registryEntry?.mobile ?? \"fullscreen\";\n const mobileSidebarAs = registryEntry?.mobileSidebarAs ?? \"drawer\";\n\n if (mobilePresentation === \"hidden\") {\n if (process.env.NODE_ENV !== \"production\" && overlayId) {\n console.warn(\n `[WindowPanel] overlay \"${overlayId}\" has window.mobile: \"hidden\" but was opened on a phone. Give its definition another presentation or gate opening.`,\n );\n }\n return null;\n }\n\n if (mobilePresentation === \"drawer\") {\n return (\n <MobileDrawerSurface\n isOpen={true}\n title={titleNode ?? title}\n onClose={handleClose}\n sidebar={sidebar}\n sidebarAs={mobileSidebarAs}\n footer={footerBar}\n actionsLeft={actionsLeft}\n actionsRight={resolvedActionsRight}\n bodyClassName={bodyClassName}\n surfaceLayer={surfaceLayer}\n sizeToContent={mobileSizeToContent}\n hideClose={mobileHideClose}\n >\n <WindowSelectionSurface>{children}</WindowSelectionSurface>\n </MobileDrawerSurface>\n );\n }\n\n if (mobilePresentation === \"card\") {\n return (\n <MobileCardSurface\n isOpen={true}\n title={titleNode ?? title}\n onClose={handleClose}\n footer={footerBar}\n actionsRight={resolvedActionsRight}\n bodyClassName={bodyClassName}\n surfaceLayer={surfaceLayer}\n >\n <WindowSelectionSurface>{children}</WindowSelectionSurface>\n </MobileCardSurface>\n );\n }\n\n // mobilePresentation === \"fullscreen\" — legacy behavior (default).\n const mobileBody =\n hasSidebar && activePaneMobile === \"sidebar\" ? (\n <div className={cn(\"h-full overflow-y-auto\", sidebarClassName)}>\n {sidebar}\n </div>\n ) : (\n children\n );\n\n const mobileEl = (\n <div\n {...surfaceLayerAttrs}\n className={cn(\n \"fixed inset-0 flex flex-col\",\n \"bg-card/98 backdrop-blur-md\",\n \"overflow-hidden\",\n deprecatedRingClass,\n className,\n )}\n style={{\n top: windowConfig.mobileTopOffset,\n zIndex,\n display: isTopWindow && !isMinimized ? undefined : \"none\",\n visibility: windowsHidden ? \"hidden\" : undefined,\n }}\n onPointerDown={onFocus}\n onPointerDownCapture={claimFront}\n onFocusCapture={claimFront}\n >\n <MobileWindowHeader\n title={titleNode ?? title}\n actionsRight={resolvedActionsRight}\n onClose={handleClose}\n hasSidebar={hasSidebar}\n activePaneMobile={activePaneMobile}\n onSetActivePane={setActivePaneMobile}\n />\n {isDebugMode && <DebugStrip rect={rect} zIndex={zIndex} />}\n <div className={cn(\"flex-1 overflow-auto min-h-0\", bodyClassName)}>\n {/* Same menu as the drawer/card paths and desktop: long-press in a\n fullscreen phone window used to open nothing. */}\n <WindowSelectionSurface>{mobileBody}</WindowSelectionSurface>\n </div>\n {footerBar}\n </div>\n );\n return portalTarget\n ? createPortal(<FloatingLayer>{mobileEl}</FloatingLayer>, portalTarget)\n : null;\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // POPPED OUT — content is rendered into a separate browser window via\n // PopoutPortal. The same WindowPanel component instance covers both\n // docked and popped-out states, so React state, refs, effects, Redux\n // subscriptions, and Supabase realtime channels all survive the transition\n // with no remount.\n //\n // The OS / browser frame provides close + minimize at the window-manager\n // level, so we render `PopoutTopBar` (no traffic lights) instead of the\n // standard `header`. The \"Dock\" button in PopoutTopBar dispatches\n // `dockWindow`, which clears the popout state and triggers the\n // `usePopoutWindow` lifecycle to close the actual browser window.\n // ────────────────────────────────────────────────────────────────────────\n if (popoutMode !== null) {\n return (\n <>\n <PopoutPortal windowId={id}>\n <div\n {...surfaceLayerAttrs}\n className=\"h-full w-full flex flex-col bg-card text-foreground\"\n >\n <PopoutTopBar\n title={titleNode ?? title}\n actionsRight={resolvedActionsRight}\n onDock={handleDockBack}\n />\n {isDebugMode && <DebugStrip rect={rect} zIndex={zIndex} />}\n <div className={cn(\"flex-1 overflow-auto min-h-0\", bodyClassName)}>\n <BodyMount host={bodyHost} />\n </div>\n {footerBar}\n </div>\n </PopoutPortal>\n {bodyPortal}\n </>\n );\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // DESKTOP — one shell and body tree across windowed/maximized/restore.\n // Minimized keeps its existing capture/retention and tray-preview semantics.\n // ────────────────────────────────────────────────────────────────────────\n const el = (\n <div\n ref={fitContent ? fitContentRef : undefined}\n data-window-panel=\"\"\n data-window-id={id}\n {...surfaceLayerAttrs}\n // A minimized tile docks at the bottom over the page: it is floating chrome, so every page\n // end (a list's pager included) clears it (lib/layout/floating-chrome.ts). 2026-10-05: the\n // /data pager's next-page arrows sat under the tile.\n {...(isMinimized ? { \"data-matrx-floating-bottom\": \"\" } : {})}\n className={cn(\n \"fixed\",\n isMaximized ? \"overflow-hidden\" : \"overflow-visible\",\n \"matrx-window-enter\",\n // Programmatic rect changes glide; pointer drag/resize stays 1:1.\n glideReady && !isInteracting && \"matrx-window-glide\",\n // Drag-out candidate: ring-2 highlight signals \"release here to pop out\".\n isPopoutCandidate &&\n \"ring-2 ring-primary ring-offset-2 ring-offset-background transition-shadow\",\n deprecatedRingClass,\n className,\n )}\n style={{\n ...(isMaximized\n ? { inset: 0, width: \"100vw\", height: \"100dvh\" }\n : {\n left: rect.x,\n top: rect.y,\n ...(fitContent && !isMinimized\n ? { width: \"max-content\", height: \"auto\" }\n : { width: rect.width, height: rect.height }),\n }),\n zIndex,\n // Cap CSS mins to the current rect so arrange/snap geometry wins.\n // Uncapped minWidth (e.g. 640) was overriding tile widths and stacking\n // every left-edge window on top of each other.\n minWidth: isMaximized || isMinimized\n ? 0\n : fitContent\n ? (minWidth ?? 180)\n : Math.min(minWidth ?? 180, rect.width),\n minHeight: isMaximized || isMinimized\n ? 0\n : fitContent\n ? (minHeight ?? 80)\n : Math.min(minHeight ?? 80, rect.height),\n visibility: windowsHidden ? \"hidden\" : undefined,\n }}\n onPointerDown={onFocus}\n onPointerDownCapture={claimFront}\n onFocusCapture={claimFront}\n // Double-click anywhere on the minimized card — header included —\n // restores it, matching the single-click-to-restore body affordance.\n onDoubleClick={isMinimized ? handleRestoreClearingSnapshot : undefined}\n >\n {!isMinimized && !isMaximized &&\n HANDLES.map((h) => (\n <div\n key={h.edge}\n className={cn(\n h.className,\n \"z-50 hover:bg-primary/20 transition-colors\",\n )}\n style={{ touchAction: \"none\" }}\n onPointerDown={onResizeStart(h.edge)}\n />\n ))}\n <div\n className={cn(\n \"flex h-full w-full min-h-0 flex-col\",\n // Opaque window surface: a window is a solid card, never glass —\n // glass belongs only on bars floating over moving content (tap-target\n // placement rule 1). A see-through window let the page underneath\n // read through its content (Watch AI, 2026-10-12).\n isMaximized\n ? \"bg-card border border-border shadow-2xl\"\n : \"rounded-xl bg-card border border-border shadow-xl\",\n \"overflow-hidden\",\n )}\n >\n {header}\n\n {/* Debug strip — body of an open window only. A minimized tile is too small for it: the\n strip wrapped to fill the whole tile and hid the preview (MKT-077). */}\n {isDebugMode && !isMinimized && <DebugStrip rect={rect} zIndex={zIndex} />}\n\n {(\n\n <WindowPanelBodyShell\n bodyRef={bodyRef}\n fitContent={fitContent}\n isMaximized={isMaximized}\n bodyClassName={bodyClassName}\n captureDimensions={\n isMinimized\n ? pendingTrayCapture\n ? {\n width: pendingTrayCapture.width,\n height: pendingTrayCapture.height,\n }\n : (retainedBodyDimensionsRef.current ?? {\n width: Math.max(1, rect.width),\n height: Math.max(1, rect.height),\n })\n : null\n }\n >\n <BodyMount host={bodyHost} />\n </WindowPanelBodyShell>\n )}\n\n {/* Minimized: fill the empty shell body with the canonical tray preview\n (registry custom / snapshot / default). Click anywhere to restore. */}\n {isMinimized && (\n <MinimizedWindowContent\n registryKey={trayRegistryKey}\n snapshotKey={id}\n overlayInstanceId={overlayInstanceId}\n previewData={trayPreviewData}\n title={minimizedTitle}\n onRestore={handleRestoreClearingSnapshot}\n />\n )}\n\n {!isMinimized && footerBar}\n\n {/* Drag-out ghost label — overlays the body during the candidate dwell.\n Pointer-events:none so it doesn't interfere with the in-progress drag. */}\n {isPopoutCandidate && (\n <div className=\"absolute inset-0 z-30 flex items-center justify-center pointer-events-none\">\n <div className=\"px-3 py-1.5 rounded-md bg-primary text-primary-foreground text-xs font-medium shadow-lg\">\n Release to pop out\n </div>\n </div>\n )}\n </div>\n </div>\n );\n\n return (\n <>\n {portalTarget ? createPortal(<FloatingLayer>{el}</FloatingLayer>, portalTarget) : null}\n {bodyPortal}\n </>\n );\n}\n\n/**\n * Attaches the window's body container where this renders. Its layout effect runs before the\n * body's own (it is earlier in the tree), so a body measuring itself on mount sees a connected node.\n */\nfunction BodyMount({ host }: { host: HTMLDivElement | null }) {\n const slotRef = useRef<HTMLDivElement | null>(null);\n useLayoutEffect(() => {\n const slot = slotRef.current;\n if (!slot || !host) return undefined;\n slot.appendChild(host);\n return () => {\n if (host.parentNode === slot) slot.removeChild(host);\n };\n }, [host]);\n return <div ref={slotRef} className=\"contents\" data-window-body-slot=\"\" />;\n}\n\n// DebugStrip extracted to ./WindowPanel/DebugStrip.tsx (Phase 6).\n\n// ─── WindowHeader ─────────────────────────────────────────────────────────────\n\nfunction PopOutHeaderButton({ onClick }: { onClick: () => void }) {\n return (\n <button\n type=\"button\"\n className=\"p-0.5 rounded hover:bg-accent/60 transition-colors text-foreground/60 hover:text-foreground cursor-pointer\"\n onClick={onClick}\n onPointerDown={(e) => e.stopPropagation()}\n title=\"Pop out into a separate window\"\n aria-label=\"Pop out into a separate window\"\n >\n <AppWindow className=\"w-3.5 h-3.5\" />\n </button>\n );\n}\n\ninterface WindowHeaderProps {\n title?: React.ReactNode | undefined;\n minimizedTitle: string;\n actionsLeft?: React.ReactNode | undefined;\n actionsRight?: React.ReactNode | undefined;\n onDragStart: (e: React.PointerEvent) => void;\n onMinimize: () => void;\n onToggleMaximize: () => void;\n onRestore: () => void;\n onClose?: (() => void) | undefined;\n isMaximized: boolean;\n isMinimized: boolean;\n snapLeft: () => void;\n snapRight: () => void;\n snapTop: () => void;\n snapBottom: () => void;\n snapCentre: () => void;\n arrangeAll: (layout: GlobalLayoutType) => void;\n hasSidebar: boolean;\n sidebarOpen: boolean;\n onToggleSidebar: () => void;\n /** When set, a \"Save Window State\" button appears in the green traffic-light dropdown. */\n onSaveWindowState?: (() => void) | undefined;\n /**\n * When set, a header pop-out icon and green-dropdown entry are shown.\n * Clicking opens the window in a separate browser window.\n */\n onPopOut?: (() => void) | undefined;\n}\n\nfunction WindowHeader({\n title,\n minimizedTitle,\n actionsLeft,\n actionsRight,\n onDragStart,\n onMinimize,\n onToggleMaximize,\n onRestore,\n onClose,\n isMaximized,\n isMinimized,\n snapLeft,\n snapRight,\n snapTop,\n snapBottom,\n snapCentre,\n arrangeAll,\n hasSidebar,\n sidebarOpen,\n onToggleSidebar,\n onSaveWindowState,\n onPopOut,\n}: WindowHeaderProps) {\n return (\n <div\n className={cn(\n // 🚨 NEW-8 — the header is a CONTAINER, so a consumer's title/actions can\n // answer the WINDOW's width instead of the viewport's (`sm:` cannot know\n // a window is 360px on a 1440px screen — that is how D4 stayed invisible).\n // The name is `window-header`; `lib/detail/core/headerGeometry.ts` holds it.\n \"@container/window-header\",\n // Open: three in-flow columns — left zone, title, right zone. The two\n // side columns share the free space equally (never less than their\n // real content), so the title sits at the WINDOW's centre whatever\n // each side carries, and still truncates instead of running under an\n // action cluster when space is tight (D4). Minimized has no title\n // column, so it keeps the plain row.\n isMinimized\n ? \"matrx-window-header-row relative flex items-center justify-between gap-1 px-2 py-1 z-20 shrink-0\"\n : \"matrx-window-header-grid relative items-center gap-1 px-2 py-1 z-20 shrink-0\",\n \"border-b border-border/50 bg-muted/40 select-none\",\n isMaximized || isMinimized\n ? \"cursor-default\"\n : \"cursor-grab active:cursor-grabbing\",\n isMinimized && \"h-8 min-h-8 py-0 border-b border-border/50\",\n )}\n data-window-panel-state={isMinimized ? \"minimized\" : undefined}\n style={isMaximized || isMinimized ? undefined : { touchAction: \"none\" }}\n onPointerDown={isMaximized || isMinimized ? undefined : onDragStart}\n >\n {/* macOS-style hot zone: absolutely positioned to cover the full\n left side of the header (top-to-bottom, no padding). The traffic\n lights and sidebar toggle live inside it so CSS group-hover/tl\n reveals all icons when the cursor enters the zone. */}\n <div\n className={cn(\n \"group/tl absolute top-0 left-0 bottom-0 flex items-center z-20\",\n hasSidebar ? \"w-28\" : \"w-24\",\n )}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <div className=\"pl-2\">\n <TrafficLightGroup\n isMinimized={isMinimized}\n isMaximized={isMaximized}\n onClose={onClose}\n onMinimize={onMinimize}\n onRestore={onRestore}\n onToggleMaximize={onToggleMaximize}\n snapLeft={snapLeft}\n snapRight={snapRight}\n snapTop={snapTop}\n snapBottom={snapBottom}\n snapCentre={snapCentre}\n arrangeAll={arrangeAll}\n hasSidebar={hasSidebar}\n sidebarOpen={sidebarOpen}\n onToggleSidebar={onToggleSidebar}\n onSaveWindowState={onSaveWindowState}\n onPopOut={onPopOut}\n />\n </div>\n </div>\n\n <div className=\"flex items-center gap-1 z-10 shrink-0\">\n {/* Spacer matching the hot zone width so left actions don't overlap */}\n <div className={hasSidebar ? \"w-28\" : \"w-24\"} />\n\n {/* Left action zone */}\n {!isMinimized && actionsLeft && (\n <div\n className={WINDOW_CHROME_ACTIONS}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {actionsLeft}\n </div>\n )}\n </div>\n\n {/* Minimized titles use the fixed plain-text branch in an absolute layer\n (a minimized window draws no action cluster, so nothing can run under\n it) and can never inherit consumer typography or interaction from a\n rich titleNode. */}\n {isMinimized ? (\n <div className=\"absolute top-0 bottom-0 left-20 right-2 flex items-center justify-start pointer-events-none\">\n <span\n className=\"matrx-window-minimized-title block min-w-0 truncate leading-none font-semibold text-foreground\"\n data-minimized-window-title\n >\n {minimizedTitle}\n </span>\n </div>\n ) : null}\n\n {/* 🚨 D4 — Open titles stay in flow, and the action zones' REAL widths are\n reserved by the flex row itself. This used to be an `absolute inset-x-0\n justify-center` layer with `px-16` standing in for the space the\n traffic lights and the icons occupy: a short title looked centred, and\n a long one grew to `max-w-full` and was drawn UNDERNEATH the action\n cluster — in the Detail window that put the record's type chip and its\n own doors under the open-as icons (VERIFY-U-P1 D4, still open by\n geometry at VERIFY-U-P1-R2). A flex child with `min-w-0` yields exactly\n what its siblings need and truncates instead of overlapping, at every\n window width, with no `sm:` breakpoint pretending to know a window's\n size. The title is still centred — in the space that is actually free. */}\n {!isMinimized && (\n <div className=\"flex min-w-0 flex-1 items-center justify-center overflow-hidden\">\n {typeof title === \"string\" || title == null ? (\n <span className=\"min-w-0 truncate text-xs font-medium text-foreground/80\">\n {title ?? \"\"}\n </span>\n ) : (\n <div\n className=\"flex min-w-0 max-w-full items-center overflow-hidden whitespace-nowrap\"\n onPointerDown={(event) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n if (\n target.closest(\n 'a, button, input, select, textarea, [role=\"button\"], [role=\"menuitem\"], [data-window-no-drag]',\n )\n ) {\n event.stopPropagation();\n }\n }}\n >\n {title}\n </div>\n )}\n </div>\n )}\n\n {/* Right action zone */}\n <div className=\"flex items-center justify-end gap-1 z-10 shrink-0\">\n {!isMinimized && (onPopOut || actionsRight) && (\n <div\n className={WINDOW_CHROME_ACTIONS}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {onPopOut ? <PopOutHeaderButton onClick={onPopOut} /> : null}\n {actionsRight}\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ─── TrafficLightGroup ────────────────────────────────────────────────────────\n// Nested inside the group/tl hot zone — icon reveal uses CSS group-hover/tl.\n\ninterface TrafficLightGroupProps {\n isMinimized: boolean;\n isMaximized: boolean;\n onClose?: (() => void) | undefined;\n onMinimize: () => void;\n onRestore: () => void;\n onToggleMaximize: () => void;\n snapLeft: () => void;\n snapRight: () => void;\n snapTop: () => void;\n snapBottom: () => void;\n snapCentre: () => void;\n arrangeAll: (layout: GlobalLayoutType) => void;\n hasSidebar: boolean;\n sidebarOpen: boolean;\n onToggleSidebar: () => void;\n onSaveWindowState?: (() => void) | undefined;\n onPopOut?: (() => void) | undefined;\n}\n\nfunction TrafficLightGroup({\n isMinimized,\n isMaximized,\n onClose,\n onMinimize,\n onRestore,\n onToggleMaximize,\n snapLeft,\n snapRight,\n snapTop,\n snapBottom,\n snapCentre,\n arrangeAll,\n hasSidebar,\n sidebarOpen,\n onToggleSidebar,\n onSaveWindowState,\n onPopOut,\n}: TrafficLightGroupProps) {\n return (\n <div className=\"flex items-center gap-1.5 shrink-0 cursor-default\">\n {/* Red — Close */}\n <TrafficLight\n color=\"red\"\n icon={\n <X className=\"w-2 h-2 matrx-window-light-glyph\" />\n }\n onClick={onClose ?? undefined}\n disabled={!onClose}\n aria-label=\"Close\"\n />\n\n {/* Yellow — Minimize / restore */}\n <TrafficLight\n color=\"yellow\"\n icon={\n isMinimized ? (\n <Maximize2\n className=\"w-2 h-2 matrx-window-light-glyph\"\n\n />\n ) : (\n <Minus\n className=\"w-2 h-2 matrx-window-light-glyph\"\n\n />\n )\n }\n onClick={isMinimized ? onRestore : onMinimize}\n aria-label={isMinimized ? \"Restore\" : \"Minimize\"}\n />\n\n {/* Green — Maximize / dropdown */}\n {!isMinimized && (\n <GreenTrafficLight\n isMaximized={isMaximized}\n onToggleMaximize={onToggleMaximize}\n onRestore={onRestore}\n snapLeft={snapLeft}\n snapRight={snapRight}\n snapTop={snapTop}\n snapBottom={snapBottom}\n snapCentre={snapCentre}\n arrangeAll={arrangeAll}\n onSaveWindowState={onSaveWindowState}\n onPopOut={onPopOut}\n />\n )}\n\n {/* Sidebar toggle — sits tight next to the traffic lights */}\n {hasSidebar && !isMinimized && (\n <button\n type=\"button\"\n className=\"ml-0.5 p-0.5 rounded hover:bg-accent/60 transition-colors text-foreground/60 group-hover/tl:text-foreground cursor-pointer\"\n onClick={onToggleSidebar}\n title={sidebarOpen ? \"Hide sidebar\" : \"Show sidebar\"}\n aria-label={sidebarOpen ? \"Hide sidebar\" : \"Show sidebar\"}\n >\n {sidebarOpen ? (\n <PanelLeftClose className=\"w-3.5 h-3.5\" />\n ) : (\n <PanelLeft className=\"w-3.5 h-3.5\" />\n )}\n </button>\n )}\n </div>\n );\n}\n\n// ─── TrafficLight (red / yellow) ─────────────────────────────────────────────\n\ninterface TrafficLightProps {\n color: \"red\" | \"yellow\";\n icon: React.ReactNode;\n onClick?: (() => void) | undefined;\n disabled?: boolean | undefined;\n \"aria-label\"?: string | undefined;\n}\n\nfunction TrafficLight({\n color,\n icon,\n onClick,\n disabled,\n \"aria-label\": label,\n}: TrafficLightProps) {\n const base =\n \"w-3.5 h-3.5 rounded-full flex items-center justify-center transition-colors shrink-0 relative\";\n const colours =\n color === \"red\"\n ? disabled\n ? \"matrx-window-light-disabled cursor-default\"\n : \"matrx-window-light-close cursor-pointer\"\n : \"matrx-window-light-minimize cursor-pointer\";\n\n return (\n <button\n type=\"button\"\n className={cn(base, colours)}\n onClick={disabled ? undefined : onClick}\n onPointerDown={(e) => e.stopPropagation()}\n aria-label={label}\n disabled={disabled}\n >\n <span\n className={cn(\n \"opacity-0 transition-opacity duration-100\",\n !disabled && \"group-hover/tl:opacity-100\",\n )}\n >\n {icon}\n </span>\n </button>\n );\n}\n\n// ─── GreenTrafficLight (with dropdown) ───────────────────────────────────────\n\ninterface GreenTrafficLightProps {\n isMaximized: boolean;\n onToggleMaximize: () => void;\n onRestore: () => void;\n snapLeft: () => void;\n snapRight: () => void;\n snapTop: () => void;\n snapBottom: () => void;\n snapCentre: () => void;\n arrangeAll: (layout: GlobalLayoutType) => void;\n onSaveWindowState?: (() => void) | undefined;\n /** When set, renders a \"Pop out\" entry that opens the window in a separate browser window. */\n onPopOut?: (() => void) | undefined;\n}\n\nfunction GreenTrafficLight({\n isMaximized,\n onToggleMaximize,\n onRestore,\n snapLeft,\n snapRight,\n snapTop,\n snapBottom,\n snapCentre,\n arrangeAll,\n onSaveWindowState,\n onPopOut,\n}: GreenTrafficLightProps) {\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const leaveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const openDropdown = () => {\n if (leaveTimer.current) clearTimeout(leaveTimer.current);\n setDropdownOpen(true);\n };\n const scheduleClose = () => {\n leaveTimer.current = setTimeout(() => {\n setDropdownOpen(false);\n }, 120);\n };\n\n const handleAction = (fn: () => void) => {\n fn();\n setDropdownOpen(false);\n };\n\n // Close dropdown when tapping outside — skip Radix portal targets\n useEffect(() => {\n if (!dropdownOpen) return undefined;\n const onPointerOutside = (e: PointerEvent) => {\n const target = e.target as Element;\n if (containerRef.current && !containerRef.current.contains(target)) {\n if (target.closest?.(\"[data-radix-portal]\")) return;\n setDropdownOpen(false);\n }\n };\n document.addEventListener(\"pointerdown\", onPointerOutside);\n return () => document.removeEventListener(\"pointerdown\", onPointerOutside);\n }, [dropdownOpen]);\n\n return (\n <div\n ref={containerRef}\n className=\"relative\"\n onMouseEnter={openDropdown}\n onMouseLeave={scheduleClose}\n >\n {/* The dot — click toggles maximize on mouse, tap opens dropdown on touch */}\n <button\n type=\"button\"\n className={cn(\n \"w-3.5 h-3.5 rounded-full flex items-center justify-center transition-colors shrink-0\",\n \"matrx-window-light-maximize cursor-pointer\",\n )}\n onClick={(e) => {\n // On touch devices, open the dropdown instead of immediately maximizing.\n // Touch has no hover, so this is the only way to access snap/arrange options.\n if (\"ontouchstart\" in window || navigator.maxTouchPoints > 0) {\n setDropdownOpen((prev) => !prev);\n } else {\n handleAction(onToggleMaximize);\n }\n }}\n onPointerDown={(e) => e.stopPropagation()}\n aria-label={isMaximized ? \"Restore\" : \"Maximize\"}\n >\n <span className=\"opacity-0 group-hover/tl:opacity-100 transition-opacity duration-100 flex items-center justify-center relative w-full h-full\">\n {isMaximized ? (\n <Minimize2\n className=\"w-2 h-2 matrx-window-light-glyph absolute\"\n\n />\n ) : (\n <Maximize2\n className=\"w-2 h-2 matrx-window-light-glyph absolute\"\n\n />\n )}\n </span>\n </button>\n\n {/* Dropdown */}\n {dropdownOpen && (\n <div\n className={cn(\n \"absolute left-0 top-full mt-1.5 z-50\",\n \"w-52 rounded-xl overflow-hidden\",\n \"bg-card/95 backdrop-blur-xl border border-border shadow-2xl\",\n \"py-1 text-xs\",\n )}\n onMouseEnter={openDropdown}\n onMouseLeave={scheduleClose}\n >\n {/* Move & Resize section */}\n {!isMaximized && (\n <>\n <div className=\"matrx-window-tile-meta px-3 pt-1.5 pb-1 font-semibold text-muted-foreground uppercase tracking-wider\">\n Move &amp; Resize\n </div>\n <div className=\"flex flex-col gap-1 px-2 pb-2\">\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(snapLeft)}\n type=\"left-half\"\n />\n <LayoutIconButton\n onClick={() => handleAction(snapRight)}\n type=\"right-half\"\n />\n <LayoutIconButton\n onClick={() => handleAction(snapTop)}\n type=\"top-half\"\n />\n <LayoutIconButton\n onClick={() => handleAction(snapBottom)}\n type=\"bottom-half\"\n />\n </div>\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(snapCentre)}\n type=\"centre\"\n />\n <LayoutIconButton\n onClick={() => handleAction(onToggleMaximize)}\n type=\"full\"\n />\n </div>\n </div>\n <div className=\"border-t border-border/50 my-1\" />\n\n <div className=\"matrx-window-tile-meta px-3 pt-1.5 pb-1 font-semibold text-muted-foreground uppercase tracking-wider\">\n Arrange All\n </div>\n <div className=\"flex flex-col gap-1 px-2 pb-2\">\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid4\"))}\n type=\"grid4\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid6\"))}\n type=\"grid6\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid8\"))}\n type=\"grid8\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid9\"))}\n type=\"grid9\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid12\"))}\n type=\"grid12\"\n />\n </div>\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight2\"))\n }\n type=\"stackRight2\"\n />\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight3\"))\n }\n type=\"stackRight3\"\n />\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight4\"))\n }\n type=\"stackRight4\"\n />\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight5\"))\n }\n type=\"stackRight5\"\n />\n </div>\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft2\"))}\n type=\"stackLeft2\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft3\"))}\n type=\"stackLeft3\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft4\"))}\n type=\"stackLeft4\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft5\"))}\n type=\"stackLeft5\"\n />\n </div>\n </div>\n <div className=\"border-t border-border/50 my-1\" />\n </>\n )}\n\n {/* Full Screen */}\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 hover:bg-accent transition-colors text-foreground/80\"\n onClick={() => handleAction(onToggleMaximize)}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {isMaximized ? (\n <>\n <Minimize2 className=\"w-3.5 h-3.5 shrink-0\" /> Exit Full Screen\n </>\n ) : (\n <>\n <RectangleVertical className=\"w-3.5 h-3.5 shrink-0\" /> Enter\n Full Screen\n </>\n )}\n </button>\n\n {isMaximized && (\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 hover:bg-accent transition-colors text-foreground/80\"\n onClick={() => handleAction(onRestore)}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <Maximize2 className=\"w-3.5 h-3.5 shrink-0\" />\n Restore window\n </button>\n )}\n\n {/* Pop out — opens the window in a separate browser window.\n The popout hook chooses Document Picture-in-Picture (frameless,\n always-on-top) when available and the slot is free; otherwise\n falls back to a regular browser window so multiple popouts\n never interfere with each other. Hidden entirely when popout\n is unavailable (mobile / unsupported browser / already out). */}\n {onPopOut && (\n <>\n <div className=\"border-t border-border/50 my-1\" />\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 transition-colors text-foreground/80 hover:bg-accent\"\n onClick={() => handleAction(onPopOut)}\n onPointerDown={(e) => e.stopPropagation()}\n title=\"Pop out into a separate window\"\n >\n <AppWindow className=\"w-3.5 h-3.5 shrink-0\" />\n <span className=\"flex-1 text-left\">Pop out</span>\n </button>\n </>\n )}\n\n {/* Save Window State — only shown when the window is persistable */}\n {onSaveWindowState && (\n <>\n <div className=\"border-t border-border/50 my-1\" />\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 hover:bg-accent transition-colors text-foreground/80\"\n onClick={() => handleAction(onSaveWindowState)}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <Save className=\"w-3.5 h-3.5 shrink-0\" />\n Save window state\n </button>\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// MobileWindowHeader extracted to ./WindowPanel/MobileHeader.tsx (Phase 6).\n\n// SnapButton extracted to ./WindowPanel/SnapButton.tsx (Phase 6).\n\nexport default WindowPanel;\n","/**\n * The window chrome's glyphs, inlined (no icon-library dependency — design-system C19 does the\n * same). Each is the exact lucide glyph the app's WindowPanel rendered (same viewBox, paths and\n * stroke geometry), so the chrome is pixel-identical. `@ai-matrx/icons` resolves icons by NAME and\n * lazily outside its hot set; nine of these twelve are outside it, and a traffic light that\n * flashes a fallback on first paint is worse than twelve inlined paths.\n */\nimport type { ReactNode, SVGAttributes } from \"react\";\n\nexport type WindowIconProps = SVGAttributes<SVGSVGElement>;\nexport type WindowIcon = (props: WindowIconProps) => ReactNode;\n\nfunction glyph(children: ReactNode): WindowIcon {\n return function Glyph(props: WindowIconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={24}\n height={24}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n {...props}\n >\n {children}\n </svg>\n );\n };\n}\n\nexport const XIcon = glyph(<><path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" /></>);\nexport const MinusIcon = glyph(<path d=\"M5 12h14\" />);\nexport const Maximize2Icon = glyph(<><path d=\"M15 3h6v6\" /><path d=\"m21 3-7 7\" /><path d=\"m3 21 7-7\" /><path d=\"M9 21H3v-6\" /></>);\nexport const Minimize2Icon = glyph(<><path d=\"m14 10 7-7\" /><path d=\"M20 10h-6V4\" /><path d=\"m3 21 7-7\" /><path d=\"M4 14h6v6\" /></>);\nexport const RectangleVerticalIcon = glyph(<rect width=\"12\" height=\"20\" x=\"6\" y=\"2\" rx=\"2\" />);\nexport const PanelLeftCloseIcon = glyph(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /><path d=\"m16 15-3-3 3-3\" /></>);\nexport const PanelLeftIcon = glyph(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /></>);\nexport const AppWindowIcon = glyph(<><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" /><path d=\"M10 4v4\" /><path d=\"M2 8h20\" /><path d=\"M6 4v4\" /></>);\nexport const SaveIcon = glyph(\n <>\n <path d=\"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\" />\n <path d=\"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\" />\n <path d=\"M7 3v4a1 1 0 0 0 1 1h7\" />\n </>,\n);\nexport const TriangleAlertIcon = glyph(\n <>\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </>,\n);\nexport const ArrowLeftToLineIcon = glyph(<><path d=\"M3 19V5\" /><path d=\"m13 6-6 6 6 6\" /><path d=\"M7 12h14\" /></>);\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\nexport type LayoutIconType =\n // Single window\n | \"left-half\"\n | \"right-half\"\n | \"top-half\"\n | \"bottom-half\"\n | \"centre\"\n | \"full\"\n // Multi window\n | \"grid4\"\n | \"grid6\"\n | \"grid8\"\n | \"grid9\"\n | \"grid12\"\n | \"stackLeft2\"\n | \"stackLeft3\"\n | \"stackLeft4\"\n | \"stackLeft5\"\n | \"stackRight2\"\n | \"stackRight3\"\n | \"stackRight4\"\n | \"stackRight5\";\n\nexport function LayoutIcon({\n type,\n className,\n}: {\n type: LayoutIconType;\n className?: string | undefined;\n}) {\n const baseBox =\n \"w-[18px] h-[18px] border-[1.5px] border-current rounded-sm shrink-0 flex items-center justify-center p-[1px] gap-[1px] overflow-hidden\";\n const filled = \"bg-current rounded-[1px]\";\n const flexRow = \"flex flex-row w-full h-full gap-[1px]\";\n const flexCol = \"flex flex-col w-full h-full gap-[1px]\";\n\n let content: ReactNode = null;\n\n switch (type) {\n case \"left-half\":\n content = (\n <div className={flexRow}>\n <div className={cn(\"w-1/2 h-full\", filled)} />\n <div className=\"w-1/2 h-full\" />\n </div>\n );\n break;\n case \"right-half\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/2 h-full\" />\n <div className={cn(\"w-1/2 h-full\", filled)} />\n </div>\n );\n break;\n case \"top-half\":\n content = (\n <div className={flexCol}>\n <div className={cn(\"w-full h-1/2\", filled)} />\n <div className=\"w-full h-1/2\" />\n </div>\n );\n break;\n case \"bottom-half\":\n content = (\n <div className={flexCol}>\n <div className=\"w-full h-1/2\" />\n <div className={cn(\"w-full h-1/2\", filled)} />\n </div>\n );\n break;\n case \"centre\":\n content = <div className={cn(\"w-1/2 h-1/2\", filled)} />;\n break;\n case \"full\":\n content = <div className={cn(\"w-full h-full\", filled)} />;\n break;\n\n // Grid variants\n case \"grid4\":\n content = (\n <div className=\"grid grid-cols-2 grid-rows-2 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid6\":\n content = (\n <div className=\"grid grid-cols-3 grid-rows-2 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid8\":\n content = (\n <div className=\"grid grid-cols-4 grid-rows-2 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid9\":\n content = (\n <div className=\"grid grid-cols-3 grid-rows-3 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid12\":\n content = (\n <div className=\"grid grid-cols-4 grid-rows-3 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n\n // Stack variants\n case \"stackRight2\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/2 h-full\" />\n <div className=\"w-1/2 h-full flex flex-col gap-[1px]\">\n <div className={cn(\"w-full h-1/2\", filled)} />\n <div className={cn(\"w-full h-1/2\", filled)} />\n </div>\n </div>\n );\n break;\n case \"stackRight3\":\n content = (\n <div className={flexRow}>\n <div className=\"w-2/3 h-full\" />\n <div className=\"w-1/3 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n </div>\n );\n break;\n case \"stackRight4\":\n content = (\n <div className={flexRow}>\n <div className=\"w-3/4 h-full\" />\n <div className=\"w-1/4 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n </div>\n );\n break;\n case \"stackRight5\":\n content = (\n <div className={flexRow}>\n <div className=\"w-4/5 h-full\" />\n <div className=\"w-1/5 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n </div>\n );\n break;\n case \"stackLeft2\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/2 h-full flex flex-col gap-[1px]\">\n <div className={cn(\"w-full h-1/2\", filled)} />\n <div className={cn(\"w-full h-1/2\", filled)} />\n </div>\n <div className=\"w-1/2 h-full\" />\n </div>\n );\n break;\n case \"stackLeft3\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/3 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n <div className=\"w-2/3 h-full\" />\n </div>\n );\n break;\n case \"stackLeft4\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/4 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n <div className=\"w-3/4 h-full\" />\n </div>\n );\n break;\n case \"stackLeft5\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/5 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n <div className=\"w-4/5 h-full\" />\n </div>\n );\n break;\n }\n\n return <div className={cn(baseBox, className)}>{content}</div>;\n}\n\nexport function LayoutIconButton({\n onClick,\n type,\n className,\n}: {\n onClick: () => void;\n type: LayoutIconType;\n className?: string | undefined;\n}) {\n return (\n <button\n type=\"button\"\n className={cn(\n \"flex items-center justify-center flex-1 h-8 rounded-md transition-colors\",\n \"hover:bg-accent/80 text-foreground/50 hover:text-foreground\",\n className\n )}\n onClick={onClick}\n onPointerDown={(e) => e.stopPropagation()}\n title={type}\n >\n <LayoutIcon type={type} />\n </button>\n );\n}\n","\"use client\";\n\n/**\n * useWindowPanel\n *\n * Connects a single WindowPanel instance to the Redux window-manager slice.\n * Handles:\n * - Registration / cleanup on mount/unmount\n * - Drag-to-move (header pointerdown → document pointermove/pointerup)\n * - Resize (edge/corner handles → document pointermove/pointerup)\n * - Window state transitions (windowed / maximized / minimized)\n * - Focus-on-click (brings panel to top of z stack)\n *\n * Uses pointer events (not mouse events) so drag/resize works on\n * touchscreens (iPad, Tesla, etc.) as well as mouse + pen input.\n *\n * Pure CSS resize via inline styles; no Tailwind width classes after mount.\n */\n\nimport { useEffect, useRef, useCallback, useId, useState } from \"react\";\nimport { useSummonDispatch, useSummonSelector, useSummonStore } from \"@ai-matrx/summon/react\";\nimport {\n registerWindow,\n unregisterWindow,\n focusWindow,\n restoreWindow,\n maximizeWindow,\n minimizeWindow,\n updateWindowRect,\n updateWindowTitle,\n setPopoutCandidate,\n clampWindowRect,\n selectWindow,\n type WindowRect,\n type WindowPersistenceRegistration,\n confirmWindowRestored,\n windowSessionKey,\n} from \"@ai-matrx/summon\";\nimport {\n evaluateDragOut,\n DEFAULT_DRAG_OUT_CONFIG,\n INITIAL_DRAG_OUT_STATE,\n type DragOutState,\n} from \"./popout/popoutDragDetector\";\nimport { safeViewportDims } from \"@ai-matrx/summon\";\nimport { resolveAutoOpenPlacement } from \"./utils/autoOpenPlacement\";\nimport { holdDragCursor, type DragCursor } from \"@ai-matrx/design-system\";\n\n// ─── Config ────────────────────────────────────────────────────────────────────\n\nconst MIN_WIDTH = 180;\nconst MIN_HEIGHT = 80;\nconst DEFAULT_WIDTH = 320;\nconst DEFAULT_HEIGHT = 400;\n\n// ─── Types ─────────────────────────────────────────────────────────────────────\n\nexport type ResizeEdge =\n | \"e\" // right\n | \"s\" // bottom\n | \"se\" // bottom-right corner\n | \"w\" // left\n | \"sw\" // bottom-left\n | \"n\" // top\n | \"ne\" // top-right\n | \"nw\"; // top-left\n\n/** The cursor each resize edge holds for the whole resize (THE CURSOR LAW). */\nconst RESIZE_CURSOR: Record<ResizeEdge, DragCursor> = {\n e: \"ew-resize\",\n w: \"ew-resize\",\n n: \"ns-resize\",\n s: \"ns-resize\",\n se: \"nwse-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n sw: \"nesw-resize\",\n};\n\n/** Where to place the window when it first opens. */\nexport type WindowPosition =\n \"center\" | \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\";\n\n/**\n * Resolve a dimension value to pixels.\n * - number → pixels as-is\n * - string ending in \"vh\" → percentage of viewport height\n * - string ending in \"vw\" → percentage of viewport width\n */\nfunction resolveSize(\n value: number | string | undefined,\n fallback: number,\n): number {\n if (value === undefined) return fallback;\n if (typeof value === \"number\") return value;\n const { vw, vh } = safeViewportDims();\n if (value.endsWith(\"vh\")) return Math.round((parseFloat(value) / 100) * vh);\n if (value.endsWith(\"vw\")) return Math.round((parseFloat(value) / 100) * vw);\n return parseFloat(value) || fallback;\n}\n\n/**\n * How many windows this page has already placed by default, so the second one\n * does not land exactly on the first. Page-scoped on purpose: a reload starts\n * the cascade over, which is what every desktop window manager does.\n */\nconst CASCADE_COUNT = Symbol.for(\"matrx.windowPanels.defaultCascade\");\nconst CASCADE_STEP = 28;\nconst CASCADE_WRAP = 6;\n\nexport function resetDefaultWindowCascade(): void {\n (globalThis as unknown as Record<symbol, number>)[CASCADE_COUNT] = 0;\n}\n\nfunction nextCascadeStep(): number {\n const host = globalThis as unknown as Record<symbol, number>;\n const seen = host[CASCADE_COUNT] ?? 0;\n host[CASCADE_COUNT] = seen + 1;\n return (seen % CASCADE_WRAP) * CASCADE_STEP;\n}\n\n/**\n * Where a window nobody positioned opens.\n *\n * 🚨 WHY THIS IS NOT CENTERED ANY MORE (2026-09-17). The `default` arm used to\n * return the same rect as `\"center\"`: horizontally centred, a quarter of the\n * way down. That is exactly where this app puts a route's primary column, so a\n * floating window that declared no position landed ON TOP of the one control\n * the page exists for. It was found on `/exports`, where the auto-opened\n * \"Spend so far today\" window covered the drop zone on first load and swallowed\n * clicks on \"Choose a file\" — Playwright named it: `WindowPanel … subtree\n * intercepts pointer events`. Nothing about that was specific to spend or to\n * exports; every window in the registry that omits `position` had it.\n *\n * An explicit `position: \"center\"` still centres — a window that ASKED to be in\n * the middle is making a claim about itself, and this is not the place to\n * overrule it. Only the windows nobody placed move, and they move to the right\n * gutter beside the content, cascaded so a second one is visible behind the\n * first, which is what macOS, Figma and Linear do with utility windows.\n *\n * Below `NARROW_VIEWPORT` there is no gutter to park in — the content is the\n * whole screen — so a default window is clamped to the top instead of covering\n * the middle of the page, and the mobile surfaces take over from there.\n */\nconst NARROW_VIEWPORT = 768;\n\n/** Ids of auto-opened windows docked in a gutter, so the next one stacks under them. */\nconst autoDocked = new Set<string>();\n/** Open order of auto-opened windows: a window stacks only under EARLIER ones, never chases a later one. */\nconst autoOrder = new Map<string, number>();\nlet autoOrderNext = 0;\nconst earlierDocked = (id: string) =>\n (other: { id: string; state: string }) =>\n other.id !== id &&\n other.state === \"windowed\" &&\n autoDocked.has(other.id) &&\n (autoOrder.get(other.id) ?? 0) < (autoOrder.get(id) ?? 0);\n/** Seconds an auto-opened window keeps re-checking the page's layout. */\nconst AUTO_REPLACE_TICKS = 40;\n\n/** The shell header's height (`--shell-header-h`) plus a gap; 44px fallback. */\nfunction shellHeaderClearance(): number {\n const GAP = 12;\n if (typeof document === \"undefined\") return 44 + GAP;\n const root = getComputedStyle(document.documentElement);\n const raw = root.getPropertyValue(\"--shell-header-h\").trim();\n // The shell declares it in rem (\"2.75rem\") — a bare parseFloat read 2.75px\n // and opened every window at y=15, under the header.\n const n = parseFloat(raw);\n const h = raw.endsWith(\"rem\")\n ? n * (parseFloat(root.fontSize) || 16)\n : n;\n return (Number.isFinite(h) && h > 0 ? h : 44) + GAP;\n}\n\nexport function resolvePosition(\n pos: WindowPosition | undefined,\n w: number,\n h: number,\n): { x: number; y: number } {\n const { vw, vh } = safeViewportDims();\n const pad = 40;\n // A window opening at the top CLEARS the shell header — the same way every\n // time (page-pass 2026-09-27: the Feedback window opened at y=40 under a\n // 44px header, then at y=68 on the next open).\n const top = shellHeaderClearance();\n switch (pos) {\n case \"top-left\":\n return { x: pad, y: top };\n case \"top-right\":\n return { x: Math.max(0, vw - w - pad), y: top };\n case \"bottom-left\":\n return { x: pad, y: Math.max(0, vh - h - pad) };\n case \"bottom-right\":\n return { x: Math.max(0, vw - w - pad), y: Math.max(0, vh - h - pad) };\n case \"center\":\n // Centred, but never under the shell header (a tall window centred on\n // a short screen used to open at y=20, its title bar behind the header).\n return {\n x: Math.max(0, (vw - w) / 2),\n y: Math.max(top, (vh - h) / 4),\n };\n default: {\n const cascade = nextCascadeStep();\n if (vw < NARROW_VIEWPORT) {\n return {\n x: Math.max(0, Math.min(vw - w, (vw - w) / 2)),\n y: Math.max(0, Math.min(vh - h, top + cascade)),\n };\n }\n return {\n x: Math.max(0, vw - w - pad - cascade),\n y: Math.max(0, Math.min(vh - h, top + cascade)),\n };\n }\n }\n}\n\nexport interface UseWindowPanelOptions {\n /** Stable, unique id. If omitted a React useId-based id is used. */\n id?: string | undefined;\n /** Title shown in the header and tray chip. */\n title?: string | undefined;\n /**\n * Initial width. Accepts pixels (number) or viewport strings (\"60vw\").\n * Default: 320.\n */\n width?: number | string | undefined;\n /**\n * Initial height. Accepts pixels (number) or viewport strings (\"60dvh\").\n * Default: 400.\n */\n height?: number | string | undefined;\n /** Minimum width during pointer resize. Default: 180. */\n minWidth?: number | undefined;\n /** Minimum height during pointer resize. Default: 80. */\n minHeight?: number | undefined;\n /** Where to place the window initially. Default: \"center\". */\n position?: WindowPosition | undefined;\n /** Park a brand-new desktop window in the tray without a visible flash. */\n initialState?: \"windowed\" | \"minimized\" | undefined;\n /**\n * The system (not a person) opened this window. It docks in a free gutter beside the page's\n * working column, or parks in the tray when none fits — never over the page. See\n * `utils/autoOpenPlacement.ts`. WindowPanel sets this from `markAutoOpened`.\n */\n autoOpened?: boolean | undefined;\n /**\n * MKT-104: an auto-opened window with no gutter left beside the page closes itself through this\n * instead of parking a tray card over the page's controls.\n */\n onAutoNoRoom?: (() => void) | undefined;\n /**\n * @deprecated Pass `width`, `height`, and `position` instead.\n * Low-level initial rect — overrides width/height/position when provided.\n */\n initialRect?: Partial<WindowRect> | undefined;\n /** Maximum width the user can resize to. */\n maxWidth?: number | undefined;\n /** Maximum height the user can resize to. */\n maxHeight?: number | undefined;\n /**\n * Optional callback fired when the user drags the window outside the\n * viewport long enough to count as a pop-out gesture. Caller is expected\n * to open the popout window synchronously inside the user-gesture stack\n * (i.e. without `await` before the open call).\n *\n * Pass the current rect at the time of release — the popout uses it for\n * sizing.\n *\n * `undefined` disables drag-out detection entirely. Use `undefined` for\n * popouts that aren't supported (mobile, no-capability browsers, etc.)\n * so we don't waste cycles on the per-move evaluation.\n */\n onTriggerPopout?: ((rect: WindowRect) => void) | undefined;\n /** Audited local preservation identity and initial semantic/chrome state. */\n persistence?: WindowPersistenceRegistration | undefined;\n}\n\n/** Shared subset of MouseEvent / PointerEvent / TouchEvent we need. */\ntype PointerLike = {\n clientX: number;\n clientY: number;\n preventDefault: () => void;\n};\n\nexport interface UseWindowPanelReturn {\n /** The stable window id. */\n id: string;\n /** Current window state from Redux. */\n windowState: \"windowed\" | \"maximized\" | \"minimized\";\n /** Current windowed rect from Redux. */\n rect: WindowRect;\n /** z-index from Redux. */\n zIndex: number;\n /** Pointerdown handler for the drag handle (header). Works with mouse + touch + pen. */\n onDragStart: (e: React.PointerEvent) => void;\n /** Pointerdown handler factory for resize handles. Works with mouse + touch + pen. */\n onResizeStart: (edge: ResizeEdge) => (e: React.PointerEvent) => void;\n /** Bring this window to the top. */\n onFocus: () => void;\n /** Transition to windowed state. */\n onRestore: () => void;\n /** Transition to maximized state. */\n onMaximize: () => void;\n /** Transition to minimized (tray) state. */\n onMinimize: () => void;\n /** Toggle maximized ↔ windowed. */\n onToggleMaximize: () => void;\n /**\n * True while the user is actively dragging or resizing with the pointer.\n * The shell disables its geometry transition during interaction so the\n * window tracks the pointer 1:1, and re-enables it for programmatic rect\n * changes (snap, arrange, minimize→tray, restore, clamp) which then glide.\n */\n isInteracting: boolean;\n}\n\n// ─── Hook ──────────────────────────────────────────────────────────────────────\n\nexport function useWindowPanel(\n opts: UseWindowPanelOptions = {},\n): UseWindowPanelReturn {\n const reactId = useId();\n const id = opts.id ?? reactId;\n\n const dispatch = useSummonDispatch();\n const store = useSummonStore();\n const entry = useSummonSelector(selectWindow(id));\n\n const minWidth = opts.minWidth ?? MIN_WIDTH;\n const minHeight = opts.minHeight ?? MIN_HEIGHT;\n const maxWidth = opts.maxWidth ?? Infinity;\n const maxHeight = opts.maxHeight ?? Infinity;\n\n // True during an active pointer drag/resize gesture — see UseWindowPanelReturn.\n const [isInteracting, setIsInteracting] = useState(false);\n\n // ── Registration ────────────────────────────────────────────────────────────\n useEffect(() => {\n const w = opts.initialRect?.width ?? resolveSize(opts.width, DEFAULT_WIDTH);\n const h =\n opts.initialRect?.height ?? resolveSize(opts.height, DEFAULT_HEIGHT);\n const { vw, vh } = safeViewportDims();\n let autoPlaced: ReturnType<typeof resolveAutoOpenPlacement> | null = null;\n if (opts.autoOpened && vw >= NARROW_VIEWPORT) {\n if (!autoOrder.has(id)) autoOrder.set(id, autoOrderNext++);\n const siblings = Object.values(store.getState().windowManager.windows)\n .filter(earlierDocked(id))\n .map((win) => win.windowed);\n autoPlaced = resolveAutoOpenPlacement({\n width: w,\n height: h,\n minWidth,\n minHeight,\n top: shellHeaderClearance(),\n viewport: { vw, vh },\n siblings,\n });\n if (!autoPlaced.minimized) autoDocked.add(id);\n else if (opts.onAutoNoRoom) window.setTimeout(() => opts.onAutoNoRoom?.(), 0);\n }\n const pos = autoPlaced\n ? { x: autoPlaced.rect.x, y: autoPlaced.rect.y }\n : opts.initialRect?.x !== undefined || opts.initialRect?.y !== undefined\n ? {\n x: opts.initialRect?.x ?? Math.max(0, (vw - w) / 2),\n y: opts.initialRect?.y ?? Math.max(0, (vh - h) / 4),\n }\n : resolvePosition(opts.position, w, h);\n const initial: WindowRect = autoPlaced\n ? { ...autoPlaced.rect }\n : { ...pos, width: w, height: h };\n dispatch(\n registerWindow({\n id,\n ...(opts.title === undefined ? {} : { title: opts.title }),\n initial,\n ...(autoPlaced?.minimized ? { initialState: \"minimized\" as const } : opts.initialState === undefined ? {} : { initialState: opts.initialState }),\n ...(opts.persistence === undefined ? {} : { persistence: opts.persistence }),\n // Sanitized dims: a degenerate 0×0 measurement must never become the\n // clamp target, or every rect collapses to garbage (see safeViewportDims).\n viewport: { width: vw, height: vh },\n }),\n );\n const pendingKey = opts.persistence\n ? windowSessionKey(\n opts.persistence.overlayId,\n opts.persistence.instanceId,\n )\n : null;\n // StrictMode mounts, cleans up, then mounts again in development. The\n // first cleanup must not consume the pending restore before the stable\n // mount gets a chance to register.\n const confirmationTimer = pendingKey\n ? window.setTimeout(() => {\n dispatch(confirmWindowRestored(pendingKey));\n }, 0)\n : null;\n return () => {\n if (confirmationTimer !== null) window.clearTimeout(confirmationTimer);\n autoDocked.delete(id);\n autoOrder.delete(id);\n dispatch(unregisterWindow(id));\n };\n }, [id]);\n\n // ── Auto-opened windows keep clear of the page while it settles ──────────────\n // The page's working column is measured at open, but a page lays itself out AFTER a run starts\n // (Smart Add grows from one field into the full card column). Re-place every second for a while\n // until the person touches the window; the page always wins the space.\n const autoTouchedRef = useRef(false);\n useEffect(() => {\n if (isInteracting) autoTouchedRef.current = true;\n }, [isInteracting]);\n useEffect(() => {\n if (!opts.autoOpened) return undefined;\n let ticks = 0;\n let lastMinimized: boolean | null = null;\n const timer = window.setInterval(() => {\n ticks += 1;\n if (ticks > AUTO_REPLACE_TICKS) {\n window.clearInterval(timer);\n return;\n }\n const win = store.getState().windowManager.windows[id];\n if (!win || autoTouchedRef.current) return;\n const { vw, vh } = safeViewportDims();\n if (vw < NARROW_VIEWPORT) return;\n const isMin = win.state === \"minimized\";\n // A change the person made (restore/minimize by hand) ends our say.\n if (lastMinimized !== null && isMin !== lastMinimized) {\n autoTouchedRef.current = true;\n return;\n }\n if (win.state !== \"windowed\" && !isMin) return;\n const siblings = Object.values(store.getState().windowManager.windows)\n .filter(earlierDocked(id))\n .map((o) => o.windowed);\n const next = resolveAutoOpenPlacement({\n width: win.windowed.width,\n height: win.windowed.height,\n minWidth,\n minHeight,\n top: shellHeaderClearance(),\n viewport: { vw, vh },\n siblings,\n });\n if (next.minimized) {\n autoDocked.delete(id);\n if (opts.onAutoNoRoom) {\n window.clearInterval(timer);\n opts.onAutoNoRoom();\n return;\n }\n if (!isMin) {\n dispatch(minimizeWindow({ id, viewportWidth: vw, viewportHeight: vh }));\n }\n lastMinimized = true;\n return;\n }\n autoDocked.add(id);\n if (isMin) dispatch(restoreWindow(id));\n const cur = store.getState().windowManager.windows[id]?.windowed;\n if (\n !cur ||\n Math.abs(cur.x - next.rect.x) > 4 ||\n Math.abs(cur.y - next.rect.y) > 4 ||\n Math.abs(cur.width - next.rect.width) > 4 ||\n Math.abs(cur.height - next.rect.height) > 4\n ) {\n dispatch(updateWindowRect({ id, rect: next.rect }));\n }\n lastMinimized = false;\n }, 1000);\n return () => window.clearInterval(timer);\n }, [opts.autoOpened, id, minWidth, minHeight, store, dispatch]);\n\n // ── Keep title in sync if it changes after mount ─────────────────────────\n useEffect(() => {\n if (opts.title !== undefined) {\n dispatch(updateWindowTitle({ id, title: opts.title }));\n }\n }, [id, opts.title, dispatch]);\n\n // ── Drag-to-move (pointer events — works for mouse + touch + pen) ──────────\n const dragStart = useRef<{\n mx: number;\n my: number;\n wx: number;\n wy: number;\n } | null>(null);\n\n const onTriggerPopout = opts.onTriggerPopout;\n const onTriggerPopoutRef = useRef(onTriggerPopout);\n useEffect(() => {\n onTriggerPopoutRef.current = onTriggerPopout;\n }, [onTriggerPopout]);\n\n const onDragStart = useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n dispatch(focusWindow(id));\n // Allow drag in windowed AND minimized states (maximized is handled by header)\n if (!entry || entry.state === \"maximized\") return;\n dragStart.current = {\n mx: e.clientX,\n my: e.clientY,\n wx: entry.windowed.x,\n wy: entry.windowed.y,\n };\n setIsInteracting(true);\n // THE CURSOR LAW: `grabbing` on <html> for the whole drag, so it never\n // flickers as the pointer outruns the header.\n const releaseCursor = holdDragCursor();\n\n // Per-drag local state for drag-out detection. Only allocated/used\n // when popout is enabled for this window.\n let dragOutState: DragOutState = INITIAL_DRAG_OUT_STATE;\n // Snapshot rect at release for the popout sizing — drag updates rect\n // continuously, so we capture x/y/w/h at gesture-end.\n let lastClientX = e.clientX;\n let lastClientY = e.clientY;\n const popoutEnabled = onTriggerPopoutRef.current !== undefined;\n\n const onMove = (ev: PointerEvent) => {\n if (!dragStart.current) return;\n const nx = dragStart.current.wx + (ev.clientX - dragStart.current.mx);\n const ny = dragStart.current.wy + (ev.clientY - dragStart.current.my);\n dispatch(updateWindowRect({ id, rect: { x: nx, y: ny } }));\n lastClientX = ev.clientX;\n lastClientY = ev.clientY;\n\n // Drag-out detection — only run the evaluator when popout is wired.\n if (!popoutEnabled) return;\n const result = evaluateDragOut(\n { clientX: ev.clientX, clientY: ev.clientY },\n dragOutState,\n DEFAULT_DRAG_OUT_CONFIG,\n window.innerWidth,\n window.innerHeight,\n performance.now(),\n );\n // Only dispatch on candidate-state changes to avoid spamming Redux\n // with identical actions every pointermove.\n if (result.state.isCandidate !== dragOutState.isCandidate) {\n dispatch(\n setPopoutCandidate({ id: result.state.isCandidate ? id : null }),\n );\n }\n dragOutState = result.state;\n };\n\n const onUp = () => {\n const wasCandidate = dragOutState.isCandidate;\n const dragOrigin = dragStart.current;\n dragStart.current = null;\n setIsInteracting(false);\n releaseCursor();\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onUp);\n document.removeEventListener(\"pointercancel\", onUp);\n\n // Always clear candidate flag on release — even if popout fires,\n // the visual feedback should disappear immediately.\n if (popoutEnabled && dragOutState.isCandidate) {\n dispatch(setPopoutCandidate({ id: null }));\n }\n\n // Trigger popout if release happened in candidate state.\n // Run synchronously inside the pointerup user-gesture stack so the\n // browser accepts the requestWindow / window.open call.\n if (wasCandidate && onTriggerPopoutRef.current && entry) {\n // Use the LAST rect we computed during the drag — the user has\n // visually placed the window at that position, even though the\n // popout will appear at OS-controlled coordinates.\n const lastRect: WindowRect = {\n x: dragOrigin?.wx ?? entry.windowed.x,\n y: dragOrigin?.wy ?? entry.windowed.y,\n width: entry.windowed.width,\n height: entry.windowed.height,\n };\n onTriggerPopoutRef.current(lastRect);\n } else {\n // Off-screen rescue: if the user released the drag outside the\n // viewport without triggering a popout (e.g. they dragged past\n // the edge but not far enough / long enough to dwell, or popout\n // was unavailable), pull the complete window back into bounds.\n // The clamp reducer is a no-op when rect is already in bounds, so\n // this is cheap to dispatch unconditionally.\n const { vw, vh, degenerate } = safeViewportDims();\n if (!degenerate) {\n dispatch(\n clampWindowRect({ id, viewportWidth: vw, viewportHeight: vh }),\n );\n }\n }\n // Suppress unused-var lint on lastClientX/Y — they're tracked for\n // potential future telemetry (drag distance, exit edge, etc.)\n void lastClientX;\n void lastClientY;\n };\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onUp);\n document.addEventListener(\"pointercancel\", onUp);\n },\n [dispatch, id, entry],\n );\n\n // ── Resize (pointer events — works for mouse + touch + pen) ────────────────\n const onResizeStart = useCallback(\n (edge: ResizeEdge) => (e: React.PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dispatch(focusWindow(id));\n if (!entry || entry.state !== \"windowed\") return;\n\n const startMx = e.clientX;\n const startMy = e.clientY;\n const { x, y, width, height } = entry.windowed;\n setIsInteracting(true);\n // THE CURSOR LAW: the edge's resize cursor holds on <html> until release.\n const releaseCursor = holdDragCursor(RESIZE_CURSOR[edge]);\n\n const onMove = (ev: PointerEvent) => {\n const dx = ev.clientX - startMx;\n const dy = ev.clientY - startMy;\n let nx = x,\n ny = y,\n nw = width,\n nh = height;\n\n if (edge.includes(\"e\"))\n nw = Math.min(maxWidth, Math.max(minWidth, width + dx));\n if (edge.includes(\"s\"))\n nh = Math.min(maxHeight, Math.max(minHeight, height + dy));\n if (edge.includes(\"w\")) {\n nw = Math.min(maxWidth, Math.max(minWidth, width - dx));\n nx = x + (width - nw);\n }\n if (edge.includes(\"n\")) {\n nh = Math.min(maxHeight, Math.max(minHeight, height - dy));\n ny = y + (height - nh);\n }\n\n dispatch(\n updateWindowRect({\n id,\n rect: { x: nx, y: ny, width: nw, height: nh },\n }),\n );\n };\n\n const onUp = () => {\n setIsInteracting(false);\n releaseCursor();\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onUp);\n document.removeEventListener(\"pointercancel\", onUp);\n };\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onUp);\n document.addEventListener(\"pointercancel\", onUp);\n },\n [dispatch, id, entry, minWidth, minHeight, maxWidth, maxHeight],\n );\n\n // ── Window state transitions ───────────────────────────────────────────────\n const onFocus = useCallback(() => dispatch(focusWindow(id)), [dispatch, id]);\n const onRestore = useCallback(\n () => dispatch(restoreWindow(id)),\n [dispatch, id],\n );\n const onMaximize = useCallback(\n () => dispatch(maximizeWindow(id)),\n [dispatch, id],\n );\n const onMinimize = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n minimizeWindow({ id, viewportWidth: vw, viewportHeight: vh }),\n );\n }, [dispatch, id]);\n const onToggleMaximize = useCallback(() => {\n if (entry?.state === \"maximized\") dispatch(restoreWindow(id));\n else dispatch(maximizeWindow(id));\n }, [dispatch, id, entry]);\n\n // ── Stable fallback rect before first render ───────────────────────────────\n const rect: WindowRect = entry?.windowed ?? {\n x: 0,\n y: 0,\n width: opts.initialRect?.width ?? resolveSize(opts.width, DEFAULT_WIDTH),\n height:\n opts.initialRect?.height ?? resolveSize(opts.height, DEFAULT_HEIGHT),\n };\n\n return {\n id,\n windowState: entry?.state ?? \"windowed\",\n rect,\n zIndex: entry?.zIndex ?? 1000,\n onDragStart,\n onResizeStart,\n onFocus,\n onRestore,\n onMaximize,\n onMinimize,\n onToggleMaximize,\n isInteracting,\n };\n}\n","/**\n * popoutDragDetector — pure logic for \"is the user dragging this window\n * out of the viewport hard enough to mean they want to pop it out?\"\n *\n * **Threshold strategy:**\n * 1. Cursor must cross outside the viewport rect, AND\n * 2. Cursor must be at least `outsideThreshold` pixels past the edge\n * (a deliberate intent signal, not a stray mouse twitch), AND\n * 3. Cursor must DWELL outside for at least `dwellMs` milliseconds\n * (filters out drags that just transit through the edge en route\n * to a different on-screen position).\n *\n * The dwell timer resets every time the cursor crosses back inside the\n * viewport — a glance outside doesn't latch the candidate state.\n *\n * **Return shape:**\n * - `state` — the next `DragOutState` (replaces the previous on the next call)\n * - `shouldTrigger` — true when the dwell threshold has just been met. The\n * caller should fire popout on `pointerup`, NOT on this flag — the flag\n * is purely for animation/visual feedback (`isCandidate`).\n *\n * Pure function: no DOM access, no side effects. Easy to unit test.\n */\n\nexport interface DragOutConfig {\n /** Pixels past the viewport edge before considering the drag \"outside\". */\n outsideThreshold: number;\n /** Milliseconds the cursor must remain outside before becoming a candidate. */\n dwellMs: number;\n}\n\nexport interface DragOutState {\n /** Whether the dwell threshold is currently met (drives visual feedback). */\n isCandidate: boolean;\n /**\n * `performance.now()` timestamp when the cursor first crossed `outsideThreshold`.\n * `null` when the cursor is currently inside (or hasn't been outside yet).\n */\n outsideSinceMs: number | null;\n}\n\nexport interface DragOutInput {\n clientX: number;\n clientY: number;\n}\n\nexport interface DragOutEvalResult {\n state: DragOutState;\n /**\n * Edge-trigger: `true` ONLY on the first call where `isCandidate` flips\n * from `false` to `true`. Useful if a caller wants to dispatch a one-shot\n * action (e.g. haptic) on candidate entry.\n */\n shouldTrigger: boolean;\n}\n\nexport const DEFAULT_DRAG_OUT_CONFIG: DragOutConfig = {\n outsideThreshold: 80,\n dwellMs: 250,\n};\n\nexport const INITIAL_DRAG_OUT_STATE: DragOutState = {\n isCandidate: false,\n outsideSinceMs: null,\n};\n\n/**\n * Evaluate one pointermove event against the previous drag-out state.\n *\n * @param e Pointer event coords (clientX/clientY are viewport-relative)\n * @param prev Previous state from the last call (or `INITIAL_DRAG_OUT_STATE`)\n * @param cfg Threshold config\n * @param vpW Current `window.innerWidth`\n * @param vpH Current `window.innerHeight`\n * @param now Current `performance.now()` reading\n */\nexport function evaluateDragOut(\n e: DragOutInput,\n prev: DragOutState,\n cfg: DragOutConfig,\n vpW: number,\n vpH: number,\n now: number,\n): DragOutEvalResult {\n const { clientX, clientY } = e;\n const { outsideThreshold, dwellMs } = cfg;\n\n // Compute \"how far past the edge\" in each direction. Positive number = past\n // the edge by that many pixels.\n const pastLeft = -clientX; // clientX < 0 → past left edge\n const pastRight = clientX - vpW; // clientX > vpW → past right edge\n const pastTop = -clientY;\n const pastBottom = clientY - vpH;\n const maxPast = Math.max(pastLeft, pastRight, pastTop, pastBottom);\n\n const isOutsideEnough = maxPast >= outsideThreshold;\n\n if (!isOutsideEnough) {\n // Cursor is inside the viewport (or within the threshold band) — reset.\n if (prev.isCandidate || prev.outsideSinceMs !== null) {\n return {\n state: { isCandidate: false, outsideSinceMs: null },\n shouldTrigger: false,\n };\n }\n return { state: prev, shouldTrigger: false };\n }\n\n // Cursor is past the threshold. Two sub-cases:\n // a) we just crossed the threshold this frame → start the dwell timer\n // b) we've been outside for a while → check if dwell is met\n const outsideSince = prev.outsideSinceMs ?? now;\n const dwellMet = now - outsideSince >= dwellMs;\n const wasCandidate = prev.isCandidate;\n const nowCandidate = dwellMet;\n\n return {\n state: { isCandidate: nowCandidate, outsideSinceMs: outsideSince },\n shouldTrigger: !wasCandidate && nowCandidate,\n };\n}\n","/**\n * AUTO-OPENED WINDOW PLACEMENT (MKT-104, Arman 2026-10-15).\n *\n * Some windows open by themselves (debug mode's Workflow run + Watch AI windows) so a person can\n * watch progress live. They must NEVER cover the page's working column or take its clicks. This\n * is the ONE place that decides where such a window goes, for every window that is opened by the\n * system rather than by a person:\n *\n * 1. The caller marks the open with `markAutoOpened(overlayId, instanceId)` (see\n * `features/overlays/openers/openAutoOverlay.ts`); `WindowPanel` consumes the mark.\n * 2. The working column is measured from the page itself: the bounds of every visible control\n * (button, link, field) in the page body. Anything outside that box takes no clicks anyway.\n * 3. The window is docked in the widest free side gutter, shrunk to fit, stacked under any other\n * auto-opened window already there. No gutter wide enough (a narrow screen, a page that\n * fills the width) → it is not opened (`autoOpenHasRoom`), or, when the page grew under it,\n * it closes itself. A person's own press of Watch AI / Workflow run always opens it.\n *\n * Pure module: no Redux import (WindowPanel stays a leaf).\n */\n\nimport type { WindowRect } from \"@ai-matrx/summon\";\n\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\nconst GAP = 12;\nconst SIBLING_GAP = 8;\n/** Narrowest window worth docking; anything tighter goes to the tray. */\nexport const AUTO_OPEN_MIN_WIDTH = 280;\n\nfunction marks(): Set<string> {\n return globalSlot<Set<string>>(\"ai-matrx.summon.window.autoOpenedMarks\", () => new Set<string>());\n}\n\nconst markKey = (overlayId: string, instanceId: string) =>\n `${overlayId}::${instanceId}`;\n\n/** Call BEFORE dispatching the open of a window the system (not a person) opens. */\nexport function markAutoOpened(overlayId: string, instanceId: string): void {\n marks().add(markKey(overlayId, instanceId));\n}\n\n/** Peek (does not consume, so StrictMode's double render sees the same answer). */\nexport function isAutoOpened(overlayId: string, instanceId: string): boolean {\n return marks().has(markKey(overlayId, instanceId));\n}\n\n/** Forget the mark once the window is gone: a person's later reopen places normally. */\nexport function clearAutoOpened(overlayId: string, instanceId: string): void {\n marks().delete(markKey(overlayId, instanceId));\n}\n\n/** Width the shell's canvas column holds on the right (`--shell-canvas-w`): no window may dock under it. */\nfunction canvasWidth(): number {\n if (typeof document === \"undefined\") return 0;\n const raw = getComputedStyle(document.documentElement).getPropertyValue(\"--shell-canvas-w\");\n const px = Number.parseFloat(raw);\n return Number.isFinite(px) && px > 0 ? px : 0;\n}\n\nconst CONTROL_SELECTOR =\n 'button, a[href], input, textarea, select, [role=\"button\"], [role=\"tab\"], [data-clickable]';\n\n/** Left/right edge of everything on the page body that takes a click. */\nexport function measureWorkingColumn(): { left: number; right: number } | null {\n if (typeof document === \"undefined\") return null;\n const root =\n document.querySelector<HTMLElement>(\"[data-matrx-page-scroll]\") ??\n document.querySelector<HTMLElement>(\"main\") ??\n document.querySelector<HTMLElement>(\".shell-main\");\n if (!root) return null;\n const rootRect = root.getBoundingClientRect();\n let left = Infinity;\n let right = -Infinity;\n const nodes = root.querySelectorAll<HTMLElement>(CONTROL_SELECTOR);\n const limit = Math.min(nodes.length, 600);\n for (let i = 0; i < limit; i += 1) {\n const el = nodes[i];\n if (!el) continue;\n // Skip controls inside floating windows themselves.\n if (el.closest(\"[data-window-panel], [data-matrx-window]\")) continue;\n const r = el.getBoundingClientRect();\n if (r.width < 8 || r.height < 8) continue;\n if (r.bottom < rootRect.top || r.top > rootRect.bottom) continue;\n if (r.right < 0 || r.left > window.innerWidth) continue;\n left = Math.min(left, r.left);\n right = Math.max(right, r.right);\n }\n return Number.isFinite(left) ? { left, right } : null;\n}\n\n/** Fired (detail `{ overlayId, instanceId }`) when a docked auto-opened window closes itself for lack of room. */\nexport const AUTO_OPEN_NO_ROOM_EVENT = \"matrx:auto-open-no-room\";\n\n/**\n * True when a gutter beside the page's working column can hold an auto-opened window right now.\n * Callers that open windows by themselves check this FIRST: with no room the window is not opened\n * (a parked tray tile sits over the page's own bottom-right controls — MKT-104).\n */\nexport function autoOpenHasRoom(): boolean {\n if (typeof window === \"undefined\") return false;\n const vw = window.innerWidth;\n if (vw < 768) return false;\n const column = measureWorkingColumn();\n if (!column) return true;\n const leftRoot =\n document.querySelector<HTMLElement>(\"main\")?.getBoundingClientRect().left ?? 0;\n const free = Math.max(vw - canvasWidth() - column.right - GAP * 2, column.left - leftRoot - GAP * 2);\n return free >= AUTO_OPEN_MIN_WIDTH;\n}\n\nexport interface AutoOpenPlacement {\n rect: WindowRect;\n /** True when no gutter fits: open parked in the tray instead of over the page. */\n minimized: boolean;\n}\n\n/**\n * @param siblings rects of auto-opened windows already docked (to stack under them)\n */\nexport function resolveAutoOpenPlacement(args: {\n width: number;\n height: number;\n minWidth: number;\n minHeight: number;\n top: number;\n viewport: { vw: number; vh: number };\n siblings: WindowRect[];\n}): AutoOpenPlacement {\n const { vh } = args.viewport;\n // The canvas column owns the right edge: windows dock against ITS left edge, never under it.\n const vw = args.viewport.vw - canvasWidth();\n const column = measureWorkingColumn();\n const rightFree = column ? vw - column.right - GAP * 2 : vw;\n const leftRoot =\n typeof document !== \"undefined\"\n ? (document.querySelector<HTMLElement>(\"main\")?.getBoundingClientRect()\n .left ?? 0)\n : 0;\n const leftFree = column ? column.left - leftRoot - GAP * 2 : 0;\n const side = rightFree >= leftFree ? \"right\" : \"left\";\n const free = Math.max(rightFree, leftFree);\n const need = Math.min(args.minWidth, AUTO_OPEN_MIN_WIDTH);\n const parked: AutoOpenPlacement = {\n rect: {\n x: Math.max(GAP, vw - args.width - GAP),\n y: args.top,\n width: args.width,\n height: args.height,\n },\n minimized: true,\n };\n if (free < need) return parked;\n\n const width = Math.max(need, Math.min(args.width, Math.floor(free)));\n const x =\n side === \"right\"\n ? vw - width - GAP\n : Math.max(GAP, Math.round(leftRoot + GAP));\n // Stack below the lowest sibling in this gutter.\n const inGutter = args.siblings.filter(\n (s) => s.x + s.width > x && s.x < x + width,\n );\n const y = inGutter.length\n ? Math.max(...inGutter.map((s) => s.y + s.height)) + SIBLING_GAP\n : args.top;\n const room = vh - y - GAP;\n if (room < args.minHeight) return parked;\n const share = inGutter.length ? room : Math.floor((vh - args.top - GAP) / 2);\n const height = Math.min(room, Math.max(args.minHeight, Math.min(args.height, share)));\n return { rect: { x, y, width, height }, minimized: false };\n}\n","import { useSyncExternalStore } from \"react\";\n\nconst subscribe = (): (() => void) => () => {};\n\n/** False during server render and hydration, true on the client afterwards. */\nexport function useIsClient(): boolean {\n return useSyncExternalStore(subscribe, () => true, () => false);\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { DebugPort } from \"@ai-matrx/summon\";\n\nconst noSubscribe = (): (() => void) => () => {};\n\n/** The host's debug flag (ports.debug), live when the port can be subscribed to. */\nexport function useDebugFlag(debug: DebugPort): boolean {\n return useSyncExternalStore(\n debug.subscribe ? (listener) => debug.subscribe?.(listener) ?? (() => {}) : noSubscribe,\n () => debug.enabled(),\n () => false,\n );\n}\n","/**\n * Resolve the URL token a mounted window publishes.\n *\n * Registry metadata is the shared contract between the URL hydrator and the\n * mounted window. Page-local WindowPanels without registry metadata may still\n * provide an explicit key.\n */\nexport function resolveWindowUrlSyncKey(\n registryKey?: string,\n explicitKey?: string,\n): string | undefined {\n return registryKey ?? explicitKey;\n}\n","/**\n * Copy only allowlisted keys of a window's open/collected data into plain JSON (the preservation\n * allowlist, `window.preservation.dataKeys`). Functions, symbols, undefined and circular references\n * are dropped; BigInt becomes text; non-finite numbers become null; Dates become ISO text; class\n * instances are dropped. Same semantics as matrx-frontend's `sanitizeWindowSessionData`.\n */\nconst DROPPED = Symbol(\"dropped-window-value\");\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function sanitizeWindowData(value: unknown, allowedKeys: readonly string[]): Record<string, unknown> {\n if (!isRecord(value) || allowedKeys.length === 0) return {};\n const ancestors = new WeakSet<object>();\n const copy = (item: unknown): unknown => {\n if (item === undefined || typeof item === \"function\" || typeof item === \"symbol\") return DROPPED;\n if (typeof item === \"bigint\") return item.toString();\n if (typeof item === \"number\" && !Number.isFinite(item)) return null;\n if (item === null || typeof item !== \"object\") return item;\n if (item instanceof Date) return item.toJSON();\n if (ancestors.has(item)) return DROPPED;\n ancestors.add(item);\n let result: unknown;\n if (Array.isArray(item)) {\n result = item.map((child) => {\n const copied = copy(child);\n return copied === DROPPED ? null : copied;\n });\n } else if (Object.getPrototypeOf(item) === Object.prototype || Object.getPrototypeOf(item) === null) {\n result = Object.fromEntries(\n Object.entries(item).flatMap(([key, child]) => {\n const copied = copy(child);\n return copied === DROPPED ? [] : [[key, copied]];\n }),\n );\n } else {\n result = DROPPED;\n }\n ancestors.delete(item);\n return result;\n };\n try {\n const allowed = new Set(allowedKeys);\n const selected = Object.fromEntries(Object.entries(value).filter(([key]) => allowed.has(key)));\n ancestors.add(value);\n const copied = copy(selected);\n const parsed: unknown = JSON.parse(JSON.stringify(copied === DROPPED ? {} : copied) || \"{}\");\n return isRecord(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n","\"use client\";\n\n/**\n * MobileDrawerSurface — mobile presentation for a window with\n * `mobilePresentation: \"drawer\"`.\n *\n * Replaces WindowPanel's usual fullscreen mobile branch with a bottom-sheet\n * drawer (vaul) that:\n * - Opens to ~80% viewport height, user-draggable to resize.\n * - Hides drag/resize handles entirely (vaul owns interaction).\n * - Renders the sidebar content inside a nested drawer when present so\n * there's no 50/50 squeeze on narrow screens.\n * - Preserves the footer zone at the bottom of the drawer.\n *\n * Called only when `useIsMobile()` is true; on desktop the normal\n * WindowPanel shell renders instead.\n */\nimport { useState, type ReactNode } from \"react\";\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerTitle,\n} from \"@ai-matrx/design-system\";\nimport { Button } from \"@ai-matrx/design-system\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { PanelLeftIcon as SidebarIcon, XIcon as X } from \"../icons\";\nimport {\n MobileWindowActionsRow,\n MobileWindowTitleRow,\n mobileWindowTitleClass,\n} from \"../chrome/MobileTitleRow\";\n\ninterface MobileDrawerSurfaceProps {\n title: ReactNode;\n children: ReactNode;\n onClose: () => void;\n sidebar?: ReactNode | undefined;\n footer?: ReactNode | undefined;\n /** Open state — mirrors the parent's overlay-isOpen flag. */\n isOpen: boolean;\n actionsLeft?: ReactNode | undefined;\n actionsRight?: ReactNode | undefined;\n /** Optional className applied to the body scroll container. */\n bodyClassName?: string | undefined;\n /** Marks the root `data-surface-layer` (see WindowPanel `surfaceLayer`). */\n surfaceLayer?: string | undefined;\n /**\n * Size the sheet to its content (capped at 85dvh) instead of a fixed 85dvh:\n * a short form no longer sits on a band of empty sheet.\n */\n sizeToContent?: boolean | undefined;\n /** No title-row ✕: the drag handle and the window's own Cancel dismiss it. */\n hideClose?: boolean | undefined;\n /**\n * Whether the sidebar should collapse into a nested drawer when the user\n * taps the sidebar toggle. When \"inline\", the sidebar pushes the body\n * instead. Default: \"drawer\".\n */\n sidebarAs?: \"drawer\" | \"inline\" | undefined;\n}\n\nexport default function MobileDrawerSurface({\n title,\n children,\n onClose,\n sidebar,\n footer,\n isOpen,\n actionsLeft,\n actionsRight,\n bodyClassName,\n surfaceLayer,\n sizeToContent = false,\n hideClose = false,\n sidebarAs = \"drawer\",\n}: MobileDrawerSurfaceProps) {\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const hasSidebar = !!sidebar;\n\n return (\n <Drawer\n open={isOpen}\n onOpenChange={(next) => {\n if (!next) onClose();\n }}\n >\n <DrawerContent\n data-surface-layer={surfaceLayer}\n className={cn(\n \"max-h-[85dvh] px-0 pb-safe flex flex-col\",\n sizeToContent ? \"h-auto\" : \"h-[85dvh]\",\n )}\n >\n {/* Accessible title — rendered visually as our header */}\n {/* The handle row above is a 44px drag area with the bar at its\n centre; the header tucks into its lower half (no second padded\n band — the title sat 40px under the handle). */}\n <div className=\"-mt-3 flex flex-col px-3 border-b border-border/50 shrink-0\">\n {/* Row 1 is the title's alone and wraps to two lines before it\n truncates; actions + the sidebar toggle sit on row 2\n (MobileTitleRow.tsx). */}\n <MobileWindowTitleRow\n className=\"py-0\"\n trailing={\n hideClose ? null : (\n <DrawerClose asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0\"\n aria-label=\"Close\"\n >\n <X className=\"w-4 h-4\" />\n </Button>\n </DrawerClose>\n )\n }\n >\n <DrawerTitle\n data-window-mobile-title=\"\"\n className={mobileWindowTitleClass(title)}\n >\n {title}\n </DrawerTitle>\n </MobileWindowTitleRow>\n <MobileWindowActionsRow\n leading={\n actionsLeft ? (\n <div className=\"flex items-center gap-1 shrink-0\">{actionsLeft}</div>\n ) : null\n }\n actions={\n actionsRight || hasSidebar ? (\n <>\n {actionsRight}\n {hasSidebar && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n aria-label={sidebarOpen ? \"Close sidebar\" : \"Open sidebar\"}\n onClick={() => setSidebarOpen((v) => !v)}\n >\n <SidebarIcon className=\"w-4 h-4\" />\n </Button>\n )}\n </>\n ) : null\n }\n />\n </div>\n\n {/* Screen-reader description; invisible visually */}\n <DrawerDescription className=\"sr-only\">\n {typeof title === \"string\" ? title : \"Mobile window\"}\n </DrawerDescription>\n\n {/* Body + optional inline sidebar. If sidebarAs === \"drawer\", the\n sidebar opens in a nested Drawer instead. */}\n <div className=\"flex-1 flex min-h-0 overflow-hidden\">\n {hasSidebar && sidebarAs === \"inline\" && sidebarOpen && (\n <div className=\"w-2/5 min-w-[160px] border-r border-border/50 overflow-y-auto\">\n {sidebar}\n </div>\n )}\n <div\n className={cn(\n \"flex-1 min-h-0 overflow-auto\",\n bodyClassName,\n )}\n >\n {children}\n </div>\n </div>\n\n {footer && (\n <div className=\"border-t border-border/50 shrink-0\">{footer}</div>\n )}\n </DrawerContent>\n\n {/* Nested sidebar drawer (sidebarAs === \"drawer\") */}\n {hasSidebar && sidebarAs === \"drawer\" && (\n <Drawer\n open={sidebarOpen}\n onOpenChange={setSidebarOpen}\n direction=\"right\"\n >\n <DrawerContent className=\"h-[85dvh] max-h-[85dvh] w-[85vw] max-w-[420px] ml-auto flex flex-col\">\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border/50 shrink-0\">\n <DrawerTitle className=\"flex-1 text-sm font-medium\">\n Menu\n </DrawerTitle>\n <DrawerClose asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n aria-label=\"Close sidebar\"\n >\n <X className=\"w-4 h-4\" />\n </Button>\n </DrawerClose>\n </div>\n <DrawerDescription className=\"sr-only\">\n Sidebar menu\n </DrawerDescription>\n <div className=\"flex-1 min-h-0 overflow-auto\">{sidebar}</div>\n </DrawerContent>\n </Drawer>\n )}\n </Drawer>\n );\n}\n","\"use client\";\n\n/**\n * THE PHONE TITLE ROW — the one title slot every mobile window chrome uses\n * (fullscreen header, bottom-sheet drawer, utility card).\n *\n * On a phone the title is the only thing that says WHICH record this window\n * is (\"Run History — Recipe Scaler\"), so it gets the whole row and wraps to\n * two lines before it truncates. Window actions and the Sidebar/Content toggle\n * never share its row: they sit on `MobileWindowActionsRow` below it, which\n * renders nothing when there is nothing to put there.\n *\n * Guard: `__tests__/a-phone-window-title-gets-the-whole-row.test.tsx`.\n */\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\n/** Two lines, then an ellipsis — never a one-line `truncate`. */\nexport const MOBILE_WINDOW_TITLE_TEXT =\n \"line-clamp-2 break-words text-sm font-medium leading-snug text-foreground\";\n\nfunction isTextTitle(title: ReactNode): title is string | number {\n return typeof title === \"string\" || typeof title === \"number\";\n}\n\n/**\n * The title slot's classes. A text title wraps to two lines; a RICH title (a\n * control, e.g. the Chat window's agent picker) keeps its own layout. Exported\n * for a host whose title element is fixed (the drawer's accessible\n * `DrawerTitle`) — put these classes and `data-window-mobile-title` on it.\n */\nexport function mobileWindowTitleClass(title: ReactNode): string {\n return isTextTitle(title)\n ? cn(\"min-w-0 flex-1\", MOBILE_WINDOW_TITLE_TEXT)\n : \"flex min-w-0 flex-1 items-center overflow-hidden text-sm font-medium\";\n}\n\n/** The title slot. */\nexport function MobileWindowTitle({\n title,\n className,\n}: {\n title: ReactNode;\n className?: string | undefined;\n}) {\n if (title == null || title === \"\") return <div className={cn(\"min-w-0 flex-1\", className)} />;\n return (\n <div data-window-mobile-title=\"\" className={cn(mobileWindowTitleClass(title), className)}>\n {title}\n </div>\n );\n}\n\n/** Row 1: whatever leads (close / minimize) and the title, nothing else. */\nexport function MobileWindowTitleRow({\n leading,\n trailing,\n children,\n className,\n}: {\n leading?: ReactNode | undefined;\n /** A close ✕ only — never window actions. */\n trailing?: ReactNode | undefined;\n children: ReactNode;\n className?: string | undefined;\n}) {\n return (\n <div\n data-window-mobile-title-row=\"\"\n className={cn(\"flex min-h-11 items-center gap-1.5 py-1\", className)}\n >\n {leading}\n {children}\n {trailing}\n </div>\n );\n}\n\n/** Row 2: pane toggle + window actions. Absent when both are empty. */\nexport function MobileWindowActionsRow({\n leading,\n actions,\n className,\n}: {\n leading?: ReactNode | undefined;\n actions?: ReactNode | undefined;\n className?: string | undefined;\n}) {\n if (!leading && !actions) return null;\n return (\n <div\n data-window-mobile-actions-row=\"\"\n className={cn(\"flex min-h-10 items-center gap-1.5 pb-1\", className)}\n >\n {leading}\n {actions ? <div className=\"ml-auto flex items-center gap-1\">{actions}</div> : null}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * MobileCardSurface — mobile presentation for a window with\n * `mobilePresentation: \"card\"`.\n *\n * Small, z-stacked floating card anchored to the bottom-right of the\n * viewport. Used for utility/debug windows (Stream Debug, State Analyzer,\n * Message Analysis, JSON Truncator) that only need a peek view on mobile.\n *\n * Differences from MobileDrawerSurface:\n * - Non-modal: the underlying content remains interactive.\n * - Compact default size (w-[92vw] max-w-[420px], h-[60dvh]).\n * - Dismiss on outside tap, Escape, or X button.\n * - No sidebar support (these windows don't need one).\n */\nimport { useEffect, useRef, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { FloatingLayer, useFloatingLayerZIndex } from \"@ai-matrx/design-system\";\nimport { Button } from \"@ai-matrx/design-system\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { XIcon as X } from \"../icons\";\nimport {\n MobileWindowActionsRow,\n MobileWindowTitle,\n MobileWindowTitleRow,\n} from \"../chrome/MobileTitleRow\";\n\ninterface MobileCardSurfaceProps {\n title: ReactNode;\n children: ReactNode;\n onClose: () => void;\n footer?: ReactNode | undefined;\n isOpen: boolean;\n actionsRight?: ReactNode | undefined;\n bodyClassName?: string | undefined;\n /** Marks the root `data-surface-layer` (see WindowPanel `surfaceLayer`). */\n surfaceLayer?: string | undefined;\n /** Override the default max-height (60dvh). Accepts any CSS length. */\n maxHeight?: string | undefined;\n}\n\nexport default function MobileCardSurface({\n title,\n children,\n onClose,\n footer,\n isOpen,\n actionsRight,\n bodyClassName,\n surfaceLayer,\n maxHeight = \"60dvh\",\n}: MobileCardSurfaceProps) {\n const cardRef = useRef<HTMLDivElement>(null);\n\n // Escape to close\n useEffect(() => {\n if (!isOpen) return undefined;\n const onKey = (e: KeyboardEvent) => {\n // One Escape closes ONE layer (a menu inside already took it).\n if (e.key === \"Escape\" && !e.defaultPrevented) onClose();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [isOpen, onClose]);\n\n // Opened from inside a blocking sheet (every Dialog is one on a phone), the\n // card is lifted above its scrim (design-system floating-layer).\n const zIndex = useFloatingLayerZIndex(9999);\n\n if (!isOpen) return null;\n if (typeof document === \"undefined\") return null;\n\n return createPortal(\n <FloatingLayer>\n <div\n ref={cardRef}\n data-surface-layer={surfaceLayer}\n role=\"dialog\"\n aria-modal=\"false\"\n className={cn(\n \"fixed right-3 bottom-3 left-3 sm:left-auto sm:right-3\",\n \"w-auto sm:w-[92vw] sm:max-w-[420px]\",\n \"flex flex-col\",\n \"rounded-xl overflow-hidden\",\n \"bg-card/97 backdrop-blur-xl border border-border/60 shadow-2xl\",\n // Themes can override via --window-surface-* tokens in globals.css\n \"animate-[card-enter_var(--window-surface-enter-duration,220ms)_var(--window-surface-easing,ease-out)]\",\n )}\n style={{ maxHeight, zIndex, paddingBottom: \"env(safe-area-inset-bottom)\" }}\n >\n {/* Header — the title owns row 1 (two lines before it truncates);\n actions sit on their own row below (MobileTitleRow.tsx). */}\n <div className=\"flex flex-col pl-3 pr-1 border-b border-border/50 shrink-0\">\n <MobileWindowTitleRow\n trailing={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-11 w-11 shrink-0\"\n aria-label=\"Close\"\n onClick={onClose}\n >\n <X className=\"w-3.5 h-3.5\" />\n </Button>\n }\n >\n <MobileWindowTitle title={title} />\n </MobileWindowTitleRow>\n <MobileWindowActionsRow actions={actionsRight} />\n </div>\n\n {/* Body */}\n <div className={cn(\"flex-1 min-h-0 overflow-auto\", bodyClassName)}>\n {children}\n </div>\n\n {footer && (\n <div className=\"border-t border-border/50 shrink-0\">{footer}</div>\n )}\n </div>\n </FloatingLayer>,\n document.body,\n );\n}\n","\"use client\";\n\n/**\n * DebugStrip — dev-only geometry + viewport readout rendered at the top of\n * the WindowPanel body when `isDebugMode` is on. Extracted from\n * WindowPanel.tsx Phase 6 — purely presentational with its own resize\n * subscription; no coupling to the parent shell.\n */\nimport { useEffect, useState } from \"react\";\n\ninterface DebugStripProps {\n rect: { x: number; y: number; width: number; height: number };\n zIndex: number;\n}\n\nexport function DebugStrip({ rect, zIndex }: DebugStripProps) {\n const [vp, setVp] = useState(() =>\n typeof window === \"undefined\"\n ? { vw: 0, vh: 0, sw: 0, sh: 0, dpr: 1 }\n : {\n vw: window.innerWidth,\n vh: window.innerHeight,\n sw: window.screen.width,\n sh: window.screen.height,\n dpr: window.devicePixelRatio ?? 1,\n },\n );\n\n useEffect(() => {\n const update = () =>\n setVp({\n vw: window.innerWidth,\n vh: window.innerHeight,\n sw: window.screen.width,\n sh: window.screen.height,\n dpr: window.devicePixelRatio ?? 1,\n });\n window.addEventListener(\"resize\", update);\n return () => window.removeEventListener(\"resize\", update);\n }, []);\n\n const windowEntries: [string, number][] = [\n [\"x\", rect.x],\n [\"y\", rect.y],\n [\"w\", rect.width],\n [\"h\", rect.height],\n [\"z\", zIndex],\n ];\n\n const viewportEntries: [string, number | string][] = [\n [\"vw\", vp.vw],\n [\"vh\", vp.vh],\n [\"sw\", vp.sw],\n [\"sh\", vp.sh],\n [\"dpr\", vp.dpr],\n ];\n\n return (\n <div className=\"flex flex-col gap-0.5 px-3 py-1.5 border-b border-warning/20 bg-warning/5 shrink-0 font-mono text-[10px]\">\n {/* Row 1 — window position/size */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n <span className=\"text-warning uppercase tracking-wide text-[9px]\">\n win\n </span>\n {windowEntries.map(([label, val]) => (\n <span\n key={label}\n className=\"inline-flex items-center gap-0.5 leading-none\"\n >\n <span className=\"text-warning\">{label}:</span>\n <span className=\"text-warning font-bold tabular-nums\">\n {Math.round(val as number)}\n </span>\n </span>\n ))}\n </div>\n {/* Row 2 — viewport / screen */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n <span className=\"text-info uppercase tracking-wide text-[9px]\">\n vp\n </span>\n {viewportEntries.map(([label, val]) => (\n <span\n key={label}\n className=\"inline-flex items-center gap-0.5 leading-none\"\n >\n <span className=\"text-info\">{label}:</span>\n <span className=\"text-info font-bold tabular-nums\">\n {typeof val === \"number\" && !Number.isInteger(val)\n ? val.toFixed(2)\n : Math.round(val as number)}\n </span>\n </span>\n ))}\n </div>\n </div>\n );\n}\n","import { cn } from \"@ai-matrx/design-system/cn\";\n\n/** Pointer on interactive descendants in header/footer action slots (beats header grab). */\nexport const WINDOW_CHROME_INTERACTIVE =\n \"[&_button:not(:disabled)]:cursor-pointer [&_a]:cursor-pointer [&_[role=button]:not([aria-disabled=true])]:cursor-pointer [&_summary]:cursor-pointer [&_label:has(input,[role=checkbox],[role=radio])]:cursor-pointer\";\n\nexport const WINDOW_CHROME_ACTIONS = cn(\n \"flex items-center gap-0.5 shrink-0 text-foreground/80 [&_svg]:text-foreground/80\",\n WINDOW_CHROME_INTERACTIVE,\n);\n","\"use client\";\n\n/**\n * MobileWindowHeader — chrome for the fullscreen mobile takeover branch of\n * WindowPanel. Row 1: close/minimize + the title, which owns the row and wraps\n * to two lines. Row 2 (only when there is something to show): the\n * Sidebar/Content toggle and the window's actions.\n *\n * Extracted from WindowPanel.tsx Phase 6 — purely presentational.\n */\nimport type { ReactNode } from \"react\";\nimport { MinusIcon as Minus, XIcon as X } from \"../icons\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { WINDOW_CHROME_ACTIONS } from \"./chromeClasses\";\nimport {\n MobileWindowActionsRow,\n MobileWindowTitle,\n MobileWindowTitleRow,\n} from \"./MobileTitleRow\";\nimport { SegmentedControl } from \"@ai-matrx/design-system/controls\";\n\ninterface MobileWindowHeaderProps {\n title?: ReactNode | undefined;\n actionsRight?: ReactNode | undefined;\n /** Omitted until a mobile minimized tray surface is mounted. */\n onMinimize?: (() => void) | undefined;\n onClose?: (() => void) | undefined;\n hasSidebar: boolean;\n activePaneMobile: \"main\" | \"sidebar\";\n onSetActivePane: (pane: \"main\" | \"sidebar\") => void;\n}\n\nexport function MobileWindowHeader({\n title,\n actionsRight,\n onMinimize,\n onClose,\n hasSidebar,\n activePaneMobile,\n onSetActivePane,\n}: MobileWindowHeaderProps) {\n // Row 1 is the title's alone (see MobileTitleRow.tsx). The title used to be\n // the Sidebar/Content toggle's own label (`max-w-[120px] truncate`) beside\n // the actions, so \"Run History — Recipe Scaler\" read \"Run History — …\". A\n // RICH title (the Chat window's agent picker) is a control and keeps its own\n // layout in the same slot (verifier round 1, F-A1).\n const trafficLights =\n onClose || onMinimize ? (\n <div className=\"flex items-center gap-1.5 shrink-0\">\n {onClose && (\n <button\n type=\"button\"\n className=\"flex h-11 w-11 shrink-0 cursor-pointer items-center justify-center\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full matrx-window-light-close\">\n <X className=\"h-2.5 w-2.5 matrx-window-light-glyph\" />\n </span>\n </button>\n )}\n {onMinimize && (\n <button\n type=\"button\"\n className=\"flex h-11 w-11 shrink-0 cursor-pointer items-center justify-center\"\n onClick={onMinimize}\n aria-label=\"Minimize\"\n >\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full matrx-window-light-minimize\">\n <Minus\n className=\"h-2.5 w-2.5 matrx-window-light-glyph\"\n\n />\n </span>\n </button>\n )}\n </div>\n ) : null;\n\n const paneToggle = hasSidebar ? (\n <SegmentedControl aria-label=\"Pane\" value={activePaneMobile} onValueChange={onSetActivePane} data={[{ value: \"sidebar\", label: \"Sidebar\" }, { value: \"main\", label: \"Content\" }]} />\n ) : null;\n\n return (\n <div className=\"flex shrink-0 flex-col border-b border-border/50 bg-muted/40 px-2 select-none\">\n <MobileWindowTitleRow leading={trafficLights}>\n <MobileWindowTitle title={title} className=\"pr-1\" />\n </MobileWindowTitleRow>\n <MobileWindowActionsRow\n leading={paneToggle}\n actions={\n actionsRight ? (\n <div className={WINDOW_CHROME_ACTIONS}>{actionsRight}</div>\n ) : null\n }\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { TriangleAlertIcon as AlertTriangle, XIcon as X } from \"../icons\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\ninterface DeprecationBannerProps {\n replacedBy?: string | undefined;\n note?: string | undefined;\n className?: string | undefined;\n}\n\nexport function DeprecationBanner({\n replacedBy,\n note,\n className,\n}: DeprecationBannerProps) {\n const [dismissed, setDismissed] = useState(false);\n if (dismissed) return null;\n\n const message =\n note ??\n (replacedBy\n ? `Deprecated — moved to \"${replacedBy}\". This window will be removed soon.`\n : \"Deprecated — this window will be removed soon.\");\n\n return (\n <div\n className={cn(\n \"shrink-0 flex items-start gap-2 px-2 py-1 border-b border-destructive/40 bg-destructive/10 text-destructive-ink text-[11px] leading-tight\",\n className,\n )}\n >\n <AlertTriangle className=\"w-3.5 h-3.5 mt-[1px] shrink-0\" />\n <span className=\"flex-1 break-words\">{message}</span>\n <button\n type=\"button\"\n aria-label=\"Dismiss deprecation notice\"\n className=\"shrink-0 rounded hover:bg-destructive/20 p-0.5 transition-colors\"\n onClick={() => setDismissed(true)}\n >\n <X className=\"w-3 h-3\" />\n </button>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * PopoutTopBar — slim chrome strip for window content that has been popped\n * out into a Document Picture-in-Picture (or `window.open`) browser window.\n *\n * The OS / browser frame already provides close + minimize at the window\n * manager level, so this strip omits traffic lights entirely. Its only job\n * is to show the title, optional actions, and a \"Dock back\" button that\n * returns the content to the parent viewport.\n *\n * Extracted as a sibling of `MobileHeader.tsx` — purely presentational, no\n * Redux or hook dependencies. The dock + close handlers are passed in by\n * `WindowPanel` so the same component covers both the docked and popped-out\n * render paths cleanly.\n */\nimport type { ReactNode } from \"react\";\nimport { ArrowLeftToLineIcon as ArrowLeftToLine } from \"../icons\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { WINDOW_CHROME_ACTIONS } from \"./chromeClasses\";\n\nexport interface PopoutTopBarProps {\n /** Title displayed centered in the bar. Accepts string or arbitrary node. */\n title?: ReactNode | undefined;\n /** Optional content slotted on the left, before the title. */\n actionsLeft?: ReactNode | undefined;\n /** Optional content slotted on the right, before the dock button. */\n actionsRight?: ReactNode | undefined;\n /**\n * Click handler for the dock button. Should dispatch `dockWindow({ id, viewportWidth, viewportHeight })`\n * so the window returns centered in the parent viewport.\n * The browser popout window itself is closed by the `usePopoutWindow`\n * lifecycle hook in response to the Redux state change.\n */\n onDock: () => void;\n}\n\n/**\n * Visual height: 32px. Background mirrors the docked header (`bg-muted/40`)\n * so themes carry over via the cloned stylesheet without any popout-specific\n * styles.\n */\nexport function PopoutTopBar({\n title,\n actionsLeft,\n actionsRight,\n onDock,\n}: PopoutTopBarProps) {\n return (\n <div\n className={cn(\n \"flex items-center gap-1.5 px-2 py-1 min-h-[32px] shrink-0\",\n \"border-b border-border/50 bg-muted/40 select-none\",\n )}\n >\n {/* Left actions */}\n {actionsLeft && (\n <div className={WINDOW_CHROME_ACTIONS}>{actionsLeft}</div>\n )}\n\n {/* Centered title */}\n <div className=\"flex-1 flex items-center justify-center min-w-0\">\n <span className=\"text-xs font-medium text-foreground/80 truncate\">\n {title ?? \"\"}\n </span>\n </div>\n\n {/* Right actions */}\n {actionsRight && (\n <div className={WINDOW_CHROME_ACTIONS}>{actionsRight}</div>\n )}\n\n {/* Dock back button — always last, visually anchors the right side */}\n <button\n type=\"button\"\n className={cn(\n \"ml-1 p-1 rounded hover:bg-accent/60 transition-colors shrink-0 cursor-pointer\",\n \"text-foreground/60 hover:text-foreground\",\n )}\n onClick={onDock}\n title=\"Dock window\"\n aria-label=\"Dock window back to parent\"\n >\n <ArrowLeftToLine className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n );\n}\n","/**\n * Feature detection for the window-panels pop-out system.\n *\n * Three capability tiers, in order of preference:\n *\n * 1. **`\"pip\"`** — Document Picture-in-Picture API (Chromium-based browsers,\n * Chrome 116+, Edge 116+, Opera). Frameless, always-on-top floating window.\n * Detected by presence of `window.documentPictureInPicture.requestWindow`.\n *\n * 2. **`\"popup\"`** — `window.open()` fallback (Safari, Firefox, anything else).\n * Universal browser support. Shows browser chrome (URL bar, tabs).\n * Acceptable degradation: user still gets a separate window for multi-\n * monitor workflows.\n *\n * 3. **`\"none\"`** — Embedded WebViews or other contexts where neither API is\n * available (rare). The \"Pop out\" affordance should be hidden entirely.\n *\n * The detection is intentionally simple and synchronous — it runs once on\n * the client at component mount time and the result is stable for the\n * lifetime of the page.\n *\n * SSR safety: every code path branches on `typeof window` first.\n */\n\nexport type PopoutCapability = \"pip\" | \"popup\" | \"none\";\n\n/**\n * Type augmentation for the Document Picture-in-Picture API.\n * The official spec lives at https://wicg.github.io/document-picture-in-picture/.\n *\n * We declare it locally rather than relying on `lib.dom.d.ts` because\n * TypeScript's built-in DOM types are inconsistent across `@types/node`\n * versions and the API is still in WICG (not yet WHATWG) status.\n */\nexport interface DocumentPictureInPictureRequestOptions {\n width?: number;\n height?: number;\n /**\n * If `true`, suppresses the \"back to tab\" button in the PiP window's\n * chrome. Default `false` — we want the user to be able to dock back.\n */\n disallowReturnToOpener?: boolean;\n}\n\nexport interface DocumentPictureInPicture {\n requestWindow(\n options?: DocumentPictureInPictureRequestOptions,\n ): Promise<Window>;\n /** The currently open PiP window, or `null` if none. */\n readonly window: Window | null;\n}\n\n/**\n * Window-augmenting interface so callers can do\n * `(window as WindowWithPictureInPicture).documentPictureInPicture`\n * without TypeScript errors.\n */\nexport interface WindowWithDocumentPictureInPicture extends Window {\n documentPictureInPicture?: DocumentPictureInPicture;\n}\n\n/**\n * Returns the highest-fidelity popout mechanism available in the current\n * browser. Safe to call during SSR (returns `\"none\"`).\n */\nexport function detectPopoutCapability(): PopoutCapability {\n if (typeof window === \"undefined\") return \"none\";\n\n const w = window as WindowWithDocumentPictureInPicture;\n if (\n w.documentPictureInPicture &&\n typeof w.documentPictureInPicture.requestWindow === \"function\"\n ) {\n return \"pip\";\n }\n\n // `window.open` is technically always defined, but in some sandboxed\n // contexts (extensions, embedded iframes with restrictive sandbox) it\n // returns `null` for any call. We can't pre-detect that without actually\n // calling it — and calling it without a user gesture would either fail or\n // open an unwanted popup. So we optimistically advertise \"popup\" support\n // and let the caller handle the runtime null result.\n if (typeof window.open === \"function\") {\n return \"popup\";\n }\n\n return \"none\";\n}\n\n/**\n * True when the browser supports Document Picture-in-Picture (the preferred\n * popout mode). Convenience wrapper around `detectPopoutCapability()` for\n * use in conditional rendering and feature flags.\n */\nexport function supportsDocumentPictureInPicture(): boolean {\n return detectPopoutCapability() === \"pip\";\n}\n\n/**\n * True when popout is available in any form (DPiP or popup).\n * Use this to decide whether to show the \"Pop out\" affordance at all.\n */\nexport function supportsAnyPopout(): boolean {\n return detectPopoutCapability() !== \"none\";\n}\n","\"use client\";\n\n/**\n * usePopoutWindow — lifecycle hook owning the Document Picture-in-Picture\n * (or `window.open` fallback) browser-window for a single window-panel.\n *\n * **Critical user-gesture constraint:** `documentPictureInPicture.requestWindow()`\n * and `window.open()` both require a synchronous user-gesture stack\n * (mouseup, click, keydown). The hook exposes `openPopout()` as a plain\n * imperative method so the caller can invoke it directly inside the\n * `pointerup` handler that detects a drag-out — *not* via `useEffect`,\n * which would lose the gesture chain and be rejected by the browser.\n *\n * **Order of operations:** open the OS window FIRST (synchronously), then\n * dispatch `popOutWindow` to Redux only after the window resolves. If we\n * dispatched first, `WindowPanel` would re-render mid-open with a null\n * portal target and visibly flicker.\n *\n * **Close handling:** the canonical close trigger is the popout's\n * `pagehide` event, which fires for both user-clicked-X and programmatic\n * `.close()` calls. The hook idempotently disposes styles, clears the\n * map entry, and dispatches `dockWindow`.\n *\n * **Dock-back from inside popout content:** `WindowPanel`'s \"Dock\" button\n * dispatches `dockWindow` directly. The hook's `useEffect` watching\n * `popoutMode` sees the transition to `null`, calls `pipWin.close()`, and\n * the `pagehide` handler fires (idempotent, so calling `dockWindow` again\n * is a Redux no-op).\n */\nimport { useCallback, useEffect, useRef } from \"react\";\nimport { useSummonDispatch, useSummonPorts, useSummonSelector } from \"@ai-matrx/summon/react\";\nimport {\n popOutWindow,\n dockWindow,\n selectActivePipWindowId,\n selectPopoutMode,\n} from \"@ai-matrx/summon\";\nimport {\n detectPopoutCapability,\n type WindowWithDocumentPictureInPicture,\n} from \"./featureDetection\";\nimport {\n setPopoutWindow,\n deletePopoutWindow,\n getPopoutWindow,\n} from \"./popoutWindowMap\";\nimport { cloneStylesIntoDocument } from \"./cloneStyles\";\nimport { markPopoutPending, clearPopoutPending } from \"./popoutPendingStorage\";\nimport { buildDockWindowPayload } from \"@ai-matrx/summon\";\nimport { openOutbound } from \"@ai-matrx/kit/outbound\";\n\nexport interface OpenPopoutOptions {\n width: number;\n height: number;\n title: string;\n}\n\nexport type OpenPopoutResult =\n | { ok: true; mode: \"pip\" | \"popup\" }\n | {\n ok: false;\n reason:\n \"pip-slot-taken\" | \"popup-blocked\" | \"no-capability\" | \"request-failed\";\n };\n\nexport interface UsePopoutWindowReturn {\n /**\n * Open a popout for this window. MUST be called synchronously inside a\n * user-gesture handler (pointerup, click, keydown) — otherwise the browser\n * rejects the request.\n */\n openPopout(opts: OpenPopoutOptions): Promise<OpenPopoutResult>;\n /**\n * Programmatically close the popout. Triggers the same cleanup path as\n * the user clicking the browser X button. Safe to call when there's no\n * popout open.\n */\n close(): void;\n}\n\nexport function usePopoutWindow(windowId: string): UsePopoutWindowReturn {\n const dispatch = useSummonDispatch();\n const { notify } = useSummonPorts();\n const popoutMode = useSummonSelector(selectPopoutMode(windowId));\n const activePipWindowId = useSummonSelector(selectActivePipWindowId);\n\n // Hold style-cleanup for this window's popout. Disposed on close.\n const stylesDisposeRef = useRef<(() => void) | null>(null);\n\n /**\n * Idempotent close handler. Called from:\n * - `pagehide` (browser X click, programmatic close, parent navigation)\n * - `close()` (programmatic from this hook)\n * - the dock-watch effect (Redux popoutMode → null while window exists)\n */\n const handleClose = useCallback(() => {\n const win = getPopoutWindow(windowId);\n if (!win && process.env.NODE_ENV !== \"production\") {\n // No window registered — handleClose was triggered after we already\n // cleaned up. Idempotent: just ensure Redux is consistent.\n }\n stylesDisposeRef.current?.();\n stylesDisposeRef.current = null;\n deletePopoutWindow(windowId);\n // Clear the recovery flag — we're docked now, no recovery needed.\n clearPopoutPending(windowId);\n // Dispatch dockWindow if Redux still considers us popped out. The\n // reducer is itself idempotent, so a redundant dispatch is harmless.\n dispatch(dockWindow(buildDockWindowPayload(windowId)));\n // Best-effort close. If the close was triggered by `pagehide`, the\n // window is already going away. If by `close()`, this is the action.\n try {\n win?.close();\n } catch {\n /* ignore */\n }\n if (process.env.NODE_ENV !== \"production\" && win) {\n // eslint-disable-next-line no-console\n console.info(`[popout] closed window for \"${windowId}\"`);\n }\n }, [dispatch, windowId]);\n\n /**\n * Open a popout. The async work happens inside a Promise the caller can\n * await, but the *first synchronous step* (DPiP / window.open) runs\n * inside the user-gesture stack as long as the caller invokes openPopout\n * directly from a user-gesture handler.\n */\n const openPopout = useCallback(\n async (opts: OpenPopoutOptions): Promise<OpenPopoutResult> => {\n const capability = detectPopoutCapability();\n if (capability === \"none\") {\n notify.error(\"Pop-out not supported\", {\n description: \"Your browser doesn't support floating windows.\",\n });\n return { ok: false, reason: \"no-capability\" };\n }\n\n // Single-PiP-per-origin: when a different window already holds the\n // Document PiP slot, we MUST skip `requestWindow()` — calling it would\n // close the existing PiP and steal its slot (per the WICG spec). Fall\n // through to `window.open()` instead so both windows coexist\n // peacefully. The price is browser chrome on the second window.\n const slotTakenByOther =\n activePipWindowId !== null && activePipWindowId !== windowId;\n\n let pipWin: Window | null = null;\n let mode: \"pip\" | \"popup\" = \"popup\";\n\n // Try Document PiP only when the slot is free OR this same window\n // already owns it (idempotent re-popout).\n if (capability === \"pip\" && !slotTakenByOther) {\n try {\n const w = window as WindowWithDocumentPictureInPicture;\n if (w.documentPictureInPicture) {\n pipWin = await w.documentPictureInPicture.requestWindow({\n width: Math.max(200, Math.round(opts.width)),\n height: Math.max(120, Math.round(opts.height)),\n });\n mode = \"pip\";\n }\n } catch (err) {\n // Some failures (user dismissal, permission policy) are recoverable\n // by falling through to the popup path.\n console.warn(\n \"[popout] Document PiP request failed, falling back to popup:\",\n err,\n );\n }\n }\n\n // Fallback: window.open\n if (!pipWin) {\n const features = [\n \"popup=yes\",\n `width=${Math.max(200, Math.round(opts.width))}`,\n `height=${Math.max(120, Math.round(opts.height))}`,\n ].join(\",\");\n try {\n pipWin = openOutbound(\"\", `popout-${windowId}`, features);\n mode = \"popup\";\n } catch (err) {\n console.error(\"[popout] window.open failed:\", err);\n }\n }\n\n if (!pipWin) {\n notify.error(\"Pop-up blocked\", {\n description:\n \"Please allow pop-ups for this site to use floating windows.\",\n });\n return { ok: false, reason: \"popup-blocked\" };\n }\n\n // Title for the OS chrome (DPiP shows it; popup shows it in the title bar)\n try {\n pipWin.document.title = opts.title;\n } catch {\n /* ignore */\n }\n\n // Clone the CSS environment + start observers\n stylesDisposeRef.current = cloneStylesIntoDocument(\n window.document,\n pipWin.document,\n ).dispose;\n\n // Wire close lifecycle\n pipWin.addEventListener(\"pagehide\", handleClose, { once: true });\n\n // Register the window FIRST so PopoutPortal can find it on the next render\n setPopoutWindow(windowId, pipWin);\n\n // Persist a recovery hint so a parent reload can surface \"click to\n // restore\" UX. Cleared on dock-back / close in handleClose.\n markPopoutPending(windowId);\n\n // Dispatch Redux state — this triggers WindowPanel re-render which\n // mounts the PopoutPortal that finally renders content into pipWin.\n dispatch(popOutWindow({ id: windowId, mode }));\n\n if (process.env.NODE_ENV !== \"production\") {\n console.info(\n `[popout] opened ${mode} window for \"${windowId}\" (${opts.width}x${opts.height})`,\n );\n }\n\n return { ok: true, mode };\n },\n [activePipWindowId, dispatch, handleClose, notify, windowId],\n );\n\n /** Programmatic close — triggers the same lifecycle as user-clicked-X. */\n const close = useCallback(() => {\n const win = getPopoutWindow(windowId);\n if (!win) {\n // Already closed — make sure Redux is consistent.\n dispatch(dockWindow(buildDockWindowPayload(windowId)));\n return;\n }\n // Closing the window fires `pagehide`, which runs handleClose.\n try {\n win.close();\n } catch {\n handleClose();\n }\n }, [dispatch, handleClose, windowId]);\n\n // ── Dock-watch: when Redux says we're docked but we still own a window,\n // close it. This is how the in-popout \"Dock\" button drives cleanup.\n useEffect(() => {\n if (popoutMode === null && getPopoutWindow(windowId) !== null) {\n try {\n getPopoutWindow(windowId)?.close();\n } catch {\n handleClose();\n }\n }\n }, [popoutMode, windowId, handleClose]);\n\n // ── Defensive parent-unload cleanup. Document PiP auto-closes when the\n // opener unloads, but `window.open` popups can outlive their opener.\n useEffect(() => {\n const onBeforeUnload = () => {\n try {\n getPopoutWindow(windowId)?.close();\n } catch {\n /* ignore */\n }\n };\n window.addEventListener(\"beforeunload\", onBeforeUnload);\n return () => {\n window.removeEventListener(\"beforeunload\", onBeforeUnload);\n };\n }, [windowId]);\n\n return { openPopout, close };\n}\n","/**\n * popoutWindowMap — module-level registry mapping a window-panel id to its\n * currently-open popout `Window` object.\n *\n * This is intentionally module-level (not Redux) because:\n *\n * 1. **`Window` objects aren't serializable.** Putting them in Redux would\n * break the `serializableCheck` middleware and corrupt DevTools time-travel.\n *\n * 2. **Cross-component lookup without prop drilling.** `PopoutPortal`,\n * `usePopoutWindow`, and the `beforeunload` defensive cleanup all need to\n * locate a popout by id without coordinating through React context.\n *\n * 3. **Singleton lifetime matches page lifetime.** The map is naturally\n * cleared when the user navigates away or reloads.\n *\n * Subscriptions: callers can `subscribe` for change notifications. This is\n * how `PopoutPortal` discovers a newly-opened window without prop drilling\n * (its `windowId` is stable; the `Window` reference is what changes). The\n * subscription is a thin wrapper over `useSyncExternalStore`-friendly\n * primitives — see `usePopoutWindowRef` below.\n */\nimport { useSyncExternalStore } from \"react\";\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\ninterface PopoutMapState {\n readonly map: Map<string, Window>;\n readonly listeners: Set<() => void>;\n}\n\n// Global slot, never a module let: a duplicated module graph must see one map (kit D9).\nconst slot = (): PopoutMapState =>\n globalSlot<PopoutMapState>(\"ai-matrx.summon.window.popoutWindows\", () => ({ map: new Map(), listeners: new Set() }));\n\nfunction notify(): void {\n for (const fn of slot().listeners) fn();\n}\n\n/**\n * Register or replace the popout window for a given window-panel id.\n * Notifies subscribers synchronously.\n */\nexport function setPopoutWindow(id: string, win: Window): void {\n const { map } = slot();\n const prev = map.get(id);\n if (prev === win) return;\n map.set(id, win);\n notify();\n}\n\n/**\n * Remove the popout window registration for a given id. Notifies subscribers\n * if a previously-registered window is being removed.\n */\nexport function deletePopoutWindow(id: string): void {\n const { map } = slot();\n if (!map.has(id)) return;\n map.delete(id);\n notify();\n}\n\n/** Get the popout window for a given id, or `null` if none is registered. */\nexport function getPopoutWindow(id: string): Window | null {\n return slot().map.get(id) ?? null;\n}\n\n/** Iterate over every currently-registered popout window. */\nexport function forEachPopoutWindow(\n cb: (win: Window, id: string) => void,\n): void {\n for (const [id, win] of slot().map) cb(win, id);\n}\n\n/**\n * Subscribe to map changes. Returns an unsubscribe function.\n * Used internally by `usePopoutWindowRef` for `useSyncExternalStore`.\n */\nexport function subscribePopoutWindowMap(listener: () => void): () => void {\n const { listeners } = slot();\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/**\n * React hook: subscribe to the popout window for a given id and re-render\n * when it changes. Returns the live `Window` reference or `null`.\n *\n * Uses `useSyncExternalStore` for tearing-free reads under React 19 strict\n * mode and concurrent rendering.\n */\nexport function usePopoutWindowRef(id: string): Window | null {\n return useSyncExternalStore(\n subscribePopoutWindowMap,\n () => getPopoutWindow(id),\n // SSR snapshot — popouts are never present during SSR.\n () => null,\n );\n}\n","/**\n * cloneStyles — replicate the parent document's style environment into a\n * popout (Document Picture-in-Picture or `window.open`) document, then keep\n * it in sync via MutationObservers so theme toggles and HMR updates flow\n * through.\n *\n * **What gets cloned:**\n *\n * 1. A **reset stylesheet** — the popout doc starts with no `<style>` tags\n * at all, so the browser's user-agent margins/padding apply to `<body>`.\n * We inject a tiny reset that zeros margins, fills the viewport, and\n * sets the foreground/background to match the theme tokens.\n *\n * 2. Every **`<style>` tag** in the parent `<head>`. This captures Tailwind\n * 4's compiled CSS (a single inlined `<style>` block from `@tailwindcss/\n * postcss`), `next/font`'s injected font-face declarations (also inlined\n * `<style>` blocks), and any third-party CSS-in-JS that injects styles\n * into the head.\n *\n * 3. Every **`<link rel=\"stylesheet\">`** in the parent `<head>`. We clone the\n * `href`/`media`/`crossorigin`/`data-*` attributes; the popout document\n * refetches the CSS, which is fine because production builds ship CSS\n * with `immutable` cache headers (HTTP cache hit) and dev builds are\n * cached in the browser's memory cache.\n *\n * 4. The parent's **`adoptedStyleSheets`** array — Tailwind 4 may use\n * Constructable Stylesheets in some build modes. They're shareable\n * across same-realm documents (Document PiP windows are same-realm with\n * their opener), so we just push the same `CSSStyleSheet` references\n * onto the target doc.\n *\n * 5. The parent **`<html>` element's `class` and select attributes** —\n * `.dark` (drives the `@custom-variant dark` Tailwind variant), `font-*`\n * classes from `next/font` variables, `data-theme`, `data-scroll-behavior`,\n * and `lang`. These are mirrored into the popout's `<html>` so the same\n * cascade applies.\n *\n * **What gets watched (via MutationObservers):**\n *\n * - **`<head>` mutations** — added/removed `<style>`/`<link>` nodes get\n * mirrored. `characterData` changes on existing `<style>` text content\n * are also mirrored (Turbopack HMR sometimes patches `textContent` in\n * place rather than swapping nodes).\n *\n * - **`<html>` attribute changes** — `class`, `data-theme`,\n * `data-scroll-behavior` mirror in real time. Toggling dark mode in the\n * parent updates the popout's `<html>` class within one frame.\n *\n * **What is NOT cloned:**\n * - `<script>` tags — the popout has no JS context of its own; React\n * reaches in via `createPortal` from the parent's running tree.\n * - `<title>`/`<meta>` (other than ones we set ourselves) — no SEO surface\n * for an ephemeral popout window.\n *\n * Returns a `dispose()` function that disconnects observers. The cloned\n * nodes don't need explicit removal — they live as long as the popout doc\n * does.\n */\n\nconst RESET_CSS = `\nhtml, body {\n margin: 0;\n padding: 0;\n height: 100%;\n overflow: hidden;\n}\nbody {\n font-family: var(--font-sans, system-ui, -apple-system, sans-serif);\n background: hsl(var(--background));\n color: hsl(var(--foreground));\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n`.trim();\n\n/** Marker attribute we stamp on every node we own in the popout doc. */\nconst POPOUT_DATA_ATTR = \"data-popout-clone\";\n/** Sentinel value for the reset stylesheet (so we never re-clone it). */\nconst RESET_MARKER = \"reset\";\n\ninterface ClonedStylesHandle {\n /** Disconnect observers. Cloned nodes stay until the popout doc unloads. */\n dispose(): void;\n}\n\n/**\n * Clone the source document's CSS environment into the target document and\n * keep it synced via MutationObservers. Returns a handle whose `dispose()`\n * disconnects the observers.\n */\nexport function cloneStylesIntoDocument(\n source: Document,\n target: Document,\n): ClonedStylesHandle {\n // ── 1. Reset stylesheet ─────────────────────────────────────────────────\n injectResetStylesheet(target);\n\n // ── 2. Initial style/link clone (preserve order) ────────────────────────\n cloneAllStyleAndLinkNodes(source, target);\n\n // ── 3. Adopted stylesheets (Constructable Stylesheets) ──────────────────\n cloneAdoptedStylesheets(source, target);\n\n // ── 4. Mirror <html> class/attributes ───────────────────────────────────\n mirrorHtmlAttributes(source, target);\n\n // ── 5. Watch <head> for runtime CSS changes (HMR, dynamic imports) ──────\n const headObserver = new MutationObserver((mutations) => {\n handleHeadMutations(mutations, target);\n });\n headObserver.observe(source.head, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: [\"href\", \"media\"],\n });\n\n // ── 6. Watch <html> for theme-class / data-attribute changes ────────────\n const htmlObserver = new MutationObserver(() => {\n mirrorHtmlAttributes(source, target);\n });\n htmlObserver.observe(source.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\", \"data-scroll-behavior\"],\n });\n\n return {\n dispose() {\n headObserver.disconnect();\n htmlObserver.disconnect();\n },\n };\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction injectResetStylesheet(target: Document): void {\n // Idempotent: don't double-inject if cloneStylesIntoDocument is called\n // twice on the same target (shouldn't happen, but cheap defense).\n const existing = target.head.querySelector(\n `style[${POPOUT_DATA_ATTR}=\"${RESET_MARKER}\"]`,\n );\n if (existing) return;\n\n const style = target.createElement(\"style\");\n style.setAttribute(POPOUT_DATA_ATTR, RESET_MARKER);\n style.textContent = RESET_CSS;\n // Insert FIRST so authored styles cascade over our reset.\n target.head.insertBefore(style, target.head.firstChild);\n}\n\nfunction cloneAllStyleAndLinkNodes(\n source: Document,\n target: Document,\n): void {\n const nodes = source.head.querySelectorAll(\"style, link[rel='stylesheet']\");\n nodes.forEach((node) => {\n cloneOneStyleOrLink(node, target);\n });\n}\n\n/**\n * Clone a `<style>` or `<link>` from the source `<head>` into the target.\n * Tags the clone with `data-popout-clone` so we can find it again on removal.\n * Returns the clone, or `null` if the node type isn't supported.\n */\nfunction cloneOneStyleOrLink(\n node: Element,\n target: Document,\n): Element | null {\n if (node.tagName === \"STYLE\") {\n const clone = target.createElement(\"style\");\n // Copy text content explicitly — `cloneNode(true)` works for `<style>`\n // text but `textContent` is more direct and survives detached nodes.\n clone.textContent = node.textContent ?? \"\";\n copyDataAttributes(node, clone);\n clone.setAttribute(POPOUT_DATA_ATTR, getNodeKey(node));\n target.head.appendChild(clone);\n return clone;\n }\n if (\n node.tagName === \"LINK\" &&\n (node as HTMLLinkElement).rel === \"stylesheet\"\n ) {\n const link = node as HTMLLinkElement;\n const clone = target.createElement(\"link\");\n clone.rel = \"stylesheet\";\n if (link.href) clone.href = link.href;\n if (link.media) clone.media = link.media;\n if (link.crossOrigin) clone.crossOrigin = link.crossOrigin;\n if (link.integrity) clone.integrity = link.integrity;\n copyDataAttributes(link, clone);\n clone.setAttribute(POPOUT_DATA_ATTR, getNodeKey(node));\n target.head.appendChild(clone);\n return clone;\n }\n return null;\n}\n\n/**\n * Compute a stable-ish key for a source node so we can find its clone in the\n * target on removal. Uses a content hash for `<style>` and the `href` for\n * `<link>`, falling back to a position-based id stamped on the source itself.\n */\nfunction getNodeKey(node: Element): string {\n if (node.tagName === \"STYLE\") {\n // Stable per-text — Turbopack HMR rewrites textContent of the same node,\n // so we use a hash. Cheap deterministic hash is fine here; the only\n // requirement is that two different `<style>` blocks don't collide.\n return \"style:\" + cheapHash(node.textContent ?? \"\");\n }\n if (node.tagName === \"LINK\") {\n const href = (node as HTMLLinkElement).href || \"\";\n return \"link:\" + href;\n }\n return \"other:\" + Math.random().toString(36).slice(2);\n}\n\n/**\n * Tiny non-cryptographic hash. We only need different content to produce\n * different keys; collisions just mean a re-clone on a benign update.\n * djb2-style.\n */\nfunction cheapHash(s: string): string {\n let h = 5381;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) + h + s.charCodeAt(i)) | 0;\n }\n return (h >>> 0).toString(36);\n}\n\nfunction copyDataAttributes(from: Element, to: Element): void {\n for (const attr of Array.from(from.attributes)) {\n if (attr.name.startsWith(\"data-\")) {\n // Don't overwrite our own marker\n if (attr.name === POPOUT_DATA_ATTR) continue;\n to.setAttribute(attr.name, attr.value);\n }\n }\n}\n\nfunction cloneAdoptedStylesheets(source: Document, target: Document): void {\n // `adoptedStyleSheets` is read-write. Constructable stylesheets are\n // shareable across same-realm documents — Document PiP and `window.open`\n // popups are same-realm with their opener, so reference-sharing works.\n if (\n Array.isArray(source.adoptedStyleSheets) &&\n source.adoptedStyleSheets.length > 0\n ) {\n try {\n target.adoptedStyleSheets = [...source.adoptedStyleSheets];\n } catch {\n // Some sandboxed contexts may throw. Fall through silently — the\n // <style> clone path covers the common case.\n }\n }\n}\n\nfunction mirrorHtmlAttributes(source: Document, target: Document): void {\n const src = source.documentElement;\n const tgt = target.documentElement;\n\n // Mirror full className wholesale. Diffing class-by-class is unnecessary\n // — `next/font` variable classes (e.g. `__variable_e8ce0c`) can change\n // wholesale across rebuilds, and the cost of a full string copy is\n // negligible.\n if (tgt.className !== src.className) {\n tgt.className = src.className;\n }\n\n for (const attr of [\"data-theme\", \"data-scroll-behavior\", \"lang\"] as const) {\n const v = src.getAttribute(attr);\n if (v === null) {\n if (tgt.hasAttribute(attr)) tgt.removeAttribute(attr);\n } else if (tgt.getAttribute(attr) !== v) {\n tgt.setAttribute(attr, v);\n }\n }\n}\n\nfunction handleHeadMutations(\n mutations: MutationRecord[],\n target: Document,\n): void {\n for (const m of mutations) {\n // Handle added nodes\n m.addedNodes.forEach((n) => {\n if (!(n instanceof Element)) return;\n if (\n n.tagName === \"STYLE\" ||\n (n.tagName === \"LINK\" && (n as HTMLLinkElement).rel === \"stylesheet\")\n ) {\n cloneOneStyleOrLink(n, target);\n }\n });\n // Handle removed nodes\n m.removedNodes.forEach((n) => {\n if (!(n instanceof Element)) return;\n if (n.tagName !== \"STYLE\" && n.tagName !== \"LINK\") return;\n const key = getNodeKey(n);\n const cloneEl = target.head.querySelector(\n `[${POPOUT_DATA_ATTR}=\"${cssEscape(key)}\"]`,\n );\n if (cloneEl) cloneEl.remove();\n });\n // Handle characterData updates on existing <style> text (Turbopack HMR)\n if (m.type === \"characterData\" && m.target.parentElement?.tagName === \"STYLE\") {\n const styleEl = m.target.parentElement;\n const oldKey = findExistingMirrorByContent(target, styleEl.textContent ?? \"\");\n const newKey = getNodeKey(styleEl);\n if (oldKey && oldKey !== newKey) {\n // Update the existing mirror in place\n const mirror = target.head.querySelector(\n `[${POPOUT_DATA_ATTR}=\"${cssEscape(oldKey)}\"]`,\n );\n if (mirror) {\n mirror.textContent = styleEl.textContent ?? \"\";\n mirror.setAttribute(POPOUT_DATA_ATTR, newKey);\n }\n }\n }\n // Handle attribute changes on <link> (href/media swap)\n if (\n m.type === \"attributes\" &&\n m.target instanceof HTMLLinkElement &&\n m.target.rel === \"stylesheet\"\n ) {\n // Find the mirror by the OLD key (using current href - but it changed,\n // so this is a best-effort: we just re-clone if no match).\n // Simpler: remove all link clones with our marker that point to the\n // same href, and re-clone.\n const link = m.target;\n const allClones = target.head.querySelectorAll(\n `link[${POPOUT_DATA_ATTR}]`,\n );\n // Remove the (presumed) matching clone — we can't perfectly identify\n // it post-attribute-change, so the safest fallback is to re-clone.\n // In practice link-attribute changes are rare outside Next.js dev,\n // and a no-op extra clone is harmless.\n cloneOneStyleOrLink(link, target);\n // (We don't remove the old one; the new one wins via cascade order.\n // On dispose, both go away with the popout doc.)\n void allClones;\n }\n }\n}\n\n/**\n * Find a mirror element in the target whose marker matches a content hash\n * derived from `text`. Used to locate the previous mirror for a `<style>`\n * whose textContent just changed via HMR.\n *\n * Returns the *old* key if a mirror is found, so the caller can compute\n * the new key and update the mirror in place.\n */\nfunction findExistingMirrorByContent(\n target: Document,\n text: string,\n): string | null {\n // We don't actually have the OLD text here — it was overwritten before\n // our observer fired. The simplest workable approach: find any style\n // mirror whose textContent matches `text` already (unchanged) — return\n // null then, no-op. Otherwise, we can't reliably identify the old\n // mirror; appending a new clone and accepting a temporary duplicate is\n // fine because identical hashes will collide on the next sync.\n const styles = target.head.querySelectorAll(\n `style[${POPOUT_DATA_ATTR}^=\"style:\"]`,\n );\n for (const s of Array.from(styles)) {\n if (s.textContent === text) return null; // already in sync\n }\n // Fallback: return any style mirror's key — the caller will overwrite it.\n // Pick the first one (HMR rarely affects multiple style tags simultaneously).\n if (styles.length > 0) {\n return styles[0]?.getAttribute(POPOUT_DATA_ATTR) ?? null;\n }\n return null;\n}\n\n/**\n * Minimal CSS attribute selector escape — escapes characters that would\n * break a `[attr=\"value\"]` selector. Real-world keys come from our hash\n * (alphanumeric) or hrefs (which can contain colons and slashes; both are\n * valid inside double-quoted selectors but we play safe).\n */\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, \"\\\\$1\");\n}\n","/**\n * popoutPendingStorage — sessionStorage flag tracking which window(s) were\n * popped out at the time of the last parent-page unload.\n *\n * **Why:** browsers require a fresh user gesture to call\n * `documentPictureInPicture.requestWindow()` or `window.open()`. We can't\n * programmatically restore a popout on hydration; the user has to click\n * something. To make the recovery discoverable, we surface a toast on\n * reload: \"X was popped out — click to restore.\"\n *\n * **Storage key:** `matrx_popout_pending` (sessionStorage, JSON-encoded\n * `{ windowIds: string[] }`).\n *\n * **Lifecycle:**\n * 1. While a popout is open, `usePopoutWindow` writes the window id into\n * this storage on every open (idempotent set semantics).\n * 2. On dock-back / close, the id is removed.\n * 3. On parent reload: the storage entry persists across the reload (it's\n * in sessionStorage, scoped to the tab).\n * 4. The `WindowPersistenceManager` reads the entry after hydration and\n * surfaces a toast for each pending window.\n * 5. Toast click triggers `usePopoutControl.popOut()` from the click\n * handler (a fresh user gesture), satisfying browser policy.\n *\n * SSR-safe: every function checks `typeof window` before touching storage.\n */\n\nconst STORAGE_KEY = \"matrx_popout_pending\";\n\ninterface PendingState {\n windowIds: string[];\n}\n\nfunction readState(): PendingState {\n if (typeof window === \"undefined\") return { windowIds: [] };\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY);\n if (!raw) return { windowIds: [] };\n const parsed = JSON.parse(raw) as Partial<PendingState>;\n if (!Array.isArray(parsed.windowIds)) return { windowIds: [] };\n // Filter to strings — defensive against tampered storage.\n return {\n windowIds: parsed.windowIds.filter(\n (id): id is string => typeof id === \"string\",\n ),\n };\n } catch {\n return { windowIds: [] };\n }\n}\n\nfunction writeState(state: PendingState): void {\n if (typeof window === \"undefined\") return;\n try {\n if (state.windowIds.length === 0) {\n window.sessionStorage.removeItem(STORAGE_KEY);\n } else {\n window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state));\n }\n } catch {\n // Storage may be disabled (private mode, quota exceeded). Failing\n // silently means we lose the recovery toast UX, but everything else\n // keeps working.\n }\n}\n\n/** Mark a window as popped out so it can be recovered on reload. */\nexport function markPopoutPending(windowId: string): void {\n const state = readState();\n if (!state.windowIds.includes(windowId)) {\n state.windowIds.push(windowId);\n writeState(state);\n }\n}\n\n/** Clear the pending flag for a window (called on dock-back / close). */\nexport function clearPopoutPending(windowId: string): void {\n const state = readState();\n const next = state.windowIds.filter((id) => id !== windowId);\n if (next.length !== state.windowIds.length) {\n writeState({ windowIds: next });\n }\n}\n\n/** Read all pending window ids (used on hydration to surface the toast). */\nexport function getPendingPopoutWindowIds(): string[] {\n return readState().windowIds;\n}\n\n/** Clear ALL pending entries — used after surfacing the recovery toast. */\nexport function clearAllPopoutPending(): void {\n writeState({ windowIds: [] });\n}\n","\"use client\";\n\n/**\n * usePopoutControl — imperative API for triggering popout / dock from\n * outside the WindowPanel chrome (e.g. an \"Open in floating window\" button\n * elsewhere in the app, a keyboard shortcut handler, an agent-driven\n * action).\n *\n * **User-gesture caveat:** the `popOut` method must be called synchronously\n * inside a user-gesture handler (click, keydown, pointerup) — Chrome\n * rejects `documentPictureInPicture.requestWindow()` calls outside the\n * gesture stack. The popOut method is fire-and-forget; errors surface as\n * toasts via `usePopoutWindow`.\n *\n * **How it locates the live window's openPopout:** each WindowPanel that\n * mounts registers its `usePopoutWindow.openPopout` reference into a\n * module-level map keyed by window id. This hook reads from the same map\n * to invoke the live opener. The registry is owned by `WindowPanel.tsx`\n * via `registerPopoutOpener` (see below); the registration auto-cleans on\n * unmount.\n */\n\nimport { useCallback } from \"react\";\nimport { useSummonDispatch } from \"@ai-matrx/summon/react\";\nimport {\n dockWindow,\n type WindowRect,\n} from \"@ai-matrx/summon\";\nimport { buildDockWindowPayload } from \"@ai-matrx/summon\";\nimport type { OpenPopoutOptions, OpenPopoutResult } from \"./usePopoutWindow\";\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\n// ─── Module-level opener registry ────────────────────────────────────────────\n//\n// Mirrors `popoutWindowMap.ts`'s pattern but holds the open-callback rather\n// than the live Window. Registered by WindowPanel on mount; unregistered on\n// unmount. Lookup is a plain Map operation — no React subscription needed\n// since callers invoke it imperatively from event handlers.\n\ntype OpenPopoutFn = (opts: OpenPopoutOptions) => Promise<OpenPopoutResult>;\n\n// Global slot, never a module-level Map: a duplicated module graph must see one registry (kit D9).\nconst openers = (): Map<string, OpenPopoutFn> =>\n globalSlot<Map<string, OpenPopoutFn>>(\"ai-matrx.summon.window.popoutOpeners\", () => new Map());\n\n/**\n * Register a window's openPopout function. Called by WindowPanel on mount.\n * Returns an unregister function for use in the cleanup of useEffect.\n */\nexport function registerPopoutOpener(\n windowId: string,\n fn: OpenPopoutFn,\n): () => void {\n openers().set(windowId, fn);\n return () => {\n // Only delete if the entry still points to the same function — guards\n // against StrictMode double-mount races where a fresh registration may\n // race with the previous unmount's cleanup.\n if (openers().get(windowId) === fn) {\n openers().delete(windowId);\n }\n };\n}\n\n/** Get the live openPopout for a given window id, or null. */\nexport function getPopoutOpener(windowId: string): OpenPopoutFn | null {\n return openers().get(windowId) ?? null;\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────────────\n\nexport interface PopoutControlApi {\n /**\n * Pop out a specific window by its id. Must be called inside a\n * user-gesture stack. Returns the same result shape as\n * `usePopoutWindow.openPopout`. If the window isn't currently mounted,\n * returns `{ ok: false, reason: \"not-mounted\" }`.\n */\n popOut(\n windowId: string,\n opts: OpenPopoutOptions,\n ): Promise<OpenPopoutResult | { ok: false; reason: \"not-mounted\" }>;\n /** Dock a popped-out window back into the parent viewport. */\n dock(windowId: string): void;\n}\n\nexport function usePopoutControl(): PopoutControlApi {\n const dispatch = useSummonDispatch();\n\n const popOut = useCallback<PopoutControlApi[\"popOut\"]>(\n async (windowId, opts) => {\n const opener = getPopoutOpener(windowId);\n if (!opener) {\n return { ok: false, reason: \"not-mounted\" as const };\n }\n return opener(opts);\n },\n [],\n );\n\n const dock = useCallback<PopoutControlApi[\"dock\"]>(\n (windowId) => {\n const payload = buildDockWindowPayload(windowId);\n dispatch(dockWindow(payload));\n },\n [dispatch],\n );\n\n return { popOut, dock };\n}\n\n// ─── Convenience helper ──────────────────────────────────────────────────────\n//\n// Sized for the common \"open this window with a sensible default rect\" call.\n// Caller still owns the user-gesture handler.\n\nexport interface PopOutByIdOptions {\n /** Falls back to 480 if not provided. */\n width?: number | undefined;\n /** Falls back to 320 if not provided. */\n height?: number | undefined;\n /** Falls back to \"Window\" if not provided. */\n title?: string | undefined;\n}\n\nexport function buildPopoutOpts(\n rect: Partial<WindowRect> | undefined,\n opts: PopOutByIdOptions | undefined,\n): OpenPopoutOptions {\n return {\n width: opts?.width ?? rect?.width ?? 480,\n height: opts?.height ?? rect?.height ?? 320,\n title: opts?.title ?? \"Window\",\n };\n}\n","\"use client\";\n\n/**\n * PopoutPortal — wraps `createPortal` for rendering window-panel content\n * into a popout (Document Picture-in-Picture or `window.open`) document.\n *\n * Subscribes to `popoutWindowMap` via `usePopoutWindowRef` so the portal\n * automatically un-/re-mounts when the popout window opens or closes\n * without prop drilling the `Window` reference through the tree.\n *\n * Wraps children in `PopoutShell` so descendants see the popout-scoped\n * `PopoutContext` (used by `usePopoutContainer` for Radix portal\n * retargeting).\n *\n * **React tree topology:** the children stay in the *parent* React tree\n * (their Fiber is attached upstream of this `PopoutPortal`). Only the DOM\n * is mounted into the popout document. That preservation is what gives us\n * Redux/contexts/`callbackManager` for free across the window boundary.\n */\nimport { createPortal } from \"react-dom\";\nimport { useSummonSelector } from \"@ai-matrx/summon/react\";\nimport { selectPopoutMode } from \"@ai-matrx/summon\";\nimport { usePopoutWindowRef } from \"./popoutWindowMap\";\nimport { PopoutShell } from \"./PopoutShell\";\nimport type { ReactNode } from \"react\";\n\nexport interface PopoutPortalProps {\n windowId: string;\n children: ReactNode;\n}\n\nexport function PopoutPortal({ windowId, children }: PopoutPortalProps) {\n const popoutWin = usePopoutWindowRef(windowId);\n const popoutMode = useSummonSelector(selectPopoutMode(windowId));\n\n // Don't render anything until BOTH conditions hold:\n // - Redux says this window is popped out (popoutMode !== null)\n // - The actual `Window` reference is registered in popoutWindowMap\n //\n // The two can briefly disagree during open/close transitions; rendering\n // requires both to avoid mounting into a closed document.\n if (!popoutWin || popoutMode === null) return null;\n\n return createPortal(\n <PopoutShell popoutWindow={popoutWin} mode={popoutMode}>\n {children}\n </PopoutShell>,\n popoutWin.document.body,\n );\n}\n","\"use client\";\n\n/**\n * PopoutShell — wrapper that mounts inside the `createPortal` target in the\n * popout document and provides a `PopoutContext` value to descendants.\n *\n * `PopoutPortal` renders this *as the immediate child of `createPortal(...)`*\n * so every descendant inside the popout subtree sees the popout-scoped\n * document/window/container values via `usePopout()`.\n */\nimport { useMemo, type ReactNode } from \"react\";\nimport { PortalContainerProvider } from \"@ai-matrx/design-system\";\nimport {\n PopoutContext,\n type PopoutContextValue,\n type PopoutMode,\n} from \"./PopoutContext\";\n\nexport interface PopoutShellProps {\n popoutWindow: Window;\n mode: PopoutMode;\n children: ReactNode;\n}\n\nexport function PopoutShell({\n popoutWindow,\n mode,\n children,\n}: PopoutShellProps) {\n const value = useMemo<PopoutContextValue>(\n () => ({\n popoutDocument: popoutWindow.document,\n popoutWindow,\n popoutContainer: popoutWindow.document.body,\n mode,\n }),\n [popoutWindow, mode],\n );\n\n return (\n <PopoutContext.Provider value={value}>\n {/*\n * Host wiring for the @ai-matrx/design-system portal seam: package\n * primitives (Popover) read PortalContainerProvider instead of the\n * host's usePopoutContainer, so a popover opened inside a popped-out\n * window mounts into the popout's <body> — not the parent document.\n * A Dialog nested deeper re-provides its own container (nearest\n * provider wins), preserving the dialog > popout > body priority.\n */}\n <PortalContainerProvider container={value.popoutContainer}>\n {children}\n </PortalContainerProvider>\n </PopoutContext.Provider>\n );\n}\n","\"use client\";\n\n/**\n * PopoutContext — exposes the popout `Document` / `Window` / portal target\n * to descendants of a popped-out subtree.\n *\n * The default value (`popoutDocument: null`, etc.) means \"I'm rendered in\n * the parent document.\" Descendants that need to behave differently inside\n * a popout (e.g. Radix portals retargeting their content) call\n * `usePopout()` and branch on the values.\n *\n * **Architectural note:** because `createPortal` preserves the parent\n * React tree, every ancestor `Provider` cascades into the popout — Redux,\n * Theme, Tooltip, Router, all work without re-wrapping. This context is\n * for the *opposite* direction: telling popped-out content \"you're inside\n * a popout window, here's the document/window/container you should use\n * instead of the global `document`/`window`.\"\n */\nimport { createContext, useContext } from \"react\";\n\nexport type PopoutMode = \"pip\" | \"popup\";\n\nexport interface PopoutContextValue {\n /**\n * The popout `Document`. `null` when this subtree is rendered in the\n * parent (the default).\n */\n popoutDocument: Document | null;\n /**\n * The popout `Window`. `null` when this subtree is rendered in the parent.\n * Use for `addEventListener`, `matchMedia`, `innerWidth`, etc., when the\n * popout-scoped answer is what you need.\n */\n popoutWindow: Window | null;\n /**\n * Element to use as the Radix `Portal.container` prop so floating UI\n * (tooltips, popovers, dropdowns) renders inside the popout instead of\n * the parent `document.body`. Returns `null` outside a popout —\n * `usePopoutContainer` coerces this to `undefined` so Radix falls back\n * to its default container automatically.\n */\n popoutContainer: HTMLElement | null;\n /**\n * Which popout mechanism is in use. `null` outside a popout.\n * Currently only used for diagnostics; downstream components may branch\n * on it later (e.g. show different chrome for `popup` vs `pip`).\n */\n mode: PopoutMode | null;\n}\n\nconst DEFAULT_VALUE: PopoutContextValue = {\n popoutDocument: null,\n popoutWindow: null,\n popoutContainer: null,\n mode: null,\n};\n\nexport const PopoutContext =\n createContext<PopoutContextValue>(DEFAULT_VALUE);\n\n/** Read the current popout context. Always defined — never throws. */\nexport function usePopout(): PopoutContextValue {\n return useContext(PopoutContext);\n}\n","/**\n * traySnapshotMap — window id → a captured local object-URL snapshot shown in the minimized tile.\n *\n * Not Redux: image blobs stay out of the store and never touch storage. Object URLs avoid base64\n * expansion and are revoked on replacement, restore, unmount, or bounded-cache eviction. State\n * lives in a global slot so a duplicated module graph sees one map (kit globalSlot, D9).\n *\n * Lifecycle: WindowPanel captures after minimize → stored here → TrayChipPreview subscribes and\n * reads → restore / unmount clears it.\n */\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\nconst MAX_SNAPSHOTS = 16;\n\ninterface SnapshotState {\n readonly map: Map<string, string>;\n readonly listeners: Set<() => void>;\n}\n\nconst state = (): SnapshotState =>\n globalSlot<SnapshotState>(\"ai-matrx.summon.window.traySnapshots\", () => ({ map: new Map(), listeners: new Set() }));\n\nfunction notify(): void {\n for (const fn of state().listeners) fn();\n}\n\nfunction revoke(url: string | undefined): void {\n if (url && typeof URL !== \"undefined\" && typeof URL.revokeObjectURL === \"function\") URL.revokeObjectURL(url);\n}\n\n/** Store a local snapshot blob for a window and notify subscribers. */\nexport function setTraySnapshot(id: string, blob: Blob): void {\n const { map } = state();\n revoke(map.get(id));\n const objectUrl = URL.createObjectURL(blob);\n map.delete(id);\n map.set(id, objectUrl);\n while (map.size > MAX_SNAPSHOTS) {\n const oldestId = map.keys().next().value;\n if (oldestId === undefined) break;\n revoke(map.get(oldestId));\n map.delete(oldestId);\n }\n notify();\n}\n\n/** Clear the snapshot for a given window id. */\nexport function clearTraySnapshot(id: string): void {\n const { map } = state();\n const objectUrl = map.get(id);\n if (!objectUrl) return;\n map.delete(id);\n revoke(objectUrl);\n notify();\n}\n\n/** Read the snapshot for a given window id, or null. */\nexport function getTraySnapshot(id: string): string | null {\n return state().map.get(id) ?? null;\n}\n\n/** Subscribe to map changes (useSyncExternalStore-shaped). */\nexport function subscribeTraySnapshotMap(listener: () => void): () => void {\n const { listeners } = state();\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n","/**\n * defaultTraySnapshotCapture — the fallback `captureTraySnapshot` for any window without a\n * registered preview, so its minimized tile shows a small image of the real body.\n *\n * `html-to-image` is an OPTIONAL peer, loaded through ONE dynamic import on the first capture: a\n * host that never installs it gets the labelled default tile (no error, no bundle cost).\n *\n * Performance contract (do not weaken when editing):\n * - Runs exactly ONCE per minimize, inside WindowPanel's timeout race. No polling, no network, no\n * storage — the Blob lands in the bounded object-URL cache (16 entries, revoked on restore).\n * - Oversized DOM subtrees are skipped (the clone pass is synchronous and would jank).\n * - Output is downscaled (320px longest edge, 1x pixel density) WebP.\n */\n\n/** Skip capture above this many descendant elements. */\nconst MAX_CAPTURE_ELEMENT_COUNT = 3000;\n\n/** A cross-origin image the renderer cannot fetch becomes a transparent pixel, never a failed capture. */\nconst TRANSPARENT_PIXEL = \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n\nexport interface ElementThumbnailOptions {\n /** Longest edge in px (min 64). Default 320. */\n readonly maxEdge?: number;\n /** WebP quality 0–1. Default 0.62. */\n readonly quality?: number;\n}\n\n/** The one dynamic import of the optional peer. `null` when the host did not install it. */\nasync function loadToCanvas(): Promise<typeof import(\"html-to-image\").toCanvas | null> {\n try {\n const mod = await import(\"html-to-image\");\n return mod.toCanvas;\n } catch {\n return null;\n }\n}\n\n/** A small display-ready WebP thumbnail of one element, or null when html-to-image is absent. */\nexport async function captureElementThumbnail(element: HTMLElement, options: ElementThumbnailOptions = {}): Promise<Blob | null> {\n const toCanvas = await loadToCanvas();\n if (!toCanvas) return null;\n const sourceWidth = Math.max(1, element.offsetWidth);\n const sourceHeight = Math.max(1, element.offsetHeight);\n const maxEdge = Math.max(64, options.maxEdge ?? 320);\n const scale = Math.min(1, maxEdge / Math.max(sourceWidth, sourceHeight));\n const canvas = await toCanvas(element, {\n pixelRatio: 1,\n canvasWidth: Math.max(1, Math.round(sourceWidth * scale)),\n canvasHeight: Math.max(1, Math.round(sourceHeight * scale)),\n skipFonts: true,\n imagePlaceholder: TRANSPARENT_PIXEL,\n onImageErrorHandler: () => undefined,\n });\n return new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, \"image/webp\", options.quality ?? 0.62);\n });\n}\n\nexport async function defaultTraySnapshotCapture(bodyEl: HTMLElement): Promise<Blob | null> {\n try {\n if (bodyEl.querySelectorAll(\"*\").length > MAX_CAPTURE_ELEMENT_COUNT || bodyEl.offsetWidth < 8 || bodyEl.offsetHeight < 8) {\n return null;\n }\n const blob = await captureElementThumbnail(bodyEl);\n // A capture of a body that had not painted comes back as one flat colour: an empty tile.\n // Treat it as no capture so the tile shows the labelled default body instead.\n return blob && (await isFlatImage(blob)) ? null : blob;\n } catch {\n // A failed capture is never worth breaking minimize over.\n return null;\n }\n}\n\n/** True when every sampled pixel is transparent or the same colour — nothing to show. */\nasync function isFlatImage(blob: Blob): Promise<boolean> {\n try {\n const bitmap = await createImageBitmap(blob);\n const size = 24;\n const canvas = document.createElement(\"canvas\");\n canvas.width = size;\n canvas.height = size;\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!ctx) return false;\n ctx.drawImage(bitmap, 0, 0, size, size);\n bitmap.close();\n const { data } = ctx.getImageData(0, 0, size, size);\n const r0 = data[0] ?? 0;\n const g0 = data[1] ?? 0;\n const b0 = data[2] ?? 0;\n const a0 = data[3] ?? 0;\n for (let i = 0; i < data.length; i += 4) {\n if (\n Math.abs((data[i] ?? 0) - r0) > 6 ||\n Math.abs((data[i + 1] ?? 0) - g0) > 6 ||\n Math.abs((data[i + 2] ?? 0) - b0) > 6 ||\n Math.abs((data[i + 3] ?? 0) - a0) > 6\n ) {\n return false;\n }\n }\n return true;\n } catch {\n return false;\n }\n}\n","\"use client\";\n\n/**\n * MinimizedWindowContent — the body of a minimized WindowPanel shell.\n *\n * When a window is minimized it shrinks to a 240×160 card; this fills the body\n * below its fixed header with the canonical tray preview\n * (`TrayChipPreview` — custom / snapshot / default, in that order) and makes the\n * whole area click-to-restore. It is the single seam that brings the tray\n * preview registry to the *production* minimized state (the standalone\n * `WindowTray` dock is the other consumer).\n *\n * `windowId` is the registry lookup key — pass the window's `overlayId` when it\n * has one (overlay-managed windows), falling back to the runtime id. A window\n * with no registered preview lands on the default muted label, so this is safe\n * for every window, not just those with a bespoke preview.\n */\n\nimport { getOverlayMeta } from \"@ai-matrx/summon\";\nimport { TrayChipPreview } from \"./TrayChipPreview\";\n\ninterface MinimizedWindowContentProps {\n /** Registry key — `overlayId` for overlay-managed windows, else runtime id. */\n registryKey: string;\n /** Unique runtime id for the local screenshot cache. */\n snapshotKey: string;\n overlayInstanceId?: string | undefined;\n previewData?: Record<string, unknown> | undefined;\n /** Window title; falls back to the registry label when not a plain string. */\n title?: string | undefined;\n /** Restore (un-minimize) the window. Wired to a click on the whole body. */\n onRestore?: (() => void) | undefined;\n}\n\nexport function MinimizedWindowContent({\n registryKey,\n snapshotKey,\n overlayInstanceId,\n previewData,\n title,\n onRestore,\n}: MinimizedWindowContentProps) {\n const label = title ?? getOverlayMeta(registryKey)?.label ?? \"\";\n\n return (\n <button\n type=\"button\"\n onClick={onRestore}\n title=\"Click to restore\"\n className=\"flex min-h-0 flex-1 flex-col text-left focus:outline-none\"\n >\n <TrayChipPreview\n registryKey={registryKey}\n snapshotKey={snapshotKey}\n overlayInstanceId={overlayInstanceId}\n previewData={previewData}\n title={label}\n />\n </button>\n );\n}\n\nexport default MinimizedWindowContent;\n","\"use client\";\n\n/**\n * TrayChipPreview — the body of a minimized window tile.\n *\n * Three modes, in priority order:\n * 1. Custom — a preview registered with `registerTrayPreview` (best fidelity, no capture).\n * 2. Snapshot — the image captured at minimize time (`traySnapshotMap`).\n * 3. Default — a muted \"label · Window\" body, shown while a capture is pending or when it was\n * skipped/failed.\n * A custom preview that throws falls through to snapshot/default without breaking the tile.\n */\n\nimport { Component, memo, useSyncExternalStore, type ReactNode } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { getOverlayMeta, selectOverlayData, DEFAULT_INSTANCE_ID } from \"@ai-matrx/summon\";\nimport { useSummonPorts, useSummonSelector } from \"@ai-matrx/summon/react\";\nimport { getTrayPreviewEntry, type TrayPreviewContext } from \"@ai-matrx/summon/window-host\";\nimport { getTraySnapshot, subscribeTraySnapshotMap } from \"./traySnapshotMap\";\n\ninterface TrayChipPreviewProps {\n /** Registry key — the overlay id for overlay-managed windows, else the runtime id. */\n registryKey: string;\n /** Unique runtime window id used for the local snapshot cache. */\n snapshotKey: string;\n overlayInstanceId?: string | undefined;\n previewData?: Record<string, unknown> | undefined;\n title: string;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport const TrayChipPreview = memo(function TrayChipPreview({\n registryKey,\n snapshotKey,\n overlayInstanceId = DEFAULT_INSTANCE_ID,\n previewData,\n title,\n}: TrayChipPreviewProps) {\n const meta = getOverlayMeta(registryKey);\n const { Preview } = getTrayPreviewEntry(registryKey);\n const ports = useSummonPorts();\n const overlayData = useSummonSelector((state) => (meta ? selectOverlayData(state, meta.id, overlayInstanceId) : null));\n const collectedData = useSummonSelector((state) => state.windowManager.windows[snapshotKey]?.persistence?.data);\n const registryLabel = meta?.label ?? null;\n\n const fallback = <TraySnapshotImage snapshotKey={snapshotKey} registryLabel={registryLabel} title={title} />;\n\n if (Preview) {\n const ctx: TrayPreviewContext = {\n data: previewData ?? collectedData ?? (isPlainRecord(overlayData) ? overlayData : {}),\n overlayId: meta?.id ?? registryKey,\n instanceId: overlayInstanceId,\n title,\n };\n return (\n <PreviewBoundary\n fallback={fallback}\n onError={(error) => ports.errors.capture(error, { where: \"tray-preview\", overlayId: registryKey })}\n >\n <div className=\"flex-1 px-3 py-1 overflow-hidden text-xs text-muted-foreground\">\n <Preview {...ctx} />\n </div>\n </PreviewBoundary>\n );\n }\n return fallback;\n});\n\nclass PreviewBoundary extends Component<\n { fallback: ReactNode; onError: (error: unknown) => void; children: ReactNode },\n { failed: boolean }\n> {\n override state = { failed: false };\n static getDerivedStateFromError(): { failed: boolean } {\n return { failed: true };\n }\n override componentDidCatch(error: unknown): void {\n this.props.onError(error);\n }\n override render(): ReactNode {\n return this.state.failed ? this.props.fallback : this.props.children;\n }\n}\n\nconst DefaultTrayChipBody = memo(function DefaultTrayChipBody({ label }: { label: string }) {\n return (\n <div className=\"flex flex-1 flex-col justify-between overflow-hidden bg-gradient-to-br from-muted/45 via-background to-primary/5 px-3 py-2.5\">\n <div className=\"flex min-w-0 items-center gap-2.5\">\n <div\n aria-hidden=\"true\"\n className=\"flex h-8 w-8 shrink-0 flex-col gap-1 rounded-md border border-border/60 bg-background/70 p-1.5 shadow-sm\"\n >\n <span className=\"h-1 w-4 rounded-full bg-primary/45\" />\n <span className=\"h-1 w-3 rounded-full bg-muted-foreground/25\" />\n <span className=\"h-1 w-4 rounded-full bg-muted-foreground/15\" />\n </div>\n <span className=\"min-w-0 truncate text-xs font-medium text-foreground\">{label}</span>\n </div>\n <div className=\"matrx-window-tile-meta flex items-center justify-between gap-2 text-muted-foreground\">\n <span className=\"truncate uppercase tracking-wide\">Window</span>\n <span className=\"shrink-0\">Click to restore</span>\n </div>\n </div>\n );\n});\n\nconst TraySnapshotImage = memo(function TraySnapshotImage({\n snapshotKey,\n registryLabel,\n title,\n}: {\n snapshotKey: string;\n registryLabel: string | null;\n title: string;\n}) {\n // The snapshot is captured asynchronously after the window minimizes; subscribe so the tile\n // updates the moment it lands, without polling.\n const snapshot = useSyncExternalStore(\n subscribeTraySnapshotMap,\n () => getTraySnapshot(snapshotKey),\n () => null,\n );\n if (!snapshot) return <DefaultTrayChipBody label={registryLabel ?? title} />;\n return (\n <div className=\"flex-1 overflow-hidden bg-muted/30 relative\">\n <img\n src={snapshot}\n alt=\"\"\n className={cn(\"w-full h-full object-cover\", \"opacity-90 hover:opacity-100 transition-opacity\")}\n draggable={false}\n />\n </div>\n );\n});\n","// @ai-matrx/summon/window — the WindowPanel desktop: the window, its chrome, tray sync and the\n// minimized tile, snap/arrange, pop-out to a real browser window, the three phone presentations,\n// and the host options. See SUMMON-PACKAGE-DESIGN.md (common-docs) for its contract.\n\nexport { WindowPanel, type WindowPanelProps, type WindowPanelBaseProps, type WindowPanelCloseBinding } from \"./window/WindowPanel\";\nexport {\n WindowsProvider,\n useWindowConfig,\n WindowSelectionSurface,\n DEFAULT_WINDOW_CONFIG,\n DEFAULT_ESCAPE_YIELD_SELECTOR,\n DEFAULT_MOBILE_TOP_OFFSET,\n type WindowConfig,\n type WindowsProviderProps,\n type WindowSelectionSurfaceProps,\n} from \"@ai-matrx/summon/window-host\";\nexport {\n useWindowPanel,\n resolvePosition,\n resetDefaultWindowCascade,\n type UseWindowPanelOptions,\n type UseWindowPanelReturn,\n type ResizeEdge,\n type WindowPosition,\n} from \"./window/useWindowPanel\";\nexport { WindowTraySync } from \"@ai-matrx/summon/window-host\";\nexport { WindowSidebar, type WindowSidebarItem } from \"./window/WindowSidebar\";\nexport { LayoutIcon, LayoutIconButton, type LayoutIconType } from \"./window/LayoutIcon\";\nexport { useOverlaySurfaceRenderAck } from \"./window/useOverlaySurfaceRenderAck\";\n\n// Minimized tile and tray previews\nexport {\n registerTrayPreview,\n getTrayPreviewEntry,\n resetTrayPreviews,\n type TrayPreviewContext,\n type TrayPreviewEntry,\n type TraySnapshotCapture,\n} from \"@ai-matrx/summon/window-host\";\nexport { setTraySnapshot, clearTraySnapshot, getTraySnapshot, subscribeTraySnapshotMap } from \"./window/tray/traySnapshotMap\";\nexport { defaultTraySnapshotCapture, captureElementThumbnail, type ElementThumbnailOptions } from \"./window/tray/defaultTraySnapshotCapture\";\nexport { TrayChipPreview } from \"./window/tray/TrayChipPreview\";\nexport { MinimizedWindowContent } from \"./window/tray/MinimizedWindowContent\";\nexport { TrayStatusChip, type TrayStatusChipProps, type TrayStatusSegment, type TrayStatusTone } from \"./window/tray/TrayStatusChip\";\n\n// Pop-out\nexport { usePopout, PopoutContext, type PopoutContextValue, type PopoutMode } from \"./window/popout/PopoutContext\";\nexport { usePopoutContainer } from \"./window/popout/usePopoutContainer\";\nexport { usePopoutControl, getPopoutOpener, buildPopoutOpts, type PopoutControlApi, type PopOutByIdOptions } from \"./window/popout/usePopoutControl\";\nexport { usePopoutWindow, type OpenPopoutOptions, type OpenPopoutResult, type UsePopoutWindowReturn } from \"./window/popout/usePopoutWindow\";\nexport { getPopoutWindow, forEachPopoutWindow, subscribePopoutWindowMap, usePopoutWindowRef } from \"./window/popout/popoutWindowMap\";\nexport { getPendingPopoutWindowIds, clearAllPopoutPending } from \"./window/popout/popoutPendingStorage\";\nexport {\n detectPopoutCapability,\n supportsDocumentPictureInPicture,\n supportsAnyPopout,\n type PopoutCapability,\n} from \"./window/popout/featureDetection\";\nexport {\n evaluateDragOut,\n DEFAULT_DRAG_OUT_CONFIG,\n INITIAL_DRAG_OUT_STATE,\n type DragOutConfig,\n type DragOutState,\n type DragOutInput,\n type DragOutEvalResult,\n} from \"./window/popout/popoutDragDetector\";\n\n// Phone presentations and chrome pieces a host composes beside windows\nexport { default as MobileDrawerSurface } from \"./window/mobile/MobileDrawerSurface\";\nexport { default as MobileCardSurface } from \"./window/mobile/MobileCardSurface\";\nexport { MobileWindowTitle, MobileWindowTitleRow, MobileWindowActionsRow, mobileWindowTitleClass, MOBILE_WINDOW_TITLE_TEXT } from \"./window/chrome/MobileTitleRow\";\n\n// Utilities\nexport {\n markAutoOpened,\n isAutoOpened,\n clearAutoOpened,\n autoOpenHasRoom,\n measureWorkingColumn,\n resolveAutoOpenPlacement,\n AUTO_OPEN_MIN_WIDTH,\n AUTO_OPEN_NO_ROOM_EVENT,\n type AutoOpenPlacement,\n} from \"./window/utils/autoOpenPlacement\";\nexport { mayRaiseUnbidden, isUnderRoute, type UnbiddenRaiseVerdict, type UnbiddenRefusalCode } from \"./window/utils/mayRaiseUnbidden\";\nexport { assertLazyLoaded } from \"./window/utils/lazy-bundle-guard\";\nexport { sanitizeWindowData } from \"./window/utils/sanitizeWindowData\";\n","\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { ScrollArea } from \"@ai-matrx/design-system\";\n\nexport interface WindowSidebarItem {\n value: string;\n label: string;\n icon: React.ElementType;\n description?: string | undefined;\n}\n\ninterface WindowSidebarProps<T extends string = string> {\n items: WindowSidebarItem[];\n activeItem: T;\n onSelect: (value: T) => void;\n className?: string | undefined;\n}\n\nexport function WindowSidebar<T extends string = string>({\n items,\n activeItem,\n onSelect,\n className,\n}: WindowSidebarProps<T>) {\n return (\n <ScrollArea className={cn(\"flex-1 w-full\", className)}>\n <div className=\"py-2\">\n {items.map((item) => {\n const Icon = item.icon as React.FC<{ className?: string }>;\n const isActive = item.value === activeItem;\n return (\n <button\n key={item.value}\n onClick={() => onSelect(item.value as T)}\n title={item.description}\n className={cn(\n \"w-full flex items-center gap-2.5 px-3 py-2 text-left text-xs transition-colors\",\n isActive\n ? \"bg-primary/10 text-primary-ink border-r-2 border-primary\"\n : \"text-muted-foreground hover:bg-muted/50 hover:text-foreground\",\n )}\n >\n <Icon className=\"h-3.5 w-3.5 shrink-0\" />\n <span className=\"truncate\">{item.label}</span>\n </button>\n );\n })}\n </div>\n </ScrollArea>\n );\n}\n\nexport default WindowSidebar;\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { ackOverlaySurfaceRender, clearOverlaySurfaceRender } from \"@ai-matrx/summon\";\n\n/**\n * Acknowledge a visible presentation that intentionally replaces WindowPanel.\n *\n * Registered singleton window overlays normally prove they are on screen by mounting a\n * WindowPanel and registering geometry. Mobile drawers, sheets, and full-screen\n * viewers have no window-manager geometry, so their composition root must use\n * this hook while that alternate surface is active.\n */\nexport function useOverlaySurfaceRenderAck(\n overlayId: string,\n active: boolean,\n): void {\n useEffect(() => {\n if (!active) return undefined;\n ackOverlaySurfaceRender(overlayId);\n return () => clearOverlaySurfaceRender(overlayId);\n }, [active, overlayId]);\n}\n","\"use client\";\n\n/**\n * TrayStatusChip — the canonical \"minimized-window status indicator\".\n *\n * A small, presentational mini-view for the body of a minimized window (or a\n * tray chip): a tinted icon that conveys severity at a glance, a primary count,\n * an optional caption, and an optional per-tone breakdown. It is the reusable\n * primitive behind window-specific previews like the Error Inspector's bug\n * indicator — any window whose minimized value is \"a status + a few numbers\"\n * (errors, active recordings, running jobs, unread items…) maps onto this\n * instead of hand-rolling a one-off chip.\n *\n * Design contract:\n * - **Presentational only.** No store reads, no effects, no Redux. The consumer\n * subscribes to its own live source and passes plain props down. This keeps\n * the chip render-cheap and lets the consumer own the (isolated) subscription.\n * - **Tone is the signal.** `tone` tints the icon using the same colour\n * language as `lib/diagnostics/errorTiers.ts` so severity reads identically\n * everywhere (blue → yellow → amber → red).\n * - **Limit what's shown.** A minimized card is 240×160; it must stay\n * glanceable. One icon, one number, an optional caption, and a tiny\n * breakdown — no more. Breakdown segments render only when more than one is\n * non-zero (a single tone is already carried by the icon colour + count).\n *\n * Rendered INSIDE `TrayChipPreview`'s custom-mode wrapper, which already\n * supplies `flex-1`, padding, and overflow clipping — so this root only needs\n * to lay out its own row.\n */\n\nimport type { ComponentType, SVGAttributes } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\n/**\n * Severity scale, loudest-last. Maps onto the captured-error tiers but is\n * intentionally generic so non-error windows can reuse it:\n * neutral — inert / nothing notable (muted)\n * info — active & healthy, \"monitoring\" (info token)\n * warning — low / silent (yellow)\n * elevated — minor / worth a glance (amber)\n * critical — loud / needs attention (destructive red)\n */\nexport type TrayStatusTone =\n | \"neutral\"\n | \"info\"\n | \"warning\"\n | \"elevated\"\n | \"critical\";\n\ninterface ToneClasses {\n /** Icon + primary-count text colour. */\n fg: string;\n /** Breakdown dot fill. */\n dot: string;\n}\n\nconst TONE_CLASSES: Record<TrayStatusTone, ToneClasses> = {\n neutral: {\n fg: \"text-muted-foreground\",\n dot: \"bg-muted-foreground/50\",\n },\n info: {\n fg: \"text-info\",\n dot: \"bg-info\",\n },\n warning: {\n fg: \"text-warning\",\n dot: \"bg-warning\",\n },\n elevated: {\n fg: \"text-warning\",\n dot: \"bg-warning\",\n },\n critical: {\n fg: \"text-destructive\",\n dot: \"bg-destructive\",\n },\n};\n\nexport interface TrayStatusSegment {\n count: number;\n tone: TrayStatusTone;\n /** Accessible/tooltip label, e.g. \"clear errors\". */\n label?: string | undefined;\n}\n\nexport interface TrayStatusChipProps {\n /** Icon component (any SVG icon taking className) — the glanceable identity/severity mark. */\n icon: ComponentType<SVGAttributes<SVGSVGElement>>;\n /** Overall severity — tints the icon (and the primary count). */\n tone: TrayStatusTone;\n /** Primary number. Omit (or pass undefined) to show only the caption. */\n count?: number | undefined;\n /** Shown when there's no count (e.g. the all-clear / idle state). */\n caption?: string | undefined;\n /** Per-tone breakdown. Only renders when 2+ entries are non-zero. */\n segments?: TrayStatusSegment[] | undefined;\n /** Pulse the icon (e.g. unseen activity since minimize). */\n pulse?: boolean | undefined;\n}\n\nexport function TrayStatusChip({\n icon: Icon,\n tone,\n count,\n caption,\n segments,\n pulse,\n}: TrayStatusChipProps) {\n const t = TONE_CLASSES[tone];\n const visibleSegments = (segments ?? []).filter((s) => s.count > 0);\n const showBreakdown = visibleSegments.length > 1;\n const hasCount = typeof count === \"number\";\n\n // Scale matches the sibling `ErrorInspectorBadge` (h-3.5 icon / text-xs count\n // / text-[10px] detail) — the same tray text scale as every other preview.\n // Never bump these: a minimized card is 240px wide and must stay glanceable.\n return (\n <div className=\"flex h-full items-center gap-1.5 overflow-hidden\">\n <Icon\n className={cn(\"h-3.5 w-3.5 shrink-0\", t.fg, pulse && \"animate-pulse\")}\n aria-hidden\n />\n\n <div className=\"flex min-w-0 items-baseline gap-1\">\n {hasCount ? (\n <span className={cn(\"text-xs font-semibold tabular-nums\", t.fg)}>\n {count}\n </span>\n ) : null}\n {caption ? (\n <span className=\"truncate text-[11px] text-muted-foreground\">\n {caption}\n </span>\n ) : null}\n </div>\n\n {showBreakdown ? (\n <div className=\"ml-auto flex shrink-0 items-center gap-1\">\n {visibleSegments.map((s, i) => (\n <span\n key={i}\n className=\"flex items-center gap-0.5\"\n title={s.label ? `${s.count} ${s.label}` : undefined}\n >\n <span\n className={cn(\n \"h-1.5 w-1.5 rounded-full\",\n TONE_CLASSES[s.tone].dot,\n )}\n />\n <span className=\"text-[10px] tabular-nums text-muted-foreground\">\n {s.count}\n </span>\n </span>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default TrayStatusChip;\n","\"use client\";\n\n/**\n * usePopoutContainer — return the element Radix portals (Tooltip, Popover,\n * Dropdown, Dialog, Select, AlertDialog, HoverCard) should mount into.\n *\n * **The problem this solves:** by default every Radix `Portal` mounts to\n * `document.body`. When a tooltip-trigger lives inside a popped-out window\n * but the popover content portals to the *parent* document, the tooltip\n * appears in the wrong window — typically invisible to the user.\n *\n * **The fix:** wrappers around Radix primitives call this hook and pass\n * the result as `<Primitive.Portal container={...} />`. Inside a popout,\n * the result is the popout's `<body>`. Outside a popout, the result is\n * `undefined`, which Radix interprets as \"use the default\" — meaning no\n * behavior change for any of the thousands of existing usages.\n *\n * **Why `undefined` instead of `null`?** Radix's `container` prop accepts\n * `HTMLElement | null | undefined`. Passing `null` actively tries to\n * portal into a `null` target and crashes. Passing `undefined` falls\n * through to the default (`document.body`). The `?? undefined` coerces\n * the `null` we get from `PopoutContext` outside a popout into the\n * Radix-friendly default-fallthrough value.\n */\nimport { usePopout } from \"./PopoutContext\";\n\nexport function usePopoutContainer(): HTMLElement | undefined {\n return usePopout().popoutContainer ?? undefined;\n}\n","// mayRaiseUnbidden\n// THE RULE: a window nobody opened may only raise itself where it lives.\n//\n// D11 (2026-09-17, found on `/exports`): the \"Spend so far today\" window opened\n// over the Bring-your-export drop zone. Parking it in the right gutter\n// (`resolvePosition`) fixed WHERE it landed; it did not fix that it appeared at\n// all on a route whose whole job is a drop zone. The defect is PRESENCE.\n//\n// So every automatic raiser asks here first, and the answer comes from ONE\n// source of truth — `unbiddenHome` on the window's registry metadata, beside\n// the rest of that window's facts. No route blocklists, no per-window special\n// cases, no `if (pathname === \"/exports\")` anywhere.\n//\n// DEFAULT DENY. A window that declares no home cannot raise itself anywhere,\n// and the refusal is announced on the console naming the window — a raiser that\n// silently never fires is indistinguishable from a broken one.\n//\n// THIS GOVERNS UNBIDDEN RAISES ONLY. A person clicking something that opens a\n// window is not asking this question: the ordinary openers\n// (`features/overlays/openers/*`) are untouched and still work on every route.\n//\n// DEFERRING IS NOT DISCARDING. An \"away from home\" refusal means \"not here, not\n// yet\" — the caller must leave its own once-per-day / once-per-session\n// bookkeeping ALONE so the window still raises on the viewer's next visit to a\n// home route.\n//\n// Doc: features/window-panels/FEATURE.md\n\nimport { getOverlayMeta, type UnbiddenHomeRoute } from \"@ai-matrx/summon\";\n\nexport type UnbiddenRefusalCode =\n /** The registry entry declares no `unbiddenHome` (or there is no entry). */\n | \"no-declared-home\"\n /** It has a home; the viewer is not on it. Try again when they are. */\n | \"away-from-home\";\n\nexport interface UnbiddenRaiseVerdict {\n /** True only when this window may raise itself, here, right now. */\n allowed: boolean;\n /** Plain-English why, for logs and for the caller's own warning. */\n reason: string;\n /** Set only when `allowed` is false. */\n code?: UnbiddenRefusalCode | undefined;\n /** The routes this window declared as home, for diagnostics (exact ones end in \" (exact)\"). */\n home: readonly string[];\n}\n\n/**\n * True when `pathname` is `route` itself or a page nested under it.\n * `/administration` covers `/administration/spend`; it does not cover\n * `/administration-archive`.\n */\nexport function isUnderRoute(pathname: string, route: string): boolean {\n if (pathname === route) return true;\n const base = route.endsWith(\"/\") ? route.slice(0, -1) : route;\n return pathname === base || pathname.startsWith(`${base}/`);\n}\n\nfunction describeHome(h: UnbiddenHomeRoute): string {\n return typeof h === \"string\" ? h : `${h.route} (exact)`;\n}\n\n/**\n * May this window raise ITSELF — with nobody having clicked anything — while\n * the viewer is on `pathname`?\n *\n * Refusals are announced, never swallowed: a window with no declared home\n * warns (that is a registry bug someone must fix), and an away-from-home\n * deferral logs at info (that is the system working as designed).\n */\nexport function mayRaiseUnbidden(\n overlayId: string,\n pathname: string | null | undefined,\n): UnbiddenRaiseVerdict {\n const entry = getOverlayMeta(overlayId);\n const declared: readonly UnbiddenHomeRoute[] = entry?.window?.unbiddenHome ?? [];\n const home = declared.map(describeHome);\n\n if (home.length === 0) {\n const reason = entry\n ? `window \"${overlayId}\" declared no unbiddenHome in the window registry, so it may not open itself on any route`\n : `overlay \"${overlayId}\" is not in the window registry, so it has no declared home and may not open itself anywhere`;\n console.warn(`[window-panels] unbidden raise refused — ${reason}`);\n return { allowed: false, reason, code: \"no-declared-home\", home };\n }\n\n if (!pathname) {\n const reason = `window \"${overlayId}\" was asked to open itself with no current route, so its home (${home.join(\", \")}) could not be confirmed`;\n console.warn(`[window-panels] unbidden raise refused — ${reason}`);\n return { allowed: false, reason, code: \"away-from-home\", home };\n }\n\n const matched = declared.find((h) =>\n typeof h === \"string\" ? isUnderRoute(pathname, h) : pathname === h.route,\n );\n const match = matched === undefined ? undefined : describeHome(matched);\n if (!match) {\n const reason = `window \"${overlayId}\" lives on ${home.join(\", \")} — not on \"${pathname}\" — so it is deferred until the viewer is on one of its own surfaces`;\n console.info(`[window-panels] unbidden raise deferred — ${reason}`);\n return { allowed: false, reason, code: \"away-from-home\", home };\n }\n\n return {\n allowed: true,\n reason: `window \"${overlayId}\" is on its declared home \"${match}\"`,\n home,\n };\n}\n","/**\n * assertLazyLoaded — an OPT-IN bundle guard for lazily rendered modules.\n *\n * Call it at the top level of a module that must only ever load through a lazy render import\n * (`render: () => import(\"./x.render\")`). If the module is parsed during initial app boot — i.e.\n * something statically imported it into the boot graph — a loud warning names the module and the\n * eager-import chain, once per module per session. A host opts in per module; nothing in this\n * package calls it.\n *\n * Boot detection: \"boot\" is the synchronous first evaluation pass. A global slot holds the flag\n * so an HMR re-evaluation or a duplicated module graph never re-enters boot.\n */\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\ninterface GuardState {\n bootInProgress: boolean;\n readonly reported: Set<string>;\n}\n\nconst guard = (): GuardState =>\n globalSlot<GuardState>(\"ai-matrx.summon.lazyBundleGuard\", () => {\n const state: GuardState = { bootInProgress: typeof window !== \"undefined\", reported: new Set() };\n if (state.bootInProgress) {\n setTimeout(() => {\n state.bootInProgress = false;\n }, 0);\n }\n return state;\n });\n\n// Start the boot clock when this module first evaluates (it is evaluated with its importer).\nguard();\n\n/**\n * Warn when `moduleId` is evaluated during boot. `report` replaces the default console warning\n * (route it to the host's error sink).\n */\nexport function assertLazyLoaded(moduleId: string, report?: (message: string, stack: string) => void): void {\n if (typeof window === \"undefined\") return;\n // Capture the stack NOW, while the eager-import chain is still live.\n const callSiteStack = (new Error(\"call site\").stack ?? \"\")\n .split(\"\\n\")\n .filter((line) => !/lazy-bundle-guard\\.|at Error\\s*$|^Error/i.test(line))\n .join(\"\\n\");\n queueMicrotask(() => {\n const state = guard();\n if (!state.bootInProgress || state.reported.has(moduleId)) return;\n state.reported.add(moduleId);\n const message =\n `${moduleId} was parsed during initial app boot. Lazily rendered modules MUST load through ` +\n `their definition's render import — never statically from a route, layout, provider, or any ` +\n `module in the boot graph. (Reported once per session per module.)`;\n if (report) {\n report(message, callSiteStack);\n return;\n }\n console.warn(\n \"[overlays bundle leak]\",\n `\\n${message}${callSiteStack ? `\\n\\nEager-import chain (top frame is the file that statically imported it):\\n${callSiteStack}` : \"\"}`,\n );\n });\n}\n"],"mappings":";;;AAaA,OAAO,SAAS,eAAAA,cAAa,aAAAC,YAAW,SAAAC,QAAO,iBAAiB,UAAAC,SAAQ,YAAAC,iBAAgB;AACxF,SAAS,oBAAoB,iBAAAC,gBAAe,0BAAAC,yBAAwB,oBAAoB,2BAAAC,gCAA+B;AACvH,SAAS,qBAAqB,gBAAgB,uBAAuB;AACrE,SAAS,MAAAC,WAAU;AACnB,SAAS,mBAAmB;AAC5B,SAAS,gBAAAC,qBAAoB;AAC7B;AAAA,EACE;AAAA,EACA,mBAAAC;AAAA,EACA;AAAA,EACA,uBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA,qBAAAC;AAAA,EACA;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,4BAA4B,qBAAAC,oBAAmB,kBAAAC,iBAAgB,qBAAAC,oBAAmB,kBAAAC,uBAAsB;;;AC3B3G,SAmBqB,UAnBrB,KAmBqB,YAnBrB;AAHN,SAAS,MAAM,UAAiC;AAC9C,SAAO,SAAS,MAAM,OAAwB;AAC5C,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,QAAO;AAAA,QACP,aAAa;AAAA,QACb,eAAc;AAAA,QACd,gBAAe;AAAA,QACf,eAAW;AAAA,QACV,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEO,IAAM,QAAQ,MAAM,iCAAE;AAAA,sBAAC,UAAK,GAAE,cAAa;AAAA,EAAE,oBAAC,UAAK,GAAE,cAAa;AAAA,GAAE,CAAG;AACvE,IAAM,YAAY,MAAM,oBAAC,UAAK,GAAE,YAAW,CAAE;AAC7C,IAAM,gBAAgB,MAAM,iCAAE;AAAA,sBAAC,UAAK,GAAE,aAAY;AAAA,EAAE,oBAAC,UAAK,GAAE,aAAY;AAAA,EAAE,oBAAC,UAAK,GAAE,aAAY;AAAA,EAAE,oBAAC,UAAK,GAAE,cAAa;AAAA,GAAE,CAAG;AAC1H,IAAM,gBAAgB,MAAM,iCAAE;AAAA,sBAAC,UAAK,GAAE,cAAa;AAAA,EAAE,oBAAC,UAAK,GAAE,eAAc;AAAA,EAAE,oBAAC,UAAK,GAAE,aAAY;AAAA,EAAE,oBAAC,UAAK,GAAE,aAAY;AAAA,GAAE,CAAG;AAC5H,IAAM,wBAAwB,MAAM,oBAAC,UAAK,OAAM,MAAK,QAAO,MAAK,GAAE,KAAI,GAAE,KAAI,IAAG,KAAI,CAAE;AACtF,IAAM,qBAAqB,MAAM,iCAAE;AAAA,sBAAC,UAAK,OAAM,MAAK,QAAO,MAAK,GAAE,KAAI,GAAE,KAAI,IAAG,KAAI;AAAA,EAAE,oBAAC,UAAK,GAAE,WAAU;AAAA,EAAE,oBAAC,UAAK,GAAE,kBAAiB;AAAA,GAAE,CAAG;AACvI,IAAM,gBAAgB,MAAM,iCAAE;AAAA,sBAAC,UAAK,OAAM,MAAK,QAAO,MAAK,GAAE,KAAI,GAAE,KAAI,IAAG,KAAI;AAAA,EAAE,oBAAC,UAAK,GAAE,WAAU;AAAA,GAAE,CAAG;AACvG,IAAM,gBAAgB,MAAM,iCAAE;AAAA,sBAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,MAAK,QAAO,MAAK,IAAG,KAAI;AAAA,EAAE,oBAAC,UAAK,GAAE,WAAU;AAAA,EAAE,oBAAC,UAAK,GAAE,WAAU;AAAA,EAAE,oBAAC,UAAK,GAAE,UAAS;AAAA,GAAE,CAAG;AAC9I,IAAM,WAAW;AAAA,EACtB,iCACE;AAAA,wBAAC,UAAK,GAAE,sGAAqG;AAAA,IAC7G,oBAAC,UAAK,GAAE,6CAA4C;AAAA,IACpD,oBAAC,UAAK,GAAE,0BAAyB;AAAA,KACnC;AACF;AACO,IAAM,oBAAoB;AAAA,EAC/B,iCACE;AAAA,wBAAC,UAAK,GAAE,4EAA2E;AAAA,IACnF,oBAAC,UAAK,GAAE,WAAU;AAAA,IAClB,oBAAC,UAAK,GAAE,cAAa;AAAA,KACvB;AACF;AACO,IAAM,sBAAsB,MAAM,iCAAE;AAAA,sBAAC,UAAK,GAAE,WAAU;AAAA,EAAE,oBAAC,UAAK,GAAE,iBAAgB;AAAA,EAAE,oBAAC,UAAK,GAAE,YAAW;AAAA,GAAE,CAAG;;;ACvDjH,SAAS,UAAU;AA2CX,SACE,OAAAC,MADF,QAAAC,aAAA;AAlBD,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AACF,GAGG;AACD,QAAM,UACJ;AACF,QAAM,SAAS;AACf,QAAM,UAAU;AAChB,QAAM,UAAU;AAEhB,MAAI,UAAqB;AAEzB,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,gBACE,gBAAAA,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,QAC5C,gBAAAA,KAAC,SAAI,WAAU,gBAAe;AAAA,SAChC;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,gBAAe;AAAA,QAC9B,gBAAAA,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,SAC9C;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,QAC5C,gBAAAA,KAAC,SAAI,WAAU,gBAAe;AAAA,SAChC;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,gBAAe;AAAA,QAC9B,gBAAAA,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,SAC9C;AAEF;AAAA,IACF,KAAK;AACH,gBAAU,gBAAAA,KAAC,SAAI,WAAW,GAAG,eAAe,MAAM,GAAG;AACrD;AAAA,IACF,KAAK;AACH,gBAAU,gBAAAA,KAAC,SAAI,WAAW,GAAG,iBAAiB,MAAM,GAAG;AACvD;AAAA;AAAA,IAGF,KAAK;AACH,gBACE,gBAAAA,KAAC,SAAI,WAAU,wDACZ,WAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACjB,gBAAAA,KAAC,SAAY,WAAW,UAAd,CAAsB,CACjC,GACH;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAA,KAAC,SAAI,WAAU,wDACZ,WAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACvB,gBAAAA,KAAC,SAAY,WAAW,UAAd,CAAsB,CACjC,GACH;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAA,KAAC,SAAI,WAAU,wDACZ,WAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAC7B,gBAAAA,KAAC,SAAY,WAAW,UAAd,CAAsB,CACjC,GACH;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAA,KAAC,SAAI,WAAU,wDACZ,WAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAChC,gBAAAA,KAAC,SAAY,WAAW,UAAd,CAAsB,CACjC,GACH;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAA,KAAC,SAAI,WAAU,wDACZ,WAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC,MAC5C,gBAAAA,KAAC,SAAY,WAAW,UAAd,CAAsB,CACjC,GACH;AAEF;AAAA;AAAA,IAGF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,gBAAe;AAAA,QAC9B,gBAAAC,MAAC,SAAI,WAAU,wCACb;AAAA,0BAAAD,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,UAC5C,gBAAAA,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,WAC9C;AAAA,SACF;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,gBAAe;AAAA,QAC9B,gBAAAA,KAAC,SAAI,WAAU,wCACZ,WAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACd,gBAAAA,KAAC,SAAY,WAAW,GAAG,iBAAiB,MAAM,KAAxC,CAA2C,CACtD,GACH;AAAA,SACF;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,gBAAe;AAAA,QAC9B,gBAAAA,KAAC,SAAI,WAAU,wCACZ,WAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACjB,gBAAAA,KAAC,SAAY,WAAW,GAAG,iBAAiB,MAAM,KAAxC,CAA2C,CACtD,GACH;AAAA,SACF;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,gBAAe;AAAA,QAC9B,gBAAAA,KAAC,SAAI,WAAU,wCACZ,WAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACpB,gBAAAA,KAAC,SAAY,WAAW,GAAG,iBAAiB,MAAM,KAAxC,CAA2C,CACtD,GACH;AAAA,SACF;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAA,MAAC,SAAI,WAAU,wCACb;AAAA,0BAAAD,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,UAC5C,gBAAAA,KAAC,SAAI,WAAW,GAAG,gBAAgB,MAAM,GAAG;AAAA,WAC9C;AAAA,QACA,gBAAAA,KAAC,SAAI,WAAU,gBAAe;AAAA,SAChC;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,wCACZ,WAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACd,gBAAAA,KAAC,SAAY,WAAW,GAAG,iBAAiB,MAAM,KAAxC,CAA2C,CACtD,GACH;AAAA,QACA,gBAAAA,KAAC,SAAI,WAAU,gBAAe;AAAA,SAChC;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,wCACZ,WAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACjB,gBAAAA,KAAC,SAAY,WAAW,GAAG,iBAAiB,MAAM,KAAxC,CAA2C,CACtD,GACH;AAAA,QACA,gBAAAA,KAAC,SAAI,WAAU,gBAAe;AAAA,SAChC;AAEF;AAAA,IACF,KAAK;AACH,gBACE,gBAAAC,MAAC,SAAI,WAAW,SACd;AAAA,wBAAAD,KAAC,SAAI,WAAU,wCACZ,WAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACpB,gBAAAA,KAAC,SAAY,WAAW,GAAG,iBAAiB,MAAM,KAAxC,CAA2C,CACtD,GACH;AAAA,QACA,gBAAAA,KAAC,SAAI,WAAU,gBAAe;AAAA,SAChC;AAEF;AAAA,EACJ;AAEA,SAAO,gBAAAA,KAAC,SAAI,WAAW,GAAG,SAAS,SAAS,GAAI,mBAAQ;AAC1D;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,MACxC,OAAO;AAAA,MAEP,0BAAAA,KAAC,cAAW,MAAY;AAAA;AAAA,EAC1B;AAEJ;;;ACzOA,SAAS,WAAW,QAAQ,aAAa,OAAO,gBAAgB;AAChE,SAAS,mBAAmB,mBAAmB,sBAAsB;AACrE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,OACK;;;ACmBA,IAAM,0BAAyC;AAAA,EACpD,kBAAkB;AAAA,EAClB,SAAS;AACX;AAEO,IAAM,yBAAuC;AAAA,EAClD,aAAa;AAAA,EACb,gBAAgB;AAClB;AAYO,SAAS,gBACd,GACA,MACA,KACA,KACA,KACA,KACmB;AACnB,QAAM,EAAE,SAAS,QAAQ,IAAI;AAC7B,QAAM,EAAE,kBAAkB,QAAQ,IAAI;AAItC,QAAM,WAAW,CAAC;AAClB,QAAM,YAAY,UAAU;AAC5B,QAAM,UAAU,CAAC;AACjB,QAAM,aAAa,UAAU;AAC7B,QAAM,UAAU,KAAK,IAAI,UAAU,WAAW,SAAS,UAAU;AAEjE,QAAM,kBAAkB,WAAW;AAEnC,MAAI,CAAC,iBAAiB;AAEpB,QAAI,KAAK,eAAe,KAAK,mBAAmB,MAAM;AACpD,aAAO;AAAA,QACL,OAAO,EAAE,aAAa,OAAO,gBAAgB,KAAK;AAAA,QAClD,eAAe;AAAA,MACjB;AAAA,IACF;AACA,WAAO,EAAE,OAAO,MAAM,eAAe,MAAM;AAAA,EAC7C;AAKA,QAAM,eAAe,KAAK,kBAAkB;AAC5C,QAAM,WAAW,MAAM,gBAAgB;AACvC,QAAM,eAAe,KAAK;AAC1B,QAAM,eAAe;AAErB,SAAO;AAAA,IACL,OAAO,EAAE,aAAa,cAAc,gBAAgB,aAAa;AAAA,IACjE,eAAe,CAAC,gBAAgB;AAAA,EAClC;AACF;;;AD5EA,SAAS,wBAAwB;;;AEtBjC,SAAS,kBAAkB;AAE3B,IAAM,MAAM;AACZ,IAAM,cAAc;AAEb,IAAM,sBAAsB;AAEnC,SAAS,QAAqB;AAC5B,SAAO,WAAwB,0CAA0C,MAAM,oBAAI,IAAY,CAAC;AAClG;AAEA,IAAM,UAAU,CAAC,WAAmB,eAClC,GAAG,SAAS,KAAK,UAAU;AAGtB,SAAS,eAAe,WAAmB,YAA0B;AAC1E,QAAM,EAAE,IAAI,QAAQ,WAAW,UAAU,CAAC;AAC5C;AAGO,SAAS,aAAa,WAAmB,YAA6B;AAC3E,SAAO,MAAM,EAAE,IAAI,QAAQ,WAAW,UAAU,CAAC;AACnD;AAGO,SAAS,gBAAgB,WAAmB,YAA0B;AAC3E,QAAM,EAAE,OAAO,QAAQ,WAAW,UAAU,CAAC;AAC/C;AAGA,SAAS,cAAsB;AAC7B,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,MAAM,iBAAiB,SAAS,eAAe,EAAE,iBAAiB,kBAAkB;AAC1F,QAAM,KAAK,OAAO,WAAW,GAAG;AAChC,SAAO,OAAO,SAAS,EAAE,KAAK,KAAK,IAAI,KAAK;AAC9C;AAEA,IAAM,mBACJ;AAGK,SAAS,uBAA+D;AAC7E,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,OACJ,SAAS,cAA2B,0BAA0B,KAC9D,SAAS,cAA2B,MAAM,KAC1C,SAAS,cAA2B,aAAa;AACnD,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,WAAW,KAAK,sBAAsB;AAC5C,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,QAAM,QAAQ,KAAK,iBAA8B,gBAAgB;AACjE,QAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ,GAAG;AACxC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK,GAAG;AACjC,UAAM,KAAK,MAAM,CAAC;AAClB,QAAI,CAAC,GAAI;AAET,QAAI,GAAG,QAAQ,0CAA0C,EAAG;AAC5D,UAAM,IAAI,GAAG,sBAAsB;AACnC,QAAI,EAAE,QAAQ,KAAK,EAAE,SAAS,EAAG;AACjC,QAAI,EAAE,SAAS,SAAS,OAAO,EAAE,MAAM,SAAS,OAAQ;AACxD,QAAI,EAAE,QAAQ,KAAK,EAAE,OAAO,OAAO,WAAY;AAC/C,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI;AAC5B,YAAQ,KAAK,IAAI,OAAO,EAAE,KAAK;AAAA,EACjC;AACA,SAAO,OAAO,SAAS,IAAI,IAAI,EAAE,MAAM,MAAM,IAAI;AACnD;AAGO,IAAM,0BAA0B;AAOhC,SAAS,kBAA2B;AACzC,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,KAAK,OAAO;AAClB,MAAI,KAAK,IAAK,QAAO;AACrB,QAAM,SAAS,qBAAqB;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,WACJ,SAAS,cAA2B,MAAM,GAAG,sBAAsB,EAAE,QAAQ;AAC/E,QAAM,OAAO,KAAK,IAAI,KAAK,YAAY,IAAI,OAAO,QAAQ,MAAM,GAAG,OAAO,OAAO,WAAW,MAAM,CAAC;AACnG,SAAO,QAAQ;AACjB;AAWO,SAAS,yBAAyB,MAQnB;AACpB,QAAM,EAAE,GAAG,IAAI,KAAK;AAEpB,QAAM,KAAK,KAAK,SAAS,KAAK,YAAY;AAC1C,QAAM,SAAS,qBAAqB;AACpC,QAAM,YAAY,SAAS,KAAK,OAAO,QAAQ,MAAM,IAAI;AACzD,QAAM,WACJ,OAAO,aAAa,cACf,SAAS,cAA2B,MAAM,GAAG,sBAAsB,EACjE,QAAQ,IACX;AACN,QAAM,WAAW,SAAS,OAAO,OAAO,WAAW,MAAM,IAAI;AAC7D,QAAM,OAAO,aAAa,WAAW,UAAU;AAC/C,QAAM,OAAO,KAAK,IAAI,WAAW,QAAQ;AACzC,QAAM,OAAO,KAAK,IAAI,KAAK,UAAU,mBAAmB;AACxD,QAAM,SAA4B;AAAA,IAChC,MAAM;AAAA,MACJ,GAAG,KAAK,IAAI,KAAK,KAAK,KAAK,QAAQ,GAAG;AAAA,MACtC,GAAG,KAAK;AAAA,MACR,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,IACA,WAAW;AAAA,EACb;AACA,MAAI,OAAO,KAAM,QAAO;AAExB,QAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC;AACnE,QAAM,IACJ,SAAS,UACL,KAAK,QAAQ,MACb,KAAK,IAAI,KAAK,KAAK,MAAM,WAAW,GAAG,CAAC;AAE9C,QAAM,WAAW,KAAK,SAAS;AAAA,IAC7B,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,EAAE,IAAI,IAAI;AAAA,EACxC;AACA,QAAM,IAAI,SAAS,SACf,KAAK,IAAI,GAAG,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,cACnD,KAAK;AACT,QAAM,OAAO,KAAK,IAAI;AACtB,MAAI,OAAO,KAAK,UAAW,QAAO;AAClC,QAAM,QAAQ,SAAS,SAAS,OAAO,KAAK,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC3E,QAAM,SAAS,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,WAAW,KAAK,IAAI,KAAK,QAAQ,KAAK,CAAC,CAAC;AACpF,SAAO,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,OAAO,GAAG,WAAW,MAAM;AAC3D;;;AF5HA,SAAS,sBAAuC;AAIhD,IAAM,YAAY;AAClB,IAAM,aAAa;AACnB,IAAM,gBAAgB;AACtB,IAAM,iBAAiB;AAevB,IAAM,gBAAgD;AAAA,EACpD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAYA,SAAS,YACP,OACA,UACQ;AACR,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,EAAE,IAAI,GAAG,IAAI,iBAAiB;AACpC,MAAI,MAAM,SAAS,IAAI,EAAG,QAAO,KAAK,MAAO,WAAW,KAAK,IAAI,MAAO,EAAE;AAC1E,MAAI,MAAM,SAAS,IAAI,EAAG,QAAO,KAAK,MAAO,WAAW,KAAK,IAAI,MAAO,EAAE;AAC1E,SAAO,WAAW,KAAK,KAAK;AAC9B;AAOA,IAAM,gBAAgB,uBAAO,IAAI,mCAAmC;AACpE,IAAM,eAAe;AACrB,IAAM,eAAe;AAEd,SAAS,4BAAkC;AAChD,EAAC,WAAiD,aAAa,IAAI;AACrE;AAEA,SAAS,kBAA0B;AACjC,QAAM,OAAO;AACb,QAAM,OAAO,KAAK,aAAa,KAAK;AACpC,OAAK,aAAa,IAAI,OAAO;AAC7B,SAAQ,OAAO,eAAgB;AACjC;AAyBA,IAAM,kBAAkB;AAGxB,IAAM,aAAa,oBAAI,IAAY;AAEnC,IAAM,YAAY,oBAAI,IAAoB;AAC1C,IAAI,gBAAgB;AACpB,IAAM,gBAAgB,CAAC,OACrB,CAAC,UACC,MAAM,OAAO,MACb,MAAM,UAAU,cAChB,WAAW,IAAI,MAAM,EAAE,MACtB,UAAU,IAAI,MAAM,EAAE,KAAK,MAAM,UAAU,IAAI,EAAE,KAAK;AAE3D,IAAM,qBAAqB;AAG3B,SAAS,uBAA+B;AACtC,QAAME,OAAM;AACZ,MAAI,OAAO,aAAa,YAAa,QAAO,KAAKA;AACjD,QAAM,OAAO,iBAAiB,SAAS,eAAe;AACtD,QAAM,MAAM,KAAK,iBAAiB,kBAAkB,EAAE,KAAK;AAG3D,QAAM,IAAI,WAAW,GAAG;AACxB,QAAM,IAAI,IAAI,SAAS,KAAK,IACxB,KAAK,WAAW,KAAK,QAAQ,KAAK,MAClC;AACJ,UAAQ,OAAO,SAAS,CAAC,KAAK,IAAI,IAAI,IAAI,MAAMA;AAClD;AAEO,SAAS,gBACd,KACA,GACA,GAC0B;AAC1B,QAAM,EAAE,IAAI,GAAG,IAAI,iBAAiB;AACpC,QAAM,MAAM;AAIZ,QAAM,MAAM,qBAAqB;AACjC,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO,EAAE,GAAG,KAAK,GAAG,IAAI;AAAA,IAC1B,KAAK;AACH,aAAO,EAAE,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,GAAG,IAAI;AAAA,IAChD,KAAK;AACH,aAAO,EAAE,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE;AAAA,IAChD,KAAK;AACH,aAAO,EAAE,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE;AAAA,IACtE,KAAK;AAGH,aAAO;AAAA,QACL,GAAG,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,QAC3B,GAAG,KAAK,IAAI,MAAM,KAAK,KAAK,CAAC;AAAA,MAC/B;AAAA,IACF,SAAS;AACP,YAAM,UAAU,gBAAgB;AAChC,UAAI,KAAK,iBAAiB;AACxB,eAAO;AAAA,UACL,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC,CAAC;AAAA,UAC7C,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,OAAO,CAAC;AAAA,QAChD;AAAA,MACF;AACA,aAAO;AAAA,QACL,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,OAAO;AAAA,QACrC,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,OAAO,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAwGO,SAAS,eACd,OAA8B,CAAC,GACT;AACtB,QAAM,UAAU,MAAM;AACtB,QAAM,KAAK,KAAK,MAAM;AAEtB,QAAM,WAAW,kBAAkB;AACnC,QAAM,QAAQ,eAAe;AAC7B,QAAM,QAAQ,kBAAkB,aAAa,EAAE,CAAC;AAEhD,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,YAAY,KAAK,aAAa;AAGpC,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AAGxD,YAAU,MAAM;AACd,UAAM,IAAI,KAAK,aAAa,SAAS,YAAY,KAAK,OAAO,aAAa;AAC1E,UAAM,IACJ,KAAK,aAAa,UAAU,YAAY,KAAK,QAAQ,cAAc;AACrE,UAAM,EAAE,IAAI,GAAG,IAAI,iBAAiB;AACpC,QAAI,aAAiE;AACrE,QAAI,KAAK,cAAc,MAAM,iBAAiB;AAC5C,UAAI,CAAC,UAAU,IAAI,EAAE,EAAG,WAAU,IAAI,IAAI,eAAe;AACzD,YAAM,WAAW,OAAO,OAAO,MAAM,SAAS,EAAE,cAAc,OAAO,EAClE,OAAO,cAAc,EAAE,CAAC,EACxB,IAAI,CAAC,QAAQ,IAAI,QAAQ;AAC5B,mBAAa,yBAAyB;AAAA,QACpC,OAAO;AAAA,QACP,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,KAAK,qBAAqB;AAAA,QAC1B,UAAU,EAAE,IAAI,GAAG;AAAA,QACnB;AAAA,MACF,CAAC;AACD,UAAI,CAAC,WAAW,UAAW,YAAW,IAAI,EAAE;AAAA,eACnC,KAAK,aAAc,QAAO,WAAW,MAAM,KAAK,eAAe,GAAG,CAAC;AAAA,IAC9E;AACA,UAAM,MAAM,aACR,EAAE,GAAG,WAAW,KAAK,GAAG,GAAG,WAAW,KAAK,EAAE,IAC7C,KAAK,aAAa,MAAM,UAAa,KAAK,aAAa,MAAM,SAC3D;AAAA,MACE,GAAG,KAAK,aAAa,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,MAClD,GAAG,KAAK,aAAa,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,IACpD,IACA,gBAAgB,KAAK,UAAU,GAAG,CAAC;AACzC,UAAM,UAAsB,aACxB,EAAE,GAAG,WAAW,KAAK,IACrB,EAAE,GAAG,KAAK,OAAO,GAAG,QAAQ,EAAE;AAClC;AAAA,MACE,eAAe;AAAA,QACb;AAAA,QACA,GAAI,KAAK,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;AAAA,QACxD;AAAA,QACA,GAAI,YAAY,YAAY,EAAE,cAAc,YAAqB,IAAI,KAAK,iBAAiB,SAAY,CAAC,IAAI,EAAE,cAAc,KAAK,aAAa;AAAA,QAC9I,GAAI,KAAK,gBAAgB,SAAY,CAAC,IAAI,EAAE,aAAa,KAAK,YAAY;AAAA;AAAA;AAAA,QAG1E,UAAU,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,MACpC,CAAC;AAAA,IACH;AACA,UAAM,aAAa,KAAK,cACpB;AAAA,MACE,KAAK,YAAY;AAAA,MACjB,KAAK,YAAY;AAAA,IACnB,IACA;AAIJ,UAAM,oBAAoB,aACtB,OAAO,WAAW,MAAM;AACtB,eAAS,sBAAsB,UAAU,CAAC;AAAA,IAC5C,GAAG,CAAC,IACJ;AACJ,WAAO,MAAM;AACX,UAAI,sBAAsB,KAAM,QAAO,aAAa,iBAAiB;AACrE,iBAAW,OAAO,EAAE;AACpB,gBAAU,OAAO,EAAE;AACnB,eAAS,iBAAiB,EAAE,CAAC;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,EAAE,CAAC;AAMP,QAAM,iBAAiB,OAAO,KAAK;AACnC,YAAU,MAAM;AACd,QAAI,cAAe,gBAAe,UAAU;AAAA,EAC9C,GAAG,CAAC,aAAa,CAAC;AAClB,YAAU,MAAM;AACd,QAAI,CAAC,KAAK,WAAY,QAAO;AAC7B,QAAI,QAAQ;AACZ,QAAI,gBAAgC;AACpC,UAAM,QAAQ,OAAO,YAAY,MAAM;AACrC,eAAS;AACT,UAAI,QAAQ,oBAAoB;AAC9B,eAAO,cAAc,KAAK;AAC1B;AAAA,MACF;AACA,YAAM,MAAM,MAAM,SAAS,EAAE,cAAc,QAAQ,EAAE;AACrD,UAAI,CAAC,OAAO,eAAe,QAAS;AACpC,YAAM,EAAE,IAAI,GAAG,IAAI,iBAAiB;AACpC,UAAI,KAAK,gBAAiB;AAC1B,YAAM,QAAQ,IAAI,UAAU;AAE5B,UAAI,kBAAkB,QAAQ,UAAU,eAAe;AACrD,uBAAe,UAAU;AACzB;AAAA,MACF;AACA,UAAI,IAAI,UAAU,cAAc,CAAC,MAAO;AACxC,YAAM,WAAW,OAAO,OAAO,MAAM,SAAS,EAAE,cAAc,OAAO,EAClE,OAAO,cAAc,EAAE,CAAC,EACxB,IAAI,CAAC,MAAM,EAAE,QAAQ;AACxB,YAAM,OAAO,yBAAyB;AAAA,QACpC,OAAO,IAAI,SAAS;AAAA,QACpB,QAAQ,IAAI,SAAS;AAAA,QACrB;AAAA,QACA;AAAA,QACA,KAAK,qBAAqB;AAAA,QAC1B,UAAU,EAAE,IAAI,GAAG;AAAA,QACnB;AAAA,MACF,CAAC;AACD,UAAI,KAAK,WAAW;AAClB,mBAAW,OAAO,EAAE;AACpB,YAAI,KAAK,cAAc;AACrB,iBAAO,cAAc,KAAK;AAC1B,eAAK,aAAa;AAClB;AAAA,QACF;AACA,YAAI,CAAC,OAAO;AACV,mBAAS,eAAe,EAAE,IAAI,eAAe,IAAI,gBAAgB,GAAG,CAAC,CAAC;AAAA,QACxE;AACA,wBAAgB;AAChB;AAAA,MACF;AACA,iBAAW,IAAI,EAAE;AACjB,UAAI,MAAO,UAAS,cAAc,EAAE,CAAC;AACrC,YAAM,MAAM,MAAM,SAAS,EAAE,cAAc,QAAQ,EAAE,GAAG;AACxD,UACE,CAAC,OACD,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,KAChC,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,KAChC,KAAK,IAAI,IAAI,QAAQ,KAAK,KAAK,KAAK,IAAI,KACxC,KAAK,IAAI,IAAI,SAAS,KAAK,KAAK,MAAM,IAAI,GAC1C;AACA,iBAAS,iBAAiB,EAAE,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC;AAAA,MACpD;AACA,sBAAgB;AAAA,IAClB,GAAG,GAAI;AACP,WAAO,MAAM,OAAO,cAAc,KAAK;AAAA,EACzC,GAAG,CAAC,KAAK,YAAY,IAAI,UAAU,WAAW,OAAO,QAAQ,CAAC;AAG9D,YAAU,MAAM;AACd,QAAI,KAAK,UAAU,QAAW;AAC5B,eAAS,kBAAkB,EAAE,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,IAAI,KAAK,OAAO,QAAQ,CAAC;AAG7B,QAAM,YAAY,OAKR,IAAI;AAEd,QAAM,kBAAkB,KAAK;AAC7B,QAAM,qBAAqB,OAAO,eAAe;AACjD,YAAU,MAAM;AACd,uBAAmB,UAAU;AAAA,EAC/B,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,cAAc;AAAA,IAClB,CAAC,MAA0B;AACzB,QAAE,eAAe;AACjB,eAAS,YAAY,EAAE,CAAC;AAExB,UAAI,CAAC,SAAS,MAAM,UAAU,YAAa;AAC3C,gBAAU,UAAU;AAAA,QAClB,IAAI,EAAE;AAAA,QACN,IAAI,EAAE;AAAA,QACN,IAAI,MAAM,SAAS;AAAA,QACnB,IAAI,MAAM,SAAS;AAAA,MACrB;AACA,uBAAiB,IAAI;AAGrB,YAAM,gBAAgB,eAAe;AAIrC,UAAI,eAA6B;AAGjC,UAAI,cAAc,EAAE;AACpB,UAAI,cAAc,EAAE;AACpB,YAAM,gBAAgB,mBAAmB,YAAY;AAErD,YAAM,SAAS,CAAC,OAAqB;AACnC,YAAI,CAAC,UAAU,QAAS;AACxB,cAAM,KAAK,UAAU,QAAQ,MAAM,GAAG,UAAU,UAAU,QAAQ;AAClE,cAAM,KAAK,UAAU,QAAQ,MAAM,GAAG,UAAU,UAAU,QAAQ;AAClE,iBAAS,iBAAiB,EAAE,IAAI,MAAM,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC;AACzD,sBAAc,GAAG;AACjB,sBAAc,GAAG;AAGjB,YAAI,CAAC,cAAe;AACpB,cAAM,SAAS;AAAA,UACb,EAAE,SAAS,GAAG,SAAS,SAAS,GAAG,QAAQ;AAAA,UAC3C;AAAA,UACA;AAAA,UACA,OAAO;AAAA,UACP,OAAO;AAAA,UACP,YAAY,IAAI;AAAA,QAClB;AAGA,YAAI,OAAO,MAAM,gBAAgB,aAAa,aAAa;AACzD;AAAA,YACE,mBAAmB,EAAE,IAAI,OAAO,MAAM,cAAc,KAAK,KAAK,CAAC;AAAA,UACjE;AAAA,QACF;AACA,uBAAe,OAAO;AAAA,MACxB;AAEA,YAAM,OAAO,MAAM;AACjB,cAAM,eAAe,aAAa;AAClC,cAAM,aAAa,UAAU;AAC7B,kBAAU,UAAU;AACpB,yBAAiB,KAAK;AACtB,sBAAc;AACd,iBAAS,oBAAoB,eAAe,MAAM;AAClD,iBAAS,oBAAoB,aAAa,IAAI;AAC9C,iBAAS,oBAAoB,iBAAiB,IAAI;AAIlD,YAAI,iBAAiB,aAAa,aAAa;AAC7C,mBAAS,mBAAmB,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,QAC3C;AAKA,YAAI,gBAAgB,mBAAmB,WAAW,OAAO;AAIvD,gBAAM,WAAuB;AAAA,YAC3B,GAAG,YAAY,MAAM,MAAM,SAAS;AAAA,YACpC,GAAG,YAAY,MAAM,MAAM,SAAS;AAAA,YACpC,OAAO,MAAM,SAAS;AAAA,YACtB,QAAQ,MAAM,SAAS;AAAA,UACzB;AACA,6BAAmB,QAAQ,QAAQ;AAAA,QACrC,OAAO;AAOL,gBAAM,EAAE,IAAI,IAAI,WAAW,IAAI,iBAAiB;AAChD,cAAI,CAAC,YAAY;AACf;AAAA,cACE,gBAAgB,EAAE,IAAI,eAAe,IAAI,gBAAgB,GAAG,CAAC;AAAA,YAC/D;AAAA,UACF;AAAA,QACF;AAGA,aAAK;AACL,aAAK;AAAA,MACP;AACA,eAAS,iBAAiB,eAAe,MAAM;AAC/C,eAAS,iBAAiB,aAAa,IAAI;AAC3C,eAAS,iBAAiB,iBAAiB,IAAI;AAAA,IACjD;AAAA,IACA,CAAC,UAAU,IAAI,KAAK;AAAA,EACtB;AAGA,QAAM,gBAAgB;AAAA,IACpB,CAAC,SAAqB,CAAC,MAA0B;AAC/C,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAClB,eAAS,YAAY,EAAE,CAAC;AACxB,UAAI,CAAC,SAAS,MAAM,UAAU,WAAY;AAE1C,YAAM,UAAU,EAAE;AAClB,YAAM,UAAU,EAAE;AAClB,YAAM,EAAE,GAAG,GAAG,OAAO,OAAO,IAAI,MAAM;AACtC,uBAAiB,IAAI;AAErB,YAAM,gBAAgB,eAAe,cAAc,IAAI,CAAC;AAExD,YAAM,SAAS,CAAC,OAAqB;AACnC,cAAM,KAAK,GAAG,UAAU;AACxB,cAAM,KAAK,GAAG,UAAU;AACxB,YAAI,KAAK,GACP,KAAK,GACL,KAAK,OACL,KAAK;AAEP,YAAI,KAAK,SAAS,GAAG;AACnB,eAAK,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,QAAQ,EAAE,CAAC;AACxD,YAAI,KAAK,SAAS,GAAG;AACnB,eAAK,KAAK,IAAI,WAAW,KAAK,IAAI,WAAW,SAAS,EAAE,CAAC;AAC3D,YAAI,KAAK,SAAS,GAAG,GAAG;AACtB,eAAK,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,QAAQ,EAAE,CAAC;AACtD,eAAK,KAAK,QAAQ;AAAA,QACpB;AACA,YAAI,KAAK,SAAS,GAAG,GAAG;AACtB,eAAK,KAAK,IAAI,WAAW,KAAK,IAAI,WAAW,SAAS,EAAE,CAAC;AACzD,eAAK,KAAK,SAAS;AAAA,QACrB;AAEA;AAAA,UACE,iBAAiB;AAAA,YACf;AAAA,YACA,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,GAAG;AAAA,UAC9C,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,OAAO,MAAM;AACjB,yBAAiB,KAAK;AACtB,sBAAc;AACd,iBAAS,oBAAoB,eAAe,MAAM;AAClD,iBAAS,oBAAoB,aAAa,IAAI;AAC9C,iBAAS,oBAAoB,iBAAiB,IAAI;AAAA,MACpD;AACA,eAAS,iBAAiB,eAAe,MAAM;AAC/C,eAAS,iBAAiB,aAAa,IAAI;AAC3C,eAAS,iBAAiB,iBAAiB,IAAI;AAAA,IACjD;AAAA,IACA,CAAC,UAAU,IAAI,OAAO,UAAU,WAAW,UAAU,SAAS;AAAA,EAChE;AAGA,QAAM,UAAU,YAAY,MAAM,SAAS,YAAY,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;AAC3E,QAAM,YAAY;AAAA,IAChB,MAAM,SAAS,cAAc,EAAE,CAAC;AAAA,IAChC,CAAC,UAAU,EAAE;AAAA,EACf;AACA,QAAM,aAAa;AAAA,IACjB,MAAM,SAAS,eAAe,EAAE,CAAC;AAAA,IACjC,CAAC,UAAU,EAAE;AAAA,EACf;AACA,QAAM,aAAa,YAAY,MAAM;AACnC,UAAM,EAAE,IAAI,GAAG,IAAI,iBAAiB;AACpC;AAAA,MACE,eAAe,EAAE,IAAI,eAAe,IAAI,gBAAgB,GAAG,CAAC;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,UAAU,EAAE,CAAC;AACjB,QAAM,mBAAmB,YAAY,MAAM;AACzC,QAAI,OAAO,UAAU,YAAa,UAAS,cAAc,EAAE,CAAC;AAAA,QACvD,UAAS,eAAe,EAAE,CAAC;AAAA,EAClC,GAAG,CAAC,UAAU,IAAI,KAAK,CAAC;AAGxB,QAAM,OAAmB,OAAO,YAAY;AAAA,IAC1C,GAAG;AAAA,IACH,GAAG;AAAA,IACH,OAAO,KAAK,aAAa,SAAS,YAAY,KAAK,OAAO,aAAa;AAAA,IACvE,QACE,KAAK,aAAa,UAAU,YAAY,KAAK,QAAQ,cAAc;AAAA,EACvE;AAEA,SAAO;AAAA,IACL;AAAA,IACA,aAAa,OAAO,SAAS;AAAA,IAC7B;AAAA,IACA,QAAQ,OAAO,UAAU;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AGvsBA,SAAS,4BAA4B;AAErC,IAAM,YAAY,MAAoB,MAAM;AAAC;AAGtC,SAAS,cAAuB;AACrC,SAAO,qBAAqB,WAAW,MAAM,MAAM,MAAM,KAAK;AAChE;;;ACPA,SAAS,wBAAAC,6BAA4B;AAGrC,IAAM,cAAc,MAAoB,MAAM;AAAC;AAGxC,SAAS,aAAa,OAA2B;AACtD,SAAOA;AAAA,IACL,MAAM,YAAY,CAAC,aAAa,MAAM,YAAY,QAAQ,MAAM,MAAM;AAAA,IAAC,KAAK;AAAA,IAC5E,MAAM,MAAM,QAAQ;AAAA,IACpB,MAAM;AAAA,EACR;AACF;;;AP+CA,SAAS,sBAAsB;;;AQpDxB,SAAS,wBACd,aACA,aACoB;AACpB,SAAO,eAAe;AACxB;;;ACNA,IAAM,UAAU,uBAAO,sBAAsB;AAE7C,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEO,SAAS,mBAAmB,OAAgB,aAAyD;AAC1G,MAAI,CAAC,SAAS,KAAK,KAAK,YAAY,WAAW,EAAG,QAAO,CAAC;AAC1D,QAAM,YAAY,oBAAI,QAAgB;AACtC,QAAM,OAAO,CAAC,SAA2B;AACvC,QAAI,SAAS,UAAa,OAAO,SAAS,cAAc,OAAO,SAAS,SAAU,QAAO;AACzF,QAAI,OAAO,SAAS,SAAU,QAAO,KAAK,SAAS;AACnD,QAAI,OAAO,SAAS,YAAY,CAAC,OAAO,SAAS,IAAI,EAAG,QAAO;AAC/D,QAAI,SAAS,QAAQ,OAAO,SAAS,SAAU,QAAO;AACtD,QAAI,gBAAgB,KAAM,QAAO,KAAK,OAAO;AAC7C,QAAI,UAAU,IAAI,IAAI,EAAG,QAAO;AAChC,cAAU,IAAI,IAAI;AAClB,QAAI;AACJ,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,eAAS,KAAK,IAAI,CAAC,UAAU;AAC3B,cAAM,SAAS,KAAK,KAAK;AACzB,eAAO,WAAW,UAAU,OAAO;AAAA,MACrC,CAAC;AAAA,IACH,WAAW,OAAO,eAAe,IAAI,MAAM,OAAO,aAAa,OAAO,eAAe,IAAI,MAAM,MAAM;AACnG,eAAS,OAAO;AAAA,QACd,OAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC7C,gBAAM,SAAS,KAAK,KAAK;AACzB,iBAAO,WAAW,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC;AAAA,QACjD,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,eAAS;AAAA,IACX;AACA,cAAU,OAAO,IAAI;AACrB,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,UAAU,IAAI,IAAI,WAAW;AACnC,UAAM,WAAW,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,QAAQ,IAAI,GAAG,CAAC,CAAC;AAC7F,cAAU,IAAI,KAAK;AACnB,UAAM,SAAS,KAAK,QAAQ;AAC5B,UAAM,SAAkB,KAAK,MAAM,KAAK,UAAU,WAAW,UAAU,CAAC,IAAI,MAAM,KAAK,IAAI;AAC3F,WAAO,SAAS,MAAM,IAAI,SAAS,CAAC;AAAA,EACtC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;ATUA,SAAS,iBAAiB,8BAA8B;;;AU7CxD,SAAS,YAAAC,iBAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,SAAS,MAAAC,WAAU;;;ACXnB,SAAS,MAAAC,WAAU;AA8ByB,gBAAAC,MAsBxC,QAAAC,aAtBwC;AA3BrC,IAAM,2BACX;AAEF,SAAS,YAAY,OAA4C;AAC/D,SAAO,OAAO,UAAU,YAAY,OAAO,UAAU;AACvD;AAQO,SAAS,uBAAuB,OAA0B;AAC/D,SAAO,YAAY,KAAK,IACpBF,IAAG,kBAAkB,wBAAwB,IAC7C;AACN;AAGO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AACF,GAGG;AACD,MAAI,SAAS,QAAQ,UAAU,GAAI,QAAO,gBAAAC,KAAC,SAAI,WAAWD,IAAG,kBAAkB,SAAS,GAAG;AAC3F,SACE,gBAAAC,KAAC,SAAI,4BAAyB,IAAG,WAAWD,IAAG,uBAAuB,KAAK,GAAG,SAAS,GACpF,iBACH;AAEJ;AAGO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,SACE,gBAAAE;AAAA,IAAC;AAAA;AAAA,MACC,gCAA6B;AAAA,MAC7B,WAAWF,IAAG,2CAA2C,SAAS;AAAA,MAEjE;AAAA;AAAA,QACA;AAAA,QACA;AAAA;AAAA;AAAA,EACH;AAEJ;AAGO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI,CAAC,WAAW,CAAC,QAAS,QAAO;AACjC,SACE,gBAAAE;AAAA,IAAC;AAAA;AAAA,MACC,kCAA+B;AAAA,MAC/B,WAAWF,IAAG,2CAA2C,SAAS;AAAA,MAEjE;AAAA;AAAA,QACA,UAAU,gBAAAC,KAAC,SAAI,WAAU,mCAAmC,mBAAQ,IAAS;AAAA;AAAA;AAAA,EAChF;AAEJ;;;ADiBoB,SAqBJ,YAAAE,WArBI,OAAAC,MAqBJ,QAAAC,aArBI;AApDL,SAAR,oBAAqC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,YAAY;AACd,GAA6B;AAC3B,QAAM,CAAC,aAAa,cAAc,IAAIC,UAAS,KAAK;AACpD,QAAM,aAAa,CAAC,CAAC;AAErB,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,cAAc,CAAC,SAAS;AACtB,YAAI,CAAC,KAAM,SAAQ;AAAA,MACrB;AAAA,MAEA;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,sBAAoB;AAAA,YACpB,WAAWE;AAAA,cACT;AAAA,cACA,gBAAgB,WAAW;AAAA,YAC7B;AAAA,YAMA;AAAA,8BAAAF,MAAC,SAAI,WAAU,+DAIb;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAU;AAAA,oBACV,UACE,YAAY,OACV,gBAAAA,KAAC,eAAY,SAAO,MAClB,0BAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,MAAK;AAAA,wBACL,SAAQ;AAAA,wBACR,MAAK;AAAA,wBACL,WAAU;AAAA,wBACV,cAAW;AAAA,wBAEX,0BAAAA,KAAC,SAAE,WAAU,WAAU;AAAA;AAAA,oBACzB,GACF;AAAA,oBAIJ,0BAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,4BAAyB;AAAA,wBACzB,WAAW,uBAAuB,KAAK;AAAA,wBAEtC;AAAA;AAAA,oBACH;AAAA;AAAA,gBACF;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,SACE,cACE,gBAAAA,KAAC,SAAI,WAAU,oCAAoC,uBAAY,IAC7D;AAAA,oBAEN,SACE,gBAAgB,aACd,gBAAAC,MAAAF,WAAA,EACG;AAAA;AAAA,sBACA,cACC,gBAAAC;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,SAAQ;AAAA,0BACR,MAAK;AAAA,0BACL,WAAU;AAAA,0BACV,cAAY,cAAc,kBAAkB;AAAA,0BAC5C,SAAS,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;AAAA,0BAEvC,0BAAAA,KAAC,iBAAY,WAAU,WAAU;AAAA;AAAA,sBACnC;AAAA,uBAEJ,IACE;AAAA;AAAA,gBAER;AAAA,iBACF;AAAA,cAGA,gBAAAA,KAAC,qBAAkB,WAAU,WAC1B,iBAAO,UAAU,WAAW,QAAQ,iBACvC;AAAA,cAIA,gBAAAC,MAAC,SAAI,WAAU,uCACZ;AAAA,8BAAc,cAAc,YAAY,eACvC,gBAAAD,KAAC,SAAI,WAAU,iEACZ,mBACH;AAAA,gBAEF,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAWG;AAAA,sBACT;AAAA,sBACA;AAAA,oBACF;AAAA,oBAEC;AAAA;AAAA,gBACH;AAAA,iBACF;AAAA,cAEC,UACC,gBAAAH,KAAC,SAAI,WAAU,sCAAsC,kBAAO;AAAA;AAAA;AAAA,QAEhE;AAAA,QAGC,cAAc,cAAc,YAC3B,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM;AAAA,YACN,cAAc;AAAA,YACd,WAAU;AAAA,YAEV,0BAAAC,MAAC,iBAAc,WAAU,wEACvB;AAAA,8BAAAA,MAAC,SAAI,WAAU,wEACb;AAAA,gCAAAD,KAAC,eAAY,WAAU,8BAA6B,kBAEpD;AAAA,gBACA,gBAAAA,KAAC,eAAY,SAAO,MAClB,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBAEX,0BAAAA,KAAC,SAAE,WAAU,WAAU;AAAA;AAAA,gBACzB,GACF;AAAA,iBACF;AAAA,cACA,gBAAAA,KAAC,qBAAkB,WAAU,WAAU,0BAEvC;AAAA,cACA,gBAAAA,KAAC,SAAI,WAAU,gCAAgC,mBAAQ;AAAA,eACzD;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AEzMA,SAAS,aAAAI,YAAW,UAAAC,eAA8B;AAClD,SAAS,oBAAoB;AAC7B,SAAS,eAAe,8BAA8B;AACtD,SAAS,UAAAC,eAAc;AACvB,SAAS,MAAAC,WAAU;AAyEb,SAWQ,OAAAC,MAXR,QAAAC,aAAA;AAnDS,SAAR,kBAAmC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAA2B;AACzB,QAAM,UAAUC,QAAuB,IAAI;AAG3C,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,QAAQ,CAAC,MAAqB;AAElC,UAAI,EAAE,QAAQ,YAAY,CAAC,EAAE,iBAAkB,SAAQ;AAAA,IACzD;AACA,aAAS,iBAAiB,WAAW,KAAK;AAC1C,WAAO,MAAM,SAAS,oBAAoB,WAAW,KAAK;AAAA,EAC5D,GAAG,CAAC,QAAQ,OAAO,CAAC;AAIpB,QAAM,SAAS,uBAAuB,IAAI;AAE1C,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,aAAa,YAAa,QAAO;AAE5C,SAAO;AAAA,IACL,gBAAAH,KAAC,iBACD,0BAAAC;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,sBAAoB;AAAA,QACpB,MAAK;AAAA,QACL,cAAW;AAAA,QACX,WAAWG;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA,QACF;AAAA,QACA,OAAO,EAAE,WAAW,QAAQ,eAAe,8BAA8B;AAAA,QAIzE;AAAA,0BAAAH,MAAC,SAAI,WAAU,8DACb;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,UACE,gBAAAA;AAAA,kBAACK;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,cAAW;AAAA,oBACX,SAAS;AAAA,oBAET,0BAAAL,KAAC,SAAE,WAAU,eAAc;AAAA;AAAA,gBAC7B;AAAA,gBAGF,0BAAAA,KAAC,qBAAkB,OAAc;AAAA;AAAA,YACnC;AAAA,YACA,gBAAAA,KAAC,0BAAuB,SAAS,cAAc;AAAA,aACjD;AAAA,UAGA,gBAAAA,KAAC,SAAI,WAAWI,IAAG,gCAAgC,aAAa,GAC7D,UACH;AAAA,UAEC,UACC,gBAAAJ,KAAC,SAAI,WAAU,sCAAsC,kBAAO;AAAA;AAAA;AAAA,IAEhE,GACA;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;ACrHA,SAAS,aAAAM,YAAW,YAAAC,iBAAgB;AAqD5B,gBAAAC,MAQI,QAAAC,aARJ;AA9CD,SAAS,WAAW,EAAE,MAAM,OAAO,GAAoB;AAC5D,QAAM,CAAC,IAAI,KAAK,IAAIF;AAAA,IAAS,MAC3B,OAAO,WAAW,cACd,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,IACrC;AAAA,MACE,IAAI,OAAO;AAAA,MACX,IAAI,OAAO;AAAA,MACX,IAAI,OAAO,OAAO;AAAA,MAClB,IAAI,OAAO,OAAO;AAAA,MAClB,KAAK,OAAO,oBAAoB;AAAA,IAClC;AAAA,EACN;AAEA,EAAAD,WAAU,MAAM;AACd,UAAM,SAAS,MACb,MAAM;AAAA,MACJ,IAAI,OAAO;AAAA,MACX,IAAI,OAAO;AAAA,MACX,IAAI,OAAO,OAAO;AAAA,MAClB,IAAI,OAAO,OAAO;AAAA,MAClB,KAAK,OAAO,oBAAoB;AAAA,IAClC,CAAC;AACH,WAAO,iBAAiB,UAAU,MAAM;AACxC,WAAO,MAAM,OAAO,oBAAoB,UAAU,MAAM;AAAA,EAC1D,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAoC;AAAA,IACxC,CAAC,KAAK,KAAK,CAAC;AAAA,IACZ,CAAC,KAAK,KAAK,CAAC;AAAA,IACZ,CAAC,KAAK,KAAK,KAAK;AAAA,IAChB,CAAC,KAAK,KAAK,MAAM;AAAA,IACjB,CAAC,KAAK,MAAM;AAAA,EACd;AAEA,QAAM,kBAA+C;AAAA,IACnD,CAAC,MAAM,GAAG,EAAE;AAAA,IACZ,CAAC,MAAM,GAAG,EAAE;AAAA,IACZ,CAAC,MAAM,GAAG,EAAE;AAAA,IACZ,CAAC,MAAM,GAAG,EAAE;AAAA,IACZ,CAAC,OAAO,GAAG,GAAG;AAAA,EAChB;AAEA,SACE,gBAAAG,MAAC,SAAI,WAAU,4GAEb;AAAA,oBAAAA,MAAC,SAAI,WAAU,qCACb;AAAA,sBAAAD,KAAC,UAAK,WAAU,mDAAkD,iBAElE;AAAA,MACC,cAAc,IAAI,CAAC,CAAC,OAAO,GAAG,MAC7B,gBAAAC;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UAEV;AAAA,4BAAAA,MAAC,UAAK,WAAU,gBAAgB;AAAA;AAAA,cAAM;AAAA,eAAC;AAAA,YACvC,gBAAAD,KAAC,UAAK,WAAU,uCACb,eAAK,MAAM,GAAa,GAC3B;AAAA;AAAA;AAAA,QANK;AAAA,MAOP,CACD;AAAA,OACH;AAAA,IAEA,gBAAAC,MAAC,SAAI,WAAU,qCACb;AAAA,sBAAAD,KAAC,UAAK,WAAU,gDAA+C,gBAE/D;AAAA,MACC,gBAAgB,IAAI,CAAC,CAAC,OAAO,GAAG,MAC/B,gBAAAC;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UAEV;AAAA,4BAAAA,MAAC,UAAK,WAAU,aAAa;AAAA;AAAA,cAAM;AAAA,eAAC;AAAA,YACpC,gBAAAD,KAAC,UAAK,WAAU,oCACb,iBAAO,QAAQ,YAAY,CAAC,OAAO,UAAU,GAAG,IAC7C,IAAI,QAAQ,CAAC,IACb,KAAK,MAAM,GAAa,GAC9B;AAAA;AAAA;AAAA,QARK;AAAA,MASP,CACD;AAAA,OACH;AAAA,KACF;AAEJ;;;ACjGA,SAAS,MAAAE,WAAU;AAGZ,IAAM,4BACX;AAEK,IAAM,wBAAwBA;AAAA,EACnC;AAAA,EACA;AACF;;;ACUA,SAAS,wBAAwB;AA6B3B,SASQ,OAAAC,MATR,QAAAC,aAAA;AAhBC,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAM1B,QAAM,gBACJ,WAAW,aACT,gBAAAA,MAAC,SAAI,WAAU,sCACZ;AAAA,eACC,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS;AAAA,QACT,cAAW;AAAA,QAEX,0BAAAA,KAAC,UAAK,WAAU,kFACd,0BAAAA,KAAC,SAAE,WAAU,wCAAuC,GACtD;AAAA;AAAA,IACF;AAAA,IAED,cACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS;AAAA,QACT,cAAW;AAAA,QAEX,0BAAAA,KAAC,UAAK,WAAU,qFACd,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA;AAAA,QAEZ,GACF;AAAA;AAAA,IACF;AAAA,KAEJ,IACE;AAEN,QAAM,aAAa,aACjB,gBAAAA,KAAC,oBAAiB,cAAW,QAAO,OAAO,kBAAkB,eAAe,iBAAiB,MAAM,CAAC,EAAE,OAAO,WAAW,OAAO,UAAU,GAAG,EAAE,OAAO,QAAQ,OAAO,UAAU,CAAC,GAAG,IAChL;AAEJ,SACE,gBAAAC,MAAC,SAAI,WAAU,iFACb;AAAA,oBAAAD,KAAC,wBAAqB,SAAS,eAC7B,0BAAAA,KAAC,qBAAkB,OAAc,WAAU,QAAO,GACpD;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,SACE,eACE,gBAAAA,KAAC,SAAI,WAAW,uBAAwB,wBAAa,IACnD;AAAA;AAAA,IAER;AAAA,KACF;AAEJ;;;AChGA,SAAS,YAAAE,iBAAgB;AAEzB,SAAS,MAAAC,WAAU;AAuBf,SAME,OAAAC,MANF,QAAAC,aAAA;AAfG,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAChD,MAAI,UAAW,QAAO;AAEtB,QAAM,UACJ,SACC,aACG,+BAA0B,UAAU,yCACpC;AAEN,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAWF;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,wBAAAC,KAAC,qBAAc,WAAU,iCAAgC;AAAA,QACzD,gBAAAA,KAAC,UAAK,WAAU,sBAAsB,mBAAQ;AAAA,QAC9C,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAW;AAAA,YACX,WAAU;AAAA,YACV,SAAS,MAAM,aAAa,IAAI;AAAA,YAEhC,0BAAAA,KAAC,SAAE,WAAU,WAAU;AAAA;AAAA,QACzB;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC3BA,SAAS,MAAAG,WAAU;AA+Bf,SAQI,OAAAC,MARJ,QAAAC,aAAA;AAPG,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAGC;AAAA,uBACC,gBAAAF,KAAC,SAAI,WAAW,uBAAwB,uBAAY;AAAA,QAItD,gBAAAA,KAAC,SAAI,WAAU,mDACb,0BAAAA,KAAC,UAAK,WAAU,mDACb,mBAAS,IACZ,GACF;AAAA,QAGC,gBACC,gBAAAA,KAAC,SAAI,WAAW,uBAAwB,wBAAa;AAAA,QAIvD,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAWE;AAAA,cACT;AAAA,cACA;AAAA,YACF;AAAA,YACA,SAAS;AAAA,YACT,OAAM;AAAA,YACN,cAAW;AAAA,YAEX,0BAAAF,KAAC,uBAAgB,WAAU,eAAc;AAAA;AAAA,QAC3C;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACtBO,SAAS,yBAA2C;AACzD,MAAI,OAAO,WAAW,YAAa,QAAO;AAE1C,QAAM,IAAI;AACV,MACE,EAAE,4BACF,OAAO,EAAE,yBAAyB,kBAAkB,YACpD;AACA,WAAO;AAAA,EACT;AAQA,MAAI,OAAO,OAAO,SAAS,YAAY;AACrC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAOO,SAAS,mCAA4C;AAC1D,SAAO,uBAAuB,MAAM;AACtC;AAMO,SAAS,oBAA6B;AAC3C,SAAO,uBAAuB,MAAM;AACtC;;;AC3EA,SAAS,eAAAG,cAAa,aAAAC,YAAW,UAAAC,eAAc;AAC/C,SAAS,qBAAAC,oBAAmB,gBAAgB,qBAAAC,0BAAyB;AACrE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACdP,SAAS,wBAAAC,6BAA4B;AACrC,SAAS,cAAAC,mBAAkB;AAQ3B,IAAM,OAAO,MACXA,YAA2B,wCAAwC,OAAO,EAAE,KAAK,oBAAI,IAAI,GAAG,WAAW,oBAAI,IAAI,EAAE,EAAE;AAErH,SAAS,SAAe;AACtB,aAAW,MAAM,KAAK,EAAE,UAAW,IAAG;AACxC;AAMO,SAAS,gBAAgB,IAAY,KAAmB;AAC7D,QAAM,EAAE,IAAI,IAAI,KAAK;AACrB,QAAM,OAAO,IAAI,IAAI,EAAE;AACvB,MAAI,SAAS,IAAK;AAClB,MAAI,IAAI,IAAI,GAAG;AACf,SAAO;AACT;AAMO,SAAS,mBAAmB,IAAkB;AACnD,QAAM,EAAE,IAAI,IAAI,KAAK;AACrB,MAAI,CAAC,IAAI,IAAI,EAAE,EAAG;AAClB,MAAI,OAAO,EAAE;AACb,SAAO;AACT;AAGO,SAAS,gBAAgB,IAA2B;AACzD,SAAO,KAAK,EAAE,IAAI,IAAI,EAAE,KAAK;AAC/B;AAGO,SAAS,oBACd,IACM;AACN,aAAW,CAAC,IAAI,GAAG,KAAK,KAAK,EAAE,IAAK,IAAG,KAAK,EAAE;AAChD;AAMO,SAAS,yBAAyB,UAAkC;AACzE,QAAM,EAAE,UAAU,IAAI,KAAK;AAC3B,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;AASO,SAAS,mBAAmB,IAA2B;AAC5D,SAAOD;AAAA,IACL;AAAA,IACA,MAAM,gBAAgB,EAAE;AAAA;AAAA,IAExB,MAAM;AAAA,EACR;AACF;;;ACxCA,IAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAchB,KAAK;AAGP,IAAM,mBAAmB;AAEzB,IAAM,eAAe;AAYd,SAAS,wBACd,QACA,QACoB;AAEpB,wBAAsB,MAAM;AAG5B,4BAA0B,QAAQ,MAAM;AAGxC,0BAAwB,QAAQ,MAAM;AAGtC,uBAAqB,QAAQ,MAAM;AAGnC,QAAM,eAAe,IAAI,iBAAiB,CAAC,cAAc;AACvD,wBAAoB,WAAW,MAAM;AAAA,EACvC,CAAC;AACD,eAAa,QAAQ,OAAO,MAAM;AAAA,IAChC,WAAW;AAAA,IACX,SAAS;AAAA,IACT,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,iBAAiB,CAAC,QAAQ,OAAO;AAAA,EACnC,CAAC;AAGD,QAAM,eAAe,IAAI,iBAAiB,MAAM;AAC9C,yBAAqB,QAAQ,MAAM;AAAA,EACrC,CAAC;AACD,eAAa,QAAQ,OAAO,iBAAiB;AAAA,IAC3C,YAAY;AAAA,IACZ,iBAAiB,CAAC,SAAS,cAAc,sBAAsB;AAAA,EACjE,CAAC;AAED,SAAO;AAAA,IACL,UAAU;AACR,mBAAa,WAAW;AACxB,mBAAa,WAAW;AAAA,IAC1B;AAAA,EACF;AACF;AAIA,SAAS,sBAAsB,QAAwB;AAGrD,QAAM,WAAW,OAAO,KAAK;AAAA,IAC3B,SAAS,gBAAgB,KAAK,YAAY;AAAA,EAC5C;AACA,MAAI,SAAU;AAEd,QAAM,QAAQ,OAAO,cAAc,OAAO;AAC1C,QAAM,aAAa,kBAAkB,YAAY;AACjD,QAAM,cAAc;AAEpB,SAAO,KAAK,aAAa,OAAO,OAAO,KAAK,UAAU;AACxD;AAEA,SAAS,0BACP,QACA,QACM;AACN,QAAM,QAAQ,OAAO,KAAK,iBAAiB,+BAA+B;AAC1E,QAAM,QAAQ,CAAC,SAAS;AACtB,wBAAoB,MAAM,MAAM;AAAA,EAClC,CAAC;AACH;AAOA,SAAS,oBACP,MACA,QACgB;AAChB,MAAI,KAAK,YAAY,SAAS;AAC5B,UAAM,QAAQ,OAAO,cAAc,OAAO;AAG1C,UAAM,cAAc,KAAK,eAAe;AACxC,uBAAmB,MAAM,KAAK;AAC9B,UAAM,aAAa,kBAAkB,WAAW,IAAI,CAAC;AACrD,WAAO,KAAK,YAAY,KAAK;AAC7B,WAAO;AAAA,EACT;AACA,MACE,KAAK,YAAY,UAChB,KAAyB,QAAQ,cAClC;AACA,UAAM,OAAO;AACb,UAAM,QAAQ,OAAO,cAAc,MAAM;AACzC,UAAM,MAAM;AACZ,QAAI,KAAK,KAAM,OAAM,OAAO,KAAK;AACjC,QAAI,KAAK,MAAO,OAAM,QAAQ,KAAK;AACnC,QAAI,KAAK,YAAa,OAAM,cAAc,KAAK;AAC/C,QAAI,KAAK,UAAW,OAAM,YAAY,KAAK;AAC3C,uBAAmB,MAAM,KAAK;AAC9B,UAAM,aAAa,kBAAkB,WAAW,IAAI,CAAC;AACrD,WAAO,KAAK,YAAY,KAAK;AAC7B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOA,SAAS,WAAW,MAAuB;AACzC,MAAI,KAAK,YAAY,SAAS;AAI5B,WAAO,WAAW,UAAU,KAAK,eAAe,EAAE;AAAA,EACpD;AACA,MAAI,KAAK,YAAY,QAAQ;AAC3B,UAAM,OAAQ,KAAyB,QAAQ;AAC/C,WAAO,UAAU;AAAA,EACnB;AACA,SAAO,WAAW,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;AACtD;AAOA,SAAS,UAAU,GAAmB;AACpC,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,SAAM,KAAK,KAAK,IAAI,EAAE,WAAW,CAAC,IAAK;AAAA,EACzC;AACA,UAAQ,MAAM,GAAG,SAAS,EAAE;AAC9B;AAEA,SAAS,mBAAmB,MAAe,IAAmB;AAC5D,aAAW,QAAQ,MAAM,KAAK,KAAK,UAAU,GAAG;AAC9C,QAAI,KAAK,KAAK,WAAW,OAAO,GAAG;AAEjC,UAAI,KAAK,SAAS,iBAAkB;AACpC,SAAG,aAAa,KAAK,MAAM,KAAK,KAAK;AAAA,IACvC;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,QAAkB,QAAwB;AAIzE,MACE,MAAM,QAAQ,OAAO,kBAAkB,KACvC,OAAO,mBAAmB,SAAS,GACnC;AACA,QAAI;AACF,aAAO,qBAAqB,CAAC,GAAG,OAAO,kBAAkB;AAAA,IAC3D,QAAQ;AAAA,IAGR;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,QAAkB,QAAwB;AACtE,QAAM,MAAM,OAAO;AACnB,QAAM,MAAM,OAAO;AAMnB,MAAI,IAAI,cAAc,IAAI,WAAW;AACnC,QAAI,YAAY,IAAI;AAAA,EACtB;AAEA,aAAW,QAAQ,CAAC,cAAc,wBAAwB,MAAM,GAAY;AAC1E,UAAM,IAAI,IAAI,aAAa,IAAI;AAC/B,QAAI,MAAM,MAAM;AACd,UAAI,IAAI,aAAa,IAAI,EAAG,KAAI,gBAAgB,IAAI;AAAA,IACtD,WAAW,IAAI,aAAa,IAAI,MAAM,GAAG;AACvC,UAAI,aAAa,MAAM,CAAC;AAAA,IAC1B;AAAA,EACF;AACF;AAEA,SAAS,oBACP,WACA,QACM;AACN,aAAW,KAAK,WAAW;AAEzB,MAAE,WAAW,QAAQ,CAAC,MAAM;AAC1B,UAAI,EAAE,aAAa,SAAU;AAC7B,UACE,EAAE,YAAY,WACb,EAAE,YAAY,UAAW,EAAsB,QAAQ,cACxD;AACA,4BAAoB,GAAG,MAAM;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,MAAE,aAAa,QAAQ,CAAC,MAAM;AAC5B,UAAI,EAAE,aAAa,SAAU;AAC7B,UAAI,EAAE,YAAY,WAAW,EAAE,YAAY,OAAQ;AACnD,YAAM,MAAM,WAAW,CAAC;AACxB,YAAM,UAAU,OAAO,KAAK;AAAA,QAC1B,IAAI,gBAAgB,KAAK,UAAU,GAAG,CAAC;AAAA,MACzC;AACA,UAAI,QAAS,SAAQ,OAAO;AAAA,IAC9B,CAAC;AAED,QAAI,EAAE,SAAS,mBAAmB,EAAE,OAAO,eAAe,YAAY,SAAS;AAC7E,YAAM,UAAU,EAAE,OAAO;AACzB,YAAM,SAAS,4BAA4B,QAAQ,QAAQ,eAAe,EAAE;AAC5E,YAAM,SAAS,WAAW,OAAO;AACjC,UAAI,UAAU,WAAW,QAAQ;AAE/B,cAAM,SAAS,OAAO,KAAK;AAAA,UACzB,IAAI,gBAAgB,KAAK,UAAU,MAAM,CAAC;AAAA,QAC5C;AACA,YAAI,QAAQ;AACV,iBAAO,cAAc,QAAQ,eAAe;AAC5C,iBAAO,aAAa,kBAAkB,MAAM;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAEA,QACE,EAAE,SAAS,gBACX,EAAE,kBAAkB,mBACpB,EAAE,OAAO,QAAQ,cACjB;AAKA,YAAM,OAAO,EAAE;AACf,YAAM,YAAY,OAAO,KAAK;AAAA,QAC5B,QAAQ,gBAAgB;AAAA,MAC1B;AAKA,0BAAoB,MAAM,MAAM;AAGhC,WAAK;AAAA,IACP;AAAA,EACF;AACF;AAUA,SAAS,4BACP,QACA,MACe;AAOf,QAAM,SAAS,OAAO,KAAK;AAAA,IACzB,SAAS,gBAAgB;AAAA,EAC3B;AACA,aAAW,KAAK,MAAM,KAAK,MAAM,GAAG;AAClC,QAAI,EAAE,gBAAgB,KAAM,QAAO;AAAA,EACrC;AAGA,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,OAAO,CAAC,GAAG,aAAa,gBAAgB,KAAK;AAAA,EACtD;AACA,SAAO;AACT;AAQA,SAAS,UAAU,GAAmB;AACpC,SAAO,EAAE,QAAQ,YAAY,MAAM;AACrC;;;ACzWA,IAAM,cAAc;AAMpB,SAAS,YAA0B;AACjC,MAAI,OAAO,WAAW,YAAa,QAAO,EAAE,WAAW,CAAC,EAAE;AAC1D,MAAI;AACF,UAAM,MAAM,OAAO,eAAe,QAAQ,WAAW;AACrD,QAAI,CAAC,IAAK,QAAO,EAAE,WAAW,CAAC,EAAE;AACjC,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,CAAC,MAAM,QAAQ,OAAO,SAAS,EAAG,QAAO,EAAE,WAAW,CAAC,EAAE;AAE7D,WAAO;AAAA,MACL,WAAW,OAAO,UAAU;AAAA,QAC1B,CAAC,OAAqB,OAAO,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO,EAAE,WAAW,CAAC,EAAE;AAAA,EACzB;AACF;AAEA,SAAS,WAAWE,QAA2B;AAC7C,MAAI,OAAO,WAAW,YAAa;AACnC,MAAI;AACF,QAAIA,OAAM,UAAU,WAAW,GAAG;AAChC,aAAO,eAAe,WAAW,WAAW;AAAA,IAC9C,OAAO;AACL,aAAO,eAAe,QAAQ,aAAa,KAAK,UAAUA,MAAK,CAAC;AAAA,IAClE;AAAA,EACF,QAAQ;AAAA,EAIR;AACF;AAGO,SAAS,kBAAkB,UAAwB;AACxD,QAAMA,SAAQ,UAAU;AACxB,MAAI,CAACA,OAAM,UAAU,SAAS,QAAQ,GAAG;AACvC,IAAAA,OAAM,UAAU,KAAK,QAAQ;AAC7B,eAAWA,MAAK;AAAA,EAClB;AACF;AAGO,SAAS,mBAAmB,UAAwB;AACzD,QAAMA,SAAQ,UAAU;AACxB,QAAM,OAAOA,OAAM,UAAU,OAAO,CAAC,OAAO,OAAO,QAAQ;AAC3D,MAAI,KAAK,WAAWA,OAAM,UAAU,QAAQ;AAC1C,eAAW,EAAE,WAAW,KAAK,CAAC;AAAA,EAChC;AACF;AAGO,SAAS,4BAAsC;AACpD,SAAO,UAAU,EAAE;AACrB;AAGO,SAAS,wBAA8B;AAC5C,aAAW,EAAE,WAAW,CAAC,EAAE,CAAC;AAC9B;;;AH5CA,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AA+BtB,SAAS,gBAAgB,UAAyC;AACvE,QAAM,WAAWC,mBAAkB;AACnC,QAAM,EAAE,QAAAC,QAAO,IAAI,eAAe;AAClC,QAAM,aAAaC,mBAAkB,iBAAiB,QAAQ,CAAC;AAC/D,QAAM,oBAAoBA,mBAAkB,uBAAuB;AAGnE,QAAM,mBAAmBC,QAA4B,IAAI;AAQzD,QAAM,cAAcC,aAAY,MAAM;AACpC,UAAM,MAAM,gBAAgB,QAAQ;AACpC,QAAI,CAAC,OAAO,yBAAyB,cAAc;AAAA,IAGnD;AACA,qBAAiB,UAAU;AAC3B,qBAAiB,UAAU;AAC3B,uBAAmB,QAAQ;AAE3B,uBAAmB,QAAQ;AAG3B,aAAS,WAAW,uBAAuB,QAAQ,CAAC,CAAC;AAGrD,QAAI;AACF,WAAK,MAAM;AAAA,IACb,QAAQ;AAAA,IAER;AACA,QAAI,yBAAyB,gBAAgB,KAAK;AAEhD,cAAQ,KAAK,+BAA+B,QAAQ,GAAG;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,UAAU,QAAQ,CAAC;AAQvB,QAAM,aAAaA;AAAA,IACjB,OAAO,SAAuD;AAC5D,YAAM,aAAa,uBAAuB;AAC1C,UAAI,eAAe,QAAQ;AACzB,QAAAH,QAAO,MAAM,yBAAyB;AAAA,UACpC,aAAa;AAAA,QACf,CAAC;AACD,eAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB;AAAA,MAC9C;AAOA,YAAM,mBACJ,sBAAsB,QAAQ,sBAAsB;AAEtD,UAAI,SAAwB;AAC5B,UAAI,OAAwB;AAI5B,UAAI,eAAe,SAAS,CAAC,kBAAkB;AAC7C,YAAI;AACF,gBAAM,IAAI;AACV,cAAI,EAAE,0BAA0B;AAC9B,qBAAS,MAAM,EAAE,yBAAyB,cAAc;AAAA,cACtD,OAAO,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,cAC3C,QAAQ,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,MAAM,CAAC;AAAA,YAC/C,CAAC;AACD,mBAAO;AAAA,UACT;AAAA,QACF,SAAS,KAAK;AAGZ,kBAAQ;AAAA,YACN;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,UAAI,CAAC,QAAQ;AACX,cAAM,WAAW;AAAA,UACf;AAAA,UACA,SAAS,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC;AAAA,UAC9C,UAAU,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC;AAAA,QAClD,EAAE,KAAK,GAAG;AACV,YAAI;AACF,mBAAS,aAAa,IAAI,UAAU,QAAQ,IAAI,QAAQ;AACxD,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,kBAAQ,MAAM,gCAAgC,GAAG;AAAA,QACnD;AAAA,MACF;AAEA,UAAI,CAAC,QAAQ;AACX,QAAAA,QAAO,MAAM,kBAAkB;AAAA,UAC7B,aACE;AAAA,QACJ,CAAC;AACD,eAAO,EAAE,IAAI,OAAO,QAAQ,gBAAgB;AAAA,MAC9C;AAGA,UAAI;AACF,eAAO,SAAS,QAAQ,KAAK;AAAA,MAC/B,QAAQ;AAAA,MAER;AAGA,uBAAiB,UAAU;AAAA,QACzB,OAAO;AAAA,QACP,OAAO;AAAA,MACT,EAAE;AAGF,aAAO,iBAAiB,YAAY,aAAa,EAAE,MAAM,KAAK,CAAC;AAG/D,sBAAgB,UAAU,MAAM;AAIhC,wBAAkB,QAAQ;AAI1B,eAAS,aAAa,EAAE,IAAI,UAAU,KAAK,CAAC,CAAC;AAE7C,UAAI,yBAAyB,cAAc;AACzC,gBAAQ;AAAA,UACN,mBAAmB,IAAI,gBAAgB,QAAQ,MAAM,KAAK,KAAK,IAAI,KAAK,MAAM;AAAA,QAChF;AAAA,MACF;AAEA,aAAO,EAAE,IAAI,MAAM,KAAK;AAAA,IAC1B;AAAA,IACA,CAAC,mBAAmB,UAAU,aAAaA,SAAQ,QAAQ;AAAA,EAC7D;AAGA,QAAM,QAAQG,aAAY,MAAM;AAC9B,UAAM,MAAM,gBAAgB,QAAQ;AACpC,QAAI,CAAC,KAAK;AAER,eAAS,WAAW,uBAAuB,QAAQ,CAAC,CAAC;AACrD;AAAA,IACF;AAEA,QAAI;AACF,UAAI,MAAM;AAAA,IACZ,QAAQ;AACN,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,UAAU,aAAa,QAAQ,CAAC;AAIpC,EAAAC,WAAU,MAAM;AACd,QAAI,eAAe,QAAQ,gBAAgB,QAAQ,MAAM,MAAM;AAC7D,UAAI;AACF,wBAAgB,QAAQ,GAAG,MAAM;AAAA,MACnC,QAAQ;AACN,oBAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,UAAU,WAAW,CAAC;AAItC,EAAAA,WAAU,MAAM;AACd,UAAM,iBAAiB,MAAM;AAC3B,UAAI;AACF,wBAAgB,QAAQ,GAAG,MAAM;AAAA,MACnC,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO,iBAAiB,gBAAgB,cAAc;AACtD,WAAO,MAAM;AACX,aAAO,oBAAoB,gBAAgB,cAAc;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO,EAAE,YAAY,MAAM;AAC7B;;;AI/PA,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,qBAAAC,0BAAyB;AAClC;AAAA,EACE,cAAAC;AAAA,OAEK;AACP,SAAS,0BAAAC,+BAA8B;AAEvC,SAAS,cAAAC,mBAAkB;AAY3B,IAAM,UAAU,MACdA,YAAsC,wCAAwC,MAAM,oBAAI,IAAI,CAAC;AAMxF,SAAS,qBACd,UACA,IACY;AACZ,UAAQ,EAAE,IAAI,UAAU,EAAE;AAC1B,SAAO,MAAM;AAIX,QAAI,QAAQ,EAAE,IAAI,QAAQ,MAAM,IAAI;AAClC,cAAQ,EAAE,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AACF;AAGO,SAAS,gBAAgB,UAAuC;AACrE,SAAO,QAAQ,EAAE,IAAI,QAAQ,KAAK;AACpC;AAmBO,SAAS,mBAAqC;AACnD,QAAM,WAAWH,mBAAkB;AAEnC,QAAM,SAASD;AAAA,IACb,OAAO,UAAU,SAAS;AACxB,YAAM,SAAS,gBAAgB,QAAQ;AACvC,UAAI,CAAC,QAAQ;AACX,eAAO,EAAE,IAAI,OAAO,QAAQ,cAAuB;AAAA,MACrD;AACA,aAAO,OAAO,IAAI;AAAA,IACpB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,OAAOA;AAAA,IACX,CAAC,aAAa;AACZ,YAAM,UAAUG,wBAAuB,QAAQ;AAC/C,eAASD,YAAW,OAAO,CAAC;AAAA,IAC9B;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,SAAO,EAAE,QAAQ,KAAK;AACxB;AAgBO,SAAS,gBACd,MACA,MACmB;AACnB,SAAO;AAAA,IACL,OAAO,MAAM,SAAS,MAAM,SAAS;AAAA,IACrC,QAAQ,MAAM,UAAU,MAAM,UAAU;AAAA,IACxC,OAAO,MAAM,SAAS;AAAA,EACxB;AACF;;;ACnHA,SAAS,gBAAAG,qBAAoB;AAC7B,SAAS,qBAAAC,0BAAyB;AAClC,SAAS,oBAAAC,yBAAwB;;;ACXjC,SAAS,eAA+B;AACxC,SAAS,+BAA+B;;;ACOxC,SAAS,eAAe,kBAAkB;AAgC1C,IAAM,gBAAoC;AAAA,EACxC,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,MAAM;AACR;AAEO,IAAM,gBACX,cAAkC,aAAa;AAG1C,SAAS,YAAgC;AAC9C,SAAO,WAAW,aAAa;AACjC;;;ADdM,gBAAAC,aAAA;AAzBC,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL,gBAAgB,aAAa;AAAA,MAC7B;AAAA,MACA,iBAAiB,aAAa,SAAS;AAAA,MACvC;AAAA,IACF;AAAA,IACA,CAAC,cAAc,IAAI;AAAA,EACrB;AAEA,SACE,gBAAAA,MAAC,cAAc,UAAd,EAAuB,OAStB,0BAAAA,MAAC,2BAAwB,WAAW,MAAM,iBACvC,UACH,GACF;AAEJ;;;ADVI,gBAAAC,aAAA;AAbG,SAAS,aAAa,EAAE,UAAU,SAAS,GAAsB;AACtE,QAAM,YAAY,mBAAmB,QAAQ;AAC7C,QAAM,aAAaC,mBAAkBC,kBAAiB,QAAQ,CAAC;AAQ/D,MAAI,CAAC,aAAa,eAAe,KAAM,QAAO;AAE9C,SAAOC;AAAA,IACL,gBAAAH,MAAC,eAAY,cAAc,WAAW,MAAM,YACzC,UACH;AAAA,IACA,UAAU,SAAS;AAAA,EACrB;AACF;;;AGvCA,SAAS,cAAAI,mBAAkB;AAE3B,IAAM,gBAAgB;AAOtB,IAAM,QAAQ,MACZA,YAA0B,wCAAwC,OAAO,EAAE,KAAK,oBAAI,IAAI,GAAG,WAAW,oBAAI,IAAI,EAAE,EAAE;AAEpH,SAASC,UAAe;AACtB,aAAW,MAAM,MAAM,EAAE,UAAW,IAAG;AACzC;AAEA,SAAS,OAAO,KAA+B;AAC7C,MAAI,OAAO,OAAO,QAAQ,eAAe,OAAO,IAAI,oBAAoB,WAAY,KAAI,gBAAgB,GAAG;AAC7G;AAGO,SAAS,gBAAgB,IAAY,MAAkB;AAC5D,QAAM,EAAE,IAAI,IAAI,MAAM;AACtB,SAAO,IAAI,IAAI,EAAE,CAAC;AAClB,QAAM,YAAY,IAAI,gBAAgB,IAAI;AAC1C,MAAI,OAAO,EAAE;AACb,MAAI,IAAI,IAAI,SAAS;AACrB,SAAO,IAAI,OAAO,eAAe;AAC/B,UAAM,WAAW,IAAI,KAAK,EAAE,KAAK,EAAE;AACnC,QAAI,aAAa,OAAW;AAC5B,WAAO,IAAI,IAAI,QAAQ,CAAC;AACxB,QAAI,OAAO,QAAQ;AAAA,EACrB;AACA,EAAAA,QAAO;AACT;AAGO,SAAS,kBAAkB,IAAkB;AAClD,QAAM,EAAE,IAAI,IAAI,MAAM;AACtB,QAAM,YAAY,IAAI,IAAI,EAAE;AAC5B,MAAI,CAAC,UAAW;AAChB,MAAI,OAAO,EAAE;AACb,SAAO,SAAS;AAChB,EAAAA,QAAO;AACT;AAGO,SAAS,gBAAgB,IAA2B;AACzD,SAAO,MAAM,EAAE,IAAI,IAAI,EAAE,KAAK;AAChC;AAGO,SAAS,yBAAyB,UAAkC;AACzE,QAAM,EAAE,UAAU,IAAI,MAAM;AAC5B,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;;;ACrDA,IAAM,4BAA4B;AAGlC,IAAM,oBAAoB;AAU1B,eAAe,eAAwE;AACrF,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,eAAe;AACxC,WAAO,IAAI;AAAA,EACb,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,wBAAwB,SAAsB,UAAmC,CAAC,GAAyB;AAC/H,QAAM,WAAW,MAAM,aAAa;AACpC,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,cAAc,KAAK,IAAI,GAAG,QAAQ,WAAW;AACnD,QAAM,eAAe,KAAK,IAAI,GAAG,QAAQ,YAAY;AACrD,QAAM,UAAU,KAAK,IAAI,IAAI,QAAQ,WAAW,GAAG;AACnD,QAAM,QAAQ,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,aAAa,YAAY,CAAC;AACvE,QAAM,SAAS,MAAM,SAAS,SAAS;AAAA,IACrC,YAAY;AAAA,IACZ,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,KAAK,CAAC;AAAA,IACxD,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,eAAe,KAAK,CAAC;AAAA,IAC1D,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,qBAAqB,MAAM;AAAA,EAC7B,CAAC;AACD,SAAO,IAAI,QAAqB,CAAC,YAAY;AAC3C,WAAO,OAAO,SAAS,cAAc,QAAQ,WAAW,IAAI;AAAA,EAC9D,CAAC;AACH;AAEA,eAAsB,2BAA2B,QAA2C;AAC1F,MAAI;AACF,QAAI,OAAO,iBAAiB,GAAG,EAAE,SAAS,6BAA6B,OAAO,cAAc,KAAK,OAAO,eAAe,GAAG;AACxH,aAAO;AAAA,IACT;AACA,UAAM,OAAO,MAAM,wBAAwB,MAAM;AAGjD,WAAO,QAAS,MAAM,YAAY,IAAI,IAAK,OAAO;AAAA,EACpD,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAGA,eAAe,YAAY,MAA8B;AACvD,MAAI;AACF,UAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,UAAM,OAAO;AACb,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ;AACf,WAAO,SAAS;AAChB,UAAM,MAAM,OAAO,WAAW,MAAM,EAAE,oBAAoB,KAAK,CAAC;AAChE,QAAI,CAAC,IAAK,QAAO;AACjB,QAAI,UAAU,QAAQ,GAAG,GAAG,MAAM,IAAI;AACtC,WAAO,MAAM;AACb,UAAM,EAAE,KAAK,IAAI,IAAI,aAAa,GAAG,GAAG,MAAM,IAAI;AAClD,UAAM,KAAK,KAAK,CAAC,KAAK;AACtB,UAAM,KAAK,KAAK,CAAC,KAAK;AACtB,UAAM,KAAK,KAAK,CAAC,KAAK;AACtB,UAAM,KAAK,KAAK,CAAC,KAAK;AACtB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UACE,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,EAAE,IAAI,KAChC,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,KACpC,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,KACpC,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,EAAE,IAAI,GACpC;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ACtFA,SAAS,kBAAAC,uBAAsB;;;ACL/B,SAAS,WAAW,MAAM,wBAAAC,6BAA4C;AACtE,SAAS,MAAAC,WAAU;AACnB,SAAS,gBAAgB,mBAAmB,2BAA2B;AACvE,SAAS,kBAAAC,iBAAgB,qBAAAC,0BAAyB;AAClD,SAAS,2BAAoD;AA+B1C,gBAAAC,OA2CX,QAAAC,cA3CW;AAlBnB,SAAS,cAAc,OAAkD;AACvE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEO,IAAM,kBAAkB,KAAK,SAASC,iBAAgB;AAAA,EAC3D;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,OAAO,eAAe,WAAW;AACvC,QAAM,EAAE,QAAQ,IAAI,oBAAoB,WAAW;AACnD,QAAM,QAAQC,gBAAe;AAC7B,QAAM,cAAcC,mBAAkB,CAACC,WAAW,OAAO,kBAAkBA,QAAO,KAAK,IAAI,iBAAiB,IAAI,IAAK;AACrH,QAAM,gBAAgBD,mBAAkB,CAACC,WAAUA,OAAM,cAAc,QAAQ,WAAW,GAAG,aAAa,IAAI;AAC9G,QAAM,gBAAgB,MAAM,SAAS;AAErC,QAAM,WAAW,gBAAAL,MAAC,qBAAkB,aAA0B,eAA8B,OAAc;AAE1G,MAAI,SAAS;AACX,UAAM,MAA0B;AAAA,MAC9B,MAAM,eAAe,kBAAkB,cAAc,WAAW,IAAI,cAAc,CAAC;AAAA,MACnF,WAAW,MAAM,MAAM;AAAA,MACvB,YAAY;AAAA,MACZ;AAAA,IACF;AACA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,SAAS,CAAC,UAAU,MAAM,OAAO,QAAQ,OAAO,EAAE,OAAO,gBAAgB,WAAW,YAAY,CAAC;AAAA,QAEjG,0BAAAA,MAAC,SAAI,WAAU,kEACb,0BAAAA,MAAC,WAAS,GAAG,KAAK,GACpB;AAAA;AAAA,IACF;AAAA,EAEJ;AACA,SAAO;AACT,CAAC;AAED,IAAM,kBAAN,cAA8B,UAG5B;AAAA,EACS,QAAQ,EAAE,QAAQ,MAAM;AAAA,EACjC,OAAO,2BAAgD;AACrD,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AAAA,EACS,kBAAkB,OAAsB;AAC/C,SAAK,MAAM,QAAQ,KAAK;AAAA,EAC1B;AAAA,EACS,SAAoB;AAC3B,WAAO,KAAK,MAAM,SAAS,KAAK,MAAM,WAAW,KAAK,MAAM;AAAA,EAC9D;AACF;AAEA,IAAM,sBAAsB,KAAK,SAASM,qBAAoB,EAAE,MAAM,GAAsB;AAC1F,SACE,gBAAAL,OAAC,SAAI,WAAU,gIACb;AAAA,oBAAAA,OAAC,SAAI,WAAU,qCACb;AAAA,sBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,UAEV;AAAA,4BAAAD,MAAC,UAAK,WAAU,sCAAqC;AAAA,YACrD,gBAAAA,MAAC,UAAK,WAAU,+CAA8C;AAAA,YAC9D,gBAAAA,MAAC,UAAK,WAAU,+CAA8C;AAAA;AAAA;AAAA,MAChE;AAAA,MACA,gBAAAA,MAAC,UAAK,WAAU,wDAAwD,iBAAM;AAAA,OAChF;AAAA,IACA,gBAAAC,OAAC,SAAI,WAAU,wFACb;AAAA,sBAAAD,MAAC,UAAK,WAAU,oCAAmC,oBAAM;AAAA,MACzD,gBAAAA,MAAC,UAAK,WAAU,YAAW,8BAAgB;AAAA,OAC7C;AAAA,KACF;AAEJ,CAAC;AAED,IAAM,oBAAoB,KAAK,SAASO,mBAAkB;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AACF,GAIG;AAGD,QAAM,WAAWC;AAAA,IACf;AAAA,IACA,MAAM,gBAAgB,WAAW;AAAA,IACjC,MAAM;AAAA,EACR;AACA,MAAI,CAAC,SAAU,QAAO,gBAAAR,MAAC,uBAAoB,OAAO,iBAAiB,OAAO;AAC1E,SACE,gBAAAA,MAAC,SAAI,WAAU,+CACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,WAAWS,IAAG,8BAA8B,iDAAiD;AAAA,MAC7F,WAAW;AAAA;AAAA,EACb,GACF;AAEJ,CAAC;;;ADrFK,gBAAAC,aAAA;AAjBC,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgC;AAC9B,QAAM,QAAQ,SAASC,gBAAe,WAAW,GAAG,SAAS;AAE7D,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAM;AAAA,MACN,WAAU;AAAA,MAEV,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO;AAAA;AAAA,MACT;AAAA;AAAA,EACF;AAEJ;;;A7BmBA,SAAS,uBAAAE,4BAAqD;AAgGxD,SA8iCI,YAAAC,WA9iCJ,OAAAC,OA8iCI,QAAAC,cA9iCJ;AAnFN,IAAM,kBAAkB;AAExB,IAAM,UAAuB;AAAA,EAC3B;AAAA,IACE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AAAA,EACA;AAAA;AAAA,IAEE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WACE;AAAA,EACJ;AACF;AAQA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAWE;AAAA;AAAA;AAAA;AAAA;AAAA,QAKT;AAAA,QACA,CAAC,eAAe;AAAA,QAChB,cAAc;AAAA,QACd,qBAAqB;AAAA,MACvB;AAAA,MACA,gCAA4B;AAAA,MAC5B,OAAO,qBAAqB;AAAA,MAE5B,0BAAAF;AAAA,QAAC;AAAA;AAAA,UACC,WAAWE;AAAA,YACT;AAAA,YACA,CAAC,eAAe;AAAA,YAChB;AAAA,UACF;AAAA,UAEC;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAuKA,IAAM,yBAAyB;AAMxB,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB;AAAA,EACA,uBAAuB;AAAA,EACvB;AAAA,EACA;AAAA,EACA,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,GAAG;AACL,GAAqB;AAGnB,QAAM,WAAW,2BAA2B;AAC5C,QAAM,kBAAkB,aAAa,SAAS,mBAAmB,QAAQ,SAAS,cAAc;AAChG,QAAM,YAAgC,kBAAkB,kBAAkB,WAAW,SAAS,YAAY;AAC1G,QAAM,oBAAoB,0BAA0B,kBAAkB,SAAS,aAAa;AAC5F,QAAM,QAAQC,gBAAe;AAC7B,QAAM,eAAe,gBAAgB;AAIrC,QAAM,UAAUC,OAAM;AACtB,QAAM,KAAK,SAAS,MAAM;AAC1B,QAAM,kBAAkB,aAAa;AACrC,QAAM,WAAW,YAAY;AAG7B,QAAM,oBAAoB,eACtB,EAAE,sBAAsB,aAAa,IACrC;AACJ,QAAM,YAAY,YAAY;AAC9B,QAAM,eAAe,YAAYC,gBAAe,SAAS,IAAI;AAC7D,QAAM,gBAAgB,cAAc;AACpC,QAAM,sBAAsB,qBAAqBC;AAEjD,QAAM,CAAC,UAAU,IAAIC;AAAA,IACnB,MAAM,QAAQ,SAAS,KAAK,aAAa,WAAqB,mBAAmB;AAAA,EACnF;AACA,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,UAAW,QAAO;AACvB,QAAI;AACJ,WAAO,MAAM;AACX,cAAQ,OAAO;AAAA,QACb,MAAM,gBAAgB,WAAW,mBAAmB;AAAA,QACpD;AAAA,MACF;AACA,WAAK;AAAA,IACP;AAAA,EACF,GAAG,CAAC,WAAW,mBAAmB,CAAC;AACnC,QAAM,sBAAsB;AAAA,IAC1B,aACA,eAAe,gBACf,CAAC,cAAc,cACd,cAAc,aAAa,WAAW;AAAA,EACzC;AACA,QAAM,oBAAoBC;AAAA,IAAkB,CAACC,WAC3C,YAAYC,mBAAkBD,QAAO,WAAW,mBAAmB,IAAI;AAAA,EACzE;AACA,QAAM,0BAA0B,eAAe,eAC3C,mBAAmB,mBAAmB,cAAc,aAAa,QAAQ,IACzE,CAAC;AAEL,QAAM,mBAAmB,YAAY,uBAAuB,IAAI;AAKhE,QAAM,SAAS,gBAAgB,EAAE;AAKjC,EAAAF,WAAU,MAAM;AACd,WAAO,qBAAqB,IAAI,OAAO,UAAU;AAAA,EACnD,GAAG,CAAC,IAAI,OAAO,UAAU,CAAC;AAO1B,QAAM,sBAAsBI;AAAA,IAC1B,CAAC,gBAA4B;AAC3B,WAAK,OAAO,WAAW;AAAA,QACrB,OAAO,YAAY;AAAA,QACnB,QAAQ,YAAY;AAAA,QACpB,OAAO,OAAO,UAAU,WAAW,QAAQ;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,IACA,CAAC,QAAQ,KAAK;AAAA,EAChB;AAKA,QAAM,kBACJ,CAAC,YAAY,qBAAqB,SAAS,sBAAsB;AAEnE,QAAM,eAAeC,mBAAkB;AAEvC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,eAAe;AAAA,IACjB,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,aACV,MAAM;AACJ,aAAO;AAAA,QACL,IAAI,YAAY,yBAAyB,EAAE,QAAQ,EAAE,WAAW,YAAY,oBAAoB,EAAE,CAAC;AAAA,MACrG;AACA,UAAI,UAAW,cAAa,mBAAmB,aAAa,EAAE,WAAW,YAAY,oBAAoB,CAAC,CAAC;AAAA,IAC7G,IACA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,uBAAuB,YACvB;AAAA,MACE,aAAa;AAAA,QACX;AAAA,QACA,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,IACF,IACA,CAAC;AAAA,EACP,CAAC;AAMD,QAAM,eAAeC,wBAAuB,aAAa;AAIzD,QAAM,SAAS,gBAAgB,cAAc,KAAK,IAAI,cAAc,yBAAyB,aAAa,IAAI;AAE9G,QAAM,WAAWD,mBAAkB;AACnC,QAAM,gBAAgBJ,mBAAkB,mBAAmB;AAC3D,QAAM,cAAc,aAAa,MAAM,KAAK;AAU5C,EAAAD,WAAU,MAAM;AACd;AAAA,MACE,SAAS,cAAc,oBAAoB,IAAI,OAAO,EAAE,CAAC,IAAI;AAAA,IAC/D;AAAA,EACF,GAAG,CAAC,IAAI,aAAa,CAAC;AActB,QAAM,aAAa,CAAC,UAA6C;AAC/D,uBAAmB,MAAM,cAAc,QAAQ,kBAAkB,KAAK,MAAM,aAAa;AAAA,EAC3F;AAGA,QAAM,aAAaC,mBAAkB,gBAAgB;AACrD,QAAM,cAAc,CAAC,WACjB,OACA,WAAW,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW,GAAG,OAAO;AAG5D,QAAM,CAAC,kBAAkB,mBAAmB,IAAIF;AAAA,IAC9C;AAAA,EACF;AAKA,QAAM,sBAAsB,wBAAwB,cAAc,MAAM,KAAK,UAAU;AACvF,QAAM,qBAAqB,cAAc,sBAAsB,YAAY;AAC3E,iBAAe,qBAAqB,oBAAoB,WAAW;AAMnE,QAAM,cAAc,eAAe;AACnC,QAAM,eAAe,CAAC,CAAC;AACvB,QAAM,sBAAsB,eACxB,iEACA;AAGJ,QAAM,aAAa,CAAC,CAAC;AACrB,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,kBAAkB;AACjE,QAAM,CAAC,aAAa,cAAc,IAAIA;AAAA,IACpC;AAAA,EACF;AACA,QAAM,sBAAsBE,mBAAkB,wBAAwB,EAAE,CAAC;AACzE,QAAM,kBAAkBM,QAA2B,IAAI;AACvD,QAAM,2BAA2BA,QAAO,KAAK;AAQ7C,QAAM,wBAAwBH,aAAY,MAAM;AAC9C,QAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC,eAAe,cAAc;AACtE;AAAA,IACF;AACA,QAAI,YAAqC,CAAC;AAC1C,QAAI;AACF,kBAAY,gBAAgB,KAAK,CAAC;AAAA,IACpC,SAAS,OAAO;AACd,YAAM,OAAO,QAAQ,OAAO,EAAE,OAAO,iCAAiC,WAAW,YAAY,oBAAoB,CAAC;AAAA,IACpH;AACA,UAAM,OAAO,mBAAmB,EAAE,GAAG,yBAAyB,GAAG,UAAU,GAAG,cAAc,aAAa,QAAQ;AACjH;AAAA,MACE,wBAAwB;AAAA,QACtB;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA,GAAI,gBAAgB,OAAO,CAAC,IAAI,EAAE,YAAY;AAAA,MAChD,CAAC;AAAA,IACH;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAOD,QAAM,UAAUG,QAAO,qBAAqB;AAC5C,EAAAP,WAAU,MAAM;AACd,YAAQ,UAAU;AAAA,EACpB,GAAG,CAAC,qBAAqB,CAAC;AAE1B,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,oBAAqB;AAC1B,YAAQ,QAAQ;AAAA,EAClB,GAAG,CAAC,qBAAqB,mBAAmB,aAAa,CAAC;AAO1D,QAAM,cAAcI,aAAY,MAAM;AACpC,QAAI,mBAAmB,YAAY,SAAS,cAAc,WAAW;AACnE,eAAS,MAAM;AAAA,IACjB,WAAW,gBAAgB;AACzB,YAAM,OAAO,QAAQ,IAAI,MAAM,0EAA0E,GAAG,EAAE,UAAU,GAAG,CAAC;AAAA,IAC9H,WAAW,WAAW;AACpB,YAAM,0BAA0B,cAAc,aAAa,WAAW,QAAQ,iBAAiB;AAC/F,UAAI,yBAAyB;AAE3B,iBAAS,mBAAmB,aAAa,EAAE,WAAW,YAAY,oBAAoB,CAAC,CAAC;AAAA,MAC1F,WAAW,CAAC,SAAS;AACnB,cAAM,OAAO,QAAQ,IAAI,MAAM,wCAAwC,SAAS,wCAAwC,GAAG,EAAE,UAAU,CAAC;AAAA,MAC1I;AAAA,IACF;AACA,cAAU;AAAA,EACZ,GAAG,CAAC,gBAAgB,UAAU,qBAAqB,IAAI,UAAU,iBAAiB,SAAS,WAAW,mBAAmB,OAAO,cAAc,QAAQ,CAAC;AAGvJ,EAAAJ,WAAU,MAAM;AACd,QAAI,CAAC,iBAAiB,SAAU,QAAO;AACvC,UAAM,QAAQ,CAAC,MAAqB;AAClC,UAAI,EAAE,QAAQ,YAAY,EAAE,iBAAkB;AAI9C,YAAM,UAAU,MAAM;AAAA,QACpB,SAAS;AAAA,UACP,mIAAmI,aAAa,mBAAmB;AAAA,QACrK;AAAA,MACF,EAAE;AAAA,QACA,CAACQ,QACCA,IAAG,eAAe,EAAE,SAAS,KAC7B,iBAAiBA,GAAE,EAAE,eAAe,YACpC,CAACA,IAAG,QAAQ,oBAAoB,IAAI,OAAO,EAAE,CAAC,IAAI;AAAA,MACtD;AACA,UAAI,QAAS;AACb,YAAM,OAAO,SAAS;AAAA,QACpB,uCAAuC,IAAI,OAAO,EAAE,CAAC;AAAA,MACvD;AACA,UAAI,CAAC,KAAM;AACX,YAAM,IAAI,CAACA,QAAgB,OAAO,iBAAiBA,GAAE,EAAE,MAAM,KAAK;AAClE,YAAM,MAAM,MAAM;AAAA,QAChB,SAAS,iBAAiB,qCAAqC;AAAA,MACjE,EAAE,OAAuB,CAAC,MAAMA,QAAQ,CAAC,QAAQ,EAAEA,GAAE,IAAI,EAAE,IAAI,IAAIA,MAAK,MAAO,IAAI;AACnF,UAAI,QAAQ,KAAM;AAClB,QAAE,eAAe;AACjB,kBAAY;AAAA,IACd;AACA,aAAS,iBAAiB,WAAW,KAAK;AAC1C,WAAO,MAAM,SAAS,oBAAoB,WAAW,KAAK;AAAA,EAC5D,GAAG,CAAC,eAAe,UAAU,IAAI,aAAa,aAAa,mBAAmB,CAAC;AAE/E,EAAAR,WAAU,MAAM;AACd,QAAI,CAAC,uBAAuB,yBAAyB,QAAS;AAC9D,6BAAyB,UAAU;AACnC,mBAAe,oBAAoB,WAAW;AAC9C,mBAAe,oBAAoB,WAAW;AAC9C,QAAI,CAAC,oBAAoB,aAAa;AACpC,sBAAgB,SAAS,SAAS;AAAA,IACpC,WAAW,oBAAoB,aAAa;AAC1C,sBAAgB,SAAS,OAAO,oBAAoB,WAAW;AAAA,IACjE;AAAA,EACF,GAAG,CAAC,mBAAmB,CAAC;AAQxB,QAAM,CAAC,cAAc,aAAa,IAAID,UAAgC,IAAI;AAC1E,QAAM,kBAAkBU,gBAAe;AAWvC,QAAM,eAAeF,QAAO,KAAK;AAKjC,QAAM,CAAC,YAAY,aAAa,IAAIR,UAAS,KAAK;AAClD,EAAAC,WAAU,MAAM;AACd,UAAM,QAAQ,OAAO,WAAW,MAAM,cAAc,IAAI,GAAG,eAAe;AAC1E,WAAO,MAAM,OAAO,aAAa,KAAK;AAAA,EACxC,GAAG,CAAC,CAAC;AACL,EAAAA,WAAU,MAAM;AACd,QAAI,cAAe,cAAa,UAAU;AAAA,EAC5C,GAAG,CAAC,aAAa,CAAC;AAClB,QAAM,oBAAoB,SAAS;AACnC,QAAM,gBACJ,SAAS,aAAa,MAAM,UAC5B,SAAS,aAAa,MAAM;AAE9B,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,cAAc,YAAY,gBAAgB,WAAY,QAAO;AAClE,UAAMQ,MAAK;AACX,QAAI,CAACA,IAAI,QAAO;AAChB,QAAI,SAAS;AACb,UAAM,KAAK,IAAI,eAAe,CAAC,YAAY;AAIzC,UAAI,CAAC,UAAU,gBAAgB,SAAS,EAAE,cAAc,QAAQ,EAAE,GAAG,UAAU,WAAY;AAC3F,YAAM,QAAQ,QAAQ,CAAC;AACvB,UAAI,CAAC,MAAO;AACZ,YAAM,EAAE,OAAO,OAAO,IAAI,MAAM;AAEhC,YAAM,UAAUA,IAAG,eAAeA,IAAG;AACrC,YAAM,UAAUA,IAAG,cAAcA,IAAG;AACpC,YAAM,WAAW,KAAK,KAAK,QAAQ,OAAO;AAC1C,YAAM,YAAY,KAAK,KAAK,SAAS,OAAO;AAC5C,YAAM,WACJ,CAAC,aAAa,WACd,iBACA,sBAAsB;AACxB;AAAA,QACEE,kBAAiB;AAAA,UACf;AAAA,UACA,MAAM;AAAA,YACJ,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,GAAI,WACA,gBAAgB,mBAAmB,UAAU,SAAS,IACtD,CAAC;AAAA,UACP;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACD,OAAG,QAAQF,GAAE;AACb,WAAO,MAAM;AACX,eAAS;AACT,SAAG,WAAW;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,YAAY,cAAc,UAAU,aAAa,IAAI,UAAU,iBAAiB,mBAAmB,aAAa,CAAC;AAErH,QAAM,gBAAgBJ,aAAY,MAAM;AACtC,UAAM,QAAQ,gBAAgB;AAC9B,QAAI,CAAC,MAAO;AACZ,QAAI,aAAa;AACf,UAAI,sBAAsB;AACxB;AAAA,UACEM,kBAAiB;AAAA,YACf;AAAA,YACA,MAAM,EAAE,OAAO,KAAK,QAAQ,mBAAmB;AAAA,UACjD,CAAC;AAAA,QACH;AACA,8BAAsB,MAAM,MAAM,SAAS,CAAC;AAAA,MAC9C,OAAO;AACL,cAAM,SAAS;AAAA,MACjB;AAAA,IACF,OAAO;AACL,UAAI,sBAAsB;AACxB;AAAA,UACEA,kBAAiB;AAAA,YACf;AAAA,YACA,MAAM,EAAE,OAAO,KAAK,QAAQ,mBAAmB;AAAA,UACjD,CAAC;AAAA,QACH;AACA,8BAAsB,MAAM,MAAM,OAAO,kBAAkB,CAAC;AAAA,MAC9D,OAAO;AACL,cAAM,OAAO,kBAAkB;AAAA,MACjC;AAAA,IACF;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,EACP,CAAC;AAED,QAAM,sBAAsBN;AAAA,IAC1B,CAAC,cAA0D;AACzD,qBAAe,UAAU,eAAe,CAAC;AACzC,UAAI,UAAU,WAAW,EAAG,gBAAe,UAAU,QAAQ;AAC7D,UAAI,qBAAqB;AACvB;AAAA,UACE,wBAAwB;AAAA,YACtB;AAAA,YACA,aAAa,UAAU,eAAe;AAAA,YACtC,aACE,UAAU,WAAW,IAAI,UAAU,WAAW;AAAA,UAClD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,UAAU,IAAI,qBAAqB,WAAW;AAAA,EACjD;AAGA,QAAM,eAAe,YAAY,SAAS,OAAO;AAEjD,QAAM,CAAC,QAAQ,IAAIL,UAAgC,MAAM;AACvD,QAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,SAAK,aAAa,yBAAyB,EAAE;AAC7C,WAAO;AAAA,EACT,CAAC;AAMD,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,UAAW,QAAO;AACvB,qBAAiB,WAAW,EAAE;AAC9B,WAAO,MAAM,mBAAmB,WAAW,EAAE;AAAA,EAC/C,GAAG,CAAC,WAAW,EAAE,CAAC;AAGlB,QAAM,uBAAuB,gBAAgB,WAAW;AAGxD,QAAM,WAAWI,aAAY,MAAM;AACjC,UAAM,EAAE,IAAI,GAAG,IAAIO,kBAAiB;AACpC;AAAA,MACED,kBAAiB;AAAA,QACf;AAAA,QACA,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK,MAAM,KAAK,CAAC,GAAG,QAAQ,GAAG;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,UAAU,EAAE,CAAC;AAEjB,QAAM,YAAYN,aAAY,MAAM;AAClC,UAAM,EAAE,IAAI,GAAG,IAAIO,kBAAiB;AACpC,UAAM,OAAO,KAAK,MAAM,KAAK,CAAC;AAC9B;AAAA,MACED,kBAAiB;AAAA,QACf;AAAA,QACA,MAAM,EAAE,GAAG,MAAM,GAAG,GAAG,OAAO,KAAK,MAAM,QAAQ,GAAG;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,UAAU,EAAE,CAAC;AAEjB,QAAM,UAAUN,aAAY,MAAM;AAChC,UAAM,EAAE,IAAI,GAAG,IAAIO,kBAAiB;AACpC;AAAA,MACED,kBAAiB;AAAA,QACf;AAAA,QACA,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,IAAI,QAAQ,KAAK,MAAM,KAAK,CAAC,EAAE;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,UAAU,EAAE,CAAC;AAEjB,QAAM,aAAaN,aAAY,MAAM;AACnC,UAAM,EAAE,IAAI,GAAG,IAAIO,kBAAiB;AACpC,UAAM,OAAO,KAAK,MAAM,KAAK,CAAC;AAC9B;AAAA,MACED,kBAAiB;AAAA,QACf;AAAA,QACA,MAAM,EAAE,GAAG,GAAG,GAAG,MAAM,OAAO,IAAI,QAAQ,KAAK,KAAK;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,UAAU,EAAE,CAAC;AAEjB,QAAM,aAAaN,aAAY,MAAM;AACnC,UAAM,EAAE,IAAI,GAAG,IAAIO,kBAAiB;AACpC,UAAM,IAAI,KAAK,IAAI,KAAK,OAAO,EAAE;AACjC,UAAM,IAAI,KAAK,IAAI,KAAK,QAAQ,EAAE;AAClC;AAAA,MACED,kBAAiB;AAAA,QACf;AAAA,QACA,MAAM;AAAA,UACJ,GAAG,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,UAC1B,GAAG,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,UAC1B,OAAO;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,UAAU,IAAI,KAAK,OAAO,KAAK,MAAM,CAAC;AAE1C,QAAM,aAAaN;AAAA,IACjB,CAAC,WAA6B;AAC5B,YAAM,EAAE,IAAI,GAAG,IAAIO,kBAAiB;AACpC;AAAA,QACE,qBAAqB;AAAA,UACnB;AAAA,UACA,eAAe;AAAA,UACf,gBAAgB;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAIA,QAAM,aAAaV,mBAAkBW,kBAAiB,EAAE,CAAC;AAGzD,QAAM,cAAc,UAAU;AAC9B,QAAM,uBAAuB,mBAAmB;AAChD,QAAM,YAAY,mBAAmB,EAAE;AACvC,QAAM,YAAY,eAAe,QAAQ,cAAc;AACvD,QAAM,kBAAkB,MAAM;AAAA,IAC5B,MACE,aAAa,YACT,EAAE,gBAAgB,UAAU,UAAU,cAAc,WAAW,iBAAiB,UAAU,SAAS,MAAM,MAAM,WAAW,IAC1H;AAAA,IACN,CAAC,WAAW,WAAW,YAAY,WAAW;AAAA,EAChD;AACA,QAAM,sBAAsB,aAAa,YAAY,UAAU,SAAS,OAAO;AAC/E,QAAM,oBAAoBX,mBAAkB,uBAAuB;AAWnE,QAAM,gBACJ,CAAC,oBACD,CAAC,YACD,qBAAqB,UACrB,gBAAgB,eAChB,eAAe;AAIjB,QAAM,eAAeG,aAAY,MAAM;AACrC,SAAK,OAAO,WAAW;AAAA,MACrB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,OAAO,OAAO,UAAU,WAAW,QAAQ;AAAA,IAC7C,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,KAAK,OAAO,KAAK,QAAQ,KAAK,CAAC;AAE3C,QAAM,iBAAiBA,aAAY,MAAM;AACvC,aAASS,YAAWC,wBAAuB,EAAE,CAAC,CAAC;AAAA,EACjD,GAAG,CAAC,UAAU,EAAE,CAAC;AAMjB,QAAM,UAAUP,QAA8B,IAAI;AAClD,QAAM,4BAA4BA,QAGxB,IAAI;AACd,QAAM,uBAAuBA,QAAO,CAAC;AAIrC,QAAM,mBAAmBjB,qBAAoB,eAAe;AAC5D,QAAM,uBACJ,uBACA,iBAAiB,wBAChB,iBAAiB,UAAU,SAAY;AAC1C,QAAM,CAAC,oBAAoB,qBAAqB,IAAIS,UAK1C,IAAI;AACd,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAE5C,MAAS;AAEX,QAAM,iBAAiBK,aAAY,MAAM;AACvC,QAAI;AACJ,QAAI;AACF,kBAAY,gBAAgB;AAAA,IAC9B,SAAS,OAAO;AACd,YAAM,OAAO,QAAQ,OAAO,EAAE,OAAO,4BAA4B,UAAU,gBAAgB,CAAC;AAAA,IAC9F;AACA,QAAI,aAAa,OAAO,cAAc,UAAU;AAC9C,yBAAmB,SAAS;AAAA,IAC9B;AACA,QAAI,oBAAqB,SAAQ,QAAQ;AACzC,UAAM,SAAS,QAAQ;AACvB,UAAM,aAAa,EAAE,qBAAqB;AAC1C,QAAI,QAAQ;AACV,YAAM,SAAS,OAAO,sBAAsB;AAC5C,gCAA0B,UAAU;AAAA,QAClC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,KAAK,CAAC;AAAA,QAC3C,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,MAAM,CAAC;AAAA,MAC/C;AAAA,IACF;AACA,QAAI,wBAAwB,QAAQ;AAClC,YAAM,SAAS,OAAO,sBAAsB;AAC5C,4BAAsB;AAAA,QACpB,SAAS;AAAA,QACT,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,KAAK,CAAC;AAAA,QAC3C,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,MAAM,CAAC;AAAA,QAC7C;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,4BAAsB,IAAI;AAAA,IAC5B;AACA,eAAW;AAAA,EACb,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,EAAAJ,WAAU,MAAM;AACd,QAAI,gBAAgB,eAAe,CAAC,mBAAoB,QAAO;AAC/D,UAAM,SAAS,QAAQ;AACvB,QAAI,CAAC,QAAQ;AACX,4BAAsB,IAAI;AAC1B,aAAO;AAAA,IACT;AAEA,QAAI,YAAY;AAChB,UAAM,EAAE,SAAS,WAAW,IAAI;AAChC,QAAI;AACJ,UAAM,UAAU,IAAI,QAAc,CAAC,YAAY;AAC7C,kBAAY,WAAW,MAAM,QAAQ,IAAI,GAAG,GAAG;AAAA,IACjD,CAAC;AACD,SAAK,QAAQ,KAAK,CAAC,QAAQ,MAAM,GAAG,OAAO,CAAC,EACzC,KAAK,CAAC,SAAS;AACd,UAAI,QAAQ,CAAC,aAAa,qBAAqB,YAAY,YAAY;AACrE,wBAAgB,IAAI,IAAI;AAAA,MAC1B;AAAA,IACF,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,UAAI,CAAC,UAAW,OAAM,OAAO,QAAQ,KAAK,EAAE,OAAO,uBAAuB,UAAU,GAAG,CAAC;AAAA,IAC1F,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,UAAW,cAAa,SAAS;AACrC,UAAI,CAAC,aAAa,qBAAqB,YAAY,YAAY;AAC7D;AAAA,UAAsB,CAAC,YACrB,SAAS,eAAe,aAAa,OAAO;AAAA,QAC9C;AAAA,MACF;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,kBAAY;AACZ,UAAI,UAAW,cAAa,SAAS;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,IAAI,oBAAoB,OAAO,WAAW,CAAC;AAE/C,QAAM,gCAAgCI,aAAY,MAAM;AACtD,yBAAqB,WAAW;AAChC,0BAAsB,IAAI;AAC1B,sBAAkB,EAAE;AACpB,cAAU;AAAA,EACZ,GAAG,CAAC,IAAI,SAAS,CAAC;AAGlB,EAAAJ,WAAU,MAAM;AACd,WAAO,MAAM;AACX,2BAAqB,WAAW;AAChC,wBAAkB,EAAE;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,EAAE,CAAC;AAKP,QAAM,uBAAuBO,QAAO,WAAW;AAC/C,EAAAP,WAAU,MAAM;AACd,UAAM,eAAe,qBAAqB,YAAY;AACtD,yBAAqB,UAAU;AAC/B,QAAI,CAAC,gBAAgB,gBAAgB,YAAa;AAElD,UAAM,oBAAoB,EAAE,qBAAqB;AACjD,sBAAkB,EAAE;AACpB,mBAAe,MAAM;AACnB;AAAA,QAAsB,CAAC,YACrB,WAAW,QAAQ,aAAa,oBAAoB,OAAO;AAAA,MAC7D;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,IAAI,WAAW,CAAC;AAQpB,QAAM,eAAeO,QAA2B,WAAW;AAC3D,QAAM,oBAAoBA,QAA0B,UAAU;AAC9D,EAAAP,WAAU,MAAM;AACd,UAAM,iBACJ,aAAa,YAAY,cAAc,kBAAkB,YAAY;AACvE,UAAM,gBAAgB,gBAAgB,cAAc,eAAe;AACnE,iBAAa,UAAU;AACvB,sBAAkB,UAAU;AAC5B,QAAI,kBAAkB,eAAe;AAKnC,YAAM,EAAE,IAAI,IAAI,WAAW,IAAIW,kBAAiB;AAChD,UAAI,WAAY;AAChB,eAASI,iBAAgB,EAAE,IAAI,eAAe,IAAI,gBAAgB,GAAG,CAAC,CAAC;AAAA,IACzE;AAAA,EACF,GAAG,CAAC,UAAU,IAAI,aAAa,UAAU,CAAC;AAE1C,QAAM,cAAc,gBAAgB;AACpC,QAAM,cAAc,gBAAgB;AACpC,QAAM,oBAAoB,sBAAsB;AAEhD,EAAAf,WAAU,MAAM;AACd,QAAI,CAAC,YAAY,CAAC,YAAa;AAC/B,QAAI,YAAY;AAChB,mBAAe,MAAM;AACnB,UAAI,CAAC,UAAW,+BAA8B;AAAA,IAChD,CAAC;AACD,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,+BAA+B,aAAa,QAAQ,CAAC;AACzD,QAAM,iBACJ,OAAO,KAAK,KACZH,gBAAe,eAAe,GAAG,SACjC;AAGF,QAAM,SACJ,gBAAAL;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,aAAa;AAAA,MACpB;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA,SAAS;AAAA,MACT,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB,mBAAmB,YAAY,wBAAwB;AAAA,MACvD,UAAU,gBAAgB,eAAe;AAAA;AAAA,EAC3C;AASF,QAAM,oBACJ,kBAAkB,SAAS,sBAAsB;AAEnD,QAAM,YACJ,cAAc,oBACZ,gBAAAC,OAAC,uBAAoB,aAAY,cAAa,WAAU,kBACrD;AAAA,kBACC,gBAAAA,OAAAF,WAAA,EACE;AAAA,sBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,UAAU;AAAA,UACV,aAAa,cAAc,qBAAqB;AAAA,UAChD,SAAS;AAAA,UACT,aAAW;AAAA,UACX,eAAe;AAAA,UACf,qBAAoB;AAAA,UACpB,UAAU;AAAA,UACV,OAAO,EAAE,UAAU,SAAS;AAAA,UAE5B,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAWE;AAAA,gBACT;AAAA,gBACA;AAAA,cACF;AAAA,cAEC;AAAA;AAAA,UACH;AAAA;AAAA,MACF;AAAA,MAIA,gBAAAF;AAAA,QAAC;AAAA;AAAA,UACC,WACE,cAAc,SAAY;AAAA;AAAA,MAE9B;AAAA,OACF;AAAA,IAEF,gBAAAA,MAAC,kBAAe,IAAG,QAAO,SAAS,KAAK,WAAU,WAChD,0BAAAA,MAAC,SAAI,WAAU,gDACZ,UACH,GACF;AAAA,IACC,qBACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,sBAAAC,MAAC,mBAAgB;AAAA,MACjB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,aAAa;AAAA,UACb,SAAS;AAAA,UACT,qBAAoB;AAAA,UACpB,OAAO,EAAE,UAAU,SAAS;AAAA,UAE5B,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAWE;AAAA,gBACT;AAAA,gBACA;AAAA,cACF;AAAA,cAEC;AAAA;AAAA,UACH;AAAA;AAAA,MACF;AAAA,OACF;AAAA,KAEJ,IAEA;AAKJ,QAAM,cACJ,gBAAAF,MAAC,0BACE,yBACC,gBAAAC,OAAC,SAAI,WAAU,gCACb;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,YAAY,aAAa;AAAA,QACzB,MAAM,aAAa;AAAA;AAAA,IACrB;AAAA,IACA,gBAAAA,MAAC,SAAI,WAAU,kBAAkB,qBAAU;AAAA,KAC7C,IAEA,WAEJ;AAGF,QAAM,iBAAiB,cAAc,gBAAgB;AACrD,QAAM,YAAY,UAAU;AAM5B,QAAM,cACJ,gBAAAC,OAAAF,WAAA,EACE;AAAA,oBAAAC,MAAC,SAAI,WAAU,oCAAoC,sBAAW;AAAA,IAC9D,gBAAAA,MAAC,SAAI,WAAU,iDACZ,wBACH;AAAA,IACA,gBAAAA,MAAC,SAAI,WAAU,oCAAoC,uBAAY;AAAA,KACjE;AAGF,QAAM,YAAY,YAChB,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAWE;AAAA;AAAA,QAET;AAAA,QACA;AAAA,QACA,kBAAkB;AAAA;AAAA,QAGhB;AAAA,MACJ;AAAA,MACA,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,MAEvC,qBACE,kBAAkB,QACjB,cAEA,gBAAAF,MAAC,SAAI,WAAU,2BAA2B,uBAAY;AAAA;AAAA,EAE5D,IACE;AAcJ,QAAM,aACJ,aAAa,YAAY,CAAC,WACtBwB;AAAA,IACE,gBAAAxB,MAAC,cAAc,UAAd,EAAuB,OAAO,iBAC7B,0BAAAA,MAACyB,0BAAA,EAAwB,WAAW,qBAGlC,0BAAAzB,MAAC,SAAI,WAAU,YAAW,eAAe,SAAS,sBAAsB,YAAY,gBAAgB,YACjG,uBACH,GACF,GACF;AAAA,IACA;AAAA,EACF,IACA;AAEN,MAAI,UAAU;AACZ,UAAM,qBACJ,8BAA8B,eAAe,UAAU;AACzD,UAAM,kBAAkB,eAAe,mBAAmB;AAE1D,QAAI,uBAAuB,UAAU;AACnC,UAAI,yBAAyB,gBAAgB,WAAW;AACtD,gBAAQ;AAAA,UACN,0BAA0B,SAAS;AAAA,QACrC;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,QAAI,uBAAuB,UAAU;AACnC,aACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,OAAO,aAAa;AAAA,UACpB,SAAS;AAAA,UACT;AAAA,UACA,WAAW;AAAA,UACX,QAAQ;AAAA,UACR;AAAA,UACA,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA,eAAe;AAAA,UACf,WAAW;AAAA,UAEX,0BAAAA,MAAC,0BAAwB,UAAS;AAAA;AAAA,MACpC;AAAA,IAEJ;AAEA,QAAI,uBAAuB,QAAQ;AACjC,aACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,OAAO,aAAa;AAAA,UACpB,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UAEA,0BAAAA,MAAC,0BAAwB,UAAS;AAAA;AAAA,MACpC;AAAA,IAEJ;AAGA,UAAM,aACJ,cAAc,qBAAqB,YACjC,gBAAAA,MAAC,SAAI,WAAWE,IAAG,0BAA0B,gBAAgB,GAC1D,mBACH,IAEA;AAGJ,UAAM,WACJ,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,WAAWC;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL,KAAK,aAAa;AAAA,UAClB;AAAA,UACA,SAAS,eAAe,CAAC,cAAc,SAAY;AAAA,UACnD,YAAY,gBAAgB,WAAW;AAAA,QACzC;AAAA,QACA,eAAe;AAAA,QACf,sBAAsB;AAAA,QACtB,gBAAgB;AAAA,QAEhB;AAAA,0BAAAF;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,aAAa;AAAA,cACpB,cAAc;AAAA,cACd,SAAS;AAAA,cACT;AAAA,cACA;AAAA,cACA,iBAAiB;AAAA;AAAA,UACnB;AAAA,UACC,eAAe,gBAAAA,MAAC,cAAW,MAAY,QAAgB;AAAA,UACxD,gBAAAA,MAAC,SAAI,WAAWE,IAAG,gCAAgC,aAAa,GAG9D,0BAAAF,MAAC,0BAAwB,sBAAW,GACtC;AAAA,UACC;AAAA;AAAA;AAAA,IACH;AAEF,WAAO,eACHwB,cAAa,gBAAAxB,MAAC0B,gBAAA,EAAe,oBAAS,GAAkB,YAAY,IACpE;AAAA,EACN;AAeA,MAAI,eAAe,MAAM;AACvB,WACE,gBAAAzB,OAAAF,WAAA,EACA;AAAA,sBAAAC,MAAC,gBAAa,UAAU,IACtB,0BAAAC;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ,WAAU;AAAA,UAEV;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,aAAa;AAAA,gBACpB,cAAc;AAAA,gBACd,QAAQ;AAAA;AAAA,YACV;AAAA,YACC,eAAe,gBAAAA,MAAC,cAAW,MAAY,QAAgB;AAAA,YACxD,gBAAAA,MAAC,SAAI,WAAWE,IAAG,gCAAgC,aAAa,GAC9D,0BAAAF,MAAC,aAAU,MAAM,UAAU,GAC7B;AAAA,YACC;AAAA;AAAA;AAAA,MACH,GACF;AAAA,MACC;AAAA,OACD;AAAA,EAEJ;AAMA,QAAM,KACJ,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,aAAa,gBAAgB;AAAA,MAClC,qBAAkB;AAAA,MAChB,kBAAgB;AAAA,MACjB,GAAG;AAAA,MAIH,GAAI,cAAc,EAAE,8BAA8B,GAAG,IAAI,CAAC;AAAA,MAC3D,WAAWC;AAAA,QACT;AAAA,QACA,cAAc,oBAAoB;AAAA,QAClC;AAAA;AAAA,QAEA,cAAc,CAAC,iBAAiB;AAAA;AAAA,QAEhC,qBACE;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL,GAAI,cACA,EAAE,OAAO,GAAG,OAAO,SAAS,QAAQ,SAAS,IAC7C;AAAA,UACE,MAAM,KAAK;AAAA,UACX,KAAK,KAAK;AAAA,UACV,GAAI,cAAc,CAAC,cACf,EAAE,OAAO,eAAe,QAAQ,OAAO,IACvC,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AAAA,QAC/C;AAAA,QACJ;AAAA;AAAA;AAAA;AAAA,QAIA,UAAU,eAAe,cACrB,IACA,aACG,YAAY,MACb,KAAK,IAAI,YAAY,KAAK,KAAK,KAAK;AAAA,QAC1C,WAAW,eAAe,cACtB,IACA,aACG,aAAa,KACd,KAAK,IAAI,aAAa,IAAI,KAAK,MAAM;AAAA,QAC3C,YAAY,gBAAgB,WAAW;AAAA,MACzC;AAAA,MACA,eAAe;AAAA,MACb,sBAAsB;AAAA,MACtB,gBAAgB;AAAA,MAGlB,eAAe,cAAc,gCAAgC;AAAA,MAE5D;AAAA,SAAC,eAAe,CAAC,eAChB,QAAQ,IAAI,CAAC,MACX,gBAAAF;AAAA,UAAC;AAAA;AAAA,YAEC,WAAWE;AAAA,cACT,EAAE;AAAA,cACF;AAAA,YACF;AAAA,YACA,OAAO,EAAE,aAAa,OAAO;AAAA,YAC7B,eAAe,cAAc,EAAE,IAAI;AAAA;AAAA,UAN9B,EAAE;AAAA,QAOT,CACD;AAAA,QACH,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,WAAWC;AAAA,cACT;AAAA;AAAA;AAAA;AAAA;AAAA,cAKA,cACI,4CACA;AAAA,cACJ;AAAA,YACF;AAAA,YAEC;AAAA;AAAA,cAIA,eAAe,CAAC,eAAe,gBAAAF,MAAC,cAAW,MAAY,QAAgB;AAAA,cAItE,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,mBACE,cACI,qBACE;AAAA,oBACE,OAAO,mBAAmB;AAAA,oBAC1B,QAAQ,mBAAmB;AAAA,kBAC7B,IACC,0BAA0B,WAAW;AAAA,oBACpC,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK;AAAA,oBAC7B,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM;AAAA,kBACjC,IACF;AAAA,kBAGN,0BAAAA,MAAC,aAAU,MAAM,UAAU;AAAA;AAAA,cAC7B;AAAA,cAKD,eACC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,aAAa;AAAA,kBACb,aAAa;AAAA,kBACb;AAAA,kBACA,aAAa;AAAA,kBACb,OAAO;AAAA,kBACP,WAAW;AAAA;AAAA,cACb;AAAA,cAGD,CAAC,eAAe;AAAA,cAIhB,qBACC,gBAAAA,MAAC,SAAI,WAAU,8EACb,0BAAAA,MAAC,SAAI,WAAU,2FAA0F,gCAEzG,GACF;AAAA;AAAA;AAAA,QAEJ;AAAA;AAAA;AAAA,EACF;AAGF,SACE,gBAAAC,OAAAF,WAAA,EACG;AAAA,mBAAeyB,cAAa,gBAAAxB,MAAC0B,gBAAA,EAAe,cAAG,GAAkB,YAAY,IAAI;AAAA,IACjF;AAAA,KACH;AAEJ;AAMA,SAAS,UAAU,EAAE,KAAK,GAAoC;AAC5D,QAAM,UAAUX,QAA8B,IAAI;AAClD,kBAAgB,MAAM;AACpB,UAAMY,QAAO,QAAQ;AACrB,QAAI,CAACA,SAAQ,CAAC,KAAM,QAAO;AAC3B,IAAAA,MAAK,YAAY,IAAI;AACrB,WAAO,MAAM;AACX,UAAI,KAAK,eAAeA,MAAM,CAAAA,MAAK,YAAY,IAAI;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AACT,SAAO,gBAAA3B,MAAC,SAAI,KAAK,SAAS,WAAU,YAAW,yBAAsB,IAAG;AAC1E;AAMA,SAAS,mBAAmB,EAAE,QAAQ,GAA4B;AAChE,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV;AAAA,MACA,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,MACxC,OAAM;AAAA,MACN,cAAW;AAAA,MAEX,0BAAAA,MAAC,iBAAU,WAAU,eAAc;AAAA;AAAA,EACrC;AAEJ;AAgCA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAWC;AAAA;AAAA;AAAA;AAAA;AAAA,QAKT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOA,cACI,qGACA;AAAA,QACJ;AAAA,QACA,eAAe,cACX,mBACA;AAAA,QACJ,eAAe;AAAA,MACjB;AAAA,MACA,2BAAyB,cAAc,cAAc;AAAA,MACrD,OAAO,eAAe,cAAc,SAAY,EAAE,aAAa,OAAO;AAAA,MACtE,eAAe,eAAe,cAAc,SAAY;AAAA,MAMxD;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,WAAWE;AAAA,cACT;AAAA,cACA,aAAa,SAAS;AAAA,YACxB;AAAA,YACA,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,YAExC,0BAAAF,MAAC,SAAI,WAAU,QACb,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA;AAAA,YACF,GACF;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAC,OAAC,SAAI,WAAU,yCAEb;AAAA,0BAAAD,MAAC,SAAI,WAAW,aAAa,SAAS,QAAQ;AAAA,UAG7C,CAAC,eAAe,eACf,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,cACX,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,cAEvC;AAAA;AAAA,UACH;AAAA,WAEJ;AAAA,QAMC,cACC,gBAAAA,MAAC,SAAI,WAAU,+FACb,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,+BAA2B;AAAA,YAE1B;AAAA;AAAA,QACH,GACF,IACE;AAAA,QAaH,CAAC,eACA,gBAAAA,MAAC,SAAI,WAAU,mEACZ,iBAAO,UAAU,YAAY,SAAS,OACrC,gBAAAA,MAAC,UAAK,WAAU,2DACb,mBAAS,IACZ,IAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,eAAe,CAAC,UAAU;AACxB,oBAAM,SAAS,MAAM;AACrB,kBAAI,EAAE,kBAAkB,SAAU;AAClC,kBACE,OAAO;AAAA,gBACL;AAAA,cACF,GACA;AACA,sBAAM,gBAAgB;AAAA,cACxB;AAAA,YACF;AAAA,YAEC;AAAA;AAAA,QACH,GAEJ;AAAA,QAIF,gBAAAA,MAAC,SAAI,WAAU,qDACZ,WAAC,gBAAgB,YAAY,iBAC5B,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,YACX,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,YAEvC;AAAA,yBAAW,gBAAAD,MAAC,sBAAmB,SAAS,UAAU,IAAK;AAAA,cACvD;AAAA;AAAA;AAAA,QACH,GAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAyBA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,SACE,gBAAAC,OAAC,SAAI,WAAU,qDAEb;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,MACE,gBAAAA,MAAC,SAAE,WAAU,oCAAmC;AAAA,QAElD,SAAS,WAAW;AAAA,QACpB,UAAU,CAAC;AAAA,QACX,cAAW;AAAA;AAAA,IACb;AAAA,IAGA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,MACE,cACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA;AAAA,QAEZ,IAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA;AAAA,QAEZ;AAAA,QAGJ,SAAS,cAAc,YAAY;AAAA,QACnC,cAAY,cAAc,YAAY;AAAA;AAAA,IACxC;AAAA,IAGC,CAAC,eACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,IAID,cAAc,CAAC,eACd,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS;AAAA,QACT,OAAO,cAAc,iBAAiB;AAAA,QACtC,cAAY,cAAc,iBAAiB;AAAA,QAE1C,wBACC,gBAAAA,MAAC,sBAAe,WAAU,eAAc,IAExC,gBAAAA,MAAC,iBAAU,WAAU,eAAc;AAAA;AAAA,IAEvC;AAAA,KAEJ;AAEJ;AAYA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAChB,GAAsB;AACpB,QAAM,OACJ;AACF,QAAM,UACJ,UAAU,QACN,WACE,+CACA,4CACF;AAEN,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAWE,IAAG,MAAM,OAAO;AAAA,MAC3B,SAAS,WAAW,SAAY;AAAA,MAChC,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,MACxC,cAAY;AAAA,MACZ;AAAA,MAEA,0BAAAF;AAAA,QAAC;AAAA;AAAA,UACC,WAAWE;AAAA,YACT;AAAA,YACA,CAAC,YAAY;AAAA,UACf;AAAA,UAEC;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAmBA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,CAAC,cAAc,eAAe,IAAIK,UAAS,KAAK;AACtD,QAAM,aAAaQ,QAA6C,IAAI;AACpE,QAAM,eAAeA,QAAuB,IAAI;AAEhD,QAAM,eAAe,MAAM;AACzB,QAAI,WAAW,QAAS,cAAa,WAAW,OAAO;AACvD,oBAAgB,IAAI;AAAA,EACtB;AACA,QAAM,gBAAgB,MAAM;AAC1B,eAAW,UAAU,WAAW,MAAM;AACpC,sBAAgB,KAAK;AAAA,IACvB,GAAG,GAAG;AAAA,EACR;AAEA,QAAM,eAAe,CAAC,OAAmB;AACvC,OAAG;AACH,oBAAgB,KAAK;AAAA,EACvB;AAGA,EAAAP,WAAU,MAAM;AACd,QAAI,CAAC,aAAc,QAAO;AAC1B,UAAM,mBAAmB,CAAC,MAAoB;AAC5C,YAAM,SAAS,EAAE;AACjB,UAAI,aAAa,WAAW,CAAC,aAAa,QAAQ,SAAS,MAAM,GAAG;AAClE,YAAI,OAAO,UAAU,qBAAqB,EAAG;AAC7C,wBAAgB,KAAK;AAAA,MACvB;AAAA,IACF;AACA,aAAS,iBAAiB,eAAe,gBAAgB;AACzD,WAAO,MAAM,SAAS,oBAAoB,eAAe,gBAAgB;AAAA,EAC3E,GAAG,CAAC,YAAY,CAAC;AAEjB,SACE,gBAAAP;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACV,cAAc;AAAA,MACd,cAAc;AAAA,MAGd;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAWE;AAAA,cACT;AAAA,cACA;AAAA,YACF;AAAA,YACA,SAAS,CAAC,MAAM;AAGd,kBAAI,kBAAkB,UAAU,UAAU,iBAAiB,GAAG;AAC5D,gCAAgB,CAAC,SAAS,CAAC,IAAI;AAAA,cACjC,OAAO;AACL,6BAAa,gBAAgB;AAAA,cAC/B;AAAA,YACF;AAAA,YACA,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,YACxC,cAAY,cAAc,YAAY;AAAA,YAEtC,0BAAAF,MAAC,UAAK,WAAU,gIACb,wBACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA;AAAA,YAEZ,IAEA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA;AAAA,YAEZ,GAEJ;AAAA;AAAA,QACF;AAAA,QAGC,gBACC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,WAAWC;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA,cAAc;AAAA,YACd,cAAc;AAAA,YAGb;AAAA,eAAC,eACA,gBAAAD,OAAAF,WAAA,EACE;AAAA,gCAAAC,MAAC,SAAI,WAAU,wGAAuG,2BAEtH;AAAA,gBACA,gBAAAC,OAAC,SAAI,WAAU,iCACb;AAAA,kCAAAA,OAAC,SAAI,WAAU,6BACb;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,QAAQ;AAAA,wBACpC,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,SAAS;AAAA,wBACrC,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,OAAO;AAAA,wBACnC,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,UAAU;AAAA,wBACtC,MAAK;AAAA;AAAA,oBACP;AAAA,qBACF;AAAA,kBACA,gBAAAC,OAAC,SAAI,WAAU,6BACb;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,UAAU;AAAA,wBACtC,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,gBAAgB;AAAA,wBAC5C,MAAK;AAAA;AAAA,oBACP;AAAA,qBACF;AAAA,mBACF;AAAA,gBACA,gBAAAA,MAAC,SAAI,WAAU,kCAAiC;AAAA,gBAEhD,gBAAAA,MAAC,SAAI,WAAU,wGAAuG,yBAEtH;AAAA,gBACA,gBAAAC,OAAC,SAAI,WAAU,iCACb;AAAA,kCAAAA,OAAC,SAAI,WAAU,6BACb;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,OAAO,CAAC;AAAA,wBACrD,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,OAAO,CAAC;AAAA,wBACrD,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,OAAO,CAAC;AAAA,wBACrD,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,OAAO,CAAC;AAAA,wBACrD,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,QAAQ,CAAC;AAAA,wBACtD,MAAK;AAAA;AAAA,oBACP;AAAA,qBACF;AAAA,kBACA,gBAAAC,OAAC,SAAI,WAAU,6BACb;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MACP,aAAa,MAAM,WAAW,aAAa,CAAC;AAAA,wBAE9C,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MACP,aAAa,MAAM,WAAW,aAAa,CAAC;AAAA,wBAE9C,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MACP,aAAa,MAAM,WAAW,aAAa,CAAC;AAAA,wBAE9C,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MACP,aAAa,MAAM,WAAW,aAAa,CAAC;AAAA,wBAE9C,MAAK;AAAA;AAAA,oBACP;AAAA,qBACF;AAAA,kBACA,gBAAAC,OAAC,SAAI,WAAU,6BACb;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,YAAY,CAAC;AAAA,wBAC1D,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,YAAY,CAAC;AAAA,wBAC1D,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,YAAY,CAAC;AAAA,wBAC1D,MAAK;AAAA;AAAA,oBACP;AAAA,oBACA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,SAAS,MAAM,aAAa,MAAM,WAAW,YAAY,CAAC;AAAA,wBAC1D,MAAK;AAAA;AAAA,oBACP;AAAA,qBACF;AAAA,mBACF;AAAA,gBACA,gBAAAA,MAAC,SAAI,WAAU,kCAAiC;AAAA,iBAClD;AAAA,cAIF,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS,MAAM,aAAa,gBAAgB;AAAA,kBAC5C,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,kBAEvC,wBACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,oCAAAC,MAAC,iBAAU,WAAU,wBAAuB;AAAA,oBAAE;AAAA,qBAChD,IAEA,gBAAAC,OAAAF,WAAA,EACE;AAAA,oCAAAC,MAAC,yBAAkB,WAAU,wBAAuB;AAAA,oBAAE;AAAA,qBAExD;AAAA;AAAA,cAEJ;AAAA,cAEC,eACC,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,SAAS,MAAM,aAAa,SAAS;AAAA,kBACrC,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,kBAExC;AAAA,oCAAAD,MAAC,iBAAU,WAAU,wBAAuB;AAAA,oBAAE;AAAA;AAAA;AAAA,cAEhD;AAAA,cASD,YACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,gCAAAC,MAAC,SAAI,WAAU,kCAAiC;AAAA,gBAChD,gBAAAC;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,SAAS,MAAM,aAAa,QAAQ;AAAA,oBACpC,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,oBACxC,OAAM;AAAA,oBAEN;AAAA,sCAAAD,MAAC,iBAAU,WAAU,wBAAuB;AAAA,sBAC5C,gBAAAA,MAAC,UAAK,WAAU,oBAAmB,qBAAO;AAAA;AAAA;AAAA,gBAC5C;AAAA,iBACF;AAAA,cAID,qBACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,gCAAAC,MAAC,SAAI,WAAU,kCAAiC;AAAA,gBAChD,gBAAAC;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,SAAS,MAAM,aAAa,iBAAiB;AAAA,oBAC7C,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,oBAExC;AAAA,sCAAAD,MAAC,YAAK,WAAU,wBAAuB;AAAA,sBAAE;AAAA;AAAA;AAAA,gBAE3C;AAAA,iBACF;AAAA;AAAA;AAAA,QAEJ;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;A+Bt0EA;AAAA,EACE;AAAA,EACA,mBAAA4B;AAAA,EACA,0BAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAUP,SAAS,sBAAsB;;;ACtB/B,SAAS,MAAAC,YAAU;AACnB,SAAS,kBAAkB;AA6Bf,SAWE,OAAAC,OAXF,QAAAC,cAAA;AAbL,SAAS,cAAyC;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,SACE,gBAAAD,MAAC,cAAW,WAAWD,KAAG,iBAAiB,SAAS,GAClD,0BAAAC,MAAC,SAAI,WAAU,QACZ,gBAAM,IAAI,CAAC,SAAS;AACnB,UAAM,OAAO,KAAK;AAClB,UAAM,WAAW,KAAK,UAAU;AAChC,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,SAAS,MAAM,SAAS,KAAK,KAAU;AAAA,QACvC,OAAO,KAAK;AAAA,QACZ,WAAWF;AAAA,UACT;AAAA,UACA,WACI,6DACA;AAAA,QACN;AAAA,QAEA;AAAA,0BAAAC,MAAC,QAAK,WAAU,wBAAuB;AAAA,UACvC,gBAAAA,MAAC,UAAK,WAAU,YAAY,eAAK,OAAM;AAAA;AAAA;AAAA,MAXlC,KAAK;AAAA,IAYZ;AAAA,EAEJ,CAAC,GACH,GACF;AAEJ;;;AClDA,SAAS,aAAAE,kBAAiB;AAC1B,SAAS,yBAAyB,iCAAiC;AAU5D,SAAS,2BACd,WACA,QACM;AACN,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ,QAAO;AACpB,4BAAwB,SAAS;AACjC,WAAO,MAAM,0BAA0B,SAAS;AAAA,EAClD,GAAG,CAAC,QAAQ,SAAS,CAAC;AACxB;;;AFSA;AAAA,EACE;AAAA,EACA,uBAAAC;AAAA,EACA;AAAA,OAIK;;;AGPP,SAAS,MAAAC,YAAU;AAwFb,gBAAAC,OAKA,QAAAC,cALA;AA/DN,IAAM,eAAoD;AAAA,EACxD,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,KAAK;AAAA,EACP;AAAA,EACA,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK;AAAA,EACP;AAAA,EACA,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,KAAK;AAAA,EACP;AAAA,EACA,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,KAAK;AAAA,EACP;AAAA,EACA,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,KAAK;AAAA,EACP;AACF;AAwBO,SAAS,eAAe;AAAA,EAC7B,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,IAAI,aAAa,IAAI;AAC3B,QAAM,mBAAmB,YAAY,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;AAClE,QAAM,gBAAgB,gBAAgB,SAAS;AAC/C,QAAM,WAAW,OAAO,UAAU;AAKlC,SACE,gBAAAA,OAAC,SAAI,WAAU,oDACb;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,WAAWD,KAAG,wBAAwB,EAAE,IAAI,SAAS,eAAe;AAAA,QACpE,eAAW;AAAA;AAAA,IACb;AAAA,IAEA,gBAAAE,OAAC,SAAI,WAAU,qCACZ;AAAA,iBACC,gBAAAD,MAAC,UAAK,WAAWD,KAAG,sCAAsC,EAAE,EAAE,GAC3D,iBACH,IACE;AAAA,MACH,UACC,gBAAAC,MAAC,UAAK,WAAU,8CACb,mBACH,IACE;AAAA,OACN;AAAA,IAEC,gBACC,gBAAAA,MAAC,SAAI,WAAU,4CACZ,0BAAgB,IAAI,CAAC,GAAG,MACvB,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QACV,OAAO,EAAE,QAAQ,GAAG,EAAE,KAAK,IAAI,EAAE,KAAK,KAAK;AAAA,QAE3C;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,WAAWD;AAAA,gBACT;AAAA,gBACA,aAAa,EAAE,IAAI,EAAE;AAAA,cACvB;AAAA;AAAA,UACF;AAAA,UACA,gBAAAC,MAAC,UAAK,WAAU,kDACb,YAAE,OACL;AAAA;AAAA;AAAA,MAZK;AAAA,IAaP,CACD,GACH,IACE;AAAA,KACN;AAEJ;;;ACtIO,SAAS,qBAA8C;AAC5D,SAAO,UAAU,EAAE,mBAAmB;AACxC;;;ACAA,SAAS,kBAAAE,uBAA8C;AAwBhD,SAAS,aAAa,UAAkB,OAAwB;AACrE,MAAI,aAAa,MAAO,QAAO;AAC/B,QAAM,OAAO,MAAM,SAAS,GAAG,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AACxD,SAAO,aAAa,QAAQ,SAAS,WAAW,GAAG,IAAI,GAAG;AAC5D;AAEA,SAAS,aAAa,GAA8B;AAClD,SAAO,OAAO,MAAM,WAAW,IAAI,GAAG,EAAE,KAAK;AAC/C;AAUO,SAAS,iBACd,WACA,UACsB;AACtB,QAAM,QAAQA,gBAAe,SAAS;AACtC,QAAM,WAAyC,OAAO,QAAQ,gBAAgB,CAAC;AAC/E,QAAM,OAAO,SAAS,IAAI,YAAY;AAEtC,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,SAAS,QACX,WAAW,SAAS,8FACpB,YAAY,SAAS;AACzB,YAAQ,KAAK,iDAA4C,MAAM,EAAE;AACjE,WAAO,EAAE,SAAS,OAAO,QAAQ,MAAM,oBAAoB,KAAK;AAAA,EAClE;AAEA,MAAI,CAAC,UAAU;AACb,UAAM,SAAS,WAAW,SAAS,kEAAkE,KAAK,KAAK,IAAI,CAAC;AACpH,YAAQ,KAAK,iDAA4C,MAAM,EAAE;AACjE,WAAO,EAAE,SAAS,OAAO,QAAQ,MAAM,kBAAkB,KAAK;AAAA,EAChE;AAEA,QAAM,UAAU,SAAS;AAAA,IAAK,CAAC,MAC7B,OAAO,MAAM,WAAW,aAAa,UAAU,CAAC,IAAI,aAAa,EAAE;AAAA,EACrE;AACA,QAAM,QAAQ,YAAY,SAAY,SAAY,aAAa,OAAO;AACtE,MAAI,CAAC,OAAO;AACV,UAAM,SAAS,WAAW,SAAS,cAAc,KAAK,KAAK,IAAI,CAAC,mBAAc,QAAQ;AACtF,YAAQ,KAAK,kDAA6C,MAAM,EAAE;AAClE,WAAO,EAAE,SAAS,OAAO,QAAQ,MAAM,kBAAkB,KAAK;AAAA,EAChE;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,WAAW,SAAS,8BAA8B,KAAK;AAAA,IAC/D;AAAA,EACF;AACF;;;AC/FA,SAAS,cAAAC,mBAAkB;AAO3B,IAAM,QAAQ,MACZA,YAAuB,mCAAmC,MAAM;AAC9D,QAAMC,SAAoB,EAAE,gBAAgB,OAAO,WAAW,aAAa,UAAU,oBAAI,IAAI,EAAE;AAC/F,MAAIA,OAAM,gBAAgB;AACxB,eAAW,MAAM;AACf,MAAAA,OAAM,iBAAiB;AAAA,IACzB,GAAG,CAAC;AAAA,EACN;AACA,SAAOA;AACT,CAAC;AAGH,MAAM;AAMC,SAAS,iBAAiB,UAAkB,QAAyD;AAC1G,MAAI,OAAO,WAAW,YAAa;AAEnC,QAAM,iBAAiB,IAAI,MAAM,WAAW,EAAE,SAAS,IACpD,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,CAAC,2CAA2C,KAAK,IAAI,CAAC,EACvE,KAAK,IAAI;AACZ,iBAAe,MAAM;AACnB,UAAMA,SAAQ,MAAM;AACpB,QAAI,CAACA,OAAM,kBAAkBA,OAAM,SAAS,IAAI,QAAQ,EAAG;AAC3D,IAAAA,OAAM,SAAS,IAAI,QAAQ;AAC3B,UAAM,UACJ,GAAG,QAAQ;AAGb,QAAI,QAAQ;AACV,aAAO,SAAS,aAAa;AAC7B;AAAA,IACF;AACA,YAAQ;AAAA,MACN;AAAA,MACA;AAAA,EAAK,OAAO,GAAG,gBAAgB;AAAA;AAAA;AAAA,EAAgF,aAAa,KAAK,EAAE;AAAA,IACrI;AAAA,EACF,CAAC;AACH;","names":["useCallback","useEffect","useId","useRef","useState","FloatingLayer","useFloatingLayerZIndex","PortalContainerProvider","cn","createPortal","clampWindowRect","DEFAULT_INSTANCE_ID","dockWindow","buildDockWindowPayload","getOverlayMeta","safeViewportDims","selectOverlayData","selectPopoutMode","updateWindowRect","useSummonDispatch","useSummonPorts","useSummonSelector","useSummonStore","jsx","jsxs","GAP","useSyncExternalStore","useState","cn","cn","jsx","jsxs","Fragment","jsx","jsxs","useState","cn","useEffect","useRef","Button","cn","jsx","jsxs","useRef","useEffect","cn","Button","useEffect","useState","jsx","jsxs","cn","jsx","jsxs","useState","cn","jsx","jsxs","useState","cn","jsx","jsxs","cn","useCallback","useEffect","useRef","useSummonDispatch","useSummonSelector","useSyncExternalStore","globalSlot","state","useSummonDispatch","notify","useSummonSelector","useRef","useCallback","useEffect","useCallback","useSummonDispatch","dockWindow","buildDockWindowPayload","globalSlot","createPortal","useSummonSelector","selectPopoutMode","jsx","jsx","useSummonSelector","selectPopoutMode","createPortal","globalSlot","notify","getOverlayMeta","useSyncExternalStore","cn","useSummonPorts","useSummonSelector","jsx","jsxs","TrayChipPreview","useSummonPorts","useSummonSelector","state","DefaultTrayChipBody","TraySnapshotImage","useSyncExternalStore","cn","jsx","getOverlayMeta","getTrayPreviewEntry","Fragment","jsx","jsxs","cn","useSummonPorts","useId","getOverlayMeta","DEFAULT_INSTANCE_ID","useState","useEffect","useSummonSelector","state","selectOverlayData","useCallback","useSummonDispatch","useFloatingLayerZIndex","useRef","el","useSummonStore","updateWindowRect","safeViewportDims","selectPopoutMode","dockWindow","buildDockWindowPayload","clampWindowRect","createPortal","PortalContainerProvider","FloatingLayer","slot","useWindowConfig","WindowSelectionSurface","cn","jsx","jsxs","useEffect","getTrayPreviewEntry","cn","jsx","jsxs","getOverlayMeta","globalSlot","state"]}
1
+ {"version":3,"sources":["../src/window/WindowPanel.tsx","../src/window/icons.tsx","../src/window/LayoutIcon.tsx","../src/window/useWindowPanel.ts","../src/window/popout/popoutDragDetector.ts","../src/window/utils/autoOpenPlacement.ts","../src/window/utils/useIsClient.ts","../src/window/utils/useDebugFlag.ts","../src/window/utils/urlSyncIdentity.ts","../src/window/utils/sanitizeWindowData.ts","../src/window/mobile/MobileDrawerSurface.tsx","../src/window/chrome/MobileTitleRow.tsx","../src/window/mobile/MobileCardSurface.tsx","../src/window/chrome/DebugStrip.tsx","../src/window/chrome/chromeClasses.ts","../src/window/chrome/MobileHeader.tsx","../src/window/chrome/DeprecationBanner.tsx","../src/window/chrome/PopoutTopBar.tsx","../src/window/popout/featureDetection.ts","../src/window/popout/usePopoutWindow.ts","../src/window/popout/popoutWindowMap.ts","../src/window/popout/cloneStyles.ts","../src/window/popout/popoutPendingStorage.ts","../src/window/popout/usePopoutControl.ts","../src/window/popout/PopoutPortal.tsx","../src/window/popout/PopoutShell.tsx","../src/window/popout/PopoutContext.tsx","../src/window/tray/traySnapshotMap.ts","../src/window/tray/defaultTraySnapshotCapture.ts","../src/window/tray/MinimizedWindowContent.tsx","../src/window/tray/TrayChipPreview.tsx","../src/window.ts","../src/window/WindowSidebar.tsx","../src/window/useOverlaySurfaceRenderAck.ts","../src/window/tray/TrayStatusChip.tsx","../src/window/popout/usePopoutContainer.ts","../src/window/utils/mayRaiseUnbidden.ts","../src/window/utils/lazy-bundle-guard.ts"],"sourcesContent":["\"use client\";\n\n/**\n * WindowPanel — a floating, draggable, resizable, maximizable, minimizable OS-style window, with\n * snap/arrange, a minimized tile with a captured preview, pop-out to a real browser window, and\n * three phone presentations. Ported from matrx-frontend `features/window-panels/WindowPanel.tsx`.\n *\n * Body identity: the body subtree renders into ONE stable detached container through a portal at a\n * fixed position in this component's tree; each presentation (windowed, maximized, minimized,\n * popped out) only decides WHERE that container is attached. So maximize, minimize, pop-out and\n * dock never remount the body — its state, refs, effects and subscriptions survive every move.\n */\n\nimport React, { useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\";\nimport { announceLayerFront, FloatingLayer, useFloatingLayerZIndex, usePortalContainer, PortalContainerProvider } from \"@ai-matrx/design-system\";\nimport { ResizablePanelGroup, ResizablePanel, ResizableHandle } from \"@ai-matrx/design-system\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { useIsMobile } from \"@ai-matrx/kit/media-query\";\nimport { createPortal } from \"react-dom\";\nimport {\n arrangeActiveWindows,\n clampWindowRect,\n overlaysRawActions,\n DEFAULT_INSTANCE_ID,\n dockWindow,\n buildDockWindowPayload,\n getOverlayMeta,\n safeViewportDims,\n selectAllWindows,\n selectOverlayData,\n selectPopoutCandidateId,\n selectPopoutMode,\n selectWindowPersistence,\n selectWindowsHidden,\n updateWindowPersistence,\n updateWindowRect,\n ackOverlayRender,\n clearOverlayRender,\n type GlobalLayoutType,\n type MobilePresentation,\n type WindowRect,\n} from \"@ai-matrx/summon\";\nimport { useOptionalOverlayInstance, useSummonDispatch, useSummonPorts, useSummonSelector, useSummonStore } from \"@ai-matrx/summon/react\";\nimport {\n AppWindowIcon as AppWindow,\n Maximize2Icon as Maximize2,\n Minimize2Icon as Minimize2,\n MinusIcon as Minus,\n PanelLeftCloseIcon as PanelLeftClose,\n PanelLeftIcon as PanelLeft,\n RectangleVerticalIcon as RectangleVertical,\n SaveIcon as Save,\n XIcon as X,\n} from \"./icons\";\nimport { LayoutIconButton } from \"./LayoutIcon\";\nimport { resolvePosition, useWindowPanel, type UseWindowPanelOptions, type ResizeEdge } from \"./useWindowPanel\";\nimport { AUTO_OPEN_NO_ROOM_EVENT, clearAutoOpened, isAutoOpened } from \"./utils/autoOpenPlacement\";\nimport { useIsClient } from \"./utils/useIsClient\";\nimport { useDebugFlag } from \"./utils/useDebugFlag\";\nimport { useOverlayLink } from \"@ai-matrx/summon/url\";\nimport { resolveWindowUrlSyncKey } from \"./utils/urlSyncIdentity\";\nimport { sanitizeWindowData } from \"./utils/sanitizeWindowData\";\nimport { useWindowConfig, WindowSelectionSurface } from \"@ai-matrx/summon/window-host\";\nimport MobileDrawerSurface from \"./mobile/MobileDrawerSurface\";\nimport MobileCardSurface from \"./mobile/MobileCardSurface\";\nimport { DebugStrip } from \"./chrome/DebugStrip\";\nimport { MobileWindowHeader } from \"./chrome/MobileHeader\";\nimport { WINDOW_CHROME_ACTIONS, WINDOW_CHROME_INTERACTIVE } from \"./chrome/chromeClasses\";\nimport { DeprecationBanner } from \"./chrome/DeprecationBanner\";\nimport { PopoutTopBar } from \"./chrome/PopoutTopBar\";\nimport { detectPopoutCapability } from \"./popout/featureDetection\";\nimport { usePopoutWindow } from \"./popout/usePopoutWindow\";\nimport { registerPopoutOpener } from \"./popout/usePopoutControl\";\nimport { PopoutPortal } from \"./popout/PopoutPortal\";\nimport { PopoutContext, usePopout, type PopoutContextValue } from \"./popout/PopoutContext\";\nimport { usePopoutWindowRef } from \"./popout/popoutWindowMap\";\nimport { setTraySnapshot, clearTraySnapshot } from \"./tray/traySnapshotMap\";\nimport { defaultTraySnapshotCapture } from \"./tray/defaultTraySnapshotCapture\";\nimport { MinimizedWindowContent } from \"./tray/MinimizedWindowContent\";\nimport { getTrayPreviewEntry, type TraySnapshotCapture } from \"@ai-matrx/summon/window-host\";\n\n/** The imperative handle of a ResizablePanel (react-resizable-panels v4), via the design-system component. */\ntype SidebarPanelHandle = NonNullable<Extract<React.ComponentProps<typeof ResizablePanel>[\"panelRef\"], { current: unknown }>[\"current\"]>;\n\n// ─── Resize handle descriptors ───────────────────────────────────────────────\n\ninterface HandleDef {\n edge: ResizeEdge;\n className: string;\n}\n\n/** How long after opening a window places itself without gliding (the entrance is 400ms). */\nconst GLIDE_SETTLE_MS = 800;\n\nconst HANDLES: HandleDef[] = [\n {\n edge: \"e\",\n className:\n \"absolute right-0 top-2 bottom-2 w-2.5 translate-x-1/2 cursor-ew-resize\",\n },\n {\n edge: \"w\",\n className:\n \"absolute left-0 top-2 bottom-2 w-2.5 -translate-x-1/2 cursor-ew-resize\",\n },\n {\n edge: \"s\",\n className:\n \"absolute bottom-0 left-2 right-2 h-2.5 translate-y-1/2 cursor-ns-resize\",\n },\n {\n // Start after the traffic-light hot zone (w-28) — top-left is close/minimize/maximize.\n edge: \"n\",\n className:\n \"absolute top-0 left-2 right-2 h-2.5 -translate-y-1/2 cursor-ns-resize\",\n },\n {\n edge: \"se\",\n className:\n \"absolute bottom-0 right-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nwse-resize\",\n },\n {\n edge: \"sw\",\n className:\n \"absolute bottom-0 left-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nesw-resize\",\n },\n {\n edge: \"ne\",\n className:\n \"absolute top-0 right-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nesw-resize\",\n },\n {\n edge: \"nw\",\n className:\n \"absolute top-0 left-0 w-2.5 h-2.5 -translate-x-1/4 -translate-y-1/4 cursor-nwse-resize\",\n },\n];\n\n/**\n * Desktop body shell — consumers style the inner slot via `bodyClassName`\n * only. The outer guard ring is structural: it keeps full-bleed children off the\n * resize-handle hit zones and uses pointer-events-none so bare edge clicks reach\n * the handle layer (z-50) even when inner content is `absolute inset-0`.\n */\nfunction WindowPanelBodyShell({\n bodyRef,\n fitContent,\n isMaximized,\n bodyClassName,\n captureDimensions,\n children,\n}: {\n bodyRef: React.RefObject<HTMLDivElement | null>;\n fitContent?: boolean | undefined;\n isMaximized?: boolean | undefined;\n bodyClassName?: string | undefined;\n captureDimensions?: { width: number; height: number } | null | undefined;\n children: React.ReactNode;\n}) {\n return (\n <div\n ref={bodyRef}\n className={cn(\n // The structural guard ring is part of the body surface, not window\n // chrome. Painting it with the canonical page background keeps the\n // 2px resize-handle gutter visually continuous with full-bleed bodies\n // such as Chat instead of exposing the card-coloured window shell.\n \"relative z-0 min-h-0 flex-1 overflow-hidden bg-background pointer-events-none\",\n !isMaximized && \"p-0.5\",\n fitContent && \"overflow-visible\",\n captureDimensions && \"matrx-window-body-offscreen\",\n )}\n data-window-panel-body-shell\n style={captureDimensions ?? undefined}\n >\n <div\n className={cn(\n \"h-full min-h-0 overflow-auto pointer-events-auto\",\n !isMaximized && \"matrx-window-body-inner\",\n bodyClassName,\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\n/**\n * Props that don't participate in the close-binding discrimination.\n * Kept as an intersection base so the discriminated union below can layer\n * the close-binding contract on top without losing intellisense on the\n * common props.\n */\nexport interface WindowPanelBaseProps extends UseWindowPanelOptions {\n children: React.ReactNode;\n title?: string | undefined;\n /** Rich title rendered in the header. Falls back to `title` (string) when omitted. */\n titleNode?: React.ReactNode | undefined;\n /** @deprecated Use `actionsLeft` and `actionsRight` instead */\n actions?: React.ReactNode | undefined;\n actionsLeft?: React.ReactNode | undefined;\n actionsRight?: React.ReactNode | undefined;\n bodyClassName?: string | undefined;\n className?: string | undefined;\n /**\n * Rare escape hatch for page-local windows that have no overlay definition\n * but still need an explicit mobile surface. Registered overlays keep their\n * presentation in their definition (`window.mobile`).\n */\n mobilePresentationOverride?: MobilePresentation | undefined;\n /**\n * The surface this window REGISTERS (its own `SurfaceRuntimeProvider`).\n * Marks every root with `data-surface-layer`, so the unregistered-window\n * reader (`features/surfaces/runtime/window-forms.ts`) leaves it alone —\n * one way for an agent to write a field, never two.\n */\n surfaceLayer?: string | undefined;\n /** Phone drawer presentation: size the sheet to the content (max 85dvh). */\n mobileSizeToContent?: boolean | undefined;\n /**\n * Escape closes this window when it is the TOPMOST window and nothing above\n * it (a menu, popover, dialog, the workspace picker) is open to take the\n * key. Opt in for windows whose close is safe (their draft is kept, or\n * there is nothing to lose). Desktop only — a phone sheet has its own.\n */\n closeOnEscape?: boolean | undefined;\n /** Phone drawer presentation: no title-row ✕ (the handle and the window's own Cancel dismiss it). */\n mobileHideClose?: boolean | undefined;\n minWidth?: number | undefined;\n minHeight?: number | undefined;\n urlSyncKey?: string | undefined;\n urlSyncId?: string | undefined;\n urlSyncArgs?: Record<string, string> | undefined;\n /** Content to render in a collapsible left sidebar panel */\n sidebar?: React.ReactNode | undefined;\n /** Default width for the sidebar in pixels (default: 200) */\n sidebarDefaultSize?: number | undefined;\n /** Minimum width in pixels before the sidebar collapses (default: 150) */\n sidebarMinSize?: number | undefined;\n /** Whether the sidebar starts open (default: true) */\n defaultSidebarOpen?: boolean | undefined;\n /** Class name applied to the sidebar panel content wrapper */\n sidebarClassName?: string | undefined;\n /**\n * When true, opening the sidebar grows the window width by sidebarDefaultSize\n * and closing it shrinks it back, keeping the body content width constant.\n */\n sidebarExpandsWindow?: boolean | undefined;\n /**\n * Content for a collapsible RIGHT secondary panel — the canonical home for a\n * history / inspector / details pane that belongs to the window, not the body.\n * Resizable, mirrors the left `sidebar`. Desktop only; handle mobile in the\n * consumer (e.g. a Drawer) — see `features/notes` for the reference pattern.\n */\n secondaryPanel?: React.ReactNode | undefined;\n /** Whether the secondary panel is open (default: true when `secondaryPanel` is provided). */\n secondaryPanelOpen?: boolean | undefined;\n /** Default width for the secondary panel in pixels (default: 360) */\n secondaryPanelDefaultSize?: number | undefined;\n /** Minimum width in pixels for the secondary panel (default: 240) */\n secondaryPanelMinSize?: number | undefined;\n /** Class name applied to the secondary panel content wrapper */\n secondaryPanelClassName?: string | undefined;\n /**\n * When true, hides the header pop-out affordance (icon + green-dropdown entry).\n * Pop-out is shown by default on desktop when the browser supports it.\n */\n hidePopOutButton?: boolean | undefined;\n /** Content rendered in a full-width footer bar below the body. Renders as a single flex row. For zoned layout, use footerLeft/footerCenter/footerRight instead. */\n footer?: React.ReactNode | undefined;\n /** Left-aligned footer content (use instead of `footer` for zoned layout) */\n footerLeft?: React.ReactNode | undefined;\n /** Center-aligned footer content */\n footerCenter?: React.ReactNode | undefined;\n /** Right-aligned footer content */\n footerRight?: React.ReactNode | undefined;\n /**\n * Styling posture for the footer wrapper. Default `\"bar\"` applies the compact\n * metadata-bar chrome (thin chips, `text-xs`, tiny buttons/icons via descendant\n * selectors) tuned for status rows like `NoteMetadataBar`. That chrome CRUSHES\n * rich content — use `\"rich\"` when the footer hosts a composer / input bar /\n * anything with full-size buttons or a multi-row textarea (e.g. `SmartAgentInput`).\n * `\"rich\"` drops the compact descendant selectors and the `bg-muted/40` chrome,\n * leaving just `shrink-0 border-t` so the slot's own content owns its layout.\n */\n footerVariant?: \"bar\" | \"rich\" | undefined;\n /**\n * When true, the windowed panel sizes itself to fit its content rather than\n * using the explicit width/height from Redux. A ResizeObserver syncs the\n * measured dimensions back into Redux so drag/snap operations still work.\n * The panel will still respect minWidth/minHeight constraints.\n */\n fitContent?: boolean | undefined;\n\n /**\n * Called by WindowPanel before a save so the child component can return\n * its current content state for the local refresh-preservation cache.\n * Return value must be a plain object (JSON-serializable).\n */\n onCollectData?: (() => Record<string, unknown>) | undefined;\n /**\n * Optional snapshot capture function for the minimized tray chip.\n * WindowPanel invokes it after minimizing against a briefly retained,\n * offscreen body and stores the resulting Blob in a bounded local cache.\n * Pass this from the window component if it implements custom capture logic.\n */\n captureTraySnapshot?: TraySnapshotCapture | undefined;\n /** Overlay instance used by semantic minimized previews. Defaults to `default`. */\n overlayInstanceId?: string | undefined;\n}\n\n/**\n * The close-binding contract — enforced by the type system.\n *\n * Every WindowPanel declares HOW it closes. Exactly three shapes are valid:\n *\n * 1. Overlay-managed: `overlayId`. Close dispatches `closeOverlay` for that overlay (and the\n * instance this window renders, when it renders inside an SummonHost instance or passes\n * `overlayInstanceId`). The close-lifecycle middleware tombstones preservation, disposes the\n * instance's handles and runs persistence flushers; the host then unmounts the body. `onClose`\n * is an OPTIONAL hook for extra work.\n * 2. Instance-bound: `boundToOverlay` — the window renders inside an SummonHost-rendered overlay\n * and closes through that instance (`useOptionalOverlayInstance().close`). Rendering it outside\n * an overlay reports an error through the error port and the close button closes nothing.\n * 3. Page-local: `onClose`, REQUIRED, because nothing else will close the window.\n *\n * Passing none of them is a compile error: the silent-failure mode where the X rendered as a dead\n * button (matrx-frontend, Notes incident 2026-05-26). Do NOT make these all optional.\n */\nexport type WindowPanelCloseBinding =\n | {\n overlayId: string;\n boundToOverlay?: never | undefined;\n /** Optional extra cleanup hook (cancel uploads, save drafts, etc.). */\n onClose?: (() => void) | undefined;\n }\n | {\n overlayId?: never | undefined;\n /** Close through the enclosing SummonHost instance. */\n boundToOverlay: true;\n onClose?: (() => void) | undefined;\n }\n | {\n overlayId?: never | undefined;\n boundToOverlay?: never | undefined;\n /** Required when the panel is rendered page-locally (no overlay). */\n onClose: () => void;\n };\n\n/** Minimized tiles paint above any open window (managerZIndex counts up from 1000). */\nconst MINIMIZED_TILE_Z_FLOOR = 5000;\n\nexport type WindowPanelProps = WindowPanelBaseProps & WindowPanelCloseBinding;\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\nexport function WindowPanel({\n children,\n title,\n titleNode,\n actions,\n actionsLeft,\n actionsRight,\n onClose,\n bodyClassName,\n className,\n mobilePresentationOverride,\n surfaceLayer,\n mobileSizeToContent,\n closeOnEscape = false,\n mobileHideClose = false,\n minWidth,\n minHeight,\n urlSyncKey,\n urlSyncId,\n urlSyncArgs,\n sidebar,\n sidebarDefaultSize = 200,\n sidebarMinSize = 100,\n defaultSidebarOpen = true,\n sidebarClassName,\n sidebarExpandsWindow = false,\n secondaryPanel,\n secondaryPanelOpen,\n secondaryPanelDefaultSize = 360,\n secondaryPanelMinSize = 240,\n secondaryPanelClassName,\n footer,\n footerLeft,\n footerCenter,\n footerRight,\n footerVariant = \"bar\",\n fitContent = false,\n overlayId: overlayIdProp,\n boundToOverlay,\n onCollectData,\n captureTraySnapshot,\n overlayInstanceId: overlayInstanceIdProp,\n hidePopOutButton = false,\n ...hookOpts\n}: WindowPanelProps) {\n // Inside an SummonHost-rendered overlay the instance supplies identity and close; explicit\n // props win. A page-local window has no instance and closes through `onClose`.\n const instance = useOptionalOverlayInstance();\n const instanceMatches = instance !== null && (boundToOverlay === true || instance.overlayId === overlayIdProp);\n const overlayId: string | undefined = overlayIdProp ?? (boundToOverlay && instance ? instance.overlayId : undefined);\n const overlayInstanceId = overlayInstanceIdProp ?? (instanceMatches ? instance.instanceId : undefined);\n const ports = useSummonPorts();\n const windowConfig = useWindowConfig();\n // ── Pre-compute id and popout capabilities BEFORE useWindowPanel so we\n // can pass `onTriggerPopout` to the drag-detection logic. The id is\n // derived the same way useWindowPanel does internally (`opts.id ?? useId()`).\n const reactId = useId();\n const id = hookOpts.id ?? reactId;\n const trayRegistryKey = overlayId ?? id;\n const isMobile = useIsMobile();\n // `data-surface-layer` (literal: importing window-forms would pull the\n // surface writeback into every window's chunk).\n const surfaceLayerAttrs = surfaceLayer\n ? { \"data-surface-layer\": surfaceLayer }\n : undefined;\n const isMounted = useIsClient();\n const registryMeta = overlayId ? getOverlayMeta(overlayId) : undefined;\n const registryEntry = registryMeta?.window;\n const effectiveInstanceId = overlayInstanceId ?? DEFAULT_INSTANCE_ID;\n // MKT-104: a window the system opened (debug auto-open) docks beside the page, never over it.\n const [autoOpened] = useState(\n () => Boolean(overlayId) && isAutoOpened(overlayId as string, effectiveInstanceId),\n );\n useEffect(() => {\n if (!overlayId) return undefined;\n let timer: number | undefined;\n return () => {\n timer = window.setTimeout(\n () => clearAutoOpened(overlayId, effectiveInstanceId),\n 100,\n );\n void timer;\n };\n }, [overlayId, effectiveInstanceId]);\n const preservationEnabled = Boolean(\n overlayId &&\n registryEntry?.preservation &&\n !registryEntry.ephemeral &&\n (registryMeta?.instance !== \"multi\" || overlayInstanceId),\n );\n const overlayLaunchData = useSummonSelector((state) =>\n overlayId ? selectOverlayData(state, overlayId, effectiveInstanceId) : null,\n );\n const initialPreservationData = registryEntry?.preservation\n ? sanitizeWindowData(overlayLaunchData, registryEntry.preservation.dataKeys)\n : {};\n\n const popoutCapability = isMounted ? detectPopoutCapability() : null;\n\n // popout lifecycle hook — owns the actual browser popout window and its\n // open/close lifecycle. Always called (id is stable) but its `openPopout`\n // is only invoked when the user actually triggers a popout.\n const popout = usePopoutWindow(id);\n\n // Register the live openPopout in the module-level opener map so external\n // callers (`usePopoutControl`) can trigger popout for this window. Cleanup\n // on unmount is handled by the returned unregister function.\n useEffect(() => {\n return registerPopoutOpener(id, popout.openPopout);\n }, [id, popout.openPopout]);\n\n // Drag-out callback fired by useWindowPanel when the user drags this\n // window outside the viewport beyond the dwell threshold. Receives the\n // dragged rect at release time so popout sizing matches user intent.\n // The popout opener internally enforces single-PiP slot and surfaces\n // toasts on failure, so we don't double-check here.\n const handleDragOutPopout = useCallback(\n (draggedRect: WindowRect) => {\n void popout.openPopout({\n width: draggedRect.width,\n height: draggedRect.height,\n title: typeof title === \"string\" ? title : \"Window\",\n });\n },\n [popout, title],\n );\n\n // Hand drag-out detection a callback ONLY when popout is meaningful here:\n // - desktop only (mobile path is fully separate)\n // - browser must support some form of popout\n const onTriggerPopout =\n !isMobile && popoutCapability !== \"none\" ? handleDragOutPopout : undefined;\n\n const autoDispatch = useSummonDispatch();\n // Pass title and our pre-computed id+trigger into the hook\n const {\n windowState,\n rect,\n zIndex: managerZIndex,\n onDragStart,\n onResizeStart,\n onFocus,\n onRestore,\n onMinimize,\n onToggleMaximize,\n isInteracting,\n } = useWindowPanel({\n ...hookOpts,\n id,\n title,\n autoOpened,\n onAutoNoRoom: autoOpened\n ? () => {\n window.dispatchEvent(\n new CustomEvent(AUTO_OPEN_NO_ROOM_EVENT, { detail: { overlayId, instanceId: effectiveInstanceId } }),\n );\n if (overlayId) autoDispatch(overlaysRawActions.closeOverlay({ overlayId, instanceId: effectiveInstanceId }));\n }\n : undefined,\n minWidth,\n minHeight,\n onTriggerPopout,\n ...(preservationEnabled && overlayId\n ? {\n persistence: {\n overlayId,\n instanceId: effectiveInstanceId,\n data: initialPreservationData,\n sidebarOpen: defaultSidebarOpen,\n sidebarSize: sidebarDefaultSize,\n },\n }\n : {}),\n });\n\n // A window opened from inside a blocking Dialog/Sheet/Drawer is lifted to\n // the modal tier so it paints above that surface's scrim — otherwise the\n // click that picks an option lands on the scrim and closes the modal\n // (design-system floating-layer; the Source screen's association picker).\n const liftedZIndex = useFloatingLayerZIndex(managerZIndex);\n // A minimized tile is dock chrome: it rides above every open window, so a focused window can\n // never bury it (MKT-077 — the tile sat 2 below the front window and only a strip showed).\n // Stays below the tray (9999) and the modal tier.\n const zIndex = windowState === \"minimized\" ? Math.max(liftedZIndex, MINIMIZED_TILE_Z_FLOOR + managerZIndex) : liftedZIndex;\n\n const dispatch = useSummonDispatch();\n const windowsHidden = useSummonSelector(selectWindowsHidden);\n const isDebugMode = useDebugFlag(ports.debug);\n\n // THE FRONT-MOST LAYER (design-system `announceLayerFront`): a window that\n // opens or comes to the front tells every windowed Dialog, which steps\n // behind it — so an agent window opened from the Agents menu over Table\n // settings is usable (register ai-reachable-everywhere, ARE-010). The\n // manager raises `zIndex` exactly when this window becomes the top one.\n // Keyed on the MANAGER's z, never the lifted one: a modal opening or\n // closing lifts every window, and must not make each of them announce\n // itself front-most (which would bury every windowed Dialog behind them).\n useEffect(() => {\n announceLayerFront(\n document.querySelector(`[data-window-id=\"${CSS.escape(id)}\"]`),\n );\n }, [id, managerZIndex]);\n\n // A PRESS OR FOCUS IN THIS WINDOW CLAIMS THE FRONT AGAIN. The mount-time\n // announce above is not enough when the window is RENDERED from inside a\n // windowed Dialog's React tree (the reference picker's \"Browse files\" opens\n // the file picker window that way): React bubbles a portaled child's\n // synthetic focus / pointer events to its React ancestors, so the window's\n // own autofocus reached the Dialog's `onFocusCapture`, which brought the\n // Dialog back to z 10000 OVER the window it had just stepped behind (live\n // 2026-10-02: window 1000, Dialog 10000 — \"nothing happens\"). Capture\n // handlers run ancestors first, so this one fires AFTER the Dialog's and has\n // the last word. Guard: __tests__/aWindowOpenedFromADialogStaysInFront.test.tsx\n // The body renders through its own portal (stable identity across pop-out), so its wrapper\n // claims too; it announces the window shell it is attached to.\n const claimFront = (event: React.SyntheticEvent<HTMLElement>) => {\n announceLayerFront(event.currentTarget.closest(\"[data-window-id]\") ?? event.currentTarget);\n };\n\n // On mobile, only the topmost non-minimized window is rendered visible.\n const allWindows = useSummonSelector(selectAllWindows);\n const isTopWindow = !isMobile\n ? true\n : allWindows.find((w) => w.state !== \"minimized\")?.id === id;\n\n // Mobile sidebar/content toggle (not stored in Redux — purely a view concern)\n const [activePaneMobile, setActivePaneMobile] = useState<\"main\" | \"sidebar\">(\n \"main\",\n );\n\n // Address-bar link: the definition's `link.key` is canonical for overlay-managed windows;\n // page-local windows without a definition may pass explicit props. This keeps a stale caller\n // prop from publishing a token the link hydrator cannot reopen.\n const effectiveUrlSyncKey = resolveWindowUrlSyncKey(registryMeta?.link?.key, urlSyncKey);\n const effectiveUrlSyncId = urlSyncId ?? (effectiveUrlSyncKey ? overlayId : undefined);\n useOverlayLink(effectiveUrlSyncKey, effectiveUrlSyncId, urlSyncArgs);\n\n // Deprecation marker — when set on the registry entry, the shell renders a\n // red ring + dismissible banner so users can see at a glance that this\n // window is on its way out. Used during consolidation while the old window\n // is kept around for side-by-side parity verification with its replacement.\n const deprecation = registryEntry?.deprecated;\n const isDeprecated = !!deprecation;\n const deprecatedRingClass = isDeprecated\n ? \"ring-2 ring-destructive ring-offset-2 ring-offset-background\"\n : \"\";\n\n // ── Sidebar state ─────────────────────────────────────────────────────────\n const hasSidebar = !!sidebar;\n const [sidebarOpen, setSidebarOpen] = useState(defaultSidebarOpen);\n const [sidebarSize, setSidebarSize] = useState<number | null>(\n sidebarDefaultSize,\n );\n const restoredPersistence = useSummonSelector(selectWindowPersistence(id));\n const sidebarPanelRef = useRef<SidebarPanelHandle>(null);\n const restoredChromeAppliedRef = useRef(false);\n\n // ── Persistence ───────────────────────────────────────────────────────────\n /**\n * Stage the window's chrome + allowlisted semantic data (open data merged with what\n * `onCollectData()` returns) in its window-manager entry. The persistence section (when on)\n * writes the workspace from the store; this never touches storage itself.\n */\n const handleSaveWindowState = useCallback(() => {\n if (!overlayId || !preservationEnabled || !registryEntry?.preservation) {\n return;\n }\n let collected: Record<string, unknown> = {};\n try {\n collected = onCollectData?.() ?? {};\n } catch (error) {\n ports.errors.capture(error, { where: \"window-preservation collector\", overlayId, instanceId: effectiveInstanceId });\n }\n const base = sanitizeWindowData({ ...initialPreservationData, ...collected }, registryEntry.preservation.dataKeys);\n dispatch(\n updateWindowPersistence({\n id,\n data: base,\n sidebarOpen,\n ...(sidebarSize === null ? {} : { sidebarSize }),\n }),\n );\n }, [\n overlayId,\n preservationEnabled,\n registryEntry,\n effectiveInstanceId,\n initialPreservationData,\n id,\n sidebarOpen,\n sidebarSize,\n onCollectData,\n ports,\n dispatch,\n ]);\n\n /**\n * Keep semantic data current while the child changes. This never writes to\n * storage directly and deliberately has no unmount flush; explicit close\n * tombstones must always win over late cleanup.\n */\n const saveRef = useRef(handleSaveWindowState);\n useEffect(() => {\n saveRef.current = handleSaveWindowState;\n }, [handleSaveWindowState]);\n\n useEffect(() => {\n if (!preservationEnabled) return;\n saveRef.current();\n }, [preservationEnabled, overlayLaunchData, onCollectData]);\n\n /**\n * Route every close through the overlay slice: the close-lifecycle middleware tombstones the\n * window's preservation identity before the host unmounts it. Inside an SummonHost instance of\n * this overlay, close goes through the instance (exact instance id).\n */\n const handleClose = useCallback(() => {\n if (instanceMatches && instance && instance.overlayId === overlayId) {\n instance.close();\n } else if (boundToOverlay) {\n ports.errors.capture(new Error(\"[summon] WindowPanel boundToOverlay rendered outside an overlay instance\"), { windowId: id });\n } else if (overlayId) {\n const hasExactOverlayIdentity = registryMeta?.instance !== \"multi\" || Boolean(overlayInstanceId);\n if (hasExactOverlayIdentity) {\n // Erased-id action: a package-internal id is a plain string (the host owns OverlayId).\n dispatch(overlaysRawActions.closeOverlay({ overlayId, instanceId: effectiveInstanceId }));\n } else if (!onClose) {\n ports.errors.capture(new Error(`[summon] Cannot close multi-instance ${overlayId} without overlayInstanceId or onClose.`), { overlayId });\n }\n }\n onClose?.();\n }, [boundToOverlay, dispatch, effectiveInstanceId, id, instance, instanceMatches, onClose, overlayId, overlayInstanceId, ports, registryMeta?.instance]);\n\n // Escape → close, only for the topmost window with nothing layered above.\n useEffect(() => {\n if (!closeOnEscape || isMobile) return undefined;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented) return;\n // A menu, popover, select, dialog or the workspace picker owns Escape.\n // Only a VISIBLE one: the header keeps a hidden \"Organizations\" listbox\n // mounted, which swallowed every Escape (found live, 2026-09-27).\n const layered = Array.from(\n document.querySelectorAll<HTMLElement>(\n `[data-radix-popper-content-wrapper], [role=\"menu\"], [role=\"listbox\"], [role=\"dialog\"][data-state=\"open\"], [role=\"alertdialog\"], ${windowConfig.escapeYieldSelector}`,\n ),\n ).some(\n (el) =>\n el.getClientRects().length > 0 &&\n getComputedStyle(el).visibility !== \"hidden\" &&\n !el.closest(`[data-window-id=\"${CSS.escape(id)}\"]`),\n );\n if (layered) return;\n const mine = document.querySelector<HTMLElement>(\n `[data-window-panel][data-window-id=\"${CSS.escape(id)}\"]`,\n );\n if (!mine) return;\n const z = (el: Element) => Number(getComputedStyle(el).zIndex) || 0;\n const top = Array.from(\n document.querySelectorAll(\"[data-window-panel][data-window-id]\"),\n ).reduce<Element | null>((best, el) => (!best || z(el) > z(best) ? el : best), null);\n if (top !== mine) return;\n e.preventDefault();\n handleClose();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [closeOnEscape, isMobile, id, handleClose, windowConfig.escapeYieldSelector]);\n\n useEffect(() => {\n if (!restoredPersistence || restoredChromeAppliedRef.current) return;\n restoredChromeAppliedRef.current = true;\n setSidebarOpen(restoredPersistence.sidebarOpen);\n setSidebarSize(restoredPersistence.sidebarSize);\n if (!restoredPersistence.sidebarOpen) {\n sidebarPanelRef.current?.collapse();\n } else if (restoredPersistence.sidebarSize) {\n sidebarPanelRef.current?.resize(restoredPersistence.sidebarSize);\n }\n }, [restoredPersistence]);\n\n // ── fitContent: sync measured shell size back into Redux ─────────────────\n // A STATE-backed ref, not useRef: the shell renders through a portal that\n // exists only after mount, so on the first effect a plain ref was still null\n // and the measurer never attached — no fitContent window ever synced its\n // measured size (or its preset position). The effect re-runs when the\n // element actually appears.\n const [fitContentEl, fitContentRef] = useState<HTMLDivElement | null>(null);\n const fitContentStore = useSummonStore();\n // A preset position (\"center\", a corner) was resolved from the DEFAULT size\n // before anything was measured, so a window that fits its content grew away\n // from where it was placed — a centered 694px picker opened with its left\n // edge at the viewport's middle and its right side off-screen. So the preset\n // FOLLOWS the measured size — a lazy body measures small first, then its\n // real size — until the person first drags or resizes the window; from then\n // on it stays where they put it. Same choice `useWindowPanel` made at\n // registration: only when the window was NOT opened at a saved\n // `initialRect` place, and only for an explicit preset (the cascade default\n // is never re-run; it advances a shared counter).\n const fitPlacedRef = useRef(false);\n // NO GLIDE WHILE THE WINDOW IS STILL BEING PLACED (2026-10-08, owner: windows \"appear, then\n // slide into place\"). Opening a window measures its content and re-places it in the frames\n // after the first paint; with `glide` on, each correction animated across the screen. Glide\n // only programmatic moves made after the opening settles (snap, arrange, tray, restore).\n const [glideReady, setGlideReady] = useState(false);\n useEffect(() => {\n const timer = window.setTimeout(() => setGlideReady(true), GLIDE_SETTLE_MS);\n return () => window.clearTimeout(timer);\n }, []);\n useEffect(() => {\n if (isInteracting) fitPlacedRef.current = true;\n }, [isInteracting]);\n const fitPresetPosition = hookOpts.position;\n const fitMayReplace =\n hookOpts.initialRect?.x === undefined &&\n hookOpts.initialRect?.y === undefined;\n\n useEffect(() => {\n if (!fitContent || isMobile || windowState !== \"windowed\") return undefined;\n const el = fitContentEl;\n if (!el) return undefined;\n let active = true;\n const ro = new ResizeObserver((entries) => {\n // Disconnect does not cancel a callback already queued by the browser.\n // Read the current store state as well as the effect lifetime so a\n // maximize dispatched before React cleans up cannot save fullscreen size.\n if (!active || fitContentStore.getState().windowManager.windows[id]?.state !== \"windowed\") return;\n const entry = entries[0];\n if (!entry) return;\n const { width, height } = entry.contentRect;\n // Include border (2px each side) to match the element's full box size\n const borderH = el.offsetHeight - el.clientHeight;\n const borderW = el.offsetWidth - el.clientWidth;\n const fitWidth = Math.ceil(width + borderW);\n const fitHeight = Math.ceil(height + borderH);\n const placeNow =\n !fitPlacedRef.current &&\n fitMayReplace &&\n fitPresetPosition !== undefined;\n dispatch(\n updateWindowRect({\n id,\n rect: {\n width: fitWidth,\n height: fitHeight,\n ...(placeNow\n ? resolvePosition(fitPresetPosition, fitWidth, fitHeight)\n : {}),\n },\n }),\n );\n });\n ro.observe(el);\n return () => {\n active = false;\n ro.disconnect();\n };\n }, [fitContent, fitContentEl, isMobile, windowState, id, dispatch, fitContentStore, fitPresetPosition, fitMayReplace]);\n\n const toggleSidebar = useCallback(() => {\n const panel = sidebarPanelRef.current;\n if (!panel) return;\n if (sidebarOpen) {\n if (sidebarExpandsWindow) {\n dispatch(\n updateWindowRect({\n id,\n rect: { width: rect.width - sidebarDefaultSize },\n }),\n );\n requestAnimationFrame(() => panel.collapse());\n } else {\n panel.collapse();\n }\n } else {\n if (sidebarExpandsWindow) {\n dispatch(\n updateWindowRect({\n id,\n rect: { width: rect.width + sidebarDefaultSize },\n }),\n );\n requestAnimationFrame(() => panel.resize(sidebarDefaultSize));\n } else {\n panel.resize(sidebarDefaultSize);\n }\n }\n }, [\n sidebarOpen,\n sidebarDefaultSize,\n sidebarExpandsWindow,\n dispatch,\n id,\n rect.width,\n ]);\n\n const handleSidebarResize = useCallback(\n (panelSize: { asPercentage: number; inPixels: number }) => {\n setSidebarOpen(panelSize.asPercentage > 0);\n if (panelSize.inPixels > 0) setSidebarSize(panelSize.inPixels);\n if (preservationEnabled) {\n dispatch(\n updateWindowPersistence({\n id,\n sidebarOpen: panelSize.asPercentage > 0,\n sidebarSize:\n panelSize.inPixels > 0 ? panelSize.inPixels : sidebarSize,\n }),\n );\n }\n },\n [dispatch, id, preservationEnabled, sidebarSize],\n );\n\n // ── Portal target (client-only) ──────────────────────────────────────────\n const portalTarget = isMounted ? document.body : null;\n // The one container the body always renders into (see \"Body identity\" below).\n const [bodyHost] = useState<HTMLDivElement | null>(() => {\n if (typeof document === \"undefined\") return null;\n const host = document.createElement(\"div\");\n host.className = \"matrx-window-body-host\";\n host.setAttribute(\"data-window-body-host\", \"\");\n return host;\n });\n\n // ── Render acknowledgement ────────────────────────────────────────────────\n // Tell the render watchdog which window-manager id actually rendered this\n // overlay, so it can verify the panel became visible (and never false-flag a\n // window whose `id` differs from its registry slug). See overlayRenderWatchdog.\n useEffect(() => {\n if (!overlayId) return undefined;\n ackOverlayRender(overlayId, id);\n return () => clearOverlayRender(overlayId, id);\n }, [overlayId, id]);\n\n // Backward compat: legacy `actions` maps to actionsRight\n const resolvedActionsRight = actionsRight ?? actions ?? null;\n\n // ── Snap helpers (Move & Resize menu) ───────────────────────────────────\n const snapLeft = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n updateWindowRect({\n id,\n rect: { x: 0, y: 0, width: Math.round(vw / 2), height: vh },\n }),\n );\n }, [dispatch, id]);\n\n const snapRight = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n const half = Math.round(vw / 2);\n dispatch(\n updateWindowRect({\n id,\n rect: { x: half, y: 0, width: vw - half, height: vh },\n }),\n );\n }, [dispatch, id]);\n\n const snapTop = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n updateWindowRect({\n id,\n rect: { x: 0, y: 0, width: vw, height: Math.round(vh / 2) },\n }),\n );\n }, [dispatch, id]);\n\n const snapBottom = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n const half = Math.round(vh / 2);\n dispatch(\n updateWindowRect({\n id,\n rect: { x: 0, y: half, width: vw, height: vh - half },\n }),\n );\n }, [dispatch, id]);\n\n const snapCentre = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n const w = Math.min(rect.width, vw);\n const h = Math.min(rect.height, vh);\n dispatch(\n updateWindowRect({\n id,\n rect: {\n x: Math.round((vw - w) / 2),\n y: Math.round((vh - h) / 2),\n width: w,\n height: h,\n },\n }),\n );\n }, [dispatch, id, rect.width, rect.height]);\n\n const arrangeAll = useCallback(\n (layout: GlobalLayoutType) => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n arrangeActiveWindows({\n layout,\n viewportWidth: vw,\n viewportHeight: vh,\n }),\n );\n },\n [dispatch],\n );\n\n // ── Pop-out menu-click wiring ─────────────────────────────────────────────\n // (popout, popoutCapability, isMobile already set up at top of component)\n const popoutMode = useSummonSelector(selectPopoutMode(id));\n // The body's popout context: this window's own popped-out document when it is out, else\n // whatever surrounds the window (a window rendered inside another popout keeps that one).\n const outerPopout = usePopout();\n const outerPortalContainer = usePortalContainer();\n const popoutWin = usePopoutWindowRef(id);\n const ownPopout = popoutMode !== null && popoutWin !== null;\n const bodyPopoutValue = React.useMemo<PopoutContextValue>(\n () =>\n ownPopout && popoutWin\n ? { popoutDocument: popoutWin.document, popoutWindow: popoutWin, popoutContainer: popoutWin.document.body, mode: popoutMode }\n : outerPopout,\n [ownPopout, popoutWin, popoutMode, outerPopout],\n );\n const bodyPortalContainer = ownPopout && popoutWin ? popoutWin.document.body : outerPortalContainer;\n const popoutCandidateId = useSummonSelector(selectPopoutCandidateId);\n\n // Menu affordance is shown only when:\n // - desktop (mobile path is fully separate)\n // - browser supports popout (DPiP or window.open)\n // - the window isn't minimized (popout from the tray is awkward UX)\n // - the window isn't already popped out\n //\n // The menu is NEVER disabled on PiP-slot-taken grounds: the popout hook\n // transparently falls back to `window.open()` for second+ popouts so the\n // user gets a working window without us blocking the action.\n const canShowPopOut =\n !hidePopOutButton &&\n !isMobile &&\n popoutCapability !== \"none\" &&\n windowState !== \"minimized\" &&\n popoutMode === null;\n\n // Menu-click handler — uses the live windowed rect (different from the\n // drag-out path which gets the rect from the gesture).\n const handlePopOut = useCallback(() => {\n void popout.openPopout({\n width: rect.width,\n height: rect.height,\n title: typeof title === \"string\" ? title : \"Window\",\n });\n }, [popout, rect.width, rect.height, title]);\n\n const handleDockBack = useCallback(() => {\n dispatch(dockWindow(buildDockWindowPayload(id)));\n }, [dispatch, id]);\n\n // ── Minimized thumbnail lifecycle ───────────────────────────────────────\n // Minimize dispatches immediately. The body ALWAYS stays mounted, offscreen, while minimized\n // (C38 R3: minimize keeps the component alive); one low-resolution local capture is taken for\n // the tile. No network, persistent storage, polling, or full-size image is involved.\n const bodyRef = useRef<HTMLDivElement | null>(null);\n const retainedBodyDimensionsRef = useRef<{\n width: number;\n height: number;\n } | null>(null);\n const captureGenerationRef = useRef(0);\n // Capture precedence: explicit prop → registered capture → the default capture for any window\n // WITHOUT a registered preview component. A window with a preview component skips capture\n // entirely — its preview is cheaper and higher-fidelity than a screenshot.\n const trayPreviewEntry = getTrayPreviewEntry(trayRegistryKey);\n const effectiveTrayCapture =\n captureTraySnapshot ??\n trayPreviewEntry.captureTraySnapshot ??\n (trayPreviewEntry.Preview ? undefined : defaultTraySnapshotCapture);\n const [pendingTrayCapture, setPendingTrayCapture] = useState<{\n capture: TraySnapshotCapture;\n width: number;\n height: number;\n generation: number;\n } | null>(null);\n const [trayPreviewData, setTrayPreviewData] = useState<\n Record<string, unknown> | undefined\n >(undefined);\n\n const handleMinimize = useCallback(() => {\n let collected: Record<string, unknown> | undefined;\n try {\n collected = onCollectData?.();\n } catch (error) {\n ports.errors.capture(error, { where: \"window preview collector\", windowId: trayRegistryKey });\n }\n if (collected && typeof collected === \"object\") {\n setTrayPreviewData(collected);\n }\n if (preservationEnabled) saveRef.current();\n const bodyEl = bodyRef.current;\n const generation = ++captureGenerationRef.current;\n if (bodyEl) {\n const bounds = bodyEl.getBoundingClientRect();\n retainedBodyDimensionsRef.current = {\n width: Math.max(1, Math.round(bounds.width)),\n height: Math.max(1, Math.round(bounds.height)),\n };\n }\n if (effectiveTrayCapture && bodyEl) {\n const bounds = bodyEl.getBoundingClientRect();\n setPendingTrayCapture({\n capture: effectiveTrayCapture,\n width: Math.max(1, Math.round(bounds.width)),\n height: Math.max(1, Math.round(bounds.height)),\n generation,\n });\n } else {\n setPendingTrayCapture(null);\n }\n onMinimize();\n }, [\n effectiveTrayCapture,\n onCollectData,\n onMinimize,\n ports,\n preservationEnabled,\n trayRegistryKey,\n ]);\n\n useEffect(() => {\n if (windowState !== \"minimized\" || !pendingTrayCapture) return undefined;\n const bodyEl = bodyRef.current;\n if (!bodyEl) {\n setPendingTrayCapture(null);\n return undefined;\n }\n\n let cancelled = false;\n const { capture, generation } = pendingTrayCapture;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<null>((resolve) => {\n timeoutId = setTimeout(() => resolve(null), 800);\n });\n void Promise.race([capture(bodyEl), timeout])\n .then((blob) => {\n if (blob && !cancelled && captureGenerationRef.current === generation) {\n setTraySnapshot(id, blob);\n }\n })\n .catch((err: unknown) => {\n if (!cancelled) ports.errors.capture(err, { where: \"captureTraySnapshot\", windowId: id });\n })\n .finally(() => {\n if (timeoutId) clearTimeout(timeoutId);\n if (!cancelled && captureGenerationRef.current === generation) {\n setPendingTrayCapture((current) =>\n current?.generation === generation ? null : current,\n );\n }\n });\n\n return () => {\n cancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n };\n }, [id, pendingTrayCapture, ports, windowState]);\n\n const handleRestoreClearingSnapshot = useCallback(() => {\n captureGenerationRef.current += 1;\n setPendingTrayCapture(null);\n clearTraySnapshot(id);\n onRestore();\n }, [id, onRestore]);\n\n // Clear any lingering snapshot on unmount.\n useEffect(() => {\n return () => {\n captureGenerationRef.current += 1;\n clearTraySnapshot(id);\n };\n }, [id]);\n\n // External exits (reveal, maximize, pop-out) do not pass through the\n // click-to-restore handler. Invalidate their pending capture and local image\n // too, so every way out of minimized state has the same cleanup contract.\n const previousTrayStateRef = useRef(windowState);\n useEffect(() => {\n const wasMinimized = previousTrayStateRef.current === \"minimized\";\n previousTrayStateRef.current = windowState;\n if (!wasMinimized || windowState === \"minimized\") return;\n\n const invalidGeneration = ++captureGenerationRef.current;\n clearTraySnapshot(id);\n queueMicrotask(() => {\n setPendingTrayCapture((current) =>\n current && current.generation < invalidGeneration ? null : current,\n );\n });\n }, [id, windowState]);\n\n // ── Off-screen rescue ────────────────────────────────────────────────────\n // If the windowed rect is fully out of reach (drag-released outside the\n // viewport without popout firing, restored from a stale preMinimizedRect,\n // or docked back from a popped-out state where the docked rect was\n // off-screen), nudge it back into a position where the user can grab it.\n // Runs whenever the window transitions INTO `windowed` from min/max/popout.\n const prevStateRef = useRef<typeof windowState>(windowState);\n const prevPopoutModeRef = useRef<typeof popoutMode>(popoutMode);\n useEffect(() => {\n const wasNonWindowed =\n prevStateRef.current !== \"windowed\" || prevPopoutModeRef.current !== null;\n const isNowWindowed = windowState === \"windowed\" && popoutMode === null;\n prevStateRef.current = windowState;\n prevPopoutModeRef.current = popoutMode;\n if (wasNonWindowed && isNowWindowed) {\n // Never rescue against an invented viewport: on a hidden tab or a\n // display:none ancestor the measurement is 0×0, and clamping to the\n // 1280×800 fallback would rewrite the user's real geometry from a\n // number no screen ever had. Skip — the next real measurement clamps.\n const { vw, vh, degenerate } = safeViewportDims();\n if (degenerate) return;\n dispatch(clampWindowRect({ id, viewportWidth: vw, viewportHeight: vh }));\n }\n }, [dispatch, id, windowState, popoutMode]);\n\n const isMinimized = windowState === \"minimized\";\n const isMaximized = windowState === \"maximized\";\n const isPopoutCandidate = popoutCandidateId === id;\n\n useEffect(() => {\n if (!isMobile || !isMinimized) return;\n let cancelled = false;\n queueMicrotask(() => {\n if (!cancelled) handleRestoreClearingSnapshot();\n });\n return () => {\n cancelled = true;\n };\n }, [handleRestoreClearingSnapshot, isMinimized, isMobile]);\n const minimizedTitle =\n title?.trim() ||\n getOverlayMeta(trayRegistryKey)?.label ||\n \"Window\";\n\n // ── Header (shared across all states) ───────────────────────────────────\n const header = (\n <WindowHeader\n title={titleNode ?? title}\n minimizedTitle={minimizedTitle}\n actionsLeft={actionsLeft}\n actionsRight={resolvedActionsRight}\n onDragStart={onDragStart}\n onMinimize={handleMinimize}\n onToggleMaximize={onToggleMaximize}\n onClose={handleClose}\n onRestore={handleRestoreClearingSnapshot}\n isMaximized={isMaximized}\n isMinimized={isMinimized}\n snapLeft={snapLeft}\n snapRight={snapRight}\n snapTop={snapTop}\n snapBottom={snapBottom}\n snapCentre={snapCentre}\n arrangeAll={arrangeAll}\n hasSidebar={hasSidebar}\n sidebarOpen={sidebarOpen}\n onToggleSidebar={toggleSidebar}\n onSaveWindowState={overlayId ? handleSaveWindowState : undefined}\n onPopOut={canShowPopOut ? handlePopOut : undefined}\n />\n );\n\n // ────────────────────────────────────────────────────────────────────────\n // Desktop body shared by windowed, maximized, and minimized states.\n // ────────────────────────────────────────────────────────────────────────\n // A secondary (right) panel is shown when content is provided and it's open.\n // Stable `id` props (sidebar/body/secondary) keep panel identity so toggling\n // the secondary panel doesn't tear down the body (and the live editor inside).\n const hasSecondaryPanel =\n secondaryPanel != null && (secondaryPanelOpen ?? true);\n\n const innerBody =\n hasSidebar || hasSecondaryPanel ? (\n <ResizablePanelGroup orientation=\"horizontal\" className=\"h-full min-h-0\">\n {hasSidebar && (\n <>\n <ResizablePanel\n id=\"sidebar\"\n panelRef={sidebarPanelRef}\n defaultSize={sidebarOpen ? sidebarDefaultSize : 0}\n minSize={sidebarMinSize}\n collapsible\n collapsedSize={0}\n groupResizeBehavior=\"preserve-pixel-size\"\n onResize={handleSidebarResize}\n style={{ overflow: \"hidden\" }}\n >\n <div\n className={cn(\n \"h-full flex flex-col min-h-0 overflow-y-auto scrollbar-thin\",\n sidebarClassName,\n )}\n >\n {sidebar}\n </div>\n </ResizablePanel>\n {/* A collapsed sidebar is 0px wide, so its handle would draw a\n stray line down the window's left edge. Keep it in the panel\n group (the library measures it) but make it invisible. */}\n <ResizableHandle\n className={\n sidebarOpen ? undefined : \"w-0 opacity-0 pointer-events-none\"\n }\n />\n </>\n )}\n <ResizablePanel id=\"body\" minSize={200} className=\"min-h-0\">\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n {children}\n </div>\n </ResizablePanel>\n {hasSecondaryPanel && (\n <>\n <ResizableHandle />\n <ResizablePanel\n id=\"secondary\"\n defaultSize={secondaryPanelDefaultSize}\n minSize={secondaryPanelMinSize}\n groupResizeBehavior=\"preserve-pixel-size\"\n style={{ overflow: \"hidden\" }}\n >\n <div\n className={cn(\n \"h-full flex flex-col min-h-0\",\n secondaryPanelClassName,\n )}\n >\n {secondaryPanel}\n </div>\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n ) : (\n children\n );\n\n // Every desktop body path (windowed, maximized, popped out, with a sidebar) is\n // one selection surface: the ONE selection toolbar and the menu work in every window.\n const bodyContent = (\n <WindowSelectionSurface>\n {isDeprecated ? (\n <div className=\"h-full flex flex-col min-h-0\">\n <DeprecationBanner\n replacedBy={deprecation?.replacement}\n note={deprecation?.reason}\n />\n <div className=\"flex-1 min-h-0\">{innerBody}</div>\n </div>\n ) : (\n innerBody\n )}\n </WindowSelectionSurface>\n );\n\n const hasZonedFooter = footerLeft || footerCenter || footerRight;\n const hasFooter = footer || hasZonedFooter;\n\n // Zoned trio — reused by both variants. In \"bar\" the wrapper is itself a flex\n // row so the trio drops in as direct children; in \"rich\" the wrapper is a\n // plain block, so the trio gets its own flex row to keep the left/center/right\n // layout (rich is normally used with a single `footer` node, though).\n const zonedFooter = (\n <>\n <div className=\"flex items-center gap-1 shrink-0\">{footerLeft}</div>\n <div className=\"flex-1 flex items-center justify-center gap-1\">\n {footerCenter}\n </div>\n <div className=\"flex items-center gap-1 shrink-0\">{footerRight}</div>\n </>\n );\n\n const footerBar = hasFooter ? (\n <div\n className={cn(\n // Always: detach from scroll + separate from the body with a top border.\n \"shrink-0 border-t border-border/50\",\n WINDOW_CHROME_INTERACTIVE,\n footerVariant === \"bar\" &&\n // Compact metadata-bar chrome — thin chips, tiny buttons/icons. Crushes\n // rich content; consumers with a composer/input bar pass footerVariant=\"rich\".\n \"flex items-center gap-1 px-2 py-1 rounded-b-xl bg-muted/40 select-none text-xs [&_svg]:h-3 [&_svg]:w-3 [&_button]:h-5 [&_button]:text-xs\",\n )}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {footer ??\n (footerVariant === \"bar\" ? (\n zonedFooter\n ) : (\n <div className=\"flex items-center gap-1\">{zonedFooter}</div>\n ))}\n </div>\n ) : null;\n\n // ────────────────────────────────────────────────────────────────────────\n // MOBILE — presentation comes from the definition (`window.mobile`):\n // \"drawer\" → bottom-sheet (vaul) with optional nested sidebar drawer\n // \"card\" → small z-stacked floating card (utility windows)\n // \"hidden\" → do not mount on mobile at all\n // \"fullscreen\" → one window at a time, fullscreen takeover (default)\n // ────────────────────────────────────────────────────────────────────────\n // ── Body identity ──────────────────────────────────────────────────────────\n // The body renders through ONE portal into ONE detached container, at a fixed position in this\n // component's output; each presentation only attaches that container (BodyMount). Maximize,\n // minimize, pop-out and dock therefore never remount the body. Proven by\n // __tests__/popoutBodyIdentity.test.tsx (it failed with a remount before this).\n const bodyPortal =\n isMounted && bodyHost && !isMobile\n ? createPortal(\n <PopoutContext.Provider value={bodyPopoutValue}>\n <PortalContainerProvider container={bodyPortalContainer}>\n {/* React bubbles synthetic events along the React tree, so the body (no longer a\n React child of the shell) carries the shell's focus / front-claim handlers. */}\n <div className=\"contents\" onPointerDown={onFocus} onPointerDownCapture={claimFront} onFocusCapture={claimFront}>\n {bodyContent}\n </div>\n </PortalContainerProvider>\n </PopoutContext.Provider>,\n bodyHost,\n )\n : null;\n\n if (isMobile) {\n const mobilePresentation: MobilePresentation =\n mobilePresentationOverride ?? registryEntry?.mobile ?? \"fullscreen\";\n const mobileSidebarAs = registryEntry?.mobileSidebarAs ?? \"drawer\";\n\n if (mobilePresentation === \"hidden\") {\n if (process.env.NODE_ENV !== \"production\" && overlayId) {\n console.warn(\n `[WindowPanel] overlay \"${overlayId}\" has window.mobile: \"hidden\" but was opened on a phone. Give its definition another presentation or gate opening.`,\n );\n }\n return null;\n }\n\n if (mobilePresentation === \"drawer\") {\n return (\n <MobileDrawerSurface\n isOpen={true}\n title={titleNode ?? title}\n onClose={handleClose}\n sidebar={sidebar}\n sidebarAs={mobileSidebarAs}\n footer={footerBar}\n actionsLeft={actionsLeft}\n actionsRight={resolvedActionsRight}\n bodyClassName={bodyClassName}\n surfaceLayer={surfaceLayer}\n sizeToContent={mobileSizeToContent}\n hideClose={mobileHideClose}\n >\n <WindowSelectionSurface>{children}</WindowSelectionSurface>\n </MobileDrawerSurface>\n );\n }\n\n if (mobilePresentation === \"card\") {\n return (\n <MobileCardSurface\n isOpen={true}\n title={titleNode ?? title}\n onClose={handleClose}\n footer={footerBar}\n actionsRight={resolvedActionsRight}\n bodyClassName={bodyClassName}\n surfaceLayer={surfaceLayer}\n >\n <WindowSelectionSurface>{children}</WindowSelectionSurface>\n </MobileCardSurface>\n );\n }\n\n // mobilePresentation === \"fullscreen\" — legacy behavior (default).\n const mobileBody =\n hasSidebar && activePaneMobile === \"sidebar\" ? (\n <div className={cn(\"h-full overflow-y-auto\", sidebarClassName)}>\n {sidebar}\n </div>\n ) : (\n children\n );\n\n const mobileEl = (\n <div\n {...surfaceLayerAttrs}\n className={cn(\n \"fixed inset-0 flex flex-col\",\n \"bg-card/98 backdrop-blur-md\",\n \"overflow-hidden\",\n deprecatedRingClass,\n className,\n )}\n style={{\n top: windowConfig.mobileTopOffset,\n zIndex,\n display: isTopWindow && !isMinimized ? undefined : \"none\",\n visibility: windowsHidden ? \"hidden\" : undefined,\n }}\n onPointerDown={onFocus}\n onPointerDownCapture={claimFront}\n onFocusCapture={claimFront}\n >\n <MobileWindowHeader\n title={titleNode ?? title}\n actionsRight={resolvedActionsRight}\n onClose={handleClose}\n hasSidebar={hasSidebar}\n activePaneMobile={activePaneMobile}\n onSetActivePane={setActivePaneMobile}\n />\n {isDebugMode && <DebugStrip rect={rect} zIndex={zIndex} />}\n <div className={cn(\"flex-1 overflow-auto min-h-0\", bodyClassName)}>\n {/* Same menu as the drawer/card paths and desktop: long-press in a\n fullscreen phone window used to open nothing. */}\n <WindowSelectionSurface>{mobileBody}</WindowSelectionSurface>\n </div>\n {footerBar}\n </div>\n );\n return portalTarget\n ? createPortal(<FloatingLayer>{mobileEl}</FloatingLayer>, portalTarget)\n : null;\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // POPPED OUT — content is rendered into a separate browser window via\n // PopoutPortal. The same WindowPanel component instance covers both\n // docked and popped-out states, so React state, refs, effects, Redux\n // subscriptions, and Supabase realtime channels all survive the transition\n // with no remount.\n //\n // The OS / browser frame provides close + minimize at the window-manager\n // level, so we render `PopoutTopBar` (no traffic lights) instead of the\n // standard `header`. The \"Dock\" button in PopoutTopBar dispatches\n // `dockWindow`, which clears the popout state and triggers the\n // `usePopoutWindow` lifecycle to close the actual browser window.\n // ────────────────────────────────────────────────────────────────────────\n if (popoutMode !== null) {\n return (\n <>\n <PopoutPortal windowId={id}>\n <div\n {...surfaceLayerAttrs}\n className=\"h-full w-full flex flex-col bg-card text-foreground\"\n >\n <PopoutTopBar\n title={titleNode ?? title}\n actionsRight={resolvedActionsRight}\n onDock={handleDockBack}\n />\n {isDebugMode && <DebugStrip rect={rect} zIndex={zIndex} />}\n <div className={cn(\"flex-1 overflow-auto min-h-0\", bodyClassName)}>\n <BodyMount host={bodyHost} />\n </div>\n {footerBar}\n </div>\n </PopoutPortal>\n {bodyPortal}\n </>\n );\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // DESKTOP — one shell and body tree across windowed/maximized/restore.\n // Minimized keeps its existing capture/retention and tray-preview semantics.\n // ────────────────────────────────────────────────────────────────────────\n const el = (\n <div\n ref={fitContent ? fitContentRef : undefined}\n data-window-panel=\"\"\n data-window-id={id}\n {...surfaceLayerAttrs}\n // A minimized tile docks at the bottom over the page: it is floating chrome, so every page\n // end (a list's pager included) clears it (lib/layout/floating-chrome.ts). 2026-10-05: the\n // /data pager's next-page arrows sat under the tile.\n {...(isMinimized ? { \"data-matrx-floating-bottom\": \"\" } : {})}\n className={cn(\n \"fixed\",\n isMaximized ? \"overflow-hidden\" : \"overflow-visible\",\n \"matrx-window-enter\",\n // Programmatic rect changes glide; pointer drag/resize stays 1:1.\n glideReady && !isInteracting && \"matrx-window-glide\",\n // Drag-out candidate: ring-2 highlight signals \"release here to pop out\".\n isPopoutCandidate &&\n \"ring-2 ring-primary ring-offset-2 ring-offset-background transition-shadow\",\n deprecatedRingClass,\n className,\n )}\n style={{\n ...(isMaximized\n ? { inset: 0, width: \"100vw\", height: \"100dvh\" }\n : {\n left: rect.x,\n top: rect.y,\n ...(fitContent && !isMinimized\n ? { width: \"max-content\", height: \"auto\" }\n : { width: rect.width, height: rect.height }),\n }),\n zIndex,\n // Cap CSS mins to the current rect so arrange/snap geometry wins.\n // Uncapped minWidth (e.g. 640) was overriding tile widths and stacking\n // every left-edge window on top of each other.\n minWidth: isMaximized || isMinimized\n ? 0\n : fitContent\n ? (minWidth ?? 180)\n : Math.min(minWidth ?? 180, rect.width),\n minHeight: isMaximized || isMinimized\n ? 0\n : fitContent\n ? (minHeight ?? 80)\n : Math.min(minHeight ?? 80, rect.height),\n visibility: windowsHidden ? \"hidden\" : undefined,\n }}\n onPointerDown={onFocus}\n onPointerDownCapture={claimFront}\n onFocusCapture={claimFront}\n // Double-click anywhere on the minimized card — header included —\n // restores it, matching the single-click-to-restore body affordance.\n onDoubleClick={isMinimized ? handleRestoreClearingSnapshot : undefined}\n >\n {!isMinimized && !isMaximized &&\n HANDLES.map((h) => (\n <div\n key={h.edge}\n className={cn(\n h.className,\n \"z-50 hover:bg-primary/20 transition-colors\",\n )}\n style={{ touchAction: \"none\" }}\n onPointerDown={onResizeStart(h.edge)}\n />\n ))}\n <div\n className={cn(\n \"flex h-full w-full min-h-0 flex-col\",\n // Opaque window surface: a window is a solid card, never glass —\n // glass belongs only on bars floating over moving content (tap-target\n // placement rule 1). A see-through window let the page underneath\n // read through its content (Watch AI, 2026-10-12).\n isMaximized\n ? \"bg-card border border-border shadow-2xl\"\n : \"rounded-xl bg-card border border-border shadow-xl\",\n \"overflow-hidden\",\n )}\n >\n {header}\n\n {/* Debug strip — body of an open window only. A minimized tile is too small for it: the\n strip wrapped to fill the whole tile and hid the preview (MKT-077). */}\n {isDebugMode && !isMinimized && <DebugStrip rect={rect} zIndex={zIndex} />}\n\n {(\n\n <WindowPanelBodyShell\n bodyRef={bodyRef}\n fitContent={fitContent}\n isMaximized={isMaximized}\n bodyClassName={bodyClassName}\n captureDimensions={\n isMinimized\n ? pendingTrayCapture\n ? {\n width: pendingTrayCapture.width,\n height: pendingTrayCapture.height,\n }\n : (retainedBodyDimensionsRef.current ?? {\n width: Math.max(1, rect.width),\n height: Math.max(1, rect.height),\n })\n : null\n }\n >\n <BodyMount host={bodyHost} />\n </WindowPanelBodyShell>\n )}\n\n {/* Minimized: fill the empty shell body with the canonical tray preview\n (registry custom / snapshot / default). Click anywhere to restore. */}\n {isMinimized && (\n <MinimizedWindowContent\n registryKey={trayRegistryKey}\n snapshotKey={id}\n overlayInstanceId={overlayInstanceId}\n previewData={trayPreviewData}\n title={minimizedTitle}\n onRestore={handleRestoreClearingSnapshot}\n />\n )}\n\n {!isMinimized && footerBar}\n\n {/* Drag-out ghost label — overlays the body during the candidate dwell.\n Pointer-events:none so it doesn't interfere with the in-progress drag. */}\n {isPopoutCandidate && (\n <div className=\"absolute inset-0 z-30 flex items-center justify-center pointer-events-none\">\n <div className=\"px-3 py-1.5 rounded-md bg-primary text-primary-foreground text-xs font-medium shadow-lg\">\n Release to pop out\n </div>\n </div>\n )}\n </div>\n </div>\n );\n\n return (\n <>\n {portalTarget ? createPortal(<FloatingLayer>{el}</FloatingLayer>, portalTarget) : null}\n {bodyPortal}\n </>\n );\n}\n\n/**\n * Attaches the window's body container where this renders. Its layout effect runs before the\n * body's own (it is earlier in the tree), so a body measuring itself on mount sees a connected node.\n */\nfunction BodyMount({ host }: { host: HTMLDivElement | null }) {\n const slotRef = useRef<HTMLDivElement | null>(null);\n useLayoutEffect(() => {\n const slot = slotRef.current;\n if (!slot || !host) return undefined;\n slot.appendChild(host);\n return () => {\n if (host.parentNode === slot) slot.removeChild(host);\n };\n }, [host]);\n return <div ref={slotRef} className=\"contents\" data-window-body-slot=\"\" />;\n}\n\n// DebugStrip extracted to ./WindowPanel/DebugStrip.tsx (Phase 6).\n\n// ─── WindowHeader ─────────────────────────────────────────────────────────────\n\nfunction PopOutHeaderButton({ onClick }: { onClick: () => void }) {\n return (\n <button\n type=\"button\"\n className=\"p-0.5 rounded hover:bg-accent/60 transition-colors text-foreground/60 hover:text-foreground cursor-pointer\"\n onClick={onClick}\n onPointerDown={(e) => e.stopPropagation()}\n title=\"Pop out into a separate window\"\n aria-label=\"Pop out into a separate window\"\n >\n <AppWindow className=\"w-3.5 h-3.5\" />\n </button>\n );\n}\n\ninterface WindowHeaderProps {\n title?: React.ReactNode | undefined;\n minimizedTitle: string;\n actionsLeft?: React.ReactNode | undefined;\n actionsRight?: React.ReactNode | undefined;\n onDragStart: (e: React.PointerEvent) => void;\n onMinimize: () => void;\n onToggleMaximize: () => void;\n onRestore: () => void;\n onClose?: (() => void) | undefined;\n isMaximized: boolean;\n isMinimized: boolean;\n snapLeft: () => void;\n snapRight: () => void;\n snapTop: () => void;\n snapBottom: () => void;\n snapCentre: () => void;\n arrangeAll: (layout: GlobalLayoutType) => void;\n hasSidebar: boolean;\n sidebarOpen: boolean;\n onToggleSidebar: () => void;\n /** When set, a \"Save Window State\" button appears in the green traffic-light dropdown. */\n onSaveWindowState?: (() => void) | undefined;\n /**\n * When set, a header pop-out icon and green-dropdown entry are shown.\n * Clicking opens the window in a separate browser window.\n */\n onPopOut?: (() => void) | undefined;\n}\n\nfunction WindowHeader({\n title,\n minimizedTitle,\n actionsLeft,\n actionsRight,\n onDragStart,\n onMinimize,\n onToggleMaximize,\n onRestore,\n onClose,\n isMaximized,\n isMinimized,\n snapLeft,\n snapRight,\n snapTop,\n snapBottom,\n snapCentre,\n arrangeAll,\n hasSidebar,\n sidebarOpen,\n onToggleSidebar,\n onSaveWindowState,\n onPopOut,\n}: WindowHeaderProps) {\n return (\n <div\n className={cn(\n // 🚨 NEW-8 — the header is a CONTAINER, so a consumer's title/actions can\n // answer the WINDOW's width instead of the viewport's (`sm:` cannot know\n // a window is 360px on a 1440px screen — that is how D4 stayed invisible).\n // The name is `window-header`; `lib/detail/core/headerGeometry.ts` holds it.\n \"@container/window-header\",\n // Open: three in-flow columns — left zone, title, right zone. The two\n // side columns share the free space equally (never less than their\n // real content), so the title sits at the WINDOW's centre whatever\n // each side carries, and still truncates instead of running under an\n // action cluster when space is tight (D4). Minimized has no title\n // column, so it keeps the plain row.\n isMinimized\n ? \"matrx-window-header-row relative flex items-center justify-between gap-1 px-2 py-1 z-20 shrink-0\"\n : \"matrx-window-header-grid relative items-center gap-1 px-2 py-1 z-20 shrink-0\",\n \"border-b border-border/50 bg-muted/40 select-none\",\n isMaximized || isMinimized\n ? \"cursor-default\"\n : \"cursor-grab active:cursor-grabbing\",\n isMinimized && \"h-8 min-h-8 py-0 border-b border-border/50\",\n )}\n data-window-panel-state={isMinimized ? \"minimized\" : undefined}\n style={isMaximized || isMinimized ? undefined : { touchAction: \"none\" }}\n onPointerDown={isMaximized || isMinimized ? undefined : onDragStart}\n >\n {/* macOS-style hot zone: absolutely positioned to cover the full\n left side of the header (top-to-bottom, no padding). The traffic\n lights and sidebar toggle live inside it so CSS group-hover/tl\n reveals all icons when the cursor enters the zone. */}\n <div\n className={cn(\n \"group/tl absolute top-0 left-0 bottom-0 flex items-center z-20\",\n hasSidebar ? \"w-28\" : \"w-24\",\n )}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <div className=\"pl-2\">\n <TrafficLightGroup\n isMinimized={isMinimized}\n isMaximized={isMaximized}\n onClose={onClose}\n onMinimize={onMinimize}\n onRestore={onRestore}\n onToggleMaximize={onToggleMaximize}\n snapLeft={snapLeft}\n snapRight={snapRight}\n snapTop={snapTop}\n snapBottom={snapBottom}\n snapCentre={snapCentre}\n arrangeAll={arrangeAll}\n hasSidebar={hasSidebar}\n sidebarOpen={sidebarOpen}\n onToggleSidebar={onToggleSidebar}\n onSaveWindowState={onSaveWindowState}\n onPopOut={onPopOut}\n />\n </div>\n </div>\n\n <div className=\"flex items-center gap-1 z-10 shrink-0\">\n {/* Spacer matching the hot zone width so left actions don't overlap */}\n <div className={hasSidebar ? \"w-28\" : \"w-24\"} />\n\n {/* Left action zone */}\n {!isMinimized && actionsLeft && (\n <div\n className={WINDOW_CHROME_ACTIONS}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {actionsLeft}\n </div>\n )}\n </div>\n\n {/* Minimized titles use the fixed plain-text branch in an absolute layer\n (a minimized window draws no action cluster, so nothing can run under\n it) and can never inherit consumer typography or interaction from a\n rich titleNode. */}\n {isMinimized ? (\n <div className=\"absolute top-0 bottom-0 left-20 right-2 flex items-center justify-start pointer-events-none\">\n <span\n className=\"matrx-window-minimized-title block min-w-0 truncate leading-none font-semibold text-foreground\"\n data-minimized-window-title\n >\n {minimizedTitle}\n </span>\n </div>\n ) : null}\n\n {/* 🚨 D4 — Open titles stay in flow, and the action zones' REAL widths are\n reserved by the flex row itself. This used to be an `absolute inset-x-0\n justify-center` layer with `px-16` standing in for the space the\n traffic lights and the icons occupy: a short title looked centred, and\n a long one grew to `max-w-full` and was drawn UNDERNEATH the action\n cluster — in the Detail window that put the record's type chip and its\n own doors under the open-as icons (VERIFY-U-P1 D4, still open by\n geometry at VERIFY-U-P1-R2). A flex child with `min-w-0` yields exactly\n what its siblings need and truncates instead of overlapping, at every\n window width, with no `sm:` breakpoint pretending to know a window's\n size. The title is still centred — in the space that is actually free. */}\n {!isMinimized && (\n <div className=\"flex min-w-0 flex-1 items-center justify-center overflow-hidden\">\n {typeof title === \"string\" || title == null ? (\n <span className=\"min-w-0 truncate text-xs font-medium text-foreground/80\">\n {title ?? \"\"}\n </span>\n ) : (\n <div\n className=\"flex min-w-0 max-w-full items-center overflow-hidden whitespace-nowrap\"\n onPointerDown={(event) => {\n const target = event.target;\n if (!(target instanceof Element)) return;\n if (\n target.closest(\n 'a, button, input, select, textarea, [role=\"button\"], [role=\"menuitem\"], [data-window-no-drag]',\n )\n ) {\n event.stopPropagation();\n }\n }}\n >\n {title}\n </div>\n )}\n </div>\n )}\n\n {/* Right action zone */}\n <div className=\"flex items-center justify-end gap-1 z-10 shrink-0\">\n {!isMinimized && (onPopOut || actionsRight) && (\n <div\n className={WINDOW_CHROME_ACTIONS}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {onPopOut ? <PopOutHeaderButton onClick={onPopOut} /> : null}\n {actionsRight}\n </div>\n )}\n </div>\n </div>\n );\n}\n\n// ─── TrafficLightGroup ────────────────────────────────────────────────────────\n// Nested inside the group/tl hot zone — icon reveal uses CSS group-hover/tl.\n\ninterface TrafficLightGroupProps {\n isMinimized: boolean;\n isMaximized: boolean;\n onClose?: (() => void) | undefined;\n onMinimize: () => void;\n onRestore: () => void;\n onToggleMaximize: () => void;\n snapLeft: () => void;\n snapRight: () => void;\n snapTop: () => void;\n snapBottom: () => void;\n snapCentre: () => void;\n arrangeAll: (layout: GlobalLayoutType) => void;\n hasSidebar: boolean;\n sidebarOpen: boolean;\n onToggleSidebar: () => void;\n onSaveWindowState?: (() => void) | undefined;\n onPopOut?: (() => void) | undefined;\n}\n\nfunction TrafficLightGroup({\n isMinimized,\n isMaximized,\n onClose,\n onMinimize,\n onRestore,\n onToggleMaximize,\n snapLeft,\n snapRight,\n snapTop,\n snapBottom,\n snapCentre,\n arrangeAll,\n hasSidebar,\n sidebarOpen,\n onToggleSidebar,\n onSaveWindowState,\n onPopOut,\n}: TrafficLightGroupProps) {\n return (\n <div className=\"flex items-center gap-1.5 shrink-0 cursor-default\">\n {/* Red — Close */}\n <TrafficLight\n color=\"red\"\n icon={\n <X className=\"w-2 h-2 matrx-window-light-glyph\" />\n }\n onClick={onClose ?? undefined}\n disabled={!onClose}\n aria-label=\"Close\"\n />\n\n {/* Yellow — Minimize / restore */}\n <TrafficLight\n color=\"yellow\"\n icon={\n isMinimized ? (\n <Maximize2\n className=\"w-2 h-2 matrx-window-light-glyph\"\n\n />\n ) : (\n <Minus\n className=\"w-2 h-2 matrx-window-light-glyph\"\n\n />\n )\n }\n onClick={isMinimized ? onRestore : onMinimize}\n aria-label={isMinimized ? \"Restore\" : \"Minimize\"}\n />\n\n {/* Green — Maximize / dropdown */}\n {!isMinimized && (\n <GreenTrafficLight\n isMaximized={isMaximized}\n onToggleMaximize={onToggleMaximize}\n onRestore={onRestore}\n snapLeft={snapLeft}\n snapRight={snapRight}\n snapTop={snapTop}\n snapBottom={snapBottom}\n snapCentre={snapCentre}\n arrangeAll={arrangeAll}\n onSaveWindowState={onSaveWindowState}\n onPopOut={onPopOut}\n />\n )}\n\n {/* Sidebar toggle — sits tight next to the traffic lights */}\n {hasSidebar && !isMinimized && (\n <button\n type=\"button\"\n className=\"ml-0.5 p-0.5 rounded hover:bg-accent/60 transition-colors text-foreground/60 group-hover/tl:text-foreground cursor-pointer\"\n onClick={onToggleSidebar}\n title={sidebarOpen ? \"Hide sidebar\" : \"Show sidebar\"}\n aria-label={sidebarOpen ? \"Hide sidebar\" : \"Show sidebar\"}\n >\n {sidebarOpen ? (\n <PanelLeftClose className=\"w-3.5 h-3.5\" />\n ) : (\n <PanelLeft className=\"w-3.5 h-3.5\" />\n )}\n </button>\n )}\n </div>\n );\n}\n\n// ─── TrafficLight (red / yellow) ─────────────────────────────────────────────\n\ninterface TrafficLightProps {\n color: \"red\" | \"yellow\";\n icon: React.ReactNode;\n onClick?: (() => void) | undefined;\n disabled?: boolean | undefined;\n \"aria-label\"?: string | undefined;\n}\n\nfunction TrafficLight({\n color,\n icon,\n onClick,\n disabled,\n \"aria-label\": label,\n}: TrafficLightProps) {\n const base =\n \"w-3.5 h-3.5 rounded-full flex items-center justify-center transition-colors shrink-0 relative\";\n const colours =\n color === \"red\"\n ? disabled\n ? \"matrx-window-light-disabled cursor-default\"\n : \"matrx-window-light-close cursor-pointer\"\n : \"matrx-window-light-minimize cursor-pointer\";\n\n return (\n <button\n type=\"button\"\n className={cn(base, colours)}\n onClick={disabled ? undefined : onClick}\n onPointerDown={(e) => e.stopPropagation()}\n aria-label={label}\n disabled={disabled}\n >\n <span\n className={cn(\n \"opacity-0 transition-opacity duration-100\",\n !disabled && \"group-hover/tl:opacity-100\",\n )}\n >\n {icon}\n </span>\n </button>\n );\n}\n\n// ─── GreenTrafficLight (with dropdown) ───────────────────────────────────────\n\ninterface GreenTrafficLightProps {\n isMaximized: boolean;\n onToggleMaximize: () => void;\n onRestore: () => void;\n snapLeft: () => void;\n snapRight: () => void;\n snapTop: () => void;\n snapBottom: () => void;\n snapCentre: () => void;\n arrangeAll: (layout: GlobalLayoutType) => void;\n onSaveWindowState?: (() => void) | undefined;\n /** When set, renders a \"Pop out\" entry that opens the window in a separate browser window. */\n onPopOut?: (() => void) | undefined;\n}\n\nfunction GreenTrafficLight({\n isMaximized,\n onToggleMaximize,\n onRestore,\n snapLeft,\n snapRight,\n snapTop,\n snapBottom,\n snapCentre,\n arrangeAll,\n onSaveWindowState,\n onPopOut,\n}: GreenTrafficLightProps) {\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const leaveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const openDropdown = () => {\n if (leaveTimer.current) clearTimeout(leaveTimer.current);\n setDropdownOpen(true);\n };\n const scheduleClose = () => {\n leaveTimer.current = setTimeout(() => {\n setDropdownOpen(false);\n }, 120);\n };\n\n const handleAction = (fn: () => void) => {\n fn();\n setDropdownOpen(false);\n };\n\n // Close dropdown when tapping outside — skip Radix portal targets\n useEffect(() => {\n if (!dropdownOpen) return undefined;\n const onPointerOutside = (e: PointerEvent) => {\n const target = e.target as Element;\n if (containerRef.current && !containerRef.current.contains(target)) {\n if (target.closest?.(\"[data-radix-portal]\")) return;\n setDropdownOpen(false);\n }\n };\n document.addEventListener(\"pointerdown\", onPointerOutside);\n return () => document.removeEventListener(\"pointerdown\", onPointerOutside);\n }, [dropdownOpen]);\n\n return (\n <div\n ref={containerRef}\n className=\"relative\"\n onMouseEnter={openDropdown}\n onMouseLeave={scheduleClose}\n >\n {/* The dot — click toggles maximize on mouse, tap opens dropdown on touch */}\n <button\n type=\"button\"\n className={cn(\n \"w-3.5 h-3.5 rounded-full flex items-center justify-center transition-colors shrink-0\",\n \"matrx-window-light-maximize cursor-pointer\",\n )}\n onClick={() => {\n // On touch devices, open the dropdown instead of immediately maximizing.\n // Touch has no hover, so this is the only way to access snap/arrange options.\n if (\"ontouchstart\" in window || navigator.maxTouchPoints > 0) {\n setDropdownOpen((prev) => !prev);\n } else {\n handleAction(onToggleMaximize);\n }\n }}\n onPointerDown={(e) => e.stopPropagation()}\n aria-label={isMaximized ? \"Restore\" : \"Maximize\"}\n >\n <span className=\"opacity-0 group-hover/tl:opacity-100 transition-opacity duration-100 flex items-center justify-center relative w-full h-full\">\n {isMaximized ? (\n <Minimize2\n className=\"w-2 h-2 matrx-window-light-glyph absolute\"\n\n />\n ) : (\n <Maximize2\n className=\"w-2 h-2 matrx-window-light-glyph absolute\"\n\n />\n )}\n </span>\n </button>\n\n {/* Dropdown */}\n {dropdownOpen && (\n <div\n className={cn(\n \"absolute left-0 top-full mt-1.5 z-50\",\n \"w-52 rounded-xl overflow-hidden\",\n \"bg-card/95 backdrop-blur-xl border border-border shadow-2xl\",\n \"py-1 text-xs\",\n )}\n onMouseEnter={openDropdown}\n onMouseLeave={scheduleClose}\n >\n {/* Move & Resize section */}\n {!isMaximized && (\n <>\n <div className=\"matrx-window-tile-meta px-3 pt-1.5 pb-1 font-semibold text-muted-foreground uppercase tracking-wider\">\n Move &amp; Resize\n </div>\n <div className=\"flex flex-col gap-1 px-2 pb-2\">\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(snapLeft)}\n type=\"left-half\"\n />\n <LayoutIconButton\n onClick={() => handleAction(snapRight)}\n type=\"right-half\"\n />\n <LayoutIconButton\n onClick={() => handleAction(snapTop)}\n type=\"top-half\"\n />\n <LayoutIconButton\n onClick={() => handleAction(snapBottom)}\n type=\"bottom-half\"\n />\n </div>\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(snapCentre)}\n type=\"centre\"\n />\n <LayoutIconButton\n onClick={() => handleAction(onToggleMaximize)}\n type=\"full\"\n />\n </div>\n </div>\n <div className=\"border-t border-border/50 my-1\" />\n\n <div className=\"matrx-window-tile-meta px-3 pt-1.5 pb-1 font-semibold text-muted-foreground uppercase tracking-wider\">\n Arrange All\n </div>\n <div className=\"flex flex-col gap-1 px-2 pb-2\">\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid4\"))}\n type=\"grid4\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid6\"))}\n type=\"grid6\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid8\"))}\n type=\"grid8\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid9\"))}\n type=\"grid9\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"grid12\"))}\n type=\"grid12\"\n />\n </div>\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight2\"))\n }\n type=\"stackRight2\"\n />\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight3\"))\n }\n type=\"stackRight3\"\n />\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight4\"))\n }\n type=\"stackRight4\"\n />\n <LayoutIconButton\n onClick={() =>\n handleAction(() => arrangeAll(\"stackRight5\"))\n }\n type=\"stackRight5\"\n />\n </div>\n <div className=\"flex gap-1 justify-center\">\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft2\"))}\n type=\"stackLeft2\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft3\"))}\n type=\"stackLeft3\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft4\"))}\n type=\"stackLeft4\"\n />\n <LayoutIconButton\n onClick={() => handleAction(() => arrangeAll(\"stackLeft5\"))}\n type=\"stackLeft5\"\n />\n </div>\n </div>\n <div className=\"border-t border-border/50 my-1\" />\n </>\n )}\n\n {/* Full Screen */}\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 hover:bg-accent transition-colors text-foreground/80\"\n onClick={() => handleAction(onToggleMaximize)}\n onPointerDown={(e) => e.stopPropagation()}\n >\n {isMaximized ? (\n <>\n <Minimize2 className=\"w-3.5 h-3.5 shrink-0\" /> Exit Full Screen\n </>\n ) : (\n <>\n <RectangleVertical className=\"w-3.5 h-3.5 shrink-0\" /> Enter\n Full Screen\n </>\n )}\n </button>\n\n {isMaximized && (\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 hover:bg-accent transition-colors text-foreground/80\"\n onClick={() => handleAction(onRestore)}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <Maximize2 className=\"w-3.5 h-3.5 shrink-0\" />\n Restore window\n </button>\n )}\n\n {/* Pop out — opens the window in a separate browser window.\n The popout hook chooses Document Picture-in-Picture (frameless,\n always-on-top) when available and the slot is free; otherwise\n falls back to a regular browser window so multiple popouts\n never interfere with each other. Hidden entirely when popout\n is unavailable (mobile / unsupported browser / already out). */}\n {onPopOut && (\n <>\n <div className=\"border-t border-border/50 my-1\" />\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 transition-colors text-foreground/80 hover:bg-accent\"\n onClick={() => handleAction(onPopOut)}\n onPointerDown={(e) => e.stopPropagation()}\n title=\"Pop out into a separate window\"\n >\n <AppWindow className=\"w-3.5 h-3.5 shrink-0\" />\n <span className=\"flex-1 text-left\">Pop out</span>\n </button>\n </>\n )}\n\n {/* Save Window State — only shown when the window is persistable */}\n {onSaveWindowState && (\n <>\n <div className=\"border-t border-border/50 my-1\" />\n <button\n type=\"button\"\n className=\"flex items-center gap-2.5 w-full px-3 py-1.5 hover:bg-accent transition-colors text-foreground/80\"\n onClick={() => handleAction(onSaveWindowState)}\n onPointerDown={(e) => e.stopPropagation()}\n >\n <Save className=\"w-3.5 h-3.5 shrink-0\" />\n Save window state\n </button>\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// MobileWindowHeader extracted to ./WindowPanel/MobileHeader.tsx (Phase 6).\n\n// SnapButton extracted to ./WindowPanel/SnapButton.tsx (Phase 6).\n\nexport default WindowPanel;\n","/**\n * The window chrome's glyphs, inlined (no icon-library dependency — design-system C19 does the\n * same). Each is the exact lucide glyph the app's WindowPanel rendered (same viewBox, paths and\n * stroke geometry), so the chrome is pixel-identical. `@ai-matrx/icons` resolves icons by NAME and\n * lazily outside its hot set; nine of these twelve are outside it, and a traffic light that\n * flashes a fallback on first paint is worse than twelve inlined paths.\n */\nimport type { ReactNode, SVGAttributes } from \"react\";\n\nexport type WindowIconProps = SVGAttributes<SVGSVGElement>;\nexport type WindowIcon = (props: WindowIconProps) => ReactNode;\n\nfunction glyph(children: ReactNode): WindowIcon {\n return function Glyph(props: WindowIconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={24}\n height={24}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n {...props}\n >\n {children}\n </svg>\n );\n };\n}\n\nexport const XIcon = glyph(<><path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" /></>);\nexport const MinusIcon = glyph(<path d=\"M5 12h14\" />);\nexport const Maximize2Icon = glyph(<><path d=\"M15 3h6v6\" /><path d=\"m21 3-7 7\" /><path d=\"m3 21 7-7\" /><path d=\"M9 21H3v-6\" /></>);\nexport const Minimize2Icon = glyph(<><path d=\"m14 10 7-7\" /><path d=\"M20 10h-6V4\" /><path d=\"m3 21 7-7\" /><path d=\"M4 14h6v6\" /></>);\nexport const RectangleVerticalIcon = glyph(<rect width=\"12\" height=\"20\" x=\"6\" y=\"2\" rx=\"2\" />);\nexport const PanelLeftCloseIcon = glyph(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /><path d=\"m16 15-3-3 3-3\" /></>);\nexport const PanelLeftIcon = glyph(<><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /></>);\nexport const AppWindowIcon = glyph(<><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" /><path d=\"M10 4v4\" /><path d=\"M2 8h20\" /><path d=\"M6 4v4\" /></>);\nexport const SaveIcon = glyph(\n <>\n <path d=\"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\" />\n <path d=\"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\" />\n <path d=\"M7 3v4a1 1 0 0 0 1 1h7\" />\n </>,\n);\nexport const TriangleAlertIcon = glyph(\n <>\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </>,\n);\nexport const ArrowLeftToLineIcon = glyph(<><path d=\"M3 19V5\" /><path d=\"m13 6-6 6 6 6\" /><path d=\"M7 12h14\" /></>);\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\nexport type LayoutIconType =\n // Single window\n | \"left-half\"\n | \"right-half\"\n | \"top-half\"\n | \"bottom-half\"\n | \"centre\"\n | \"full\"\n // Multi window\n | \"grid4\"\n | \"grid6\"\n | \"grid8\"\n | \"grid9\"\n | \"grid12\"\n | \"stackLeft2\"\n | \"stackLeft3\"\n | \"stackLeft4\"\n | \"stackLeft5\"\n | \"stackRight2\"\n | \"stackRight3\"\n | \"stackRight4\"\n | \"stackRight5\";\n\nexport function LayoutIcon({\n type,\n className,\n}: {\n type: LayoutIconType;\n className?: string | undefined;\n}) {\n const baseBox =\n \"w-[18px] h-[18px] border-[1.5px] border-current rounded-sm shrink-0 flex items-center justify-center p-[1px] gap-[1px] overflow-hidden\";\n const filled = \"bg-current rounded-[1px]\";\n const flexRow = \"flex flex-row w-full h-full gap-[1px]\";\n const flexCol = \"flex flex-col w-full h-full gap-[1px]\";\n\n let content: ReactNode = null;\n\n switch (type) {\n case \"left-half\":\n content = (\n <div className={flexRow}>\n <div className={cn(\"w-1/2 h-full\", filled)} />\n <div className=\"w-1/2 h-full\" />\n </div>\n );\n break;\n case \"right-half\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/2 h-full\" />\n <div className={cn(\"w-1/2 h-full\", filled)} />\n </div>\n );\n break;\n case \"top-half\":\n content = (\n <div className={flexCol}>\n <div className={cn(\"w-full h-1/2\", filled)} />\n <div className=\"w-full h-1/2\" />\n </div>\n );\n break;\n case \"bottom-half\":\n content = (\n <div className={flexCol}>\n <div className=\"w-full h-1/2\" />\n <div className={cn(\"w-full h-1/2\", filled)} />\n </div>\n );\n break;\n case \"centre\":\n content = <div className={cn(\"w-1/2 h-1/2\", filled)} />;\n break;\n case \"full\":\n content = <div className={cn(\"w-full h-full\", filled)} />;\n break;\n\n // Grid variants\n case \"grid4\":\n content = (\n <div className=\"grid grid-cols-2 grid-rows-2 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid6\":\n content = (\n <div className=\"grid grid-cols-3 grid-rows-2 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid8\":\n content = (\n <div className=\"grid grid-cols-4 grid-rows-2 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid9\":\n content = (\n <div className=\"grid grid-cols-3 grid-rows-3 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n case \"grid12\":\n content = (\n <div className=\"grid grid-cols-4 grid-rows-3 gap-[1px] w-full h-full\">\n {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((i) => (\n <div key={i} className={filled} />\n ))}\n </div>\n );\n break;\n\n // Stack variants\n case \"stackRight2\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/2 h-full\" />\n <div className=\"w-1/2 h-full flex flex-col gap-[1px]\">\n <div className={cn(\"w-full h-1/2\", filled)} />\n <div className={cn(\"w-full h-1/2\", filled)} />\n </div>\n </div>\n );\n break;\n case \"stackRight3\":\n content = (\n <div className={flexRow}>\n <div className=\"w-2/3 h-full\" />\n <div className=\"w-1/3 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n </div>\n );\n break;\n case \"stackRight4\":\n content = (\n <div className={flexRow}>\n <div className=\"w-3/4 h-full\" />\n <div className=\"w-1/4 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n </div>\n );\n break;\n case \"stackRight5\":\n content = (\n <div className={flexRow}>\n <div className=\"w-4/5 h-full\" />\n <div className=\"w-1/5 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n </div>\n );\n break;\n case \"stackLeft2\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/2 h-full flex flex-col gap-[1px]\">\n <div className={cn(\"w-full h-1/2\", filled)} />\n <div className={cn(\"w-full h-1/2\", filled)} />\n </div>\n <div className=\"w-1/2 h-full\" />\n </div>\n );\n break;\n case \"stackLeft3\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/3 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n <div className=\"w-2/3 h-full\" />\n </div>\n );\n break;\n case \"stackLeft4\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/4 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n <div className=\"w-3/4 h-full\" />\n </div>\n );\n break;\n case \"stackLeft5\":\n content = (\n <div className={flexRow}>\n <div className=\"w-1/5 h-full flex flex-col gap-[1px]\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className={cn(\"w-full flex-1\", filled)} />\n ))}\n </div>\n <div className=\"w-4/5 h-full\" />\n </div>\n );\n break;\n }\n\n return <div className={cn(baseBox, className)}>{content}</div>;\n}\n\nexport function LayoutIconButton({\n onClick,\n type,\n className,\n}: {\n onClick: () => void;\n type: LayoutIconType;\n className?: string | undefined;\n}) {\n return (\n <button\n type=\"button\"\n className={cn(\n \"flex items-center justify-center flex-1 h-8 rounded-md transition-colors\",\n \"hover:bg-accent/80 text-foreground/50 hover:text-foreground\",\n className\n )}\n onClick={onClick}\n onPointerDown={(e) => e.stopPropagation()}\n title={type}\n >\n <LayoutIcon type={type} />\n </button>\n );\n}\n","\"use client\";\n\n/**\n * useWindowPanel\n *\n * Connects a single WindowPanel instance to the Redux window-manager slice.\n * Handles:\n * - Registration / cleanup on mount/unmount\n * - Drag-to-move (header pointerdown → document pointermove/pointerup)\n * - Resize (edge/corner handles → document pointermove/pointerup)\n * - Window state transitions (windowed / maximized / minimized)\n * - Focus-on-click (brings panel to top of z stack)\n *\n * Uses pointer events (not mouse events) so drag/resize works on\n * touchscreens (iPad, Tesla, etc.) as well as mouse + pen input.\n *\n * Pure CSS resize via inline styles; no Tailwind width classes after mount.\n */\n\nimport { useEffect, useRef, useCallback, useId, useState } from \"react\";\nimport { useSummonDispatch, useSummonSelector, useSummonStore } from \"@ai-matrx/summon/react\";\nimport {\n registerWindow,\n unregisterWindow,\n focusWindow,\n restoreWindow,\n maximizeWindow,\n minimizeWindow,\n updateWindowRect,\n updateWindowTitle,\n setPopoutCandidate,\n clampWindowRect,\n selectWindow,\n type WindowRect,\n type WindowPersistenceRegistration,\n confirmWindowRestored,\n windowSessionKey,\n} from \"@ai-matrx/summon\";\nimport {\n evaluateDragOut,\n DEFAULT_DRAG_OUT_CONFIG,\n INITIAL_DRAG_OUT_STATE,\n type DragOutState,\n} from \"./popout/popoutDragDetector\";\nimport { safeViewportDims } from \"@ai-matrx/summon\";\nimport { resolveAutoOpenPlacement } from \"./utils/autoOpenPlacement\";\nimport { holdDragCursor, type DragCursor } from \"@ai-matrx/design-system\";\n\n// ─── Config ────────────────────────────────────────────────────────────────────\n\nconst MIN_WIDTH = 180;\nconst MIN_HEIGHT = 80;\nconst DEFAULT_WIDTH = 320;\nconst DEFAULT_HEIGHT = 400;\n\n// ─── Types ─────────────────────────────────────────────────────────────────────\n\nexport type ResizeEdge =\n | \"e\" // right\n | \"s\" // bottom\n | \"se\" // bottom-right corner\n | \"w\" // left\n | \"sw\" // bottom-left\n | \"n\" // top\n | \"ne\" // top-right\n | \"nw\"; // top-left\n\n/** The cursor each resize edge holds for the whole resize (THE CURSOR LAW). */\nconst RESIZE_CURSOR: Record<ResizeEdge, DragCursor> = {\n e: \"ew-resize\",\n w: \"ew-resize\",\n n: \"ns-resize\",\n s: \"ns-resize\",\n se: \"nwse-resize\",\n nw: \"nwse-resize\",\n ne: \"nesw-resize\",\n sw: \"nesw-resize\",\n};\n\n/** Where to place the window when it first opens. */\nexport type WindowPosition =\n \"center\" | \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\";\n\n/**\n * Resolve a dimension value to pixels.\n * - number → pixels as-is\n * - string ending in \"vh\" → percentage of viewport height\n * - string ending in \"vw\" → percentage of viewport width\n */\nfunction resolveSize(\n value: number | string | undefined,\n fallback: number,\n): number {\n if (value === undefined) return fallback;\n if (typeof value === \"number\") return value;\n const { vw, vh } = safeViewportDims();\n if (value.endsWith(\"vh\")) return Math.round((parseFloat(value) / 100) * vh);\n if (value.endsWith(\"vw\")) return Math.round((parseFloat(value) / 100) * vw);\n return parseFloat(value) || fallback;\n}\n\n/**\n * How many windows this page has already placed by default, so the second one\n * does not land exactly on the first. Page-scoped on purpose: a reload starts\n * the cascade over, which is what every desktop window manager does.\n */\nconst CASCADE_COUNT = Symbol.for(\"matrx.windowPanels.defaultCascade\");\nconst CASCADE_STEP = 28;\nconst CASCADE_WRAP = 6;\n\nexport function resetDefaultWindowCascade(): void {\n (globalThis as unknown as Record<symbol, number>)[CASCADE_COUNT] = 0;\n}\n\nfunction nextCascadeStep(): number {\n const host = globalThis as unknown as Record<symbol, number>;\n const seen = host[CASCADE_COUNT] ?? 0;\n host[CASCADE_COUNT] = seen + 1;\n return (seen % CASCADE_WRAP) * CASCADE_STEP;\n}\n\n/**\n * Where a window nobody positioned opens.\n *\n * 🚨 WHY THIS IS NOT CENTERED ANY MORE (2026-09-17). The `default` arm used to\n * return the same rect as `\"center\"`: horizontally centred, a quarter of the\n * way down. That is exactly where this app puts a route's primary column, so a\n * floating window that declared no position landed ON TOP of the one control\n * the page exists for. It was found on `/exports`, where the auto-opened\n * \"Spend so far today\" window covered the drop zone on first load and swallowed\n * clicks on \"Choose a file\" — Playwright named it: `WindowPanel … subtree\n * intercepts pointer events`. Nothing about that was specific to spend or to\n * exports; every window in the registry that omits `position` had it.\n *\n * An explicit `position: \"center\"` still centres — a window that ASKED to be in\n * the middle is making a claim about itself, and this is not the place to\n * overrule it. Only the windows nobody placed move, and they move to the right\n * gutter beside the content, cascaded so a second one is visible behind the\n * first, which is what macOS, Figma and Linear do with utility windows.\n *\n * Below `NARROW_VIEWPORT` there is no gutter to park in — the content is the\n * whole screen — so a default window is clamped to the top instead of covering\n * the middle of the page, and the mobile surfaces take over from there.\n */\nconst NARROW_VIEWPORT = 768;\n\n/** Ids of auto-opened windows docked in a gutter, so the next one stacks under them. */\nconst autoDocked = new Set<string>();\n/** Open order of auto-opened windows: a window stacks only under EARLIER ones, never chases a later one. */\nconst autoOrder = new Map<string, number>();\nlet autoOrderNext = 0;\nconst earlierDocked = (id: string) =>\n (other: { id: string; state: string }) =>\n other.id !== id &&\n other.state === \"windowed\" &&\n autoDocked.has(other.id) &&\n (autoOrder.get(other.id) ?? 0) < (autoOrder.get(id) ?? 0);\n/** Seconds an auto-opened window keeps re-checking the page's layout. */\nconst AUTO_REPLACE_TICKS = 40;\n\n/** The shell header's height (`--shell-header-h`) plus a gap; 44px fallback. */\nfunction shellHeaderClearance(): number {\n const GAP = 12;\n if (typeof document === \"undefined\") return 44 + GAP;\n const root = getComputedStyle(document.documentElement);\n const raw = root.getPropertyValue(\"--shell-header-h\").trim();\n // The shell declares it in rem (\"2.75rem\") — a bare parseFloat read 2.75px\n // and opened every window at y=15, under the header.\n const n = parseFloat(raw);\n const h = raw.endsWith(\"rem\")\n ? n * (parseFloat(root.fontSize) || 16)\n : n;\n return (Number.isFinite(h) && h > 0 ? h : 44) + GAP;\n}\n\nexport function resolvePosition(\n pos: WindowPosition | undefined,\n w: number,\n h: number,\n): { x: number; y: number } {\n const { vw, vh } = safeViewportDims();\n const pad = 40;\n // A window opening at the top CLEARS the shell header — the same way every\n // time (page-pass 2026-09-27: the Feedback window opened at y=40 under a\n // 44px header, then at y=68 on the next open).\n const top = shellHeaderClearance();\n switch (pos) {\n case \"top-left\":\n return { x: pad, y: top };\n case \"top-right\":\n return { x: Math.max(0, vw - w - pad), y: top };\n case \"bottom-left\":\n return { x: pad, y: Math.max(0, vh - h - pad) };\n case \"bottom-right\":\n return { x: Math.max(0, vw - w - pad), y: Math.max(0, vh - h - pad) };\n case \"center\":\n // Centred, but never under the shell header (a tall window centred on\n // a short screen used to open at y=20, its title bar behind the header).\n return {\n x: Math.max(0, (vw - w) / 2),\n y: Math.max(top, (vh - h) / 4),\n };\n default: {\n const cascade = nextCascadeStep();\n if (vw < NARROW_VIEWPORT) {\n return {\n x: Math.max(0, Math.min(vw - w, (vw - w) / 2)),\n y: Math.max(0, Math.min(vh - h, top + cascade)),\n };\n }\n return {\n x: Math.max(0, vw - w - pad - cascade),\n y: Math.max(0, Math.min(vh - h, top + cascade)),\n };\n }\n }\n}\n\nexport interface UseWindowPanelOptions {\n /** Stable, unique id. If omitted a React useId-based id is used. */\n id?: string | undefined;\n /** Title shown in the header and tray chip. */\n title?: string | undefined;\n /**\n * Initial width. Accepts pixels (number) or viewport strings (\"60vw\").\n * Default: 320.\n */\n width?: number | string | undefined;\n /**\n * Initial height. Accepts pixels (number) or viewport strings (\"60dvh\").\n * Default: 400.\n */\n height?: number | string | undefined;\n /** Minimum width during pointer resize. Default: 180. */\n minWidth?: number | undefined;\n /** Minimum height during pointer resize. Default: 80. */\n minHeight?: number | undefined;\n /** Where to place the window initially. Default: \"center\". */\n position?: WindowPosition | undefined;\n /** Park a brand-new desktop window in the tray without a visible flash. */\n initialState?: \"windowed\" | \"minimized\" | undefined;\n /**\n * The system (not a person) opened this window. It docks in a free gutter beside the page's\n * working column, or parks in the tray when none fits — never over the page. See\n * `utils/autoOpenPlacement.ts`. WindowPanel sets this from `markAutoOpened`.\n */\n autoOpened?: boolean | undefined;\n /**\n * MKT-104: an auto-opened window with no gutter left beside the page closes itself through this\n * instead of parking a tray card over the page's controls.\n */\n onAutoNoRoom?: (() => void) | undefined;\n /**\n * @deprecated Pass `width`, `height`, and `position` instead.\n * Low-level initial rect — overrides width/height/position when provided.\n */\n initialRect?: Partial<WindowRect> | undefined;\n /** Maximum width the user can resize to. */\n maxWidth?: number | undefined;\n /** Maximum height the user can resize to. */\n maxHeight?: number | undefined;\n /**\n * Optional callback fired when the user drags the window outside the\n * viewport long enough to count as a pop-out gesture. Caller is expected\n * to open the popout window synchronously inside the user-gesture stack\n * (i.e. without `await` before the open call).\n *\n * Pass the current rect at the time of release — the popout uses it for\n * sizing.\n *\n * `undefined` disables drag-out detection entirely. Use `undefined` for\n * popouts that aren't supported (mobile, no-capability browsers, etc.)\n * so we don't waste cycles on the per-move evaluation.\n */\n onTriggerPopout?: ((rect: WindowRect) => void) | undefined;\n /** Audited local preservation identity and initial semantic/chrome state. */\n persistence?: WindowPersistenceRegistration | undefined;\n}\n\nexport interface UseWindowPanelReturn {\n /** The stable window id. */\n id: string;\n /** Current window state from Redux. */\n windowState: \"windowed\" | \"maximized\" | \"minimized\";\n /** Current windowed rect from Redux. */\n rect: WindowRect;\n /** z-index from Redux. */\n zIndex: number;\n /** Pointerdown handler for the drag handle (header). Works with mouse + touch + pen. */\n onDragStart: (e: React.PointerEvent) => void;\n /** Pointerdown handler factory for resize handles. Works with mouse + touch + pen. */\n onResizeStart: (edge: ResizeEdge) => (e: React.PointerEvent) => void;\n /** Bring this window to the top. */\n onFocus: () => void;\n /** Transition to windowed state. */\n onRestore: () => void;\n /** Transition to maximized state. */\n onMaximize: () => void;\n /** Transition to minimized (tray) state. */\n onMinimize: () => void;\n /** Toggle maximized ↔ windowed. */\n onToggleMaximize: () => void;\n /**\n * True while the user is actively dragging or resizing with the pointer.\n * The shell disables its geometry transition during interaction so the\n * window tracks the pointer 1:1, and re-enables it for programmatic rect\n * changes (snap, arrange, minimize→tray, restore, clamp) which then glide.\n */\n isInteracting: boolean;\n}\n\n// ─── Hook ──────────────────────────────────────────────────────────────────────\n\nexport function useWindowPanel(\n opts: UseWindowPanelOptions = {},\n): UseWindowPanelReturn {\n const reactId = useId();\n const id = opts.id ?? reactId;\n\n const dispatch = useSummonDispatch();\n const store = useSummonStore();\n const entry = useSummonSelector(selectWindow(id));\n\n const minWidth = opts.minWidth ?? MIN_WIDTH;\n const minHeight = opts.minHeight ?? MIN_HEIGHT;\n const maxWidth = opts.maxWidth ?? Infinity;\n const maxHeight = opts.maxHeight ?? Infinity;\n\n // True during an active pointer drag/resize gesture — see UseWindowPanelReturn.\n const [isInteracting, setIsInteracting] = useState(false);\n\n // ── Registration ────────────────────────────────────────────────────────────\n useEffect(() => {\n const w = opts.initialRect?.width ?? resolveSize(opts.width, DEFAULT_WIDTH);\n const h =\n opts.initialRect?.height ?? resolveSize(opts.height, DEFAULT_HEIGHT);\n const { vw, vh } = safeViewportDims();\n let autoPlaced: ReturnType<typeof resolveAutoOpenPlacement> | null = null;\n if (opts.autoOpened && vw >= NARROW_VIEWPORT) {\n if (!autoOrder.has(id)) autoOrder.set(id, autoOrderNext++);\n const siblings = Object.values(store.getState().windowManager.windows)\n .filter(earlierDocked(id))\n .map((win) => win.windowed);\n autoPlaced = resolveAutoOpenPlacement({\n width: w,\n height: h,\n minWidth,\n minHeight,\n top: shellHeaderClearance(),\n viewport: { vw, vh },\n siblings,\n });\n if (!autoPlaced.minimized) autoDocked.add(id);\n else if (opts.onAutoNoRoom) window.setTimeout(() => opts.onAutoNoRoom?.(), 0);\n }\n const pos = autoPlaced\n ? { x: autoPlaced.rect.x, y: autoPlaced.rect.y }\n : opts.initialRect?.x !== undefined || opts.initialRect?.y !== undefined\n ? {\n x: opts.initialRect?.x ?? Math.max(0, (vw - w) / 2),\n y: opts.initialRect?.y ?? Math.max(0, (vh - h) / 4),\n }\n : resolvePosition(opts.position, w, h);\n const initial: WindowRect = autoPlaced\n ? { ...autoPlaced.rect }\n : { ...pos, width: w, height: h };\n dispatch(\n registerWindow({\n id,\n ...(opts.title === undefined ? {} : { title: opts.title }),\n initial,\n ...(autoPlaced?.minimized ? { initialState: \"minimized\" as const } : opts.initialState === undefined ? {} : { initialState: opts.initialState }),\n ...(opts.persistence === undefined ? {} : { persistence: opts.persistence }),\n // Sanitized dims: a degenerate 0×0 measurement must never become the\n // clamp target, or every rect collapses to garbage (see safeViewportDims).\n viewport: { width: vw, height: vh },\n }),\n );\n const pendingKey = opts.persistence\n ? windowSessionKey(\n opts.persistence.overlayId,\n opts.persistence.instanceId,\n )\n : null;\n // StrictMode mounts, cleans up, then mounts again in development. The\n // first cleanup must not consume the pending restore before the stable\n // mount gets a chance to register.\n const confirmationTimer = pendingKey\n ? window.setTimeout(() => {\n dispatch(confirmWindowRestored(pendingKey));\n }, 0)\n : null;\n return () => {\n if (confirmationTimer !== null) window.clearTimeout(confirmationTimer);\n autoDocked.delete(id);\n autoOrder.delete(id);\n dispatch(unregisterWindow(id));\n };\n }, [id]);\n\n // ── Auto-opened windows keep clear of the page while it settles ──────────────\n // The page's working column is measured at open, but a page lays itself out AFTER a run starts\n // (Smart Add grows from one field into the full card column). Re-place every second for a while\n // until the person touches the window; the page always wins the space.\n const autoTouchedRef = useRef(false);\n useEffect(() => {\n if (isInteracting) autoTouchedRef.current = true;\n }, [isInteracting]);\n useEffect(() => {\n if (!opts.autoOpened) return undefined;\n let ticks = 0;\n let lastMinimized: boolean | null = null;\n const timer = window.setInterval(() => {\n ticks += 1;\n if (ticks > AUTO_REPLACE_TICKS) {\n window.clearInterval(timer);\n return;\n }\n const win = store.getState().windowManager.windows[id];\n if (!win || autoTouchedRef.current) return;\n const { vw, vh } = safeViewportDims();\n if (vw < NARROW_VIEWPORT) return;\n const isMin = win.state === \"minimized\";\n // A change the person made (restore/minimize by hand) ends our say.\n if (lastMinimized !== null && isMin !== lastMinimized) {\n autoTouchedRef.current = true;\n return;\n }\n if (win.state !== \"windowed\" && !isMin) return;\n const siblings = Object.values(store.getState().windowManager.windows)\n .filter(earlierDocked(id))\n .map((o) => o.windowed);\n const next = resolveAutoOpenPlacement({\n width: win.windowed.width,\n height: win.windowed.height,\n minWidth,\n minHeight,\n top: shellHeaderClearance(),\n viewport: { vw, vh },\n siblings,\n });\n if (next.minimized) {\n autoDocked.delete(id);\n if (opts.onAutoNoRoom) {\n window.clearInterval(timer);\n opts.onAutoNoRoom();\n return;\n }\n if (!isMin) {\n dispatch(minimizeWindow({ id, viewportWidth: vw, viewportHeight: vh }));\n }\n lastMinimized = true;\n return;\n }\n autoDocked.add(id);\n if (isMin) dispatch(restoreWindow(id));\n const cur = store.getState().windowManager.windows[id]?.windowed;\n if (\n !cur ||\n Math.abs(cur.x - next.rect.x) > 4 ||\n Math.abs(cur.y - next.rect.y) > 4 ||\n Math.abs(cur.width - next.rect.width) > 4 ||\n Math.abs(cur.height - next.rect.height) > 4\n ) {\n dispatch(updateWindowRect({ id, rect: next.rect }));\n }\n lastMinimized = false;\n }, 1000);\n return () => window.clearInterval(timer);\n }, [opts.autoOpened, id, minWidth, minHeight, store, dispatch]);\n\n // ── Keep title in sync if it changes after mount ─────────────────────────\n useEffect(() => {\n if (opts.title !== undefined) {\n dispatch(updateWindowTitle({ id, title: opts.title }));\n }\n }, [id, opts.title, dispatch]);\n\n // ── Drag-to-move (pointer events — works for mouse + touch + pen) ──────────\n const dragStart = useRef<{\n mx: number;\n my: number;\n wx: number;\n wy: number;\n } | null>(null);\n\n const onTriggerPopout = opts.onTriggerPopout;\n const onTriggerPopoutRef = useRef(onTriggerPopout);\n useEffect(() => {\n onTriggerPopoutRef.current = onTriggerPopout;\n }, [onTriggerPopout]);\n\n const onDragStart = useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n dispatch(focusWindow(id));\n // Allow drag in windowed AND minimized states (maximized is handled by header)\n if (!entry || entry.state === \"maximized\") return;\n dragStart.current = {\n mx: e.clientX,\n my: e.clientY,\n wx: entry.windowed.x,\n wy: entry.windowed.y,\n };\n setIsInteracting(true);\n // THE CURSOR LAW: `grabbing` on <html> for the whole drag, so it never\n // flickers as the pointer outruns the header.\n const releaseCursor = holdDragCursor();\n\n // Per-drag local state for drag-out detection. Only allocated/used\n // when popout is enabled for this window.\n let dragOutState: DragOutState = INITIAL_DRAG_OUT_STATE;\n // Snapshot rect at release for the popout sizing — drag updates rect\n // continuously, so we capture x/y/w/h at gesture-end.\n let lastClientX = e.clientX;\n let lastClientY = e.clientY;\n const popoutEnabled = onTriggerPopoutRef.current !== undefined;\n\n const onMove = (ev: PointerEvent) => {\n if (!dragStart.current) return;\n const nx = dragStart.current.wx + (ev.clientX - dragStart.current.mx);\n const ny = dragStart.current.wy + (ev.clientY - dragStart.current.my);\n dispatch(updateWindowRect({ id, rect: { x: nx, y: ny } }));\n lastClientX = ev.clientX;\n lastClientY = ev.clientY;\n\n // Drag-out detection — only run the evaluator when popout is wired.\n if (!popoutEnabled) return;\n const result = evaluateDragOut(\n { clientX: ev.clientX, clientY: ev.clientY },\n dragOutState,\n DEFAULT_DRAG_OUT_CONFIG,\n window.innerWidth,\n window.innerHeight,\n performance.now(),\n );\n // Only dispatch on candidate-state changes to avoid spamming Redux\n // with identical actions every pointermove.\n if (result.state.isCandidate !== dragOutState.isCandidate) {\n dispatch(\n setPopoutCandidate({ id: result.state.isCandidate ? id : null }),\n );\n }\n dragOutState = result.state;\n };\n\n const onUp = () => {\n const wasCandidate = dragOutState.isCandidate;\n const dragOrigin = dragStart.current;\n dragStart.current = null;\n setIsInteracting(false);\n releaseCursor();\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onUp);\n document.removeEventListener(\"pointercancel\", onUp);\n\n // Always clear candidate flag on release — even if popout fires,\n // the visual feedback should disappear immediately.\n if (popoutEnabled && dragOutState.isCandidate) {\n dispatch(setPopoutCandidate({ id: null }));\n }\n\n // Trigger popout if release happened in candidate state.\n // Run synchronously inside the pointerup user-gesture stack so the\n // browser accepts the requestWindow / window.open call.\n if (wasCandidate && onTriggerPopoutRef.current && entry) {\n // Use the LAST rect we computed during the drag — the user has\n // visually placed the window at that position, even though the\n // popout will appear at OS-controlled coordinates.\n const lastRect: WindowRect = {\n x: dragOrigin?.wx ?? entry.windowed.x,\n y: dragOrigin?.wy ?? entry.windowed.y,\n width: entry.windowed.width,\n height: entry.windowed.height,\n };\n onTriggerPopoutRef.current(lastRect);\n } else {\n // Off-screen rescue: if the user released the drag outside the\n // viewport without triggering a popout (e.g. they dragged past\n // the edge but not far enough / long enough to dwell, or popout\n // was unavailable), pull the complete window back into bounds.\n // The clamp reducer is a no-op when rect is already in bounds, so\n // this is cheap to dispatch unconditionally.\n const { vw, vh, degenerate } = safeViewportDims();\n if (!degenerate) {\n dispatch(\n clampWindowRect({ id, viewportWidth: vw, viewportHeight: vh }),\n );\n }\n }\n // Suppress unused-var lint on lastClientX/Y — they're tracked for\n // potential future telemetry (drag distance, exit edge, etc.)\n void lastClientX;\n void lastClientY;\n };\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onUp);\n document.addEventListener(\"pointercancel\", onUp);\n },\n [dispatch, id, entry],\n );\n\n // ── Resize (pointer events — works for mouse + touch + pen) ────────────────\n const onResizeStart = useCallback(\n (edge: ResizeEdge) => (e: React.PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n dispatch(focusWindow(id));\n if (!entry || entry.state !== \"windowed\") return;\n\n const startMx = e.clientX;\n const startMy = e.clientY;\n const { x, y, width, height } = entry.windowed;\n setIsInteracting(true);\n // THE CURSOR LAW: the edge's resize cursor holds on <html> until release.\n const releaseCursor = holdDragCursor(RESIZE_CURSOR[edge]);\n\n const onMove = (ev: PointerEvent) => {\n const dx = ev.clientX - startMx;\n const dy = ev.clientY - startMy;\n let nx = x,\n ny = y,\n nw = width,\n nh = height;\n\n if (edge.includes(\"e\"))\n nw = Math.min(maxWidth, Math.max(minWidth, width + dx));\n if (edge.includes(\"s\"))\n nh = Math.min(maxHeight, Math.max(minHeight, height + dy));\n if (edge.includes(\"w\")) {\n nw = Math.min(maxWidth, Math.max(minWidth, width - dx));\n nx = x + (width - nw);\n }\n if (edge.includes(\"n\")) {\n nh = Math.min(maxHeight, Math.max(minHeight, height - dy));\n ny = y + (height - nh);\n }\n\n dispatch(\n updateWindowRect({\n id,\n rect: { x: nx, y: ny, width: nw, height: nh },\n }),\n );\n };\n\n const onUp = () => {\n setIsInteracting(false);\n releaseCursor();\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onUp);\n document.removeEventListener(\"pointercancel\", onUp);\n };\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onUp);\n document.addEventListener(\"pointercancel\", onUp);\n },\n [dispatch, id, entry, minWidth, minHeight, maxWidth, maxHeight],\n );\n\n // ── Window state transitions ───────────────────────────────────────────────\n const onFocus = useCallback(() => dispatch(focusWindow(id)), [dispatch, id]);\n const onRestore = useCallback(\n () => dispatch(restoreWindow(id)),\n [dispatch, id],\n );\n const onMaximize = useCallback(\n () => dispatch(maximizeWindow(id)),\n [dispatch, id],\n );\n const onMinimize = useCallback(() => {\n const { vw, vh } = safeViewportDims();\n dispatch(\n minimizeWindow({ id, viewportWidth: vw, viewportHeight: vh }),\n );\n }, [dispatch, id]);\n const onToggleMaximize = useCallback(() => {\n if (entry?.state === \"maximized\") dispatch(restoreWindow(id));\n else dispatch(maximizeWindow(id));\n }, [dispatch, id, entry]);\n\n // ── Stable fallback rect before first render ───────────────────────────────\n const rect: WindowRect = entry?.windowed ?? {\n x: 0,\n y: 0,\n width: opts.initialRect?.width ?? resolveSize(opts.width, DEFAULT_WIDTH),\n height:\n opts.initialRect?.height ?? resolveSize(opts.height, DEFAULT_HEIGHT),\n };\n\n return {\n id,\n windowState: entry?.state ?? \"windowed\",\n rect,\n zIndex: entry?.zIndex ?? 1000,\n onDragStart,\n onResizeStart,\n onFocus,\n onRestore,\n onMaximize,\n onMinimize,\n onToggleMaximize,\n isInteracting,\n };\n}\n","/**\n * popoutDragDetector — pure logic for \"is the user dragging this window\n * out of the viewport hard enough to mean they want to pop it out?\"\n *\n * **Threshold strategy:**\n * 1. Cursor must cross outside the viewport rect, AND\n * 2. Cursor must be at least `outsideThreshold` pixels past the edge\n * (a deliberate intent signal, not a stray mouse twitch), AND\n * 3. Cursor must DWELL outside for at least `dwellMs` milliseconds\n * (filters out drags that just transit through the edge en route\n * to a different on-screen position).\n *\n * The dwell timer resets every time the cursor crosses back inside the\n * viewport — a glance outside doesn't latch the candidate state.\n *\n * **Return shape:**\n * - `state` — the next `DragOutState` (replaces the previous on the next call)\n * - `shouldTrigger` — true when the dwell threshold has just been met. The\n * caller should fire popout on `pointerup`, NOT on this flag — the flag\n * is purely for animation/visual feedback (`isCandidate`).\n *\n * Pure function: no DOM access, no side effects. Easy to unit test.\n */\n\nexport interface DragOutConfig {\n /** Pixels past the viewport edge before considering the drag \"outside\". */\n outsideThreshold: number;\n /** Milliseconds the cursor must remain outside before becoming a candidate. */\n dwellMs: number;\n}\n\nexport interface DragOutState {\n /** Whether the dwell threshold is currently met (drives visual feedback). */\n isCandidate: boolean;\n /**\n * `performance.now()` timestamp when the cursor first crossed `outsideThreshold`.\n * `null` when the cursor is currently inside (or hasn't been outside yet).\n */\n outsideSinceMs: number | null;\n}\n\nexport interface DragOutInput {\n clientX: number;\n clientY: number;\n}\n\nexport interface DragOutEvalResult {\n state: DragOutState;\n /**\n * Edge-trigger: `true` ONLY on the first call where `isCandidate` flips\n * from `false` to `true`. Useful if a caller wants to dispatch a one-shot\n * action (e.g. haptic) on candidate entry.\n */\n shouldTrigger: boolean;\n}\n\nexport const DEFAULT_DRAG_OUT_CONFIG: DragOutConfig = {\n outsideThreshold: 80,\n dwellMs: 250,\n};\n\nexport const INITIAL_DRAG_OUT_STATE: DragOutState = {\n isCandidate: false,\n outsideSinceMs: null,\n};\n\n/**\n * Evaluate one pointermove event against the previous drag-out state.\n *\n * @param e Pointer event coords (clientX/clientY are viewport-relative)\n * @param prev Previous state from the last call (or `INITIAL_DRAG_OUT_STATE`)\n * @param cfg Threshold config\n * @param vpW Current `window.innerWidth`\n * @param vpH Current `window.innerHeight`\n * @param now Current `performance.now()` reading\n */\nexport function evaluateDragOut(\n e: DragOutInput,\n prev: DragOutState,\n cfg: DragOutConfig,\n vpW: number,\n vpH: number,\n now: number,\n): DragOutEvalResult {\n const { clientX, clientY } = e;\n const { outsideThreshold, dwellMs } = cfg;\n\n // Compute \"how far past the edge\" in each direction. Positive number = past\n // the edge by that many pixels.\n const pastLeft = -clientX; // clientX < 0 → past left edge\n const pastRight = clientX - vpW; // clientX > vpW → past right edge\n const pastTop = -clientY;\n const pastBottom = clientY - vpH;\n const maxPast = Math.max(pastLeft, pastRight, pastTop, pastBottom);\n\n const isOutsideEnough = maxPast >= outsideThreshold;\n\n if (!isOutsideEnough) {\n // Cursor is inside the viewport (or within the threshold band) — reset.\n if (prev.isCandidate || prev.outsideSinceMs !== null) {\n return {\n state: { isCandidate: false, outsideSinceMs: null },\n shouldTrigger: false,\n };\n }\n return { state: prev, shouldTrigger: false };\n }\n\n // Cursor is past the threshold. Two sub-cases:\n // a) we just crossed the threshold this frame → start the dwell timer\n // b) we've been outside for a while → check if dwell is met\n const outsideSince = prev.outsideSinceMs ?? now;\n const dwellMet = now - outsideSince >= dwellMs;\n const wasCandidate = prev.isCandidate;\n const nowCandidate = dwellMet;\n\n return {\n state: { isCandidate: nowCandidate, outsideSinceMs: outsideSince },\n shouldTrigger: !wasCandidate && nowCandidate,\n };\n}\n","/**\n * AUTO-OPENED WINDOW PLACEMENT (MKT-104, Arman 2026-10-15).\n *\n * Some windows open by themselves (debug mode's Workflow run + Watch AI windows) so a person can\n * watch progress live. They must NEVER cover the page's working column or take its clicks. This\n * is the ONE place that decides where such a window goes, for every window that is opened by the\n * system rather than by a person:\n *\n * 1. The caller marks the open with `markAutoOpened(overlayId, instanceId)` (see\n * `features/overlays/openers/openAutoOverlay.ts`); `WindowPanel` consumes the mark.\n * 2. The working column is measured from the page itself: the bounds of every visible control\n * (button, link, field) in the page body. Anything outside that box takes no clicks anyway.\n * 3. The window is docked in the widest free side gutter, shrunk to fit, stacked under any other\n * auto-opened window already there. No gutter wide enough (a narrow screen, a page that\n * fills the width) → it is not opened (`autoOpenHasRoom`), or, when the page grew under it,\n * it closes itself. A person's own press of Watch AI / Workflow run always opens it.\n *\n * Pure module: no Redux import (WindowPanel stays a leaf).\n */\n\nimport type { WindowRect } from \"@ai-matrx/summon\";\n\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\nconst GAP = 12;\nconst SIBLING_GAP = 8;\n/** Narrowest window worth docking; anything tighter goes to the tray. */\nexport const AUTO_OPEN_MIN_WIDTH = 280;\n\nfunction marks(): Set<string> {\n return globalSlot<Set<string>>(\"ai-matrx.summon.window.autoOpenedMarks\", () => new Set<string>());\n}\n\nconst markKey = (overlayId: string, instanceId: string) =>\n `${overlayId}::${instanceId}`;\n\n/** Call BEFORE dispatching the open of a window the system (not a person) opens. */\nexport function markAutoOpened(overlayId: string, instanceId: string): void {\n marks().add(markKey(overlayId, instanceId));\n}\n\n/** Peek (does not consume, so StrictMode's double render sees the same answer). */\nexport function isAutoOpened(overlayId: string, instanceId: string): boolean {\n return marks().has(markKey(overlayId, instanceId));\n}\n\n/** Forget the mark once the window is gone: a person's later reopen places normally. */\nexport function clearAutoOpened(overlayId: string, instanceId: string): void {\n marks().delete(markKey(overlayId, instanceId));\n}\n\n/** Width the shell's canvas column holds on the right (`--shell-canvas-w`): no window may dock under it. */\nfunction canvasWidth(): number {\n if (typeof document === \"undefined\") return 0;\n const raw = getComputedStyle(document.documentElement).getPropertyValue(\"--shell-canvas-w\");\n const px = Number.parseFloat(raw);\n return Number.isFinite(px) && px > 0 ? px : 0;\n}\n\nconst CONTROL_SELECTOR =\n 'button, a[href], input, textarea, select, [role=\"button\"], [role=\"tab\"], [data-clickable]';\n\n/** Left/right edge of everything on the page body that takes a click. */\nexport function measureWorkingColumn(): { left: number; right: number } | null {\n if (typeof document === \"undefined\") return null;\n const root =\n document.querySelector<HTMLElement>(\"[data-matrx-page-scroll]\") ??\n document.querySelector<HTMLElement>(\"main\") ??\n document.querySelector<HTMLElement>(\".shell-main\");\n if (!root) return null;\n const rootRect = root.getBoundingClientRect();\n let left = Infinity;\n let right = -Infinity;\n const nodes = root.querySelectorAll<HTMLElement>(CONTROL_SELECTOR);\n const limit = Math.min(nodes.length, 600);\n for (let i = 0; i < limit; i += 1) {\n const el = nodes[i];\n if (!el) continue;\n // Skip controls inside floating windows themselves.\n if (el.closest(\"[data-window-panel], [data-matrx-window]\")) continue;\n const r = el.getBoundingClientRect();\n if (r.width < 8 || r.height < 8) continue;\n if (r.bottom < rootRect.top || r.top > rootRect.bottom) continue;\n if (r.right < 0 || r.left > window.innerWidth) continue;\n left = Math.min(left, r.left);\n right = Math.max(right, r.right);\n }\n return Number.isFinite(left) ? { left, right } : null;\n}\n\n/** Fired (detail `{ overlayId, instanceId }`) when a docked auto-opened window closes itself for lack of room. */\nexport const AUTO_OPEN_NO_ROOM_EVENT = \"matrx:auto-open-no-room\";\n\n/**\n * True when a gutter beside the page's working column can hold an auto-opened window right now.\n * Callers that open windows by themselves check this FIRST: with no room the window is not opened\n * (a parked tray tile sits over the page's own bottom-right controls — MKT-104).\n */\nexport function autoOpenHasRoom(): boolean {\n if (typeof window === \"undefined\") return false;\n const vw = window.innerWidth;\n if (vw < 768) return false;\n const column = measureWorkingColumn();\n if (!column) return true;\n const leftRoot =\n document.querySelector<HTMLElement>(\"main\")?.getBoundingClientRect().left ?? 0;\n const free = Math.max(vw - canvasWidth() - column.right - GAP * 2, column.left - leftRoot - GAP * 2);\n return free >= AUTO_OPEN_MIN_WIDTH;\n}\n\nexport interface AutoOpenPlacement {\n rect: WindowRect;\n /** True when no gutter fits: open parked in the tray instead of over the page. */\n minimized: boolean;\n}\n\n/**\n * @param siblings rects of auto-opened windows already docked (to stack under them)\n */\nexport function resolveAutoOpenPlacement(args: {\n width: number;\n height: number;\n minWidth: number;\n minHeight: number;\n top: number;\n viewport: { vw: number; vh: number };\n siblings: WindowRect[];\n}): AutoOpenPlacement {\n const { vh } = args.viewport;\n // The canvas column owns the right edge: windows dock against ITS left edge, never under it.\n const vw = args.viewport.vw - canvasWidth();\n const column = measureWorkingColumn();\n const rightFree = column ? vw - column.right - GAP * 2 : vw;\n const leftRoot =\n typeof document !== \"undefined\"\n ? (document.querySelector<HTMLElement>(\"main\")?.getBoundingClientRect()\n .left ?? 0)\n : 0;\n const leftFree = column ? column.left - leftRoot - GAP * 2 : 0;\n const side = rightFree >= leftFree ? \"right\" : \"left\";\n const free = Math.max(rightFree, leftFree);\n const need = Math.min(args.minWidth, AUTO_OPEN_MIN_WIDTH);\n const parked: AutoOpenPlacement = {\n rect: {\n x: Math.max(GAP, vw - args.width - GAP),\n y: args.top,\n width: args.width,\n height: args.height,\n },\n minimized: true,\n };\n if (free < need) return parked;\n\n const width = Math.max(need, Math.min(args.width, Math.floor(free)));\n const x =\n side === \"right\"\n ? vw - width - GAP\n : Math.max(GAP, Math.round(leftRoot + GAP));\n // Stack below the lowest sibling in this gutter.\n const inGutter = args.siblings.filter(\n (s) => s.x + s.width > x && s.x < x + width,\n );\n const y = inGutter.length\n ? Math.max(...inGutter.map((s) => s.y + s.height)) + SIBLING_GAP\n : args.top;\n const room = vh - y - GAP;\n if (room < args.minHeight) return parked;\n const share = inGutter.length ? room : Math.floor((vh - args.top - GAP) / 2);\n const height = Math.min(room, Math.max(args.minHeight, Math.min(args.height, share)));\n return { rect: { x, y, width, height }, minimized: false };\n}\n","import { useSyncExternalStore } from \"react\";\n\nconst subscribe = (): (() => void) => () => {};\n\n/** False during server render and hydration, true on the client afterwards. */\nexport function useIsClient(): boolean {\n return useSyncExternalStore(subscribe, () => true, () => false);\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { DebugPort } from \"@ai-matrx/summon\";\n\nconst noSubscribe = (): (() => void) => () => {};\n\n/** The host's debug flag (ports.debug), live when the port can be subscribed to. */\nexport function useDebugFlag(debug: DebugPort): boolean {\n return useSyncExternalStore(\n debug.subscribe ? (listener) => debug.subscribe?.(listener) ?? (() => {}) : noSubscribe,\n () => debug.enabled(),\n () => false,\n );\n}\n","/**\n * Resolve the URL token a mounted window publishes.\n *\n * Registry metadata is the shared contract between the URL hydrator and the\n * mounted window. Page-local WindowPanels without registry metadata may still\n * provide an explicit key.\n */\nexport function resolveWindowUrlSyncKey(\n registryKey?: string,\n explicitKey?: string,\n): string | undefined {\n return registryKey ?? explicitKey;\n}\n","/**\n * Copy only allowlisted keys of a window's open/collected data into plain JSON (the preservation\n * allowlist, `window.preservation.dataKeys`). Functions, symbols, undefined and circular references\n * are dropped; BigInt becomes text; non-finite numbers become null; Dates become ISO text; class\n * instances are dropped. Same semantics as matrx-frontend's `sanitizeWindowSessionData`.\n */\nconst DROPPED = Symbol(\"dropped-window-value\");\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function sanitizeWindowData(value: unknown, allowedKeys: readonly string[]): Record<string, unknown> {\n if (!isRecord(value) || allowedKeys.length === 0) return {};\n const ancestors = new WeakSet<object>();\n const copy = (item: unknown): unknown => {\n if (item === undefined || typeof item === \"function\" || typeof item === \"symbol\") return DROPPED;\n if (typeof item === \"bigint\") return item.toString();\n if (typeof item === \"number\" && !Number.isFinite(item)) return null;\n if (item === null || typeof item !== \"object\") return item;\n if (item instanceof Date) return item.toJSON();\n if (ancestors.has(item)) return DROPPED;\n ancestors.add(item);\n let result: unknown;\n if (Array.isArray(item)) {\n result = item.map((child) => {\n const copied = copy(child);\n return copied === DROPPED ? null : copied;\n });\n } else if (Object.getPrototypeOf(item) === Object.prototype || Object.getPrototypeOf(item) === null) {\n result = Object.fromEntries(\n Object.entries(item).flatMap(([key, child]) => {\n const copied = copy(child);\n return copied === DROPPED ? [] : [[key, copied]];\n }),\n );\n } else {\n result = DROPPED;\n }\n ancestors.delete(item);\n return result;\n };\n try {\n const allowed = new Set(allowedKeys);\n const selected = Object.fromEntries(Object.entries(value).filter(([key]) => allowed.has(key)));\n ancestors.add(value);\n const copied = copy(selected);\n const parsed: unknown = JSON.parse(JSON.stringify(copied === DROPPED ? {} : copied) || \"{}\");\n return isRecord(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n","\"use client\";\n\n/**\n * MobileDrawerSurface — mobile presentation for a window with\n * `mobilePresentation: \"drawer\"`.\n *\n * Replaces WindowPanel's usual fullscreen mobile branch with a bottom-sheet\n * drawer (vaul) that:\n * - Opens to ~80% viewport height, user-draggable to resize.\n * - Hides drag/resize handles entirely (vaul owns interaction).\n * - Renders the sidebar content inside a nested drawer when present so\n * there's no 50/50 squeeze on narrow screens.\n * - Preserves the footer zone at the bottom of the drawer.\n *\n * Called only when `useIsMobile()` is true; on desktop the normal\n * WindowPanel shell renders instead.\n */\nimport { useState, type ReactNode } from \"react\";\nimport {\n Drawer,\n DrawerClose,\n DrawerContent,\n DrawerDescription,\n DrawerTitle,\n} from \"@ai-matrx/design-system\";\nimport { Button } from \"@ai-matrx/design-system\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { PanelLeftIcon as SidebarIcon, XIcon as X } from \"../icons\";\nimport {\n MobileWindowActionsRow,\n MobileWindowTitleRow,\n mobileWindowTitleClass,\n} from \"../chrome/MobileTitleRow\";\n\ninterface MobileDrawerSurfaceProps {\n title: ReactNode;\n children: ReactNode;\n onClose: () => void;\n sidebar?: ReactNode | undefined;\n footer?: ReactNode | undefined;\n /** Open state — mirrors the parent's overlay-isOpen flag. */\n isOpen: boolean;\n actionsLeft?: ReactNode | undefined;\n actionsRight?: ReactNode | undefined;\n /** Optional className applied to the body scroll container. */\n bodyClassName?: string | undefined;\n /** Marks the root `data-surface-layer` (see WindowPanel `surfaceLayer`). */\n surfaceLayer?: string | undefined;\n /**\n * Size the sheet to its content (capped at 85dvh) instead of a fixed 85dvh:\n * a short form no longer sits on a band of empty sheet.\n */\n sizeToContent?: boolean | undefined;\n /** No title-row ✕: the drag handle and the window's own Cancel dismiss it. */\n hideClose?: boolean | undefined;\n /**\n * Whether the sidebar should collapse into a nested drawer when the user\n * taps the sidebar toggle. When \"inline\", the sidebar pushes the body\n * instead. Default: \"drawer\".\n */\n sidebarAs?: \"drawer\" | \"inline\" | undefined;\n}\n\nexport default function MobileDrawerSurface({\n title,\n children,\n onClose,\n sidebar,\n footer,\n isOpen,\n actionsLeft,\n actionsRight,\n bodyClassName,\n surfaceLayer,\n sizeToContent = false,\n hideClose = false,\n sidebarAs = \"drawer\",\n}: MobileDrawerSurfaceProps) {\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const hasSidebar = !!sidebar;\n\n return (\n <Drawer\n open={isOpen}\n onOpenChange={(next) => {\n if (!next) onClose();\n }}\n >\n <DrawerContent\n data-surface-layer={surfaceLayer}\n className={cn(\n \"max-h-[85dvh] px-0 pb-safe flex flex-col\",\n sizeToContent ? \"h-auto\" : \"h-[85dvh]\",\n )}\n >\n {/* Accessible title — rendered visually as our header */}\n {/* The handle row above is a 44px drag area with the bar at its\n centre; the header tucks into its lower half (no second padded\n band — the title sat 40px under the handle). */}\n <div className=\"-mt-3 flex flex-col px-3 border-b border-border/50 shrink-0\">\n {/* Row 1 is the title's alone and wraps to two lines before it\n truncates; actions + the sidebar toggle sit on row 2\n (MobileTitleRow.tsx). */}\n <MobileWindowTitleRow\n className=\"py-0\"\n trailing={\n hideClose ? null : (\n <DrawerClose asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 shrink-0\"\n aria-label=\"Close\"\n >\n <X className=\"w-4 h-4\" />\n </Button>\n </DrawerClose>\n )\n }\n >\n <DrawerTitle\n data-window-mobile-title=\"\"\n className={mobileWindowTitleClass(title)}\n >\n {title}\n </DrawerTitle>\n </MobileWindowTitleRow>\n <MobileWindowActionsRow\n leading={\n actionsLeft ? (\n <div className=\"flex items-center gap-1 shrink-0\">{actionsLeft}</div>\n ) : null\n }\n actions={\n actionsRight || hasSidebar ? (\n <>\n {actionsRight}\n {hasSidebar && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n aria-label={sidebarOpen ? \"Close sidebar\" : \"Open sidebar\"}\n onClick={() => setSidebarOpen((v) => !v)}\n >\n <SidebarIcon className=\"w-4 h-4\" />\n </Button>\n )}\n </>\n ) : null\n }\n />\n </div>\n\n {/* Screen-reader description; invisible visually */}\n <DrawerDescription className=\"sr-only\">\n {typeof title === \"string\" ? title : \"Mobile window\"}\n </DrawerDescription>\n\n {/* Body + optional inline sidebar. If sidebarAs === \"drawer\", the\n sidebar opens in a nested Drawer instead. */}\n <div className=\"flex-1 flex min-h-0 overflow-hidden\">\n {hasSidebar && sidebarAs === \"inline\" && sidebarOpen && (\n <div className=\"w-2/5 min-w-[160px] border-r border-border/50 overflow-y-auto\">\n {sidebar}\n </div>\n )}\n <div\n className={cn(\n \"flex-1 min-h-0 overflow-auto\",\n bodyClassName,\n )}\n >\n {children}\n </div>\n </div>\n\n {footer && (\n <div className=\"border-t border-border/50 shrink-0\">{footer}</div>\n )}\n </DrawerContent>\n\n {/* Nested sidebar drawer (sidebarAs === \"drawer\") */}\n {hasSidebar && sidebarAs === \"drawer\" && (\n <Drawer\n open={sidebarOpen}\n onOpenChange={setSidebarOpen}\n direction=\"right\"\n >\n <DrawerContent className=\"h-[85dvh] max-h-[85dvh] w-[85vw] max-w-[420px] ml-auto flex flex-col\">\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border/50 shrink-0\">\n <DrawerTitle className=\"flex-1 text-sm font-medium\">\n Menu\n </DrawerTitle>\n <DrawerClose asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n aria-label=\"Close sidebar\"\n >\n <X className=\"w-4 h-4\" />\n </Button>\n </DrawerClose>\n </div>\n <DrawerDescription className=\"sr-only\">\n Sidebar menu\n </DrawerDescription>\n <div className=\"flex-1 min-h-0 overflow-auto\">{sidebar}</div>\n </DrawerContent>\n </Drawer>\n )}\n </Drawer>\n );\n}\n","\"use client\";\n\n/**\n * THE PHONE TITLE ROW — the one title slot every mobile window chrome uses\n * (fullscreen header, bottom-sheet drawer, utility card).\n *\n * On a phone the title is the only thing that says WHICH record this window\n * is (\"Run History — Recipe Scaler\"), so it gets the whole row and wraps to\n * two lines before it truncates. Window actions and the Sidebar/Content toggle\n * never share its row: they sit on `MobileWindowActionsRow` below it, which\n * renders nothing when there is nothing to put there.\n *\n * Guard: `__tests__/a-phone-window-title-gets-the-whole-row.test.tsx`.\n */\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\n/** Two lines, then an ellipsis — never a one-line `truncate`. */\nexport const MOBILE_WINDOW_TITLE_TEXT =\n \"line-clamp-2 break-words text-sm font-medium leading-snug text-foreground\";\n\nfunction isTextTitle(title: ReactNode): title is string | number {\n return typeof title === \"string\" || typeof title === \"number\";\n}\n\n/**\n * The title slot's classes. A text title wraps to two lines; a RICH title (a\n * control, e.g. the Chat window's agent picker) keeps its own layout. Exported\n * for a host whose title element is fixed (the drawer's accessible\n * `DrawerTitle`) — put these classes and `data-window-mobile-title` on it.\n */\nexport function mobileWindowTitleClass(title: ReactNode): string {\n return isTextTitle(title)\n ? cn(\"min-w-0 flex-1\", MOBILE_WINDOW_TITLE_TEXT)\n : \"flex min-w-0 flex-1 items-center overflow-hidden text-sm font-medium\";\n}\n\n/** The title slot. */\nexport function MobileWindowTitle({\n title,\n className,\n}: {\n title: ReactNode;\n className?: string | undefined;\n}) {\n if (title == null || title === \"\") return <div className={cn(\"min-w-0 flex-1\", className)} />;\n return (\n <div data-window-mobile-title=\"\" className={cn(mobileWindowTitleClass(title), className)}>\n {title}\n </div>\n );\n}\n\n/** Row 1: whatever leads (close / minimize) and the title, nothing else. */\nexport function MobileWindowTitleRow({\n leading,\n trailing,\n children,\n className,\n}: {\n leading?: ReactNode | undefined;\n /** A close ✕ only — never window actions. */\n trailing?: ReactNode | undefined;\n children: ReactNode;\n className?: string | undefined;\n}) {\n return (\n <div\n data-window-mobile-title-row=\"\"\n className={cn(\"flex min-h-11 items-center gap-1.5 py-1\", className)}\n >\n {leading}\n {children}\n {trailing}\n </div>\n );\n}\n\n/** Row 2: pane toggle + window actions. Absent when both are empty. */\nexport function MobileWindowActionsRow({\n leading,\n actions,\n className,\n}: {\n leading?: ReactNode | undefined;\n actions?: ReactNode | undefined;\n className?: string | undefined;\n}) {\n if (!leading && !actions) return null;\n return (\n <div\n data-window-mobile-actions-row=\"\"\n className={cn(\"flex min-h-10 items-center gap-1.5 pb-1\", className)}\n >\n {leading}\n {actions ? <div className=\"ml-auto flex items-center gap-1\">{actions}</div> : null}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * MobileCardSurface — mobile presentation for a window with\n * `mobilePresentation: \"card\"`.\n *\n * Small, z-stacked floating card anchored to the bottom-right of the\n * viewport. Used for utility/debug windows (Stream Debug, State Analyzer,\n * Message Analysis, JSON Truncator) that only need a peek view on mobile.\n *\n * Differences from MobileDrawerSurface:\n * - Non-modal: the underlying content remains interactive.\n * - Compact default size (w-[92vw] max-w-[420px], h-[60dvh]).\n * - Dismiss on outside tap, Escape, or X button.\n * - No sidebar support (these windows don't need one).\n */\nimport { useEffect, useRef, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { FloatingLayer, useFloatingLayerZIndex } from \"@ai-matrx/design-system\";\nimport { Button } from \"@ai-matrx/design-system\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { XIcon as X } from \"../icons\";\nimport {\n MobileWindowActionsRow,\n MobileWindowTitle,\n MobileWindowTitleRow,\n} from \"../chrome/MobileTitleRow\";\n\ninterface MobileCardSurfaceProps {\n title: ReactNode;\n children: ReactNode;\n onClose: () => void;\n footer?: ReactNode | undefined;\n isOpen: boolean;\n actionsRight?: ReactNode | undefined;\n bodyClassName?: string | undefined;\n /** Marks the root `data-surface-layer` (see WindowPanel `surfaceLayer`). */\n surfaceLayer?: string | undefined;\n /** Override the default max-height (60dvh). Accepts any CSS length. */\n maxHeight?: string | undefined;\n}\n\nexport default function MobileCardSurface({\n title,\n children,\n onClose,\n footer,\n isOpen,\n actionsRight,\n bodyClassName,\n surfaceLayer,\n maxHeight = \"60dvh\",\n}: MobileCardSurfaceProps) {\n const cardRef = useRef<HTMLDivElement>(null);\n\n // Escape to close\n useEffect(() => {\n if (!isOpen) return undefined;\n const onKey = (e: KeyboardEvent) => {\n // One Escape closes ONE layer (a menu inside already took it).\n if (e.key === \"Escape\" && !e.defaultPrevented) onClose();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [isOpen, onClose]);\n\n // Opened from inside a blocking sheet (every Dialog is one on a phone), the\n // card is lifted above its scrim (design-system floating-layer).\n const zIndex = useFloatingLayerZIndex(9999);\n\n if (!isOpen) return null;\n if (typeof document === \"undefined\") return null;\n\n return createPortal(\n <FloatingLayer>\n <div\n ref={cardRef}\n data-surface-layer={surfaceLayer}\n role=\"dialog\"\n aria-modal=\"false\"\n className={cn(\n \"fixed right-3 bottom-3 left-3 sm:left-auto sm:right-3\",\n \"w-auto sm:w-[92vw] sm:max-w-[420px]\",\n \"flex flex-col\",\n \"rounded-xl overflow-hidden\",\n \"bg-card/97 backdrop-blur-xl border border-border/60 shadow-2xl\",\n // Themes can override via --window-surface-* tokens in globals.css\n \"animate-[card-enter_var(--window-surface-enter-duration,220ms)_var(--window-surface-easing,ease-out)]\",\n )}\n style={{ maxHeight, zIndex, paddingBottom: \"env(safe-area-inset-bottom)\" }}\n >\n {/* Header — the title owns row 1 (two lines before it truncates);\n actions sit on their own row below (MobileTitleRow.tsx). */}\n <div className=\"flex flex-col pl-3 pr-1 border-b border-border/50 shrink-0\">\n <MobileWindowTitleRow\n trailing={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-11 w-11 shrink-0\"\n aria-label=\"Close\"\n onClick={onClose}\n >\n <X className=\"w-3.5 h-3.5\" />\n </Button>\n }\n >\n <MobileWindowTitle title={title} />\n </MobileWindowTitleRow>\n <MobileWindowActionsRow actions={actionsRight} />\n </div>\n\n {/* Body */}\n <div className={cn(\"flex-1 min-h-0 overflow-auto\", bodyClassName)}>\n {children}\n </div>\n\n {footer && (\n <div className=\"border-t border-border/50 shrink-0\">{footer}</div>\n )}\n </div>\n </FloatingLayer>,\n document.body,\n );\n}\n","\"use client\";\n\n/**\n * DebugStrip — dev-only geometry + viewport readout rendered at the top of\n * the WindowPanel body when `isDebugMode` is on. Extracted from\n * WindowPanel.tsx Phase 6 — purely presentational with its own resize\n * subscription; no coupling to the parent shell.\n */\nimport { useEffect, useState } from \"react\";\n\ninterface DebugStripProps {\n rect: { x: number; y: number; width: number; height: number };\n zIndex: number;\n}\n\nexport function DebugStrip({ rect, zIndex }: DebugStripProps) {\n const [vp, setVp] = useState(() =>\n typeof window === \"undefined\"\n ? { vw: 0, vh: 0, sw: 0, sh: 0, dpr: 1 }\n : {\n vw: window.innerWidth,\n vh: window.innerHeight,\n sw: window.screen.width,\n sh: window.screen.height,\n dpr: window.devicePixelRatio ?? 1,\n },\n );\n\n useEffect(() => {\n const update = () =>\n setVp({\n vw: window.innerWidth,\n vh: window.innerHeight,\n sw: window.screen.width,\n sh: window.screen.height,\n dpr: window.devicePixelRatio ?? 1,\n });\n window.addEventListener(\"resize\", update);\n return () => window.removeEventListener(\"resize\", update);\n }, []);\n\n const windowEntries: [string, number][] = [\n [\"x\", rect.x],\n [\"y\", rect.y],\n [\"w\", rect.width],\n [\"h\", rect.height],\n [\"z\", zIndex],\n ];\n\n const viewportEntries: [string, number | string][] = [\n [\"vw\", vp.vw],\n [\"vh\", vp.vh],\n [\"sw\", vp.sw],\n [\"sh\", vp.sh],\n [\"dpr\", vp.dpr],\n ];\n\n return (\n <div className=\"flex flex-col gap-0.5 px-3 py-1.5 border-b border-warning/20 bg-warning/5 shrink-0 font-mono text-[10px]\">\n {/* Row 1 — window position/size */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n <span className=\"text-warning uppercase tracking-wide text-[9px]\">\n win\n </span>\n {windowEntries.map(([label, val]) => (\n <span\n key={label}\n className=\"inline-flex items-center gap-0.5 leading-none\"\n >\n <span className=\"text-warning\">{label}:</span>\n <span className=\"text-warning font-bold tabular-nums\">\n {Math.round(val as number)}\n </span>\n </span>\n ))}\n </div>\n {/* Row 2 — viewport / screen */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n <span className=\"text-info uppercase tracking-wide text-[9px]\">\n vp\n </span>\n {viewportEntries.map(([label, val]) => (\n <span\n key={label}\n className=\"inline-flex items-center gap-0.5 leading-none\"\n >\n <span className=\"text-info\">{label}:</span>\n <span className=\"text-info font-bold tabular-nums\">\n {typeof val === \"number\" && !Number.isInteger(val)\n ? val.toFixed(2)\n : Math.round(val as number)}\n </span>\n </span>\n ))}\n </div>\n </div>\n );\n}\n","import { cn } from \"@ai-matrx/design-system/cn\";\n\n/** Pointer on interactive descendants in header/footer action slots (beats header grab). */\nexport const WINDOW_CHROME_INTERACTIVE =\n \"[&_button:not(:disabled)]:cursor-pointer [&_a]:cursor-pointer [&_[role=button]:not([aria-disabled=true])]:cursor-pointer [&_summary]:cursor-pointer [&_label:has(input,[role=checkbox],[role=radio])]:cursor-pointer\";\n\nexport const WINDOW_CHROME_ACTIONS = cn(\n \"flex items-center gap-0.5 shrink-0 text-foreground/80 [&_svg]:text-foreground/80\",\n WINDOW_CHROME_INTERACTIVE,\n);\n","\"use client\";\n\n/**\n * MobileWindowHeader — chrome for the fullscreen mobile takeover branch of\n * WindowPanel. Row 1: close/minimize + the title, which owns the row and wraps\n * to two lines. Row 2 (only when there is something to show): the\n * Sidebar/Content toggle and the window's actions.\n *\n * Extracted from WindowPanel.tsx Phase 6 — purely presentational.\n */\nimport type { ReactNode } from \"react\";\nimport { MinusIcon as Minus, XIcon as X } from \"../icons\";\nimport { WINDOW_CHROME_ACTIONS } from \"./chromeClasses\";\nimport {\n MobileWindowActionsRow,\n MobileWindowTitle,\n MobileWindowTitleRow,\n} from \"./MobileTitleRow\";\nimport { SegmentedControl } from \"@ai-matrx/design-system/controls\";\n\ninterface MobileWindowHeaderProps {\n title?: ReactNode | undefined;\n actionsRight?: ReactNode | undefined;\n /** Omitted until a mobile minimized tray surface is mounted. */\n onMinimize?: (() => void) | undefined;\n onClose?: (() => void) | undefined;\n hasSidebar: boolean;\n activePaneMobile: \"main\" | \"sidebar\";\n onSetActivePane: (pane: \"main\" | \"sidebar\") => void;\n}\n\nexport function MobileWindowHeader({\n title,\n actionsRight,\n onMinimize,\n onClose,\n hasSidebar,\n activePaneMobile,\n onSetActivePane,\n}: MobileWindowHeaderProps) {\n // Row 1 is the title's alone (see MobileTitleRow.tsx). The title used to be\n // the Sidebar/Content toggle's own label (`max-w-[120px] truncate`) beside\n // the actions, so \"Run History — Recipe Scaler\" read \"Run History — …\". A\n // RICH title (the Chat window's agent picker) is a control and keeps its own\n // layout in the same slot (verifier round 1, F-A1).\n const trafficLights =\n onClose || onMinimize ? (\n <div className=\"flex items-center gap-1.5 shrink-0\">\n {onClose && (\n <button\n type=\"button\"\n className=\"flex h-11 w-11 shrink-0 cursor-pointer items-center justify-center\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full matrx-window-light-close\">\n <X className=\"h-2.5 w-2.5 matrx-window-light-glyph\" />\n </span>\n </button>\n )}\n {onMinimize && (\n <button\n type=\"button\"\n className=\"flex h-11 w-11 shrink-0 cursor-pointer items-center justify-center\"\n onClick={onMinimize}\n aria-label=\"Minimize\"\n >\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full matrx-window-light-minimize\">\n <Minus\n className=\"h-2.5 w-2.5 matrx-window-light-glyph\"\n\n />\n </span>\n </button>\n )}\n </div>\n ) : null;\n\n const paneToggle = hasSidebar ? (\n <SegmentedControl aria-label=\"Pane\" value={activePaneMobile} onValueChange={onSetActivePane} data={[{ value: \"sidebar\", label: \"Sidebar\" }, { value: \"main\", label: \"Content\" }]} />\n ) : null;\n\n return (\n <div className=\"flex shrink-0 flex-col border-b border-border/50 bg-muted/40 px-2 select-none\">\n <MobileWindowTitleRow leading={trafficLights}>\n <MobileWindowTitle title={title} className=\"pr-1\" />\n </MobileWindowTitleRow>\n <MobileWindowActionsRow\n leading={paneToggle}\n actions={\n actionsRight ? (\n <div className={WINDOW_CHROME_ACTIONS}>{actionsRight}</div>\n ) : null\n }\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { TriangleAlertIcon as AlertTriangle, XIcon as X } from \"../icons\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\ninterface DeprecationBannerProps {\n replacedBy?: string | undefined;\n note?: string | undefined;\n className?: string | undefined;\n}\n\nexport function DeprecationBanner({\n replacedBy,\n note,\n className,\n}: DeprecationBannerProps) {\n const [dismissed, setDismissed] = useState(false);\n if (dismissed) return null;\n\n const message =\n note ??\n (replacedBy\n ? `Deprecated — moved to \"${replacedBy}\". This window will be removed soon.`\n : \"Deprecated — this window will be removed soon.\");\n\n return (\n <div\n className={cn(\n \"shrink-0 flex items-start gap-2 px-2 py-1 border-b border-destructive/40 bg-destructive/10 text-destructive-ink text-[11px] leading-tight\",\n className,\n )}\n >\n <AlertTriangle className=\"w-3.5 h-3.5 mt-[1px] shrink-0\" />\n <span className=\"flex-1 break-words\">{message}</span>\n <button\n type=\"button\"\n aria-label=\"Dismiss deprecation notice\"\n className=\"shrink-0 rounded hover:bg-destructive/20 p-0.5 transition-colors\"\n onClick={() => setDismissed(true)}\n >\n <X className=\"w-3 h-3\" />\n </button>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * PopoutTopBar — slim chrome strip for window content that has been popped\n * out into a Document Picture-in-Picture (or `window.open`) browser window.\n *\n * The OS / browser frame already provides close + minimize at the window\n * manager level, so this strip omits traffic lights entirely. Its only job\n * is to show the title, optional actions, and a \"Dock back\" button that\n * returns the content to the parent viewport.\n *\n * Extracted as a sibling of `MobileHeader.tsx` — purely presentational, no\n * Redux or hook dependencies. The dock + close handlers are passed in by\n * `WindowPanel` so the same component covers both the docked and popped-out\n * render paths cleanly.\n */\nimport type { ReactNode } from \"react\";\nimport { ArrowLeftToLineIcon as ArrowLeftToLine } from \"../icons\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { WINDOW_CHROME_ACTIONS } from \"./chromeClasses\";\n\nexport interface PopoutTopBarProps {\n /** Title displayed centered in the bar. Accepts string or arbitrary node. */\n title?: ReactNode | undefined;\n /** Optional content slotted on the left, before the title. */\n actionsLeft?: ReactNode | undefined;\n /** Optional content slotted on the right, before the dock button. */\n actionsRight?: ReactNode | undefined;\n /**\n * Click handler for the dock button. Should dispatch `dockWindow({ id, viewportWidth, viewportHeight })`\n * so the window returns centered in the parent viewport.\n * The browser popout window itself is closed by the `usePopoutWindow`\n * lifecycle hook in response to the Redux state change.\n */\n onDock: () => void;\n}\n\n/**\n * Visual height: 32px. Background mirrors the docked header (`bg-muted/40`)\n * so themes carry over via the cloned stylesheet without any popout-specific\n * styles.\n */\nexport function PopoutTopBar({\n title,\n actionsLeft,\n actionsRight,\n onDock,\n}: PopoutTopBarProps) {\n return (\n <div\n className={cn(\n \"flex items-center gap-1.5 px-2 py-1 min-h-[32px] shrink-0\",\n \"border-b border-border/50 bg-muted/40 select-none\",\n )}\n >\n {/* Left actions */}\n {actionsLeft && (\n <div className={WINDOW_CHROME_ACTIONS}>{actionsLeft}</div>\n )}\n\n {/* Centered title */}\n <div className=\"flex-1 flex items-center justify-center min-w-0\">\n <span className=\"text-xs font-medium text-foreground/80 truncate\">\n {title ?? \"\"}\n </span>\n </div>\n\n {/* Right actions */}\n {actionsRight && (\n <div className={WINDOW_CHROME_ACTIONS}>{actionsRight}</div>\n )}\n\n {/* Dock back button — always last, visually anchors the right side */}\n <button\n type=\"button\"\n className={cn(\n \"ml-1 p-1 rounded hover:bg-accent/60 transition-colors shrink-0 cursor-pointer\",\n \"text-foreground/60 hover:text-foreground\",\n )}\n onClick={onDock}\n title=\"Dock window\"\n aria-label=\"Dock window back to parent\"\n >\n <ArrowLeftToLine className=\"w-3.5 h-3.5\" />\n </button>\n </div>\n );\n}\n","/**\n * Feature detection for the window-panels pop-out system.\n *\n * Three capability tiers, in order of preference:\n *\n * 1. **`\"pip\"`** — Document Picture-in-Picture API (Chromium-based browsers,\n * Chrome 116+, Edge 116+, Opera). Frameless, always-on-top floating window.\n * Detected by presence of `window.documentPictureInPicture.requestWindow`.\n *\n * 2. **`\"popup\"`** — `window.open()` fallback (Safari, Firefox, anything else).\n * Universal browser support. Shows browser chrome (URL bar, tabs).\n * Acceptable degradation: user still gets a separate window for multi-\n * monitor workflows.\n *\n * 3. **`\"none\"`** — Embedded WebViews or other contexts where neither API is\n * available (rare). The \"Pop out\" affordance should be hidden entirely.\n *\n * The detection is intentionally simple and synchronous — it runs once on\n * the client at component mount time and the result is stable for the\n * lifetime of the page.\n *\n * SSR safety: every code path branches on `typeof window` first.\n */\n\nexport type PopoutCapability = \"pip\" | \"popup\" | \"none\";\n\n/**\n * Type augmentation for the Document Picture-in-Picture API.\n * The official spec lives at https://wicg.github.io/document-picture-in-picture/.\n *\n * We declare it locally rather than relying on `lib.dom.d.ts` because\n * TypeScript's built-in DOM types are inconsistent across `@types/node`\n * versions and the API is still in WICG (not yet WHATWG) status.\n */\nexport interface DocumentPictureInPictureRequestOptions {\n width?: number;\n height?: number;\n /**\n * If `true`, suppresses the \"back to tab\" button in the PiP window's\n * chrome. Default `false` — we want the user to be able to dock back.\n */\n disallowReturnToOpener?: boolean;\n}\n\nexport interface DocumentPictureInPicture {\n requestWindow(\n options?: DocumentPictureInPictureRequestOptions,\n ): Promise<Window>;\n /** The currently open PiP window, or `null` if none. */\n readonly window: Window | null;\n}\n\n/**\n * Window-augmenting interface so callers can do\n * `(window as WindowWithPictureInPicture).documentPictureInPicture`\n * without TypeScript errors.\n */\nexport interface WindowWithDocumentPictureInPicture extends Window {\n documentPictureInPicture?: DocumentPictureInPicture;\n}\n\n/**\n * Returns the highest-fidelity popout mechanism available in the current\n * browser. Safe to call during SSR (returns `\"none\"`).\n */\nexport function detectPopoutCapability(): PopoutCapability {\n if (typeof window === \"undefined\") return \"none\";\n\n const w = window as WindowWithDocumentPictureInPicture;\n if (\n w.documentPictureInPicture &&\n typeof w.documentPictureInPicture.requestWindow === \"function\"\n ) {\n return \"pip\";\n }\n\n // `window.open` is technically always defined, but in some sandboxed\n // contexts (extensions, embedded iframes with restrictive sandbox) it\n // returns `null` for any call. We can't pre-detect that without actually\n // calling it — and calling it without a user gesture would either fail or\n // open an unwanted popup. So we optimistically advertise \"popup\" support\n // and let the caller handle the runtime null result.\n if (typeof window.open === \"function\") {\n return \"popup\";\n }\n\n return \"none\";\n}\n\n/**\n * True when the browser supports Document Picture-in-Picture (the preferred\n * popout mode). Convenience wrapper around `detectPopoutCapability()` for\n * use in conditional rendering and feature flags.\n */\nexport function supportsDocumentPictureInPicture(): boolean {\n return detectPopoutCapability() === \"pip\";\n}\n\n/**\n * True when popout is available in any form (DPiP or popup).\n * Use this to decide whether to show the \"Pop out\" affordance at all.\n */\nexport function supportsAnyPopout(): boolean {\n return detectPopoutCapability() !== \"none\";\n}\n","\"use client\";\n\n/**\n * usePopoutWindow — lifecycle hook owning the Document Picture-in-Picture\n * (or `window.open` fallback) browser-window for a single window-panel.\n *\n * **Critical user-gesture constraint:** `documentPictureInPicture.requestWindow()`\n * and `window.open()` both require a synchronous user-gesture stack\n * (mouseup, click, keydown). The hook exposes `openPopout()` as a plain\n * imperative method so the caller can invoke it directly inside the\n * `pointerup` handler that detects a drag-out — *not* via `useEffect`,\n * which would lose the gesture chain and be rejected by the browser.\n *\n * **Order of operations:** open the OS window FIRST (synchronously), then\n * dispatch `popOutWindow` to Redux only after the window resolves. If we\n * dispatched first, `WindowPanel` would re-render mid-open with a null\n * portal target and visibly flicker.\n *\n * **Close handling:** the canonical close trigger is the popout's\n * `pagehide` event, which fires for both user-clicked-X and programmatic\n * `.close()` calls. The hook idempotently disposes styles, clears the\n * map entry, and dispatches `dockWindow`.\n *\n * **Dock-back from inside popout content:** `WindowPanel`'s \"Dock\" button\n * dispatches `dockWindow` directly. The hook's `useEffect` watching\n * `popoutMode` sees the transition to `null`, calls `pipWin.close()`, and\n * the `pagehide` handler fires (idempotent, so calling `dockWindow` again\n * is a Redux no-op).\n */\nimport { useCallback, useEffect, useRef } from \"react\";\nimport { useSummonDispatch, useSummonPorts, useSummonSelector } from \"@ai-matrx/summon/react\";\nimport {\n popOutWindow,\n dockWindow,\n selectActivePipWindowId,\n selectPopoutMode,\n} from \"@ai-matrx/summon\";\nimport {\n detectPopoutCapability,\n type WindowWithDocumentPictureInPicture,\n} from \"./featureDetection\";\nimport {\n setPopoutWindow,\n deletePopoutWindow,\n getPopoutWindow,\n} from \"./popoutWindowMap\";\nimport { cloneStylesIntoDocument } from \"./cloneStyles\";\nimport { markPopoutPending, clearPopoutPending } from \"./popoutPendingStorage\";\nimport { buildDockWindowPayload } from \"@ai-matrx/summon\";\nimport { openOutbound } from \"@ai-matrx/kit/outbound\";\n\nexport interface OpenPopoutOptions {\n width: number;\n height: number;\n title: string;\n}\n\nexport type OpenPopoutResult =\n | { ok: true; mode: \"pip\" | \"popup\" }\n | {\n ok: false;\n reason:\n \"pip-slot-taken\" | \"popup-blocked\" | \"no-capability\" | \"request-failed\";\n };\n\nexport interface UsePopoutWindowReturn {\n /**\n * Open a popout for this window. MUST be called synchronously inside a\n * user-gesture handler (pointerup, click, keydown) — otherwise the browser\n * rejects the request.\n */\n openPopout(opts: OpenPopoutOptions): Promise<OpenPopoutResult>;\n /**\n * Programmatically close the popout. Triggers the same cleanup path as\n * the user clicking the browser X button. Safe to call when there's no\n * popout open.\n */\n close(): void;\n}\n\nexport function usePopoutWindow(windowId: string): UsePopoutWindowReturn {\n const dispatch = useSummonDispatch();\n const { notify } = useSummonPorts();\n const popoutMode = useSummonSelector(selectPopoutMode(windowId));\n const activePipWindowId = useSummonSelector(selectActivePipWindowId);\n\n // Hold style-cleanup for this window's popout. Disposed on close.\n const stylesDisposeRef = useRef<(() => void) | null>(null);\n\n /**\n * Idempotent close handler. Called from:\n * - `pagehide` (browser X click, programmatic close, parent navigation)\n * - `close()` (programmatic from this hook)\n * - the dock-watch effect (Redux popoutMode → null while window exists)\n */\n const handleClose = useCallback(() => {\n const win = getPopoutWindow(windowId);\n if (!win && process.env.NODE_ENV !== \"production\") {\n // No window registered — handleClose was triggered after we already\n // cleaned up. Idempotent: just ensure Redux is consistent.\n }\n stylesDisposeRef.current?.();\n stylesDisposeRef.current = null;\n deletePopoutWindow(windowId);\n // Clear the recovery flag — we're docked now, no recovery needed.\n clearPopoutPending(windowId);\n // Dispatch dockWindow if Redux still considers us popped out. The\n // reducer is itself idempotent, so a redundant dispatch is harmless.\n dispatch(dockWindow(buildDockWindowPayload(windowId)));\n // Best-effort close. If the close was triggered by `pagehide`, the\n // window is already going away. If by `close()`, this is the action.\n try {\n win?.close();\n } catch {\n /* ignore */\n }\n if (process.env.NODE_ENV !== \"production\" && win) {\n // eslint-disable-next-line no-console\n console.info(`[popout] closed window for \"${windowId}\"`);\n }\n }, [dispatch, windowId]);\n\n /**\n * Open a popout. The async work happens inside a Promise the caller can\n * await, but the *first synchronous step* (DPiP / window.open) runs\n * inside the user-gesture stack as long as the caller invokes openPopout\n * directly from a user-gesture handler.\n */\n const openPopout = useCallback(\n async (opts: OpenPopoutOptions): Promise<OpenPopoutResult> => {\n const capability = detectPopoutCapability();\n if (capability === \"none\") {\n notify.error(\"Pop-out not supported\", {\n description: \"Your browser doesn't support floating windows.\",\n });\n return { ok: false, reason: \"no-capability\" };\n }\n\n // Single-PiP-per-origin: when a different window already holds the\n // Document PiP slot, we MUST skip `requestWindow()` — calling it would\n // close the existing PiP and steal its slot (per the WICG spec). Fall\n // through to `window.open()` instead so both windows coexist\n // peacefully. The price is browser chrome on the second window.\n const slotTakenByOther =\n activePipWindowId !== null && activePipWindowId !== windowId;\n\n let pipWin: Window | null = null;\n let mode: \"pip\" | \"popup\" = \"popup\";\n\n // Try Document PiP only when the slot is free OR this same window\n // already owns it (idempotent re-popout).\n if (capability === \"pip\" && !slotTakenByOther) {\n try {\n const w = window as WindowWithDocumentPictureInPicture;\n if (w.documentPictureInPicture) {\n pipWin = await w.documentPictureInPicture.requestWindow({\n width: Math.max(200, Math.round(opts.width)),\n height: Math.max(120, Math.round(opts.height)),\n });\n mode = \"pip\";\n }\n } catch (err) {\n // Some failures (user dismissal, permission policy) are recoverable\n // by falling through to the popup path.\n console.warn(\n \"[popout] Document PiP request failed, falling back to popup:\",\n err,\n );\n }\n }\n\n // Fallback: window.open\n if (!pipWin) {\n const features = [\n \"popup=yes\",\n `width=${Math.max(200, Math.round(opts.width))}`,\n `height=${Math.max(120, Math.round(opts.height))}`,\n ].join(\",\");\n try {\n pipWin = openOutbound(\"\", `popout-${windowId}`, features);\n mode = \"popup\";\n } catch (err) {\n console.error(\"[popout] window.open failed:\", err);\n }\n }\n\n if (!pipWin) {\n notify.error(\"Pop-up blocked\", {\n description:\n \"Please allow pop-ups for this site to use floating windows.\",\n });\n return { ok: false, reason: \"popup-blocked\" };\n }\n\n // Title for the OS chrome (DPiP shows it; popup shows it in the title bar)\n try {\n pipWin.document.title = opts.title;\n } catch {\n /* ignore */\n }\n\n // Clone the CSS environment + start observers\n stylesDisposeRef.current = cloneStylesIntoDocument(\n window.document,\n pipWin.document,\n ).dispose;\n\n // Wire close lifecycle\n pipWin.addEventListener(\"pagehide\", handleClose, { once: true });\n\n // Register the window FIRST so PopoutPortal can find it on the next render\n setPopoutWindow(windowId, pipWin);\n\n // Persist a recovery hint so a parent reload can surface \"click to\n // restore\" UX. Cleared on dock-back / close in handleClose.\n markPopoutPending(windowId);\n\n // Dispatch Redux state — this triggers WindowPanel re-render which\n // mounts the PopoutPortal that finally renders content into pipWin.\n dispatch(popOutWindow({ id: windowId, mode }));\n\n if (process.env.NODE_ENV !== \"production\") {\n console.info(\n `[popout] opened ${mode} window for \"${windowId}\" (${opts.width}x${opts.height})`,\n );\n }\n\n return { ok: true, mode };\n },\n [activePipWindowId, dispatch, handleClose, notify, windowId],\n );\n\n /** Programmatic close — triggers the same lifecycle as user-clicked-X. */\n const close = useCallback(() => {\n const win = getPopoutWindow(windowId);\n if (!win) {\n // Already closed — make sure Redux is consistent.\n dispatch(dockWindow(buildDockWindowPayload(windowId)));\n return;\n }\n // Closing the window fires `pagehide`, which runs handleClose.\n try {\n win.close();\n } catch {\n handleClose();\n }\n }, [dispatch, handleClose, windowId]);\n\n // ── Dock-watch: when Redux says we're docked but we still own a window,\n // close it. This is how the in-popout \"Dock\" button drives cleanup.\n useEffect(() => {\n if (popoutMode === null && getPopoutWindow(windowId) !== null) {\n try {\n getPopoutWindow(windowId)?.close();\n } catch {\n handleClose();\n }\n }\n }, [popoutMode, windowId, handleClose]);\n\n // ── Defensive parent-unload cleanup. Document PiP auto-closes when the\n // opener unloads, but `window.open` popups can outlive their opener.\n useEffect(() => {\n const onBeforeUnload = () => {\n try {\n getPopoutWindow(windowId)?.close();\n } catch {\n /* ignore */\n }\n };\n window.addEventListener(\"beforeunload\", onBeforeUnload);\n return () => {\n window.removeEventListener(\"beforeunload\", onBeforeUnload);\n };\n }, [windowId]);\n\n return { openPopout, close };\n}\n","/**\n * popoutWindowMap — module-level registry mapping a window-panel id to its\n * currently-open popout `Window` object.\n *\n * This is intentionally module-level (not Redux) because:\n *\n * 1. **`Window` objects aren't serializable.** Putting them in Redux would\n * break the `serializableCheck` middleware and corrupt DevTools time-travel.\n *\n * 2. **Cross-component lookup without prop drilling.** `PopoutPortal`,\n * `usePopoutWindow`, and the `beforeunload` defensive cleanup all need to\n * locate a popout by id without coordinating through React context.\n *\n * 3. **Singleton lifetime matches page lifetime.** The map is naturally\n * cleared when the user navigates away or reloads.\n *\n * Subscriptions: callers can `subscribe` for change notifications. This is\n * how `PopoutPortal` discovers a newly-opened window without prop drilling\n * (its `windowId` is stable; the `Window` reference is what changes). The\n * subscription is a thin wrapper over `useSyncExternalStore`-friendly\n * primitives — see `usePopoutWindowRef` below.\n */\nimport { useSyncExternalStore } from \"react\";\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\ninterface PopoutMapState {\n readonly map: Map<string, Window>;\n readonly listeners: Set<() => void>;\n}\n\n// Global slot, never a module let: a duplicated module graph must see one map (kit D9).\nconst slot = (): PopoutMapState =>\n globalSlot<PopoutMapState>(\"ai-matrx.summon.window.popoutWindows\", () => ({ map: new Map(), listeners: new Set() }));\n\nfunction notify(): void {\n for (const fn of slot().listeners) fn();\n}\n\n/**\n * Register or replace the popout window for a given window-panel id.\n * Notifies subscribers synchronously.\n */\nexport function setPopoutWindow(id: string, win: Window): void {\n const { map } = slot();\n const prev = map.get(id);\n if (prev === win) return;\n map.set(id, win);\n notify();\n}\n\n/**\n * Remove the popout window registration for a given id. Notifies subscribers\n * if a previously-registered window is being removed.\n */\nexport function deletePopoutWindow(id: string): void {\n const { map } = slot();\n if (!map.has(id)) return;\n map.delete(id);\n notify();\n}\n\n/** Get the popout window for a given id, or `null` if none is registered. */\nexport function getPopoutWindow(id: string): Window | null {\n return slot().map.get(id) ?? null;\n}\n\n/** Iterate over every currently-registered popout window. */\nexport function forEachPopoutWindow(\n cb: (win: Window, id: string) => void,\n): void {\n for (const [id, win] of slot().map) cb(win, id);\n}\n\n/**\n * Subscribe to map changes. Returns an unsubscribe function.\n * Used internally by `usePopoutWindowRef` for `useSyncExternalStore`.\n */\nexport function subscribePopoutWindowMap(listener: () => void): () => void {\n const { listeners } = slot();\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/**\n * React hook: subscribe to the popout window for a given id and re-render\n * when it changes. Returns the live `Window` reference or `null`.\n *\n * Uses `useSyncExternalStore` for tearing-free reads under React 19 strict\n * mode and concurrent rendering.\n */\nexport function usePopoutWindowRef(id: string): Window | null {\n return useSyncExternalStore(\n subscribePopoutWindowMap,\n () => getPopoutWindow(id),\n // SSR snapshot — popouts are never present during SSR.\n () => null,\n );\n}\n","/**\n * cloneStyles — replicate the parent document's style environment into a\n * popout (Document Picture-in-Picture or `window.open`) document, then keep\n * it in sync via MutationObservers so theme toggles and HMR updates flow\n * through.\n *\n * **What gets cloned:**\n *\n * 1. A **reset stylesheet** — the popout doc starts with no `<style>` tags\n * at all, so the browser's user-agent margins/padding apply to `<body>`.\n * We inject a tiny reset that zeros margins, fills the viewport, and\n * sets the foreground/background to match the theme tokens.\n *\n * 2. Every **`<style>` tag** in the parent `<head>`. This captures Tailwind\n * 4's compiled CSS (a single inlined `<style>` block from `@tailwindcss/\n * postcss`), `next/font`'s injected font-face declarations (also inlined\n * `<style>` blocks), and any third-party CSS-in-JS that injects styles\n * into the head.\n *\n * 3. Every **`<link rel=\"stylesheet\">`** in the parent `<head>`. We clone the\n * `href`/`media`/`crossorigin`/`data-*` attributes; the popout document\n * refetches the CSS, which is fine because production builds ship CSS\n * with `immutable` cache headers (HTTP cache hit) and dev builds are\n * cached in the browser's memory cache.\n *\n * 4. The parent's **`adoptedStyleSheets`** array — Tailwind 4 may use\n * Constructable Stylesheets in some build modes. They're shareable\n * across same-realm documents (Document PiP windows are same-realm with\n * their opener), so we just push the same `CSSStyleSheet` references\n * onto the target doc.\n *\n * 5. The parent **`<html>` element's `class` and select attributes** —\n * `.dark` (drives the `@custom-variant dark` Tailwind variant), `font-*`\n * classes from `next/font` variables, `data-theme`, `data-scroll-behavior`,\n * and `lang`. These are mirrored into the popout's `<html>` so the same\n * cascade applies.\n *\n * **What gets watched (via MutationObservers):**\n *\n * - **`<head>` mutations** — added/removed `<style>`/`<link>` nodes get\n * mirrored. `characterData` changes on existing `<style>` text content\n * are also mirrored (Turbopack HMR sometimes patches `textContent` in\n * place rather than swapping nodes).\n *\n * - **`<html>` attribute changes** — `class`, `data-theme`,\n * `data-scroll-behavior` mirror in real time. Toggling dark mode in the\n * parent updates the popout's `<html>` class within one frame.\n *\n * **What is NOT cloned:**\n * - `<script>` tags — the popout has no JS context of its own; React\n * reaches in via `createPortal` from the parent's running tree.\n * - `<title>`/`<meta>` (other than ones we set ourselves) — no SEO surface\n * for an ephemeral popout window.\n *\n * Returns a `dispose()` function that disconnects observers. The cloned\n * nodes don't need explicit removal — they live as long as the popout doc\n * does.\n */\n\nconst RESET_CSS = `\nhtml, body {\n margin: 0;\n padding: 0;\n height: 100%;\n overflow: hidden;\n}\nbody {\n font-family: var(--font-sans, system-ui, -apple-system, sans-serif);\n background: hsl(var(--background));\n color: hsl(var(--foreground));\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n`.trim();\n\n/** Marker attribute we stamp on every node we own in the popout doc. */\nconst POPOUT_DATA_ATTR = \"data-popout-clone\";\n/** Sentinel value for the reset stylesheet (so we never re-clone it). */\nconst RESET_MARKER = \"reset\";\n\ninterface ClonedStylesHandle {\n /** Disconnect observers. Cloned nodes stay until the popout doc unloads. */\n dispose(): void;\n}\n\n/**\n * Clone the source document's CSS environment into the target document and\n * keep it synced via MutationObservers. Returns a handle whose `dispose()`\n * disconnects the observers.\n */\nexport function cloneStylesIntoDocument(\n source: Document,\n target: Document,\n): ClonedStylesHandle {\n // ── 1. Reset stylesheet ─────────────────────────────────────────────────\n injectResetStylesheet(target);\n\n // ── 2. Initial style/link clone (preserve order) ────────────────────────\n cloneAllStyleAndLinkNodes(source, target);\n\n // ── 3. Adopted stylesheets (Constructable Stylesheets) ──────────────────\n cloneAdoptedStylesheets(source, target);\n\n // ── 4. Mirror <html> class/attributes ───────────────────────────────────\n mirrorHtmlAttributes(source, target);\n\n // ── 5. Watch <head> for runtime CSS changes (HMR, dynamic imports) ──────\n const headObserver = new MutationObserver((mutations) => {\n handleHeadMutations(mutations, target);\n });\n headObserver.observe(source.head, {\n childList: true,\n subtree: true,\n characterData: true,\n attributes: true,\n attributeFilter: [\"href\", \"media\"],\n });\n\n // ── 6. Watch <html> for theme-class / data-attribute changes ────────────\n const htmlObserver = new MutationObserver(() => {\n mirrorHtmlAttributes(source, target);\n });\n htmlObserver.observe(source.documentElement, {\n attributes: true,\n attributeFilter: [\"class\", \"data-theme\", \"data-scroll-behavior\"],\n });\n\n return {\n dispose() {\n headObserver.disconnect();\n htmlObserver.disconnect();\n },\n };\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction injectResetStylesheet(target: Document): void {\n // Idempotent: don't double-inject if cloneStylesIntoDocument is called\n // twice on the same target (shouldn't happen, but cheap defense).\n const existing = target.head.querySelector(\n `style[${POPOUT_DATA_ATTR}=\"${RESET_MARKER}\"]`,\n );\n if (existing) return;\n\n const style = target.createElement(\"style\");\n style.setAttribute(POPOUT_DATA_ATTR, RESET_MARKER);\n style.textContent = RESET_CSS;\n // Insert FIRST so authored styles cascade over our reset.\n target.head.insertBefore(style, target.head.firstChild);\n}\n\nfunction cloneAllStyleAndLinkNodes(\n source: Document,\n target: Document,\n): void {\n const nodes = source.head.querySelectorAll(\"style, link[rel='stylesheet']\");\n nodes.forEach((node) => {\n cloneOneStyleOrLink(node, target);\n });\n}\n\n/**\n * Clone a `<style>` or `<link>` from the source `<head>` into the target.\n * Tags the clone with `data-popout-clone` so we can find it again on removal.\n * Returns the clone, or `null` if the node type isn't supported.\n */\nfunction cloneOneStyleOrLink(\n node: Element,\n target: Document,\n): Element | null {\n if (node.tagName === \"STYLE\") {\n const clone = target.createElement(\"style\");\n // Copy text content explicitly — `cloneNode(true)` works for `<style>`\n // text but `textContent` is more direct and survives detached nodes.\n clone.textContent = node.textContent ?? \"\";\n copyDataAttributes(node, clone);\n clone.setAttribute(POPOUT_DATA_ATTR, getNodeKey(node));\n target.head.appendChild(clone);\n return clone;\n }\n if (\n node.tagName === \"LINK\" &&\n (node as HTMLLinkElement).rel === \"stylesheet\"\n ) {\n const link = node as HTMLLinkElement;\n const clone = target.createElement(\"link\");\n clone.rel = \"stylesheet\";\n if (link.href) clone.href = link.href;\n if (link.media) clone.media = link.media;\n if (link.crossOrigin) clone.crossOrigin = link.crossOrigin;\n if (link.integrity) clone.integrity = link.integrity;\n copyDataAttributes(link, clone);\n clone.setAttribute(POPOUT_DATA_ATTR, getNodeKey(node));\n target.head.appendChild(clone);\n return clone;\n }\n return null;\n}\n\n/**\n * Compute a stable-ish key for a source node so we can find its clone in the\n * target on removal. Uses a content hash for `<style>` and the `href` for\n * `<link>`, falling back to a position-based id stamped on the source itself.\n */\nfunction getNodeKey(node: Element): string {\n if (node.tagName === \"STYLE\") {\n // Stable per-text — Turbopack HMR rewrites textContent of the same node,\n // so we use a hash. Cheap deterministic hash is fine here; the only\n // requirement is that two different `<style>` blocks don't collide.\n return \"style:\" + cheapHash(node.textContent ?? \"\");\n }\n if (node.tagName === \"LINK\") {\n const href = (node as HTMLLinkElement).href || \"\";\n return \"link:\" + href;\n }\n return \"other:\" + Math.random().toString(36).slice(2);\n}\n\n/**\n * Tiny non-cryptographic hash. We only need different content to produce\n * different keys; collisions just mean a re-clone on a benign update.\n * djb2-style.\n */\nfunction cheapHash(s: string): string {\n let h = 5381;\n for (let i = 0; i < s.length; i++) {\n h = ((h << 5) + h + s.charCodeAt(i)) | 0;\n }\n return (h >>> 0).toString(36);\n}\n\nfunction copyDataAttributes(from: Element, to: Element): void {\n for (const attr of Array.from(from.attributes)) {\n if (attr.name.startsWith(\"data-\")) {\n // Don't overwrite our own marker\n if (attr.name === POPOUT_DATA_ATTR) continue;\n to.setAttribute(attr.name, attr.value);\n }\n }\n}\n\nfunction cloneAdoptedStylesheets(source: Document, target: Document): void {\n // `adoptedStyleSheets` is read-write. Constructable stylesheets are\n // shareable across same-realm documents — Document PiP and `window.open`\n // popups are same-realm with their opener, so reference-sharing works.\n if (\n Array.isArray(source.adoptedStyleSheets) &&\n source.adoptedStyleSheets.length > 0\n ) {\n try {\n target.adoptedStyleSheets = [...source.adoptedStyleSheets];\n } catch {\n // Some sandboxed contexts may throw. Fall through silently — the\n // <style> clone path covers the common case.\n }\n }\n}\n\nfunction mirrorHtmlAttributes(source: Document, target: Document): void {\n const src = source.documentElement;\n const tgt = target.documentElement;\n\n // Mirror full className wholesale. Diffing class-by-class is unnecessary\n // — `next/font` variable classes (e.g. `__variable_e8ce0c`) can change\n // wholesale across rebuilds, and the cost of a full string copy is\n // negligible.\n if (tgt.className !== src.className) {\n tgt.className = src.className;\n }\n\n for (const attr of [\"data-theme\", \"data-scroll-behavior\", \"lang\"] as const) {\n const v = src.getAttribute(attr);\n if (v === null) {\n if (tgt.hasAttribute(attr)) tgt.removeAttribute(attr);\n } else if (tgt.getAttribute(attr) !== v) {\n tgt.setAttribute(attr, v);\n }\n }\n}\n\nfunction handleHeadMutations(\n mutations: MutationRecord[],\n target: Document,\n): void {\n for (const m of mutations) {\n // Handle added nodes\n m.addedNodes.forEach((n) => {\n if (!(n instanceof Element)) return;\n if (\n n.tagName === \"STYLE\" ||\n (n.tagName === \"LINK\" && (n as HTMLLinkElement).rel === \"stylesheet\")\n ) {\n cloneOneStyleOrLink(n, target);\n }\n });\n // Handle removed nodes\n m.removedNodes.forEach((n) => {\n if (!(n instanceof Element)) return;\n if (n.tagName !== \"STYLE\" && n.tagName !== \"LINK\") return;\n const key = getNodeKey(n);\n const cloneEl = target.head.querySelector(\n `[${POPOUT_DATA_ATTR}=\"${cssEscape(key)}\"]`,\n );\n if (cloneEl) cloneEl.remove();\n });\n // Handle characterData updates on existing <style> text (Turbopack HMR)\n if (m.type === \"characterData\" && m.target.parentElement?.tagName === \"STYLE\") {\n const styleEl = m.target.parentElement;\n const oldKey = findExistingMirrorByContent(target, styleEl.textContent ?? \"\");\n const newKey = getNodeKey(styleEl);\n if (oldKey && oldKey !== newKey) {\n // Update the existing mirror in place\n const mirror = target.head.querySelector(\n `[${POPOUT_DATA_ATTR}=\"${cssEscape(oldKey)}\"]`,\n );\n if (mirror) {\n mirror.textContent = styleEl.textContent ?? \"\";\n mirror.setAttribute(POPOUT_DATA_ATTR, newKey);\n }\n }\n }\n // Handle attribute changes on <link> (href/media swap)\n if (\n m.type === \"attributes\" &&\n m.target instanceof HTMLLinkElement &&\n m.target.rel === \"stylesheet\"\n ) {\n // Find the mirror by the OLD key (using current href - but it changed,\n // so this is a best-effort: we just re-clone if no match).\n // Simpler: remove all link clones with our marker that point to the\n // same href, and re-clone.\n const link = m.target;\n const allClones = target.head.querySelectorAll(\n `link[${POPOUT_DATA_ATTR}]`,\n );\n // Remove the (presumed) matching clone — we can't perfectly identify\n // it post-attribute-change, so the safest fallback is to re-clone.\n // In practice link-attribute changes are rare outside Next.js dev,\n // and a no-op extra clone is harmless.\n cloneOneStyleOrLink(link, target);\n // (We don't remove the old one; the new one wins via cascade order.\n // On dispose, both go away with the popout doc.)\n void allClones;\n }\n }\n}\n\n/**\n * Find a mirror element in the target whose marker matches a content hash\n * derived from `text`. Used to locate the previous mirror for a `<style>`\n * whose textContent just changed via HMR.\n *\n * Returns the *old* key if a mirror is found, so the caller can compute\n * the new key and update the mirror in place.\n */\nfunction findExistingMirrorByContent(\n target: Document,\n text: string,\n): string | null {\n // We don't actually have the OLD text here — it was overwritten before\n // our observer fired. The simplest workable approach: find any style\n // mirror whose textContent matches `text` already (unchanged) — return\n // null then, no-op. Otherwise, we can't reliably identify the old\n // mirror; appending a new clone and accepting a temporary duplicate is\n // fine because identical hashes will collide on the next sync.\n const styles = target.head.querySelectorAll(\n `style[${POPOUT_DATA_ATTR}^=\"style:\"]`,\n );\n for (const s of Array.from(styles)) {\n if (s.textContent === text) return null; // already in sync\n }\n // Fallback: return any style mirror's key — the caller will overwrite it.\n // Pick the first one (HMR rarely affects multiple style tags simultaneously).\n if (styles.length > 0) {\n return styles[0]?.getAttribute(POPOUT_DATA_ATTR) ?? null;\n }\n return null;\n}\n\n/**\n * Minimal CSS attribute selector escape — escapes characters that would\n * break a `[attr=\"value\"]` selector. Real-world keys come from our hash\n * (alphanumeric) or hrefs (which can contain colons and slashes; both are\n * valid inside double-quoted selectors but we play safe).\n */\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, \"\\\\$1\");\n}\n","/**\n * popoutPendingStorage — sessionStorage flag tracking which window(s) were\n * popped out at the time of the last parent-page unload.\n *\n * **Why:** browsers require a fresh user gesture to call\n * `documentPictureInPicture.requestWindow()` or `window.open()`. We can't\n * programmatically restore a popout on hydration; the user has to click\n * something. To make the recovery discoverable, we surface a toast on\n * reload: \"X was popped out — click to restore.\"\n *\n * **Storage key:** `matrx_popout_pending` (sessionStorage, JSON-encoded\n * `{ windowIds: string[] }`).\n *\n * **Lifecycle:**\n * 1. While a popout is open, `usePopoutWindow` writes the window id into\n * this storage on every open (idempotent set semantics).\n * 2. On dock-back / close, the id is removed.\n * 3. On parent reload: the storage entry persists across the reload (it's\n * in sessionStorage, scoped to the tab).\n * 4. The `WindowPersistenceManager` reads the entry after hydration and\n * surfaces a toast for each pending window.\n * 5. Toast click triggers `usePopoutControl.popOut()` from the click\n * handler (a fresh user gesture), satisfying browser policy.\n *\n * SSR-safe: every function checks `typeof window` before touching storage.\n */\n\nconst STORAGE_KEY = \"matrx_popout_pending\";\n\ninterface PendingState {\n windowIds: string[];\n}\n\nfunction readState(): PendingState {\n if (typeof window === \"undefined\") return { windowIds: [] };\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY);\n if (!raw) return { windowIds: [] };\n const parsed = JSON.parse(raw) as Partial<PendingState>;\n if (!Array.isArray(parsed.windowIds)) return { windowIds: [] };\n // Filter to strings — defensive against tampered storage.\n return {\n windowIds: parsed.windowIds.filter(\n (id): id is string => typeof id === \"string\",\n ),\n };\n } catch {\n return { windowIds: [] };\n }\n}\n\nfunction writeState(state: PendingState): void {\n if (typeof window === \"undefined\") return;\n try {\n if (state.windowIds.length === 0) {\n window.sessionStorage.removeItem(STORAGE_KEY);\n } else {\n window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state));\n }\n } catch {\n // Storage may be disabled (private mode, quota exceeded). Failing\n // silently means we lose the recovery toast UX, but everything else\n // keeps working.\n }\n}\n\n/** Mark a window as popped out so it can be recovered on reload. */\nexport function markPopoutPending(windowId: string): void {\n const state = readState();\n if (!state.windowIds.includes(windowId)) {\n state.windowIds.push(windowId);\n writeState(state);\n }\n}\n\n/** Clear the pending flag for a window (called on dock-back / close). */\nexport function clearPopoutPending(windowId: string): void {\n const state = readState();\n const next = state.windowIds.filter((id) => id !== windowId);\n if (next.length !== state.windowIds.length) {\n writeState({ windowIds: next });\n }\n}\n\n/** Read all pending window ids (used on hydration to surface the toast). */\nexport function getPendingPopoutWindowIds(): string[] {\n return readState().windowIds;\n}\n\n/** Clear ALL pending entries — used after surfacing the recovery toast. */\nexport function clearAllPopoutPending(): void {\n writeState({ windowIds: [] });\n}\n","\"use client\";\n\n/**\n * usePopoutControl — imperative API for triggering popout / dock from\n * outside the WindowPanel chrome (e.g. an \"Open in floating window\" button\n * elsewhere in the app, a keyboard shortcut handler, an agent-driven\n * action).\n *\n * **User-gesture caveat:** the `popOut` method must be called synchronously\n * inside a user-gesture handler (click, keydown, pointerup) — Chrome\n * rejects `documentPictureInPicture.requestWindow()` calls outside the\n * gesture stack. The popOut method is fire-and-forget; errors surface as\n * toasts via `usePopoutWindow`.\n *\n * **How it locates the live window's openPopout:** each WindowPanel that\n * mounts registers its `usePopoutWindow.openPopout` reference into a\n * module-level map keyed by window id. This hook reads from the same map\n * to invoke the live opener. The registry is owned by `WindowPanel.tsx`\n * via `registerPopoutOpener` (see below); the registration auto-cleans on\n * unmount.\n */\n\nimport { useCallback } from \"react\";\nimport { useSummonDispatch } from \"@ai-matrx/summon/react\";\nimport {\n dockWindow,\n type WindowRect,\n} from \"@ai-matrx/summon\";\nimport { buildDockWindowPayload } from \"@ai-matrx/summon\";\nimport type { OpenPopoutOptions, OpenPopoutResult } from \"./usePopoutWindow\";\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\n// ─── Module-level opener registry ────────────────────────────────────────────\n//\n// Mirrors `popoutWindowMap.ts`'s pattern but holds the open-callback rather\n// than the live Window. Registered by WindowPanel on mount; unregistered on\n// unmount. Lookup is a plain Map operation — no React subscription needed\n// since callers invoke it imperatively from event handlers.\n\ntype OpenPopoutFn = (opts: OpenPopoutOptions) => Promise<OpenPopoutResult>;\n\n// Global slot, never a module-level Map: a duplicated module graph must see one registry (kit D9).\nconst openers = (): Map<string, OpenPopoutFn> =>\n globalSlot<Map<string, OpenPopoutFn>>(\"ai-matrx.summon.window.popoutOpeners\", () => new Map());\n\n/**\n * Register a window's openPopout function. Called by WindowPanel on mount.\n * Returns an unregister function for use in the cleanup of useEffect.\n */\nexport function registerPopoutOpener(\n windowId: string,\n fn: OpenPopoutFn,\n): () => void {\n openers().set(windowId, fn);\n return () => {\n // Only delete if the entry still points to the same function — guards\n // against StrictMode double-mount races where a fresh registration may\n // race with the previous unmount's cleanup.\n if (openers().get(windowId) === fn) {\n openers().delete(windowId);\n }\n };\n}\n\n/** Get the live openPopout for a given window id, or null. */\nexport function getPopoutOpener(windowId: string): OpenPopoutFn | null {\n return openers().get(windowId) ?? null;\n}\n\n// ─── Hook ────────────────────────────────────────────────────────────────────\n\nexport interface PopoutControlApi {\n /**\n * Pop out a specific window by its id. Must be called inside a\n * user-gesture stack. Returns the same result shape as\n * `usePopoutWindow.openPopout`. If the window isn't currently mounted,\n * returns `{ ok: false, reason: \"not-mounted\" }`.\n */\n popOut(\n windowId: string,\n opts: OpenPopoutOptions,\n ): Promise<OpenPopoutResult | { ok: false; reason: \"not-mounted\" }>;\n /** Dock a popped-out window back into the parent viewport. */\n dock(windowId: string): void;\n}\n\nexport function usePopoutControl(): PopoutControlApi {\n const dispatch = useSummonDispatch();\n\n const popOut = useCallback<PopoutControlApi[\"popOut\"]>(\n async (windowId, opts) => {\n const opener = getPopoutOpener(windowId);\n if (!opener) {\n return { ok: false, reason: \"not-mounted\" as const };\n }\n return opener(opts);\n },\n [],\n );\n\n const dock = useCallback<PopoutControlApi[\"dock\"]>(\n (windowId) => {\n const payload = buildDockWindowPayload(windowId);\n dispatch(dockWindow(payload));\n },\n [dispatch],\n );\n\n return { popOut, dock };\n}\n\n// ─── Convenience helper ──────────────────────────────────────────────────────\n//\n// Sized for the common \"open this window with a sensible default rect\" call.\n// Caller still owns the user-gesture handler.\n\nexport interface PopOutByIdOptions {\n /** Falls back to 480 if not provided. */\n width?: number | undefined;\n /** Falls back to 320 if not provided. */\n height?: number | undefined;\n /** Falls back to \"Window\" if not provided. */\n title?: string | undefined;\n}\n\nexport function buildPopoutOpts(\n rect: Partial<WindowRect> | undefined,\n opts: PopOutByIdOptions | undefined,\n): OpenPopoutOptions {\n return {\n width: opts?.width ?? rect?.width ?? 480,\n height: opts?.height ?? rect?.height ?? 320,\n title: opts?.title ?? \"Window\",\n };\n}\n","\"use client\";\n\n/**\n * PopoutPortal — wraps `createPortal` for rendering window-panel content\n * into a popout (Document Picture-in-Picture or `window.open`) document.\n *\n * Subscribes to `popoutWindowMap` via `usePopoutWindowRef` so the portal\n * automatically un-/re-mounts when the popout window opens or closes\n * without prop drilling the `Window` reference through the tree.\n *\n * Wraps children in `PopoutShell` so descendants see the popout-scoped\n * `PopoutContext` (used by `usePopoutContainer` for Radix portal\n * retargeting).\n *\n * **React tree topology:** the children stay in the *parent* React tree\n * (their Fiber is attached upstream of this `PopoutPortal`). Only the DOM\n * is mounted into the popout document. That preservation is what gives us\n * Redux/contexts/`callbackManager` for free across the window boundary.\n */\nimport { createPortal } from \"react-dom\";\nimport { useSummonSelector } from \"@ai-matrx/summon/react\";\nimport { selectPopoutMode } from \"@ai-matrx/summon\";\nimport { usePopoutWindowRef } from \"./popoutWindowMap\";\nimport { PopoutShell } from \"./PopoutShell\";\nimport type { ReactNode } from \"react\";\n\nexport interface PopoutPortalProps {\n windowId: string;\n children: ReactNode;\n}\n\nexport function PopoutPortal({ windowId, children }: PopoutPortalProps) {\n const popoutWin = usePopoutWindowRef(windowId);\n const popoutMode = useSummonSelector(selectPopoutMode(windowId));\n\n // Don't render anything until BOTH conditions hold:\n // - Redux says this window is popped out (popoutMode !== null)\n // - The actual `Window` reference is registered in popoutWindowMap\n //\n // The two can briefly disagree during open/close transitions; rendering\n // requires both to avoid mounting into a closed document.\n if (!popoutWin || popoutMode === null) return null;\n\n return createPortal(\n <PopoutShell popoutWindow={popoutWin} mode={popoutMode}>\n {children}\n </PopoutShell>,\n popoutWin.document.body,\n );\n}\n","\"use client\";\n\n/**\n * PopoutShell — wrapper that mounts inside the `createPortal` target in the\n * popout document and provides a `PopoutContext` value to descendants.\n *\n * `PopoutPortal` renders this *as the immediate child of `createPortal(...)`*\n * so every descendant inside the popout subtree sees the popout-scoped\n * document/window/container values via `usePopout()`.\n */\nimport { useMemo, type ReactNode } from \"react\";\nimport { PortalContainerProvider } from \"@ai-matrx/design-system\";\nimport {\n PopoutContext,\n type PopoutContextValue,\n type PopoutMode,\n} from \"./PopoutContext\";\n\nexport interface PopoutShellProps {\n popoutWindow: Window;\n mode: PopoutMode;\n children: ReactNode;\n}\n\nexport function PopoutShell({\n popoutWindow,\n mode,\n children,\n}: PopoutShellProps) {\n const value = useMemo<PopoutContextValue>(\n () => ({\n popoutDocument: popoutWindow.document,\n popoutWindow,\n popoutContainer: popoutWindow.document.body,\n mode,\n }),\n [popoutWindow, mode],\n );\n\n return (\n <PopoutContext.Provider value={value}>\n {/*\n * Host wiring for the @ai-matrx/design-system portal seam: package\n * primitives (Popover) read PortalContainerProvider instead of the\n * host's usePopoutContainer, so a popover opened inside a popped-out\n * window mounts into the popout's <body> — not the parent document.\n * A Dialog nested deeper re-provides its own container (nearest\n * provider wins), preserving the dialog > popout > body priority.\n */}\n <PortalContainerProvider container={value.popoutContainer}>\n {children}\n </PortalContainerProvider>\n </PopoutContext.Provider>\n );\n}\n","\"use client\";\n\n/**\n * PopoutContext — exposes the popout `Document` / `Window` / portal target\n * to descendants of a popped-out subtree.\n *\n * The default value (`popoutDocument: null`, etc.) means \"I'm rendered in\n * the parent document.\" Descendants that need to behave differently inside\n * a popout (e.g. Radix portals retargeting their content) call\n * `usePopout()` and branch on the values.\n *\n * **Architectural note:** because `createPortal` preserves the parent\n * React tree, every ancestor `Provider` cascades into the popout — Redux,\n * Theme, Tooltip, Router, all work without re-wrapping. This context is\n * for the *opposite* direction: telling popped-out content \"you're inside\n * a popout window, here's the document/window/container you should use\n * instead of the global `document`/`window`.\"\n */\nimport { createContext, useContext } from \"react\";\n\nexport type PopoutMode = \"pip\" | \"popup\";\n\nexport interface PopoutContextValue {\n /**\n * The popout `Document`. `null` when this subtree is rendered in the\n * parent (the default).\n */\n popoutDocument: Document | null;\n /**\n * The popout `Window`. `null` when this subtree is rendered in the parent.\n * Use for `addEventListener`, `matchMedia`, `innerWidth`, etc., when the\n * popout-scoped answer is what you need.\n */\n popoutWindow: Window | null;\n /**\n * Element to use as the Radix `Portal.container` prop so floating UI\n * (tooltips, popovers, dropdowns) renders inside the popout instead of\n * the parent `document.body`. Returns `null` outside a popout —\n * `usePopoutContainer` coerces this to `undefined` so Radix falls back\n * to its default container automatically.\n */\n popoutContainer: HTMLElement | null;\n /**\n * Which popout mechanism is in use. `null` outside a popout.\n * Currently only used for diagnostics; downstream components may branch\n * on it later (e.g. show different chrome for `popup` vs `pip`).\n */\n mode: PopoutMode | null;\n}\n\nconst DEFAULT_VALUE: PopoutContextValue = {\n popoutDocument: null,\n popoutWindow: null,\n popoutContainer: null,\n mode: null,\n};\n\nexport const PopoutContext =\n createContext<PopoutContextValue>(DEFAULT_VALUE);\n\n/** Read the current popout context. Always defined — never throws. */\nexport function usePopout(): PopoutContextValue {\n return useContext(PopoutContext);\n}\n","/**\n * traySnapshotMap — window id → a captured local object-URL snapshot shown in the minimized tile.\n *\n * Not Redux: image blobs stay out of the store and never touch storage. Object URLs avoid base64\n * expansion and are revoked on replacement, restore, unmount, or bounded-cache eviction. State\n * lives in a global slot so a duplicated module graph sees one map (kit globalSlot, D9).\n *\n * Lifecycle: WindowPanel captures after minimize → stored here → TrayChipPreview subscribes and\n * reads → restore / unmount clears it.\n */\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\nconst MAX_SNAPSHOTS = 16;\n\ninterface SnapshotState {\n readonly map: Map<string, string>;\n readonly listeners: Set<() => void>;\n}\n\nconst state = (): SnapshotState =>\n globalSlot<SnapshotState>(\"ai-matrx.summon.window.traySnapshots\", () => ({ map: new Map(), listeners: new Set() }));\n\nfunction notify(): void {\n for (const fn of state().listeners) fn();\n}\n\nfunction revoke(url: string | undefined): void {\n if (url && typeof URL !== \"undefined\" && typeof URL.revokeObjectURL === \"function\") URL.revokeObjectURL(url);\n}\n\n/** Store a local snapshot blob for a window and notify subscribers. */\nexport function setTraySnapshot(id: string, blob: Blob): void {\n const { map } = state();\n revoke(map.get(id));\n const objectUrl = URL.createObjectURL(blob);\n map.delete(id);\n map.set(id, objectUrl);\n while (map.size > MAX_SNAPSHOTS) {\n const oldestId = map.keys().next().value;\n if (oldestId === undefined) break;\n revoke(map.get(oldestId));\n map.delete(oldestId);\n }\n notify();\n}\n\n/** Clear the snapshot for a given window id. */\nexport function clearTraySnapshot(id: string): void {\n const { map } = state();\n const objectUrl = map.get(id);\n if (!objectUrl) return;\n map.delete(id);\n revoke(objectUrl);\n notify();\n}\n\n/** Read the snapshot for a given window id, or null. */\nexport function getTraySnapshot(id: string): string | null {\n return state().map.get(id) ?? null;\n}\n\n/** Subscribe to map changes (useSyncExternalStore-shaped). */\nexport function subscribeTraySnapshotMap(listener: () => void): () => void {\n const { listeners } = state();\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n","/**\n * defaultTraySnapshotCapture — the fallback `captureTraySnapshot` for any window without a\n * registered preview, so its minimized tile shows a small image of the real body.\n *\n * `html-to-image` is an OPTIONAL peer, loaded through ONE dynamic import on the first capture: a\n * host that never installs it gets the labelled default tile (no error, no bundle cost).\n *\n * Performance contract (do not weaken when editing):\n * - Runs exactly ONCE per minimize, inside WindowPanel's timeout race. No polling, no network, no\n * storage — the Blob lands in the bounded object-URL cache (16 entries, revoked on restore).\n * - Oversized DOM subtrees are skipped (the clone pass is synchronous and would jank).\n * - Output is downscaled (320px longest edge, 1x pixel density) WebP.\n */\n\n/** Skip capture above this many descendant elements. */\nconst MAX_CAPTURE_ELEMENT_COUNT = 3000;\n\n/** A cross-origin image the renderer cannot fetch becomes a transparent pixel, never a failed capture. */\nconst TRANSPARENT_PIXEL = \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n\nexport interface ElementThumbnailOptions {\n /** Longest edge in px (min 64). Default 320. */\n readonly maxEdge?: number;\n /** WebP quality 0–1. Default 0.62. */\n readonly quality?: number;\n}\n\n/** The one dynamic import of the optional peer. `null` when the host did not install it. */\nasync function loadToCanvas(): Promise<typeof import(\"html-to-image\").toCanvas | null> {\n try {\n const mod = await import(\"html-to-image\");\n return mod.toCanvas;\n } catch {\n return null;\n }\n}\n\n/** A small display-ready WebP thumbnail of one element, or null when html-to-image is absent. */\nexport async function captureElementThumbnail(element: HTMLElement, options: ElementThumbnailOptions = {}): Promise<Blob | null> {\n const toCanvas = await loadToCanvas();\n if (!toCanvas) return null;\n const sourceWidth = Math.max(1, element.offsetWidth);\n const sourceHeight = Math.max(1, element.offsetHeight);\n const maxEdge = Math.max(64, options.maxEdge ?? 320);\n const scale = Math.min(1, maxEdge / Math.max(sourceWidth, sourceHeight));\n const canvas = await toCanvas(element, {\n pixelRatio: 1,\n canvasWidth: Math.max(1, Math.round(sourceWidth * scale)),\n canvasHeight: Math.max(1, Math.round(sourceHeight * scale)),\n skipFonts: true,\n imagePlaceholder: TRANSPARENT_PIXEL,\n onImageErrorHandler: () => undefined,\n });\n return new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, \"image/webp\", options.quality ?? 0.62);\n });\n}\n\nexport async function defaultTraySnapshotCapture(bodyEl: HTMLElement): Promise<Blob | null> {\n try {\n if (bodyEl.querySelectorAll(\"*\").length > MAX_CAPTURE_ELEMENT_COUNT || bodyEl.offsetWidth < 8 || bodyEl.offsetHeight < 8) {\n return null;\n }\n const blob = await captureElementThumbnail(bodyEl);\n // A capture of a body that had not painted comes back as one flat colour: an empty tile.\n // Treat it as no capture so the tile shows the labelled default body instead.\n return blob && (await isFlatImage(blob)) ? null : blob;\n } catch {\n // A failed capture is never worth breaking minimize over.\n return null;\n }\n}\n\n/** True when every sampled pixel is transparent or the same colour — nothing to show. */\nasync function isFlatImage(blob: Blob): Promise<boolean> {\n try {\n const bitmap = await createImageBitmap(blob);\n const size = 24;\n const canvas = document.createElement(\"canvas\");\n canvas.width = size;\n canvas.height = size;\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!ctx) return false;\n ctx.drawImage(bitmap, 0, 0, size, size);\n bitmap.close();\n const { data } = ctx.getImageData(0, 0, size, size);\n const r0 = data[0] ?? 0;\n const g0 = data[1] ?? 0;\n const b0 = data[2] ?? 0;\n const a0 = data[3] ?? 0;\n for (let i = 0; i < data.length; i += 4) {\n if (\n Math.abs((data[i] ?? 0) - r0) > 6 ||\n Math.abs((data[i + 1] ?? 0) - g0) > 6 ||\n Math.abs((data[i + 2] ?? 0) - b0) > 6 ||\n Math.abs((data[i + 3] ?? 0) - a0) > 6\n ) {\n return false;\n }\n }\n return true;\n } catch {\n return false;\n }\n}\n","\"use client\";\n\n/**\n * MinimizedWindowContent — the body of a minimized WindowPanel shell.\n *\n * When a window is minimized it shrinks to a 240×160 card; this fills the body\n * below its fixed header with the canonical tray preview\n * (`TrayChipPreview` — custom / snapshot / default, in that order) and makes the\n * whole area click-to-restore. It is the single seam that brings the tray\n * preview registry to the *production* minimized state (the standalone\n * `WindowTray` dock is the other consumer).\n *\n * `windowId` is the registry lookup key — pass the window's `overlayId` when it\n * has one (overlay-managed windows), falling back to the runtime id. A window\n * with no registered preview lands on the default muted label, so this is safe\n * for every window, not just those with a bespoke preview.\n */\n\nimport { getOverlayMeta } from \"@ai-matrx/summon\";\nimport { TrayChipPreview } from \"./TrayChipPreview\";\n\ninterface MinimizedWindowContentProps {\n /** Registry key — `overlayId` for overlay-managed windows, else runtime id. */\n registryKey: string;\n /** Unique runtime id for the local screenshot cache. */\n snapshotKey: string;\n overlayInstanceId?: string | undefined;\n previewData?: Record<string, unknown> | undefined;\n /** Window title; falls back to the registry label when not a plain string. */\n title?: string | undefined;\n /** Restore (un-minimize) the window. Wired to a click on the whole body. */\n onRestore?: (() => void) | undefined;\n}\n\nexport function MinimizedWindowContent({\n registryKey,\n snapshotKey,\n overlayInstanceId,\n previewData,\n title,\n onRestore,\n}: MinimizedWindowContentProps) {\n const label = title ?? getOverlayMeta(registryKey)?.label ?? \"\";\n\n return (\n <button\n type=\"button\"\n onClick={onRestore}\n title=\"Click to restore\"\n className=\"flex min-h-0 flex-1 flex-col text-left focus:outline-none\"\n >\n <TrayChipPreview\n registryKey={registryKey}\n snapshotKey={snapshotKey}\n overlayInstanceId={overlayInstanceId}\n previewData={previewData}\n title={label}\n />\n </button>\n );\n}\n\nexport default MinimizedWindowContent;\n","\"use client\";\n\n/**\n * TrayChipPreview — the body of a minimized window tile.\n *\n * Three modes, in priority order:\n * 1. Custom — a preview registered with `registerTrayPreview` (best fidelity, no capture).\n * 2. Snapshot — the image captured at minimize time (`traySnapshotMap`).\n * 3. Default — a muted \"label · Window\" body, shown while a capture is pending or when it was\n * skipped/failed.\n * A custom preview that throws falls through to snapshot/default without breaking the tile.\n */\n\nimport { Component, memo, useSyncExternalStore, type ReactNode } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { getOverlayMeta, selectOverlayData, DEFAULT_INSTANCE_ID } from \"@ai-matrx/summon\";\nimport { useSummonPorts, useSummonSelector } from \"@ai-matrx/summon/react\";\nimport { getTrayPreviewEntry, type TrayPreviewContext } from \"@ai-matrx/summon/window-host\";\nimport { getTraySnapshot, subscribeTraySnapshotMap } from \"./traySnapshotMap\";\n\ninterface TrayChipPreviewProps {\n /** Registry key — the overlay id for overlay-managed windows, else the runtime id. */\n registryKey: string;\n /** Unique runtime window id used for the local snapshot cache. */\n snapshotKey: string;\n overlayInstanceId?: string | undefined;\n previewData?: Record<string, unknown> | undefined;\n title: string;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport const TrayChipPreview = memo(function TrayChipPreview({\n registryKey,\n snapshotKey,\n overlayInstanceId = DEFAULT_INSTANCE_ID,\n previewData,\n title,\n}: TrayChipPreviewProps) {\n const meta = getOverlayMeta(registryKey);\n const { Preview } = getTrayPreviewEntry(registryKey);\n const ports = useSummonPorts();\n const overlayData = useSummonSelector((state) => (meta ? selectOverlayData(state, meta.id, overlayInstanceId) : null));\n const collectedData = useSummonSelector((state) => state.windowManager.windows[snapshotKey]?.persistence?.data);\n const registryLabel = meta?.label ?? null;\n\n const fallback = <TraySnapshotImage snapshotKey={snapshotKey} registryLabel={registryLabel} title={title} />;\n\n if (Preview) {\n const ctx: TrayPreviewContext = {\n data: previewData ?? collectedData ?? (isPlainRecord(overlayData) ? overlayData : {}),\n overlayId: meta?.id ?? registryKey,\n instanceId: overlayInstanceId,\n title,\n };\n return (\n <PreviewBoundary\n fallback={fallback}\n onError={(error) => ports.errors.capture(error, { where: \"tray-preview\", overlayId: registryKey })}\n >\n <div className=\"flex-1 px-3 py-1 overflow-hidden text-xs text-muted-foreground\">\n <Preview {...ctx} />\n </div>\n </PreviewBoundary>\n );\n }\n return fallback;\n});\n\nclass PreviewBoundary extends Component<\n { fallback: ReactNode; onError: (error: unknown) => void; children: ReactNode },\n { failed: boolean }\n> {\n override state = { failed: false };\n static getDerivedStateFromError(): { failed: boolean } {\n return { failed: true };\n }\n override componentDidCatch(error: unknown): void {\n this.props.onError(error);\n }\n override render(): ReactNode {\n return this.state.failed ? this.props.fallback : this.props.children;\n }\n}\n\nconst DefaultTrayChipBody = memo(function DefaultTrayChipBody({ label }: { label: string }) {\n return (\n <div className=\"flex flex-1 flex-col justify-between overflow-hidden bg-gradient-to-br from-muted/45 via-background to-primary/5 px-3 py-2.5\">\n <div className=\"flex min-w-0 items-center gap-2.5\">\n <div\n aria-hidden=\"true\"\n className=\"flex h-8 w-8 shrink-0 flex-col gap-1 rounded-md border border-border/60 bg-background/70 p-1.5 shadow-sm\"\n >\n <span className=\"h-1 w-4 rounded-full bg-primary/45\" />\n <span className=\"h-1 w-3 rounded-full bg-muted-foreground/25\" />\n <span className=\"h-1 w-4 rounded-full bg-muted-foreground/15\" />\n </div>\n <span className=\"min-w-0 truncate text-xs font-medium text-foreground\">{label}</span>\n </div>\n <div className=\"matrx-window-tile-meta flex items-center justify-between gap-2 text-muted-foreground\">\n <span className=\"truncate uppercase tracking-wide\">Window</span>\n <span className=\"shrink-0\">Click to restore</span>\n </div>\n </div>\n );\n});\n\nconst TraySnapshotImage = memo(function TraySnapshotImage({\n snapshotKey,\n registryLabel,\n title,\n}: {\n snapshotKey: string;\n registryLabel: string | null;\n title: string;\n}) {\n // The snapshot is captured asynchronously after the window minimizes; subscribe so the tile\n // updates the moment it lands, without polling.\n const snapshot = useSyncExternalStore(\n subscribeTraySnapshotMap,\n () => getTraySnapshot(snapshotKey),\n () => null,\n );\n if (!snapshot) return <DefaultTrayChipBody label={registryLabel ?? title} />;\n return (\n <div className=\"flex-1 overflow-hidden bg-muted/30 relative\">\n <img\n src={snapshot}\n alt=\"\"\n className={cn(\"w-full h-full object-cover\", \"opacity-90 hover:opacity-100 transition-opacity\")}\n draggable={false}\n />\n </div>\n );\n});\n","// @ai-matrx/summon/window — the WindowPanel desktop: the window, its chrome, tray sync and the\n// minimized tile, snap/arrange, pop-out to a real browser window, the three phone presentations,\n// and the host options. See SUMMON-PACKAGE-DESIGN.md (common-docs) for its contract.\n\nexport { WindowPanel, type WindowPanelProps, type WindowPanelBaseProps, type WindowPanelCloseBinding } from \"./window/WindowPanel\";\nexport {\n WindowsProvider,\n useWindowConfig,\n WindowSelectionSurface,\n DEFAULT_WINDOW_CONFIG,\n DEFAULT_ESCAPE_YIELD_SELECTOR,\n DEFAULT_MOBILE_TOP_OFFSET,\n type WindowConfig,\n type WindowsProviderProps,\n type WindowSelectionSurfaceProps,\n} from \"@ai-matrx/summon/window-host\";\nexport {\n useWindowPanel,\n resolvePosition,\n resetDefaultWindowCascade,\n type UseWindowPanelOptions,\n type UseWindowPanelReturn,\n type ResizeEdge,\n type WindowPosition,\n} from \"./window/useWindowPanel\";\nexport { WindowTraySync } from \"@ai-matrx/summon/window-host\";\nexport { WindowSidebar, type WindowSidebarItem } from \"./window/WindowSidebar\";\nexport { LayoutIcon, LayoutIconButton, type LayoutIconType } from \"./window/LayoutIcon\";\nexport { useOverlaySurfaceRenderAck } from \"./window/useOverlaySurfaceRenderAck\";\n\n// Minimized tile and tray previews\nexport {\n registerTrayPreview,\n getTrayPreviewEntry,\n resetTrayPreviews,\n type TrayPreviewContext,\n type TrayPreviewEntry,\n type TraySnapshotCapture,\n} from \"@ai-matrx/summon/window-host\";\nexport { setTraySnapshot, clearTraySnapshot, getTraySnapshot, subscribeTraySnapshotMap } from \"./window/tray/traySnapshotMap\";\nexport { defaultTraySnapshotCapture, captureElementThumbnail, type ElementThumbnailOptions } from \"./window/tray/defaultTraySnapshotCapture\";\nexport { TrayChipPreview } from \"./window/tray/TrayChipPreview\";\nexport { MinimizedWindowContent } from \"./window/tray/MinimizedWindowContent\";\nexport { TrayStatusChip, type TrayStatusChipProps, type TrayStatusSegment, type TrayStatusTone } from \"./window/tray/TrayStatusChip\";\n\n// Pop-out\nexport { usePopout, PopoutContext, type PopoutContextValue, type PopoutMode } from \"./window/popout/PopoutContext\";\nexport { usePopoutContainer } from \"./window/popout/usePopoutContainer\";\nexport { usePopoutControl, getPopoutOpener, buildPopoutOpts, type PopoutControlApi, type PopOutByIdOptions } from \"./window/popout/usePopoutControl\";\nexport { usePopoutWindow, type OpenPopoutOptions, type OpenPopoutResult, type UsePopoutWindowReturn } from \"./window/popout/usePopoutWindow\";\nexport { getPopoutWindow, forEachPopoutWindow, subscribePopoutWindowMap, usePopoutWindowRef } from \"./window/popout/popoutWindowMap\";\nexport { getPendingPopoutWindowIds, clearAllPopoutPending } from \"./window/popout/popoutPendingStorage\";\nexport {\n detectPopoutCapability,\n supportsDocumentPictureInPicture,\n supportsAnyPopout,\n type PopoutCapability,\n} from \"./window/popout/featureDetection\";\nexport {\n evaluateDragOut,\n DEFAULT_DRAG_OUT_CONFIG,\n INITIAL_DRAG_OUT_STATE,\n type DragOutConfig,\n type DragOutState,\n type DragOutInput,\n type DragOutEvalResult,\n} from \"./window/popout/popoutDragDetector\";\n\n// Phone presentations and chrome pieces a host composes beside windows\nexport { default as MobileDrawerSurface } from \"./window/mobile/MobileDrawerSurface\";\nexport { default as MobileCardSurface } from \"./window/mobile/MobileCardSurface\";\nexport { MobileWindowTitle, MobileWindowTitleRow, MobileWindowActionsRow, mobileWindowTitleClass, MOBILE_WINDOW_TITLE_TEXT } from \"./window/chrome/MobileTitleRow\";\n\n// Utilities\nexport {\n markAutoOpened,\n isAutoOpened,\n clearAutoOpened,\n autoOpenHasRoom,\n measureWorkingColumn,\n resolveAutoOpenPlacement,\n AUTO_OPEN_MIN_WIDTH,\n AUTO_OPEN_NO_ROOM_EVENT,\n type AutoOpenPlacement,\n} from \"./window/utils/autoOpenPlacement\";\nexport { mayRaiseUnbidden, isUnderRoute, type UnbiddenRaiseVerdict, type UnbiddenRefusalCode } from \"./window/utils/mayRaiseUnbidden\";\nexport { assertLazyLoaded } from \"./window/utils/lazy-bundle-guard\";\nexport { sanitizeWindowData } from \"./window/utils/sanitizeWindowData\";\n","\"use client\";\n\nimport React from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\nimport { ScrollArea } from \"@ai-matrx/design-system\";\n\nexport interface WindowSidebarItem {\n value: string;\n label: string;\n icon: React.ElementType;\n description?: string | undefined;\n}\n\ninterface WindowSidebarProps<T extends string = string> {\n items: WindowSidebarItem[];\n activeItem: T;\n onSelect: (value: T) => void;\n className?: string | undefined;\n}\n\nexport function WindowSidebar<T extends string = string>({\n items,\n activeItem,\n onSelect,\n className,\n}: WindowSidebarProps<T>) {\n return (\n <ScrollArea className={cn(\"flex-1 w-full\", className)}>\n <div className=\"py-2\">\n {items.map((item) => {\n const Icon = item.icon as React.FC<{ className?: string }>;\n const isActive = item.value === activeItem;\n return (\n <button\n key={item.value}\n onClick={() => onSelect(item.value as T)}\n title={item.description}\n className={cn(\n \"w-full flex items-center gap-2.5 px-3 py-2 text-left text-xs transition-colors\",\n isActive\n ? \"bg-primary/10 text-primary-ink border-r-2 border-primary\"\n : \"text-muted-foreground hover:bg-muted/50 hover:text-foreground\",\n )}\n >\n <Icon className=\"h-3.5 w-3.5 shrink-0\" />\n <span className=\"truncate\">{item.label}</span>\n </button>\n );\n })}\n </div>\n </ScrollArea>\n );\n}\n\nexport default WindowSidebar;\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { ackOverlaySurfaceRender, clearOverlaySurfaceRender } from \"@ai-matrx/summon\";\n\n/**\n * Acknowledge a visible presentation that intentionally replaces WindowPanel.\n *\n * Registered singleton window overlays normally prove they are on screen by mounting a\n * WindowPanel and registering geometry. Mobile drawers, sheets, and full-screen\n * viewers have no window-manager geometry, so their composition root must use\n * this hook while that alternate surface is active.\n */\nexport function useOverlaySurfaceRenderAck(\n overlayId: string,\n active: boolean,\n): void {\n useEffect(() => {\n if (!active) return undefined;\n ackOverlaySurfaceRender(overlayId);\n return () => clearOverlaySurfaceRender(overlayId);\n }, [active, overlayId]);\n}\n","\"use client\";\n\n/**\n * TrayStatusChip — the canonical \"minimized-window status indicator\".\n *\n * A small, presentational mini-view for the body of a minimized window (or a\n * tray chip): a tinted icon that conveys severity at a glance, a primary count,\n * an optional caption, and an optional per-tone breakdown. It is the reusable\n * primitive behind window-specific previews like the Error Inspector's bug\n * indicator — any window whose minimized value is \"a status + a few numbers\"\n * (errors, active recordings, running jobs, unread items…) maps onto this\n * instead of hand-rolling a one-off chip.\n *\n * Design contract:\n * - **Presentational only.** No store reads, no effects, no Redux. The consumer\n * subscribes to its own live source and passes plain props down. This keeps\n * the chip render-cheap and lets the consumer own the (isolated) subscription.\n * - **Tone is the signal.** `tone` tints the icon using the same colour\n * language as `lib/diagnostics/errorTiers.ts` so severity reads identically\n * everywhere (blue → yellow → amber → red).\n * - **Limit what's shown.** A minimized card is 240×160; it must stay\n * glanceable. One icon, one number, an optional caption, and a tiny\n * breakdown — no more. Breakdown segments render only when more than one is\n * non-zero (a single tone is already carried by the icon colour + count).\n *\n * Rendered INSIDE `TrayChipPreview`'s custom-mode wrapper, which already\n * supplies `flex-1`, padding, and overflow clipping — so this root only needs\n * to lay out its own row.\n */\n\nimport type { ComponentType, SVGAttributes } from \"react\";\nimport { cn } from \"@ai-matrx/design-system/cn\";\n\n/**\n * Severity scale, loudest-last. Maps onto the captured-error tiers but is\n * intentionally generic so non-error windows can reuse it:\n * neutral — inert / nothing notable (muted)\n * info — active & healthy, \"monitoring\" (info token)\n * warning — low / silent (yellow)\n * elevated — minor / worth a glance (amber)\n * critical — loud / needs attention (destructive red)\n */\nexport type TrayStatusTone =\n | \"neutral\"\n | \"info\"\n | \"warning\"\n | \"elevated\"\n | \"critical\";\n\ninterface ToneClasses {\n /** Icon + primary-count text colour. */\n fg: string;\n /** Breakdown dot fill. */\n dot: string;\n}\n\nconst TONE_CLASSES: Record<TrayStatusTone, ToneClasses> = {\n neutral: {\n fg: \"text-muted-foreground\",\n dot: \"bg-muted-foreground/50\",\n },\n info: {\n fg: \"text-info\",\n dot: \"bg-info\",\n },\n warning: {\n fg: \"text-warning\",\n dot: \"bg-warning\",\n },\n elevated: {\n fg: \"text-warning\",\n dot: \"bg-warning\",\n },\n critical: {\n fg: \"text-destructive\",\n dot: \"bg-destructive\",\n },\n};\n\nexport interface TrayStatusSegment {\n count: number;\n tone: TrayStatusTone;\n /** Accessible/tooltip label, e.g. \"clear errors\". */\n label?: string | undefined;\n}\n\nexport interface TrayStatusChipProps {\n /** Icon component (any SVG icon taking className) — the glanceable identity/severity mark. */\n icon: ComponentType<SVGAttributes<SVGSVGElement>>;\n /** Overall severity — tints the icon (and the primary count). */\n tone: TrayStatusTone;\n /** Primary number. Omit (or pass undefined) to show only the caption. */\n count?: number | undefined;\n /** Shown when there's no count (e.g. the all-clear / idle state). */\n caption?: string | undefined;\n /** Per-tone breakdown. Only renders when 2+ entries are non-zero. */\n segments?: TrayStatusSegment[] | undefined;\n /** Pulse the icon (e.g. unseen activity since minimize). */\n pulse?: boolean | undefined;\n}\n\nexport function TrayStatusChip({\n icon: Icon,\n tone,\n count,\n caption,\n segments,\n pulse,\n}: TrayStatusChipProps) {\n const t = TONE_CLASSES[tone];\n const visibleSegments = (segments ?? []).filter((s) => s.count > 0);\n const showBreakdown = visibleSegments.length > 1;\n const hasCount = typeof count === \"number\";\n\n // Scale matches the sibling `ErrorInspectorBadge` (h-3.5 icon / text-xs count\n // / text-[10px] detail) — the same tray text scale as every other preview.\n // Never bump these: a minimized card is 240px wide and must stay glanceable.\n return (\n <div className=\"flex h-full items-center gap-1.5 overflow-hidden\">\n <Icon\n className={cn(\"h-3.5 w-3.5 shrink-0\", t.fg, pulse && \"animate-pulse\")}\n aria-hidden\n />\n\n <div className=\"flex min-w-0 items-baseline gap-1\">\n {hasCount ? (\n <span className={cn(\"text-xs font-semibold tabular-nums\", t.fg)}>\n {count}\n </span>\n ) : null}\n {caption ? (\n <span className=\"truncate text-[11px] text-muted-foreground\">\n {caption}\n </span>\n ) : null}\n </div>\n\n {showBreakdown ? (\n <div className=\"ml-auto flex shrink-0 items-center gap-1\">\n {visibleSegments.map((s, i) => (\n <span\n key={i}\n className=\"flex items-center gap-0.5\"\n title={s.label ? `${s.count} ${s.label}` : undefined}\n >\n <span\n className={cn(\n \"h-1.5 w-1.5 rounded-full\",\n TONE_CLASSES[s.tone].dot,\n )}\n />\n <span className=\"text-[10px] tabular-nums text-muted-foreground\">\n {s.count}\n </span>\n </span>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n\nexport default TrayStatusChip;\n","\"use client\";\n\n/**\n * usePopoutContainer — return the element Radix portals (Tooltip, Popover,\n * Dropdown, Dialog, Select, AlertDialog, HoverCard) should mount into.\n *\n * **The problem this solves:** by default every Radix `Portal` mounts to\n * `document.body`. When a tooltip-trigger lives inside a popped-out window\n * but the popover content portals to the *parent* document, the tooltip\n * appears in the wrong window — typically invisible to the user.\n *\n * **The fix:** wrappers around Radix primitives call this hook and pass\n * the result as `<Primitive.Portal container={...} />`. Inside a popout,\n * the result is the popout's `<body>`. Outside a popout, the result is\n * `undefined`, which Radix interprets as \"use the default\" — meaning no\n * behavior change for any of the thousands of existing usages.\n *\n * **Why `undefined` instead of `null`?** Radix's `container` prop accepts\n * `HTMLElement | null | undefined`. Passing `null` actively tries to\n * portal into a `null` target and crashes. Passing `undefined` falls\n * through to the default (`document.body`). The `?? undefined` coerces\n * the `null` we get from `PopoutContext` outside a popout into the\n * Radix-friendly default-fallthrough value.\n */\nimport { usePopout } from \"./PopoutContext\";\n\nexport function usePopoutContainer(): HTMLElement | undefined {\n return usePopout().popoutContainer ?? undefined;\n}\n","// mayRaiseUnbidden\n// THE RULE: a window nobody opened may only raise itself where it lives.\n//\n// D11 (2026-09-17, found on `/exports`): the \"Spend so far today\" window opened\n// over the Bring-your-export drop zone. Parking it in the right gutter\n// (`resolvePosition`) fixed WHERE it landed; it did not fix that it appeared at\n// all on a route whose whole job is a drop zone. The defect is PRESENCE.\n//\n// So every automatic raiser asks here first, and the answer comes from ONE\n// source of truth — `unbiddenHome` on the window's registry metadata, beside\n// the rest of that window's facts. No route blocklists, no per-window special\n// cases, no `if (pathname === \"/exports\")` anywhere.\n//\n// DEFAULT DENY. A window that declares no home cannot raise itself anywhere,\n// and the refusal is announced on the console naming the window — a raiser that\n// silently never fires is indistinguishable from a broken one.\n//\n// THIS GOVERNS UNBIDDEN RAISES ONLY. A person clicking something that opens a\n// window is not asking this question: the ordinary openers\n// (`features/overlays/openers/*`) are untouched and still work on every route.\n//\n// DEFERRING IS NOT DISCARDING. An \"away from home\" refusal means \"not here, not\n// yet\" — the caller must leave its own once-per-day / once-per-session\n// bookkeeping ALONE so the window still raises on the viewer's next visit to a\n// home route.\n//\n// Doc: features/window-panels/FEATURE.md\n\nimport { getOverlayMeta, type UnbiddenHomeRoute } from \"@ai-matrx/summon\";\n\nexport type UnbiddenRefusalCode =\n /** The registry entry declares no `unbiddenHome` (or there is no entry). */\n | \"no-declared-home\"\n /** It has a home; the viewer is not on it. Try again when they are. */\n | \"away-from-home\";\n\nexport interface UnbiddenRaiseVerdict {\n /** True only when this window may raise itself, here, right now. */\n allowed: boolean;\n /** Plain-English why, for logs and for the caller's own warning. */\n reason: string;\n /** Set only when `allowed` is false. */\n code?: UnbiddenRefusalCode | undefined;\n /** The routes this window declared as home, for diagnostics (exact ones end in \" (exact)\"). */\n home: readonly string[];\n}\n\n/**\n * True when `pathname` is `route` itself or a page nested under it.\n * `/administration` covers `/administration/spend`; it does not cover\n * `/administration-archive`.\n */\nexport function isUnderRoute(pathname: string, route: string): boolean {\n if (pathname === route) return true;\n const base = route.endsWith(\"/\") ? route.slice(0, -1) : route;\n return pathname === base || pathname.startsWith(`${base}/`);\n}\n\nfunction describeHome(h: UnbiddenHomeRoute): string {\n return typeof h === \"string\" ? h : `${h.route} (exact)`;\n}\n\n/**\n * May this window raise ITSELF — with nobody having clicked anything — while\n * the viewer is on `pathname`?\n *\n * Refusals are announced, never swallowed: a window with no declared home\n * warns (that is a registry bug someone must fix), and an away-from-home\n * deferral logs at info (that is the system working as designed).\n */\nexport function mayRaiseUnbidden(\n overlayId: string,\n pathname: string | null | undefined,\n): UnbiddenRaiseVerdict {\n const entry = getOverlayMeta(overlayId);\n const declared: readonly UnbiddenHomeRoute[] = entry?.window?.unbiddenHome ?? [];\n const home = declared.map(describeHome);\n\n if (home.length === 0) {\n const reason = entry\n ? `window \"${overlayId}\" declared no unbiddenHome in the window registry, so it may not open itself on any route`\n : `overlay \"${overlayId}\" is not in the window registry, so it has no declared home and may not open itself anywhere`;\n console.warn(`[window-panels] unbidden raise refused — ${reason}`);\n return { allowed: false, reason, code: \"no-declared-home\", home };\n }\n\n if (!pathname) {\n const reason = `window \"${overlayId}\" was asked to open itself with no current route, so its home (${home.join(\", \")}) could not be confirmed`;\n console.warn(`[window-panels] unbidden raise refused — ${reason}`);\n return { allowed: false, reason, code: \"away-from-home\", home };\n }\n\n const matched = declared.find((h) =>\n typeof h === \"string\" ? isUnderRoute(pathname, h) : pathname === h.route,\n );\n const match = matched === undefined ? undefined : describeHome(matched);\n if (!match) {\n const reason = `window \"${overlayId}\" lives on ${home.join(\", \")} — not on \"${pathname}\" — so it is deferred until the viewer is on one of its own surfaces`;\n console.info(`[window-panels] unbidden raise deferred — ${reason}`);\n return { allowed: false, reason, code: \"away-from-home\", home };\n }\n\n return {\n allowed: true,\n reason: `window \"${overlayId}\" is on its declared home \"${match}\"`,\n home,\n };\n}\n","/**\n * assertLazyLoaded — an OPT-IN bundle guard for lazily rendered modules.\n *\n * Call it at the top level of a module that must only ever load through a lazy render import\n * (`render: () => import(\"./x.render\")`). If the module is parsed during initial app boot — i.e.\n * something statically imported it into the boot graph — a loud warning names the module and the\n * eager-import chain, once per module per session. A host opts in per module; nothing in this\n * package calls it.\n *\n * Boot detection: \"boot\" is the synchronous first evaluation pass. A global slot holds the flag\n * so an HMR re-evaluation or a duplicated module graph never re-enters boot.\n */\nimport { globalSlot } from \"@ai-matrx/kit/global-slot\";\n\ninterface GuardState {\n bootInProgress: boolean;\n readonly reported: Set<string>;\n}\n\nconst guard = (): GuardState =>\n globalSlot<GuardState>(\"ai-matrx.summon.lazyBundleGuard\", () => {\n const state: GuardState = { bootInProgress: typeof window !== \"undefined\", reported: new Set() };\n if (state.bootInProgress) {\n setTimeout(() => {\n state.bootInProgress = false;\n }, 0);\n }\n return state;\n });\n\n// Start the boot clock when this module first evaluates (it is evaluated with its importer).\nguard();\n\n/**\n * Warn when `moduleId` is evaluated during boot. `report` replaces the default console warning\n * (route it to the host's error sink).\n */\nexport function assertLazyLoaded(moduleId: string, report?: (message: string, stack: string) => void): void {\n if (typeof window === \"undefined\") return;\n // Capture the stack NOW, while the eager-import chain is still live.\n const callSiteStack = (new Error(\"call site\").stack ?? \"\")\n .split(\"\\n\")\n .filter((line) => !/lazy-bundle-guard\\.|at Error\\s*$|^Error/i.test(line))\n .join(\"\\n\");\n queueMicrotask(() => {\n const state = guard();\n if (!state.bootInProgress || state.reported.has(moduleId)) return;\n state.reported.add(moduleId);\n const message =\n `${moduleId} was parsed during initial app boot. Lazily rendered modules MUST load through ` +\n `their definition's render import — never statically from a route, layout, provider, or any ` +\n `module in the boot graph. (Reported once per session per module.)`;\n if (report) {\n report(message, callSiteStack);\n return;\n }\n console.warn(\n \"[overlays bundle leak]\",\n `\\n${message}${callSiteStack ? `\\n\\nEager-import chain (top frame is the file that statically imported it):\\n${callSiteStack}` : \"\"}`,\n );\n });\n}\n"],"mappings":"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","names":["useCallback","useEffect","useId","useRef","useState","FloatingLayer","useFloatingLayerZIndex","PortalContainerProvider","cn","createPortal","clampWindowRect","DEFAULT_INSTANCE_ID","dockWindow","buildDockWindowPayload","getOverlayMeta","safeViewportDims","selectOverlayData","selectPopoutMode","updateWindowRect","useSummonDispatch","useSummonPorts","useSummonSelector","useSummonStore","jsx","jsxs","GAP","useSyncExternalStore","useState","cn","cn","jsx","jsxs","Fragment","jsx","jsxs","useState","cn","useEffect","useRef","Button","cn","jsx","jsxs","useRef","useEffect","cn","Button","useEffect","useState","jsx","jsxs","cn","jsx","jsxs","useState","cn","jsx","jsxs","useState","cn","jsx","jsxs","cn","useCallback","useEffect","useRef","useSummonDispatch","useSummonSelector","useSyncExternalStore","globalSlot","state","useSummonDispatch","notify","useSummonSelector","useRef","useCallback","useEffect","useCallback","useSummonDispatch","dockWindow","buildDockWindowPayload","globalSlot","createPortal","useSummonSelector","selectPopoutMode","jsx","jsx","useSummonSelector","selectPopoutMode","createPortal","globalSlot","notify","getOverlayMeta","useSyncExternalStore","cn","useSummonPorts","useSummonSelector","jsx","jsxs","TrayChipPreview","useSummonPorts","useSummonSelector","state","DefaultTrayChipBody","TraySnapshotImage","useSyncExternalStore","cn","jsx","getOverlayMeta","getTrayPreviewEntry","Fragment","jsx","jsxs","cn","useSummonPorts","useId","getOverlayMeta","DEFAULT_INSTANCE_ID","useState","useEffect","useSummonSelector","state","selectOverlayData","useCallback","useSummonDispatch","useFloatingLayerZIndex","useRef","el","useSummonStore","updateWindowRect","safeViewportDims","selectPopoutMode","dockWindow","buildDockWindowPayload","clampWindowRect","createPortal","PortalContainerProvider","FloatingLayer","slot","useWindowConfig","WindowSelectionSurface","cn","jsx","jsxs","useEffect","getTrayPreviewEntry","cn","jsx","jsxs","getOverlayMeta","globalSlot","state"]}