@opengeni/react 7.4.0 → 7.5.0-canary.36919050519001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -27
- package/dist/artifacts-document.js +3 -2
- package/dist/artifacts-presentation.js +3 -2
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +1 -0
- package/dist/artifacts.js +516 -1413
- package/dist/artifacts.js.map +1 -1
- package/dist/{browser-viewer-2E6R2Y4W.js → browser-viewer-Z7S7QEJL.js} +6 -5
- package/dist/chat-interactive-block-UGBTNB3L.js +11 -0
- package/dist/{chunk-Y3QTZN2F.js → chunk-2VFNCX4E.js} +6 -6
- package/dist/{chunk-UDD6DLLT.js → chunk-3IJJEYW4.js} +15 -3
- package/dist/chunk-3IJJEYW4.js.map +1 -0
- package/dist/chunk-4RVYOY4O.js +379 -0
- package/dist/chunk-4RVYOY4O.js.map +1 -0
- package/dist/chunk-5CVXZA3Y.js +292 -0
- package/dist/chunk-5CVXZA3Y.js.map +1 -0
- package/dist/{chunk-5YK2ZDIG.js → chunk-5J4FOW6Q.js} +2 -10
- package/dist/chunk-5J4FOW6Q.js.map +1 -0
- package/dist/{chunk-KVERXCFY.js → chunk-5KYZIQFY.js} +40 -3
- package/dist/chunk-5KYZIQFY.js.map +1 -0
- package/dist/{chunk-KNDIXZN6.js → chunk-7UAMYXJY.js} +25 -18
- package/dist/{chunk-KNDIXZN6.js.map → chunk-7UAMYXJY.js.map} +1 -1
- package/dist/{chunk-SEEVCT36.js → chunk-A4UJB2MM.js} +2 -2
- package/dist/{chunk-X4HIN6TV.js → chunk-AFLPWUQ7.js} +71 -162
- package/dist/chunk-AFLPWUQ7.js.map +1 -0
- package/dist/chunk-B3V6TG77.js +41 -0
- package/dist/chunk-B3V6TG77.js.map +1 -0
- package/dist/{chunk-XEJEOAOV.js → chunk-B7WMS3CS.js} +51 -40
- package/dist/chunk-B7WMS3CS.js.map +1 -0
- package/dist/{chunk-S5JQ4R22.js → chunk-BDKR6BAR.js} +54 -24
- package/dist/chunk-BDKR6BAR.js.map +1 -0
- package/dist/{chunk-4MDLEHXL.js → chunk-DYWBUX5Q.js} +24 -12
- package/dist/chunk-DYWBUX5Q.js.map +1 -0
- package/dist/{chunk-YZ3YYMOM.js → chunk-E3G7SAYZ.js} +252 -624
- package/dist/chunk-E3G7SAYZ.js.map +1 -0
- package/dist/chunk-JT4JW7BC.js +54 -0
- package/dist/chunk-JT4JW7BC.js.map +1 -0
- package/dist/{chunk-5AZSK6MV.js → chunk-LWNLETQT.js} +5 -5
- package/dist/{chunk-USXVQACU.js → chunk-M7LBYP63.js} +5 -4
- package/dist/{chunk-USXVQACU.js.map → chunk-M7LBYP63.js.map} +1 -1
- package/dist/{chunk-L4OSXQ6H.js → chunk-NBOHNRLJ.js} +1289 -1060
- package/dist/chunk-NBOHNRLJ.js.map +1 -0
- package/dist/chunk-RHREZ7BO.js +11 -0
- package/dist/chunk-RHREZ7BO.js.map +1 -0
- package/dist/chunk-SCOTPE2I.js +589 -0
- package/dist/chunk-SCOTPE2I.js.map +1 -0
- package/dist/chunk-WEHMPOXK.js +39 -0
- package/dist/chunk-WEHMPOXK.js.map +1 -0
- package/dist/chunk-WRHIZYZF.js +988 -0
- package/dist/chunk-WRHIZYZF.js.map +1 -0
- package/dist/{chunk-3E2AITTZ.js → chunk-WUISZ3WU.js} +32 -28
- package/dist/{chunk-3E2AITTZ.js.map → chunk-WUISZ3WU.js.map} +1 -1
- package/dist/chunk-XCHWDJ22.js +107 -0
- package/dist/chunk-XCHWDJ22.js.map +1 -0
- package/dist/{chunk-DUEBTL3N.js → chunk-Y2PRMYLC.js} +4 -3
- package/dist/{chunk-DUEBTL3N.js.map → chunk-Y2PRMYLC.js.map} +1 -1
- package/dist/chunk-YBXQDQFX.js +1772 -0
- package/dist/chunk-YBXQDQFX.js.map +1 -0
- package/dist/chunk-YV4L3ILF.js +9 -0
- package/dist/chunk-YV4L3ILF.js.map +1 -0
- package/dist/{chunk-V2ABIVYJ.js → chunk-ZXSEDZP7.js} +70 -6
- package/dist/chunk-ZXSEDZP7.js.map +1 -0
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +27 -0
- package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
- package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
- package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
- package/dist/components/artifacts/editable-artifact-view.d.ts +46 -0
- package/dist/components/artifacts/index.d.ts +7 -0
- package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +23 -0
- package/dist/components/browser-select-control.d.ts +3 -1
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/desktop-viewer.d.ts +1 -1
- package/dist/components/message-timeline.d.ts +20 -3
- package/dist/components/open-geni-links.d.ts +16 -0
- package/dist/components/session-conversation.d.ts +20 -1
- package/dist/components/timeline-pill-geometry.d.ts +8 -0
- package/dist/components/timeline-pill-placement.d.ts +24 -0
- package/dist/components/usage-limit-notice.d.ts +49 -0
- package/dist/components/usage-member-list.d.ts +91 -0
- package/dist/components/usage-meter.d.ts +73 -0
- package/dist/composer.js +5 -5
- package/dist/{computer-viewer-WMJE6OA3.js → computer-viewer-KJWLH3GI.js} +7 -5
- package/dist/connect.js +7 -6
- package/dist/connect.js.map +1 -1
- package/dist/conversation-timeline.d.ts +1 -1
- package/dist/desktop.d.ts +7 -0
- package/dist/desktop.js +26 -0
- package/dist/desktop.js.map +1 -0
- package/dist/editor.d.ts +7 -0
- package/dist/editor.js +21 -0
- package/dist/editor.js.map +1 -0
- package/dist/hooks/latest-question.d.ts +1 -1
- package/dist/hooks/use-composer.d.ts +4 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +460 -1386
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +8 -6
- package/dist/interaction.js.map +1 -1
- package/dist/{latest-question-QB4EUCW5.js → latest-question-IS445HOW.js} +3 -3
- package/dist/lib/format.d.ts +6 -1
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/machines.js +2 -2
- package/dist/{markdown-table-layout-PFUEZ2U4.js → markdown-table-layout-QXSLK4BY.js} +37 -5
- package/dist/markdown-table-layout-QXSLK4BY.js.map +1 -0
- package/dist/{queue-surface-implementation-IM2HD3SK.js → queue-surface-implementation-2CAQAIHM.js} +2 -2
- package/dist/realtime.js +3 -3
- package/dist/{sandbox-files-PXPIZAFG.js → sandbox-files-AEJTWGT4.js} +8 -5
- package/dist/sandbox-files-AEJTWGT4.js.map +1 -0
- package/dist/session-ui.d.ts +9 -2
- package/dist/session-ui.js +39 -20
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +4 -4
- package/dist/sites.js +4 -289
- package/dist/sites.js.map +1 -1
- package/dist/terminal.d.ts +8 -0
- package/dist/terminal.js +31 -0
- package/dist/terminal.js.map +1 -0
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/genie-loading.d.ts +3 -1
- package/dist/timeline/types.d.ts +8 -1
- package/dist/{timeline-annotation-selection-ODLVF4OI.js → timeline-annotation-selection-DMLMM2TX.js} +6 -1
- package/dist/timeline-annotation-selection-DMLMM2TX.js.map +1 -0
- package/dist/timeline-pill-geometry-Z23V243M.js +110 -0
- package/dist/timeline-pill-geometry-Z23V243M.js.map +1 -0
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +13 -0
- package/dist/usage.js +1073 -0
- package/dist/usage.js.map +1 -0
- package/package.json +19 -3
- package/src/artifacts.ts +37 -0
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +185 -0
- package/src/components/artifacts/chat-interactive-block.tsx +260 -0
- package/src/components/artifacts/deferred-chat-media.tsx +67 -0
- package/src/components/artifacts/editable-artifact-ui.tsx +3 -1
- package/src/components/artifacts/editable-artifact-view.tsx +187 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
- package/src/components/artifacts/editable-document.tsx +34 -36
- package/src/components/artifacts/editable-presentation.tsx +21 -16
- package/src/components/artifacts/index.ts +41 -0
- package/src/components/artifacts/latest-task-runner.ts +49 -0
- package/src/components/artifacts/session-artifact-viewer.tsx +376 -0
- package/src/components/artifacts/site-view.tsx +116 -0
- package/src/components/browser-select-control.tsx +4 -1
- package/src/components/browser-viewer.tsx +81 -22
- package/src/components/code-editor.tsx +13 -16
- package/src/components/computer-viewer.tsx +51 -23
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/markdown-table-layout.ts +49 -5
- package/src/components/markdown.tsx +5 -2
- package/src/components/message-timeline.tsx +557 -516
- package/src/components/open-geni-links.tsx +24 -0
- package/src/components/sandbox-terminal.tsx +48 -11
- package/src/components/session-chrome.tsx +22 -3
- package/src/components/session-conversation.tsx +195 -102
- package/src/components/timeline-annotation-selection.tsx +7 -0
- package/src/components/timeline-pill-geometry.ts +169 -0
- package/src/components/timeline-pill-placement.ts +99 -0
- package/src/components/usage-limit-notice.tsx +179 -0
- package/src/components/usage-member-list.tsx +792 -0
- package/src/components/usage-meter.tsx +382 -0
- package/src/conversation-timeline.ts +10 -2
- package/src/desktop.ts +24 -0
- package/src/editor.ts +13 -0
- package/src/hooks/use-available-models.ts +1 -1
- package/src/hooks/use-composer.ts +57 -2
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-usage.ts +100 -0
- package/src/index.ts +22 -0
- package/src/lib/format.ts +32 -6
- package/src/lib/workbench-peers.ts +62 -0
- package/src/session-ui.ts +22 -0
- package/src/terminal.ts +26 -0
- package/src/timeline/activity-rail.tsx +5 -3
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/genie-loading.tsx +16 -6
- package/src/timeline/projection.ts +78 -4
- package/src/timeline/types.ts +8 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +50 -0
- package/styles/compiled.css +325 -0
- package/dist/chunk-4MDLEHXL.js.map +0 -1
- package/dist/chunk-5YK2ZDIG.js.map +0 -1
- package/dist/chunk-KVERXCFY.js.map +0 -1
- package/dist/chunk-L4OSXQ6H.js.map +0 -1
- package/dist/chunk-S5JQ4R22.js.map +0 -1
- package/dist/chunk-UDD6DLLT.js.map +0 -1
- package/dist/chunk-UGMKPUEM.js +0 -299
- package/dist/chunk-UGMKPUEM.js.map +0 -1
- package/dist/chunk-V2ABIVYJ.js.map +0 -1
- package/dist/chunk-X4HIN6TV.js.map +0 -1
- package/dist/chunk-XEJEOAOV.js.map +0 -1
- package/dist/chunk-YZ3YYMOM.js.map +0 -1
- package/dist/markdown-table-layout-PFUEZ2U4.js.map +0 -1
- package/dist/timeline-annotation-selection-ODLVF4OI.js.map +0 -1
- /package/dist/{browser-viewer-2E6R2Y4W.js.map → browser-viewer-Z7S7QEJL.js.map} +0 -0
- /package/dist/{computer-viewer-WMJE6OA3.js.map → chat-interactive-block-UGBTNB3L.js.map} +0 -0
- /package/dist/{chunk-Y3QTZN2F.js.map → chunk-2VFNCX4E.js.map} +0 -0
- /package/dist/{chunk-SEEVCT36.js.map → chunk-A4UJB2MM.js.map} +0 -0
- /package/dist/{chunk-5AZSK6MV.js.map → chunk-LWNLETQT.js.map} +0 -0
- /package/dist/{sandbox-files-PXPIZAFG.js.map → computer-viewer-KJWLH3GI.js.map} +0 -0
- /package/dist/{latest-question-QB4EUCW5.js.map → latest-question-IS445HOW.js.map} +0 -0
- /package/dist/{queue-surface-implementation-IM2HD3SK.js.map → queue-surface-implementation-2CAQAIHM.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/sandbox-files.tsx","../src/hooks/use-sandbox-files.ts","../src/lib/sandbox-liveness.ts","../src/file-node-visibility.ts","../src/components/code-editor.tsx","../src/components/file-browser.tsx","../src/lib/use-unicode-fonts.ts","../src/components/pierre-file.tsx"],"sourcesContent":["import { FileCode2Icon, FileWarningIcon, LoaderCircleIcon } from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\nimport { Group, Panel, Separator } from \"react-resizable-panels\";\nimport { cn } from \"../lib/cn\";\nimport { prefersReducedMotion } from \"../lib/motion\";\nimport { useThemeType } from \"../lib/use-theme-type\";\nimport {\n CapturedFileUnavailableError,\n type SandboxFilesGitSummary,\n type UseSandboxFilesResult,\n} from \"../hooks/use-sandbox-files\";\nimport type { UseSandboxGitResult } from \"../hooks/use-sandbox-git\";\nimport { filePathVisibility, type FileNodeVisibilityPredicate } from \"../file-node-visibility\";\nimport { CodeEditor } from \"./code-editor\";\nimport { FileBrowser } from \"./file-browser\";\nimport { PierreFile } from \"./pierre-file\";\n\nexport type SandboxFilesProps = {\n /** From `useSandboxFiles(...)`. */\n files: UseSandboxFilesResult;\n /** Compatibility fallback for callers that have not yet adopted `files.gitSummary`. */\n git?: UseSandboxGitResult | undefined;\n /** @deprecated Diffs live in the dedicated Changes tab now; accepted for\n * source-compat but unused (the Files surface is a browser + viewer). */\n stagedGit?: UseSandboxGitResult | undefined;\n /** Whether a FileSystem surface is advertised (drives the unavailable notice). */\n fileSystemAvailable?: boolean | undefined;\n /** Use Pierre's Shiki highlighter for the viewer (default true; plain fallback). */\n usePierre?: boolean | undefined;\n /** Allow in-place editing of tree files (CodeMirror). Default true. When false\n * the surface is review-only: every text file opens in the read-only viewer. */\n editable?: boolean | undefined;\n /** Fired once when the user first edits an open file (wake-on-edit intent). The\n * dock warms the box on this so the save lands fast; opening/reading never fires\n * it. Browsing the tree/diff must not warm a box. */\n onEditIntent?: (() => void) | undefined;\n /** Restore the file last viewed in this task. Invalid/missing paths still\n * surface the ordinary file-view error instead of changing files silently. */\n initialSelectedPath?: string | null | undefined;\n onSelectedPathChange?: ((path: string | null) => void) | undefined;\n /** Presentation-only node filter shared with the tree and selected-file view. */\n isNodeVisible?: FileNodeVisibilityPredicate | undefined;\n /** A deliberate file-open path routed here by the parent workspace. */\n requestedPath?: string | undefined;\n /** 1-based line to reveal after `requestedPath` opens. */\n requestedLine?: number | null | undefined;\n /** Identity for one guarded-file request. Increment this when the same path is\n * deliberately requested again; it also lets a pending request be consumed\n * without overriding later manual tree navigation. Defaults to the path. */\n requestedPathRequestId?: string | number | undefined;\n /** False while the parent is waking a cold sandbox for `requestedPath`. */\n requestedPathReady?: boolean | undefined;\n /** The machine is cold and no durable capture exists yet. Render an explicit\n * wake gate instead of an empty-tree lie or an implicit Channel-A read. */\n workspaceResting?: boolean | undefined;\n /** A deliberate wake has started but the live file surface is not ready yet. */\n workspaceWaking?: boolean | undefined;\n /** Whether live reads are currently authoritative. */\n liveWorkspaceReady?: boolean | undefined;\n /** Failed live negotiation; never present a failure as an ongoing wake. */\n workspaceError?: Error | null | undefined;\n /** Deliberately wake the machine to read content absent from the capture. */\n onWakeWorkspace?: (() => void) | undefined;\n themeType?: \"dark\" | \"light\" | undefined;\n className?: string | undefined;\n};\n\n/**\n * The Files surface: a branch/dirty header, the full lazy file tree, and a\n * viewer/editor pane for the selected file. This is the workspace BROWSER — pick\n * a file to read or edit it. Diff review lives in the dedicated Changes tab (this\n * surface deliberately does NOT replicate the changed-files list, and does not\n * diff here — one job per tab). The agent commits; the human reviews.\n */\nexport function SandboxFiles({\n files,\n git,\n fileSystemAvailable = true,\n usePierre = true,\n editable = true,\n onEditIntent,\n initialSelectedPath,\n onSelectedPathChange,\n isNodeVisible,\n requestedPath,\n requestedLine,\n requestedPathRequestId,\n requestedPathReady = true,\n workspaceResting = false,\n workspaceWaking = false,\n liveWorkspaceReady = true,\n workspaceError = null,\n onWakeWorkspace,\n themeType,\n className,\n}: SandboxFilesProps) {\n const [selected, setSelected] = useState<string | null>(() => initialSelectedPath ?? null);\n // View vs Edit for the selected file. Resets to View on every new selection so\n // opening a file never lands you in a stale dirty editor for a different path.\n const [editMode, setEditMode] = useState(false);\n const [focusLine, setFocusLine] = useState<number | null>(null);\n const [treeRevealRequest, setTreeRevealRequest] = useState<{\n path: string;\n requestId: string | number;\n } | null>(null);\n const [liveRequestedPath, setLiveRequestedPath] = useState<string | null>(null);\n const [viewReloadRevision, setViewReloadRevision] = useState(0);\n const viewerScrollRef = useRef<HTMLDivElement | null>(null);\n const pendingRequestRef = useRef<string | number | null>(null);\n const handledRequestRef = useRef<string | number | null>(null);\n const requestKey = requestedPath ? (requestedPathRequestId ?? requestedPath) : null;\n\n useEffect(() => {\n if (!requestedPath || requestKey === null) {\n pendingRequestRef.current = null;\n handledRequestRef.current = null;\n setTreeRevealRequest(null);\n return;\n }\n if (handledRequestRef.current === requestKey) {\n return;\n }\n if (!requestedPathReady) {\n pendingRequestRef.current = requestKey;\n setTreeRevealRequest(null);\n return;\n }\n if (isNodeVisible && files.loading && files.tree.length === 0) return;\n if (isNodeVisible && !files.loading && files.tree.length === 0) {\n handledRequestRef.current = requestKey;\n pendingRequestRef.current = null;\n setTreeRevealRequest(null);\n return;\n }\n if (filePathVisibility(files.tree, requestedPath, isNodeVisible) === \"hidden\") {\n handledRequestRef.current = requestKey;\n pendingRequestRef.current = null;\n setTreeRevealRequest(null);\n return;\n }\n handledRequestRef.current = requestKey;\n pendingRequestRef.current = null;\n setSelected(requestedPath);\n onSelectedPathChange?.(requestedPath);\n setEditMode(false);\n setFocusLine(requestedLine != null && requestedLine > 0 ? requestedLine : null);\n setTreeRevealRequest({ path: requestedPath, requestId: requestKey });\n setViewReloadRevision((revision) => revision + 1);\n }, [\n files.loading,\n files.tree,\n isNodeVisible,\n onSelectedPathChange,\n requestKey,\n requestedLine,\n requestedPath,\n requestedPathReady,\n ]);\n\n // Side-by-side (tree left, viewer right) once the surface is wide enough;\n // stacked (tree over viewer) on a narrow dock. Tracked off the container so it\n // reacts to the dock resize, not just the viewport.\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [wide, setWide] = useState(false);\n useEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n const update = () => setWide(el.getBoundingClientRect().width >= 720);\n update();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(update);\n observer.observe(el);\n // WorkspaceDock maximization changes its persistent surface from a sized\n // panel child to `fixed inset-0`. Chromium can retain the child's observer\n // size across that containing-block change even though its visible bounding\n // box is now viewport-wide. Follow the surface mode as a deterministic\n // second signal so the tree/viewer orientation matches what is painted.\n const surface = el.closest(\"[data-workspace-surface]\");\n const surfaceObserver =\n surface && typeof MutationObserver !== \"undefined\" ? new MutationObserver(update) : null;\n surfaceObserver?.observe(surface!, {\n attributes: true,\n attributeFilter: [\"class\", \"style\"],\n });\n return () => {\n observer.disconnect();\n surfaceObserver?.disconnect();\n };\n }, []);\n // Resolve the effective viewer theme from the host palette (the `data-og-theme`\n // attribute the demo/app sets), defaulting to dark, unless the caller forced one.\n const resolvedTheme = useThemeType(themeType);\n\n // The selected tree file opens in the viewer (read-only) or the editor (when\n // writable). Nothing is auto-selected — the pane waits for a tree click, so the\n // Files tab opens as a calm browser, not a diff.\n const selectedVisibility = selected\n ? filePathVisibility(files.tree, selected, isNodeVisible)\n : \"unknown\";\n const visibilityPending = Boolean(isNodeVisible && files.loading && files.tree.length === 0);\n const viewPath = selectedVisibility === \"hidden\" || visibilityPending ? null : selected;\n useEffect(() => {\n if (selected === null || selectedVisibility !== \"hidden\") return;\n setSelected(null);\n onSelectedPathChange?.(null);\n setEditMode(false);\n setFocusLine(null);\n setTreeRevealRequest(null);\n setLiveRequestedPath(null);\n }, [onSelectedPathChange, selected, selectedVisibility]);\n const fileView = useFileView(\n viewPath,\n files.readFile,\n `${files.contentRevision ?? 0}:${viewReloadRevision}`,\n );\n\n useEffect(() => {\n if (focusLine === null && viewReloadRevision > 0 && viewerScrollRef.current) {\n viewerScrollRef.current.scrollTop = 0;\n }\n }, [focusLine, viewReloadRevision]);\n\n // Selecting a (different) file always returns to View — never drop the user into\n // an editor whose buffer belongs to the previously-selected path. Manual\n // navigation also consumes a pending guarded-file request: a late cold→warm\n // transition must never pull the user away from the file they chose meanwhile.\n const selectFile = useCallback(\n (path: string) => {\n if (pendingRequestRef.current !== null) {\n handledRequestRef.current = pendingRequestRef.current;\n pendingRequestRef.current = null;\n }\n setSelected(path);\n onSelectedPathChange?.(path);\n setEditMode(false);\n setFocusLine(null);\n setTreeRevealRequest(null);\n setLiveRequestedPath(null);\n setViewReloadRevision(0);\n },\n [onSelectedPathChange],\n );\n\n // A tree file is editable only when it is a real, fully-loaded text file: not\n // binary (would corrupt on save) and not truncated (we only hold a PREFIX). The\n // editor is then additionally gated on the `editable` prop; anything failing this\n // opens read-only in the viewer.\n const canEdit =\n editable &&\n viewPath !== null &&\n !fileView.loading &&\n fileView.error === null &&\n !fileView.isBinary &&\n !fileView.truncated &&\n fileView.content !== null;\n const showEditor = canEdit && editMode;\n const captureFileUnavailable =\n fileView.error instanceof CapturedFileUnavailableError ? fileView.error : null;\n const waitingForSelectedFile =\n !workspaceError &&\n liveRequestedPath === viewPath &&\n (!liveWorkspaceReady || files.loading) &&\n captureFileUnavailable !== null;\n\n if (workspaceError && !liveWorkspaceReady && files.source !== \"capture\") {\n return (\n <Notice className={className} title=\"Could not open live workspace\" announce=\"alert\">\n <p>{workspaceError.message}</p>\n {onWakeWorkspace ? (\n <WakeButton onClick={onWakeWorkspace}>Retry live workspace</WakeButton>\n ) : null}\n </Notice>\n );\n }\n\n if (workspaceResting || workspaceWaking) {\n return (\n <div className={cn(\"h-full\", className)} data-opengeni-workspace-resting>\n <Notice\n icon={\n workspaceWaking ? (\n <LoaderCircleIcon\n className=\"size-5 animate-spin motion-reduce:animate-none\"\n aria-hidden\n />\n ) : (\n <FileCode2Icon className=\"size-5\" aria-hidden />\n )\n }\n title={workspaceWaking ? \"Waking workspace\" : \"Workspace is resting\"}\n announce=\"status\"\n >\n <p>\n {workspaceWaking\n ? \"Connecting to the live file system…\"\n : \"No captured revision is available yet. Wake the sandbox to browse its current files.\"}\n </p>\n {!workspaceWaking && onWakeWorkspace ? (\n <WakeButton onClick={onWakeWorkspace}>Open live workspace</WakeButton>\n ) : null}\n </Notice>\n </div>\n );\n }\n\n if (!fileSystemAvailable) {\n return (\n <Notice\n className={className}\n icon={<FileWarningIcon className=\"size-5\" aria-hidden />}\n title=\"Files unavailable\"\n announce=\"alert\"\n >\n This sandbox does not expose a file system.\n </Notice>\n );\n }\n\n return (\n <div ref={rootRef} className={cn(\"flex h-full min-h-0 min-w-0 flex-col\", className)}>\n {/* Branch + dirty header (context; NOT the changed-files list). */}\n <GitHeader\n loading={\n Boolean(files.loading || files.gitLoading || files.source === null || git?.loading) &&\n files.gitSummary === null\n }\n git={\n files.gitSummary ?? {\n branch: git?.branch ?? null,\n isRepo: git?.isRepo ?? false,\n repoCount: git?.repoCount ?? 0,\n ahead: git?.ahead ?? 0,\n behind: git?.behind ?? 0,\n dirtyCount: git?.diff.length ?? 0,\n }\n }\n />\n\n <Group\n orientation={wide ? \"horizontal\" : \"vertical\"}\n className={cn(\"min-h-0 flex-1\", wide ? \"flex-row\" : \"flex-col\")}\n >\n {/* Tree pane: the full lazy file tree. A fixed left column when wide, a top\n band when narrow. */}\n <Panel\n id=\"sandbox-files-tree\"\n defaultSize={wide ? \"280px\" : \"40%\"}\n minSize={wide ? \"180px\" : \"120px\"}\n maxSize={wide ? \"60%\" : \"70%\"}\n className=\"flex min-h-0 min-w-0 flex-col\"\n >\n <FileBrowser\n result={files}\n isNodeVisible={isNodeVisible}\n selectedPath={selected ?? undefined}\n {...(treeRevealRequest\n ? {\n revealPath: treeRevealRequest.path,\n revealPathRequestId: treeRevealRequest.requestId,\n }\n : {})}\n onSelectFile={selectFile}\n editable={editable}\n emptyState=\"This directory is empty\"\n className=\"min-w-0 flex-1\"\n />\n </Panel>\n\n <Separator\n aria-label=\"Resize file tree\"\n className={cn(\n \"group relative z-10 shrink-0 cursor-col-resize outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent\",\n \"w-px bg-og-border after:absolute after:inset-y-0 after:left-1/2 after:w-3 after:-translate-x-1/2\",\n \"hover:bg-og-accent focus-visible:bg-og-accent data-[separator-state=dragging]:bg-og-accent\",\n !wide &&\n \"h-px w-full cursor-row-resize after:inset-x-0 after:inset-y-auto after:top-1/2 after:h-3 after:w-full after:-translate-x-0 after:-translate-y-1/2\",\n )}\n />\n\n {/* Viewer pane: the selected file's contents (read-only) or the editor.\n Fills the remaining width when side-by-side, sits below the tree when\n stacked. */}\n <Panel\n id=\"sandbox-files-viewer\"\n minSize={wide ? \"240px\" : \"160px\"}\n className={cn(\"flex min-h-0 min-w-0 flex-col\", !wide && \"border-t border-og-border\")}\n >\n <div className=\"flex shrink-0 items-center justify-between gap-2 border-b border-og-border bg-og-surface-1 px-2 py-1\">\n <span\n data-opengeni-selected-file\n className=\"min-w-0 truncate font-og-mono text-og-xs text-og-fg-muted\"\n >\n {selected\n ? focusLine !== null\n ? `${selected}:${focusLine}`\n : selected\n : \"No file selected\"}\n </span>\n {/* View/Edit toggle — only for a real, fully-loaded text file the editor\n can safely round-trip. Binary/truncated/read-only files never get an\n Edit affordance (they'd corrupt on save or can't be written). */}\n {canEdit && (\n <Segmented\n options={[\n { value: \"view\", label: \"View\" },\n { value: \"edit\", label: \"Edit\" },\n ]}\n value={editMode ? \"edit\" : \"view\"}\n onChange={(v) => setEditMode(v === \"edit\")}\n />\n )}\n </div>\n <div\n ref={viewerScrollRef}\n className=\"min-h-0 flex-1 overflow-auto\"\n data-opengeni-file-viewer-scroll\n >\n {viewPath ? (\n showEditor && fileView.content !== null ? (\n <CodeEditor\n key={viewPath}\n path={viewPath}\n initialContents={fileView.content}\n themeType={resolvedTheme}\n onSave={(contents, expectedContents) =>\n files.writeFile(viewPath, contents, { expectedContent: expectedContents })\n }\n onOverwrite={(contents) => files.writeFile(viewPath, contents, { force: true })}\n onReload={() => setViewReloadRevision((revision) => revision + 1)}\n {...(onEditIntent ? { onEditIntent } : {})}\n className=\"h-full\"\n />\n ) : workspaceError &&\n (liveRequestedPath === viewPath || requestedPath === viewPath) &&\n !liveWorkspaceReady ? (\n <Notice title=\"Could not open live file\" announce=\"alert\">\n <p>{workspaceError.message}</p>\n {onWakeWorkspace ? (\n <WakeButton onClick={onWakeWorkspace}>Retry live file</WakeButton>\n ) : null}\n </Notice>\n ) : waitingForSelectedFile ? (\n <Notice\n icon={\n <LoaderCircleIcon\n className=\"size-5 animate-spin motion-reduce:animate-none\"\n aria-hidden\n />\n }\n title=\"Waking workspace\"\n announce=\"status\"\n >\n Opening {viewPath} when the live file system is ready…\n </Notice>\n ) : captureFileUnavailable ? (\n <Notice icon={<FileCode2Icon className=\"size-5\" aria-hidden />} title=\"On machine\">\n <p>\n {captureFileUnavailable.reason === \"too-large\"\n ? \"This file is larger than the captured preview limit.\"\n : captureFileUnavailable.reason === \"content-missing\"\n ? \"The captured copy is no longer available.\"\n : \"This file was indexed, but it was not changed in the captured turn.\"}\n </p>\n {onWakeWorkspace ? (\n <WakeButton\n onClick={() => {\n setLiveRequestedPath(viewPath);\n if (liveWorkspaceReady) void files.refresh();\n else onWakeWorkspace();\n }}\n >\n {liveWorkspaceReady ? \"Retry live file\" : \"Open live file\"}\n </WakeButton>\n ) : null}\n </Notice>\n ) : fileView.error ? (\n <Notice announce=\"alert\">\n Could not open {viewPath}: {fileView.error.message}\n </Notice>\n ) : fileView.loading ? (\n <Notice announce=\"status\">Loading {viewPath}…</Notice>\n ) : fileView.imageUrl ? (\n <RasterFilePreview\n key={fileView.imageUrl}\n src={fileView.imageUrl}\n path={viewPath}\n />\n ) : fileView.isBinary ? (\n <Notice>\n {viewPath} is a binary file ({fileView.sizeBytes ?? 0} bytes).\n </Notice>\n ) : fileView.content !== null ? (\n <>\n {fileView.truncated && (\n <div className=\"border-b border-og-border bg-og-surface-1 px-2 py-1 text-og-xs text-og-status-running\">\n Large file — showing a truncated preview ({fileView.sizeBytes ?? 0} bytes\n loaded). Editing is disabled to avoid corrupting the file.\n </div>\n )}\n {usePierre && focusLine === null ? (\n <PierreFile\n key={`${viewPath}:${viewReloadRevision}`}\n path={viewPath}\n contents={fileView.content}\n themeType={resolvedTheme}\n fallback={\n <pre className=\"overflow-auto whitespace-pre p-2 font-og-mono text-og-sm text-og-fg\">\n {fileView.content}\n </pre>\n }\n className=\"p-1\"\n />\n ) : focusLine !== null ? (\n <LineNumberedFile\n path={viewPath}\n contents={fileView.content}\n focusLine={focusLine}\n />\n ) : (\n <pre className=\"overflow-auto whitespace-pre p-2 font-og-mono text-og-sm text-og-fg\">\n {fileView.content}\n </pre>\n )}\n </>\n ) : (\n <Notice announce=\"status\">Loading {viewPath}…</Notice>\n )\n ) : // Nothing selected — the tree shows the whole workspace; pick a file.\n requestedPath && !requestedPathReady ? (\n workspaceError ? (\n <Notice title=\"Could not open live file\" announce=\"alert\">\n <p>{workspaceError.message}</p>\n {onWakeWorkspace ? (\n <WakeButton onClick={onWakeWorkspace}>Retry live file</WakeButton>\n ) : null}\n </Notice>\n ) : (\n <Notice\n icon={\n <LoaderCircleIcon\n className=\"size-5 animate-spin motion-reduce:animate-none\"\n aria-hidden\n />\n }\n title=\"Waking sandbox\"\n announce=\"status\"\n >\n Opening {requestedPath} when the live workspace is ready…\n </Notice>\n )\n ) : (\n <Notice icon={<FileCode2Icon className=\"size-5\" aria-hidden />} title=\"Choose a file\">\n Select a file in the tree to preview it.\n </Notice>\n )}\n </div>\n </Panel>\n </Group>\n </div>\n );\n}\n\nfunction WakeButton({ children, onClick }: { children: ReactNode; onClick: () => void }) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className=\"mt-1 inline-flex min-h-11 items-center justify-center rounded-og-md border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-2 text-og-sm font-medium transition-colors hover:bg-og-primary-hover focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent focus-visible:ring-offset-2 focus-visible:ring-offset-og-bg\"\n >\n {children}\n </button>\n );\n}\n\nfunction LineNumberedFile({\n path,\n contents,\n focusLine,\n}: {\n path: string;\n contents: string;\n focusLine: number;\n}) {\n const lines = contents.split(\"\\n\");\n const inRange = focusLine >= 1 && focusLine <= lines.length;\n const targetRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n targetRef.current?.scrollIntoView({\n block: \"center\",\n behavior: prefersReducedMotion() ? \"auto\" : \"smooth\",\n });\n }, [path, focusLine, contents]);\n\n return (\n <div\n className=\"h-full min-h-0 overflow-auto font-og-mono text-og-sm text-og-fg\"\n role=\"region\"\n aria-label={inRange ? `${path} at line ${focusLine}` : path}\n >\n {!inRange ? (\n <p\n className=\"border-b border-og-border bg-og-surface-1 px-2 py-1 text-og-xs text-og-fg-muted\"\n role=\"status\"\n >\n Line {focusLine} is past the end of this file.\n </p>\n ) : null}\n <div>\n {lines.map((text, index) => {\n const lineNumber = index + 1;\n const focused = inRange && lineNumber === focusLine;\n return (\n <div\n key={lineNumber}\n ref={focused ? targetRef : undefined}\n data-opengeni-file-line={lineNumber}\n {...(focused ? { \"data-opengeni-focus-line\": \"\" } : {})}\n aria-current={focused ? \"location\" : undefined}\n className={cn(\"flex gap-3 px-2 py-0.5 leading-6\", focused && \"bg-og-accent-soft\")}\n >\n <span className=\"w-11 shrink-0 select-none text-right tabular-nums text-og-fg-subtle\">\n {lineNumber}\n </span>\n <pre className=\"min-w-0 flex-1 whitespace-pre-wrap break-words\">{text || \" \"}</pre>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction GitHeader({ git, loading }: { git: SandboxFilesGitSummary; loading: boolean }) {\n if (loading) {\n return (\n <div\n className=\"flex shrink-0 items-center gap-2 border-b border-og-border bg-og-surface-1 px-2 py-1 text-og-sm text-og-fg-muted\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <LoaderCircleIcon\n className=\"size-3.5 shrink-0 animate-spin motion-reduce:animate-none\"\n aria-hidden\n />\n <span>Loading repository…</span>\n </div>\n );\n }\n const dirty = git.dirtyCount > 0;\n return (\n <div className=\"flex shrink-0 items-center gap-2 border-b border-og-border bg-og-surface-1 px-2 py-1 text-og-sm\">\n <span\n aria-hidden=\"true\"\n className={cn(\n \"size-2 shrink-0 rounded-full\",\n dirty ? \"bg-og-status-running\" : \"bg-og-status-idle\",\n )}\n />\n <span className=\"sr-only\">\n {dirty ? `Uncommitted changes in ${git.dirtyCount} files` : \"No uncommitted changes\"}\n </span>\n <span className=\"truncate font-og-mono text-og-fg\">\n {git.repoCount > 1\n ? `${git.repoCount} repositories`\n : (git.branch ?? (git.isRepo ? \"(detached)\" : \"no repo\"))}\n </span>\n {(git.ahead > 0 || git.behind > 0) && (\n <span className=\"flex shrink-0 items-center gap-1.5 text-og-xs text-og-fg-subtle\">\n {/* Small arrow glyphs can make axe's pixel overlap heuristic inconclusive.\n Keep both counters in the same computed-contrast audit as the dirty count. */}\n {git.ahead > 0 && <span data-contrast-audited>↑{git.ahead}</span>}\n {git.behind > 0 && <span data-contrast-audited>↓{git.behind}</span>}\n </span>\n )}\n {dirty && (\n <span\n aria-hidden=\"true\"\n data-contrast-audited\n className=\"ml-auto shrink-0 text-og-xs text-og-fg-subtle\"\n >\n {git.dirtyCount} changed\n </span>\n )}\n </div>\n );\n}\n\nfunction Segmented({\n options,\n value,\n onChange,\n}: {\n options: { value: string; label: string }[];\n value: string;\n onChange: (value: string) => void;\n}) {\n return (\n <div className=\"flex flex-wrap items-center rounded-og-sm border border-og-border p-0.5\">\n {options.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => onChange(opt.value)}\n className={cn(\n \"min-h-7 rounded-og-xs px-1.5 py-0.5 text-og-xs focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent max-[1023px]:min-h-11 max-[1023px]:min-w-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11\",\n opt.value === value\n ? \"bg-og-accent-soft text-og-fg\"\n : \"text-og-fg-subtle hover:text-og-fg\",\n )}\n >\n {opt.label}\n </button>\n ))}\n </div>\n );\n}\n\ntype FileViewState = {\n content: string | null;\n imageUrl?: string | null;\n isBinary: boolean;\n /** The backend truncated the read (size cap hit) — content is a PREFIX only.\n * Editing+saving such a file would write the prefix back and corrupt it, so\n * the editor must stay read-only for a truncated read. */\n truncated: boolean;\n sizeBytes: number | null;\n loading: boolean;\n error: Error | null;\n};\n\n/**\n * Read a file's contents for the viewer pane. Calls `fs.read` (text by default;\n * the backend flags binary), decodes a base64 payload if one comes back, and\n * exposes loading/error/binary state. Re-fetches when the path changes; ignores\n * a stale resolve after the selection moves on.\n */\nfunction useFileView(\n path: string | null,\n readFile: UseSandboxFilesResult[\"readFile\"],\n reloadRevision: string | number = 0,\n): FileViewState {\n const previousPathRef = useRef<string | null>(null);\n const [state, setState] = useState<FileViewState>({\n content: null,\n isBinary: false,\n truncated: false,\n sizeBytes: null,\n loading: false,\n error: null,\n });\n useEffect(() => {\n if (!path) {\n previousPathRef.current = null;\n setState({\n content: null,\n isBinary: false,\n truncated: false,\n sizeBytes: null,\n loading: false,\n error: null,\n });\n return;\n }\n const pathChanged = previousPathRef.current !== path;\n previousPathRef.current = path;\n let cancelled = false;\n const abort = new AbortController();\n if (pathChanged) {\n setState({\n content: null,\n isBinary: false,\n truncated: false,\n sizeBytes: null,\n loading: true,\n error: null,\n });\n } else {\n // Keep the last successful preview visible while a remote Modal read\n // revalidates it. Replacing useful content with a multi-second spinner\n // makes a live workspace feel slower and hides the state being refreshed.\n setState((previous) => ({ ...previous, error: null }));\n }\n void readFile(path, { signal: abort.signal })\n .then((res) => {\n if (cancelled) return;\n const content = res.isBinary\n ? null\n : res.encoding === \"base64\"\n ? decodeBase64Utf8(res.content)\n : res.content;\n setState({\n content,\n imageUrl:\n !res.truncated && res.encoding === \"base64\" ? rasterImageUrl(path, res.content) : null,\n isBinary: res.isBinary,\n truncated: res.truncated,\n sizeBytes: res.sizeBytes,\n loading: false,\n error: null,\n });\n })\n .catch((cause) => {\n if (cancelled) return;\n const error = cause instanceof Error ? cause : new Error(String(cause));\n setState((previous) =>\n pathChanged\n ? {\n content: null,\n isBinary: false,\n truncated: false,\n sizeBytes: null,\n loading: false,\n error,\n }\n : { ...previous, loading: false, error },\n );\n });\n return () => {\n cancelled = true;\n abort.abort();\n };\n }, [path, readFile, reloadRevision]);\n return state;\n}\n\n/** Only raster formats belong in this preview; never interpret SVG/HTML as a document. */\nfunction rasterImageUrl(path: string, content: string): string | null {\n const extension = path.split(\".\").pop()?.toLowerCase();\n const mime =\n extension === \"png\"\n ? \"image/png\"\n : extension === \"jpg\" || extension === \"jpeg\"\n ? \"image/jpeg\"\n : extension === \"gif\"\n ? \"image/gif\"\n : extension === \"webp\"\n ? \"image/webp\"\n : null;\n return mime ? `data:${mime};base64,${content}` : null;\n}\n\nfunction RasterFilePreview({ src, path }: { src: string; path: string }) {\n const [failed, setFailed] = useState(false);\n return failed ? (\n <Notice title=\"Image preview unavailable\" announce=\"alert\">\n Could not decode {path} as an image.\n </Notice>\n ) : (\n <img\n src={src}\n alt={path}\n onError={() => setFailed(true)}\n className=\"max-w-full object-contain\"\n />\n );\n}\n\n/** Decode a base64 payload to a UTF-8 string (browser `atob` + TextDecoder). */\nfunction decodeBase64Utf8(b64: string): string {\n try {\n if (typeof atob === \"function\") {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return new TextDecoder().decode(bytes);\n }\n } catch {\n /* fall through to returning the raw payload */\n }\n return b64;\n}\n\nfunction Notice({\n children,\n className,\n icon,\n title,\n announce,\n}: {\n children: ReactNode;\n className?: string | undefined;\n icon?: ReactNode | undefined;\n title?: string | undefined;\n announce?: \"status\" | \"alert\" | undefined;\n}) {\n return (\n <div\n role={announce}\n aria-atomic={announce ? \"true\" : undefined}\n aria-live={announce === \"alert\" ? \"assertive\" : announce === \"status\" ? \"polite\" : undefined}\n className={cn(\n \"flex h-full items-center justify-center p-4 text-center text-og-sm text-og-fg-subtle\",\n className,\n )}\n >\n <div className=\"flex max-w-sm flex-col items-center gap-2.5\">\n {icon ? (\n <span className=\"grid size-10 place-items-center rounded-og-lg border border-og-border bg-og-surface-1 text-og-fg-muted shadow-sm\">\n {icon}\n </span>\n ) : null}\n {title ? <p className=\"font-medium text-og-fg\">{title}</p> : null}\n <div data-contrast-audited className=\"leading-5\">\n {children}\n </div>\n </div>\n </div>\n );\n}\n","import type {\n FileSystemRouteIdentity,\n FsChangedPayload,\n FsReadResponse,\n FsTreeNode,\n FsWriteResponse,\n GitChangedPayload,\n GitFileStatusCode,\n GitStatusResponse,\n OpenGeniRequestOptions,\n SessionCapabilities,\n SessionEvent,\n WorkspaceCaptureManifest,\n} from \"@opengeni/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { type ClientOverride, useOpenGeni } from \"../provider\";\nimport { sandboxAcceptsLiveIo } from \"../lib/sandbox-liveness\";\n\n/** The git-status overlay a file row may carry (tints modified files in the tree). */\nexport type FileTreeStatus = \"added\" | \"modified\" | \"deleted\" | \"renamed\" | \"untracked\";\n\nexport type CapturedFileUnavailableReason = \"not-captured\" | \"too-large\" | \"content-missing\";\n\n/** A cold capture can index a path without retaining its contents. Components\n * use this typed result to offer an explicit wake action instead of silently\n * turning passive review into a live sandbox read. */\nexport class CapturedFileUnavailableError extends Error {\n readonly code = \"captured_file_unavailable\";\n\n constructor(\n readonly path: string,\n readonly reason: CapturedFileUnavailableReason,\n ) {\n super(\n reason === \"too-large\"\n ? `${path} exceeds the captured preview limit.`\n : reason === \"content-missing\"\n ? `${path} is no longer available in this capture.`\n : `${path} was not changed in this captured turn.`,\n );\n this.name = \"CapturedFileUnavailableError\";\n }\n}\n\nexport class FileWriteConflictError extends Error {\n readonly code = \"file_write_conflict\";\n\n constructor(\n readonly path: string,\n readonly expectedContent: string,\n readonly liveContent: string,\n ) {\n super(`${path} changed on the machine. Reload it or explicitly overwrite the live version.`);\n this.name = \"FileWriteConflictError\";\n }\n}\n\nexport type SandboxWriteFileOptions = {\n /** Exact text loaded into the editor. The live file is re-read before write;\n * divergence fails closed with FileWriteConflictError. */\n expectedContent?: string | undefined;\n /** Deliberately bypass the expected-content guard after a visible conflict. */\n force?: boolean | undefined;\n};\n\n/** A node in the Pierre file tree. `children === undefined` ⇒ an unexpanded dir\n * (lazy treeMode); `children: []` ⇒ an expanded-but-empty dir. */\nexport type FileTreeNode = {\n /** Opaque path returned by the selected target's FileSystem boundary. */\n path: string;\n name: string;\n kind: \"file\" | \"dir\";\n children?: FileTreeNode[] | undefined;\n size?: number | null | undefined;\n status?: FileTreeStatus | undefined;\n /** A residue dir the capture COLLAPSED (node_modules, .git, dist, …): its\n * contents were never indexed. Cold, expanding it can't list children — the\n * UI shows an inline \"contents on machine\" row until the box is warm. */\n truncated?: boolean | undefined;\n};\n\nexport type UseSandboxFilesOptions = ClientOverride & {\n /** Live event log (usually `useSessionEvents().events`) — drives auto-refresh\n * on `fs.changed` / `git.changed`. */\n events?: SessionEvent[] | undefined;\n /** Initial path to list (workspace root by default). */\n rootPath?: string | undefined;\n /** Exact capability identity for the selected filesystem route. A route/root\n * change resets this hook and makes stale provider requests fail retryably. */\n route?: FileSystemRouteIdentity | undefined;\n /** Hold off the initial list (e.g. panel collapsed). Default true. */\n enabled?: boolean | undefined;\n /** Pause live reads/invalidation while preserving the last rendered result. */\n active?: boolean | undefined;\n /** Repository roots advertised by capabilities, relative to the workspace. */\n repoPaths?: readonly string[] | undefined;\n /** The lease liveness. `null` means capability negotiation has not produced\n * an authoritative lifecycle value yet and therefore blocks live I/O. Omitting\n * the option preserves the legacy direct-hook behavior. The structured FileSystem\n * capability is advertised even on a COLD box, so the mount-time list can race\n * the box: it lists before the box is warm, gets an empty/errored result, and\n * (with no `fs.changed` event) never re-lists. Passing liveness re-lists when\n * the box first becomes warm, so the tree populates as soon as the box is up. */\n liveness?: SessionCapabilities[\"liveness\"] | null | undefined;\n /** The latest turn-end workspace capture (from `useWorkspaceCapture`). The tree\n * paints immediately from this durable index, then a warm box reconciles live\n * in place. If that live read fails, the capture remains a truthful read-only\n * fallback instead of turning into an empty error surface. */\n capture?: WorkspaceCaptureManifest | null | undefined;\n /** Called when an OPTIMISTIC mutation is reverted because its background\n * Channel-A op failed (e.g. a 409 rename collision). The host wires this to a\n * toast — the tree silently rolls the node back, the user sees why. */\n onMutationError?: ((error: Error, op: string) => void) | undefined;\n};\n\nexport type UseSandboxFilesResult = {\n /** The tree roots (the listed root's children). */\n tree: FileTreeNode[];\n /** Lazy-expand a directory node in place (lists its immediate children). */\n expand: (path: string) => Promise<void>;\n /** Paths whose lazy `fs.list` is currently in flight — the FileBrowser shows a\n * spinner on these nodes so a 2-3s Channel-A list never looks frozen. */\n expandingPaths: Set<string>;\n /** Read a file for the preview pane (text or base64-for-binary, size-capped). */\n readFile: (path: string, options?: OpenGeniRequestOptions) => Promise<FsReadResponse>;\n /** Write a file (overwrite, last-writer-wins) — the editor save path.\n * Optimistic: a brand-new file is spliced into the tree immediately and the\n * Channel-A write runs in the background; on failure the splice is reverted. */\n writeFile: (\n path: string,\n content: string,\n options?: SandboxWriteFileOptions,\n ) => Promise<FsWriteResponse>;\n /** Create a new empty file (refuses to clobber an existing path: overwrite=false). */\n createFile: (path: string) => Promise<void>;\n /** Create a directory (recursive by default). */\n createDir: (path: string) => Promise<void>;\n /** Delete a path (pass recursive=true for a non-empty directory). */\n deleteEntry: (path: string, recursive?: boolean) => Promise<void>;\n /** Move / rename a path (rename == move). Refuses to clobber unless overwrite=true. */\n moveEntry: (path: string, newPath: string, opts?: { overwrite?: boolean }) => Promise<void>;\n /** Re-list the whole tree from the root. */\n refresh: () => Promise<void>;\n /** Monotonic invalidation token for open file previews. Advances when an\n * external filesystem change or completed agent tool may have changed bytes. */\n contentRevision?: number | undefined;\n /** Which source the tree is currently served from: the live box, the turn-end\n * capture (cold/offline), or neither yet. M5's source badge reads this. */\n source: \"live\" | \"capture\" | null;\n /** When the served capture was taken (ISO), when `source === \"capture\"`. */\n capturedAt: string | null;\n /** Lightweight repository context loaded by the same status request that tints files. */\n gitSummary?: SandboxFilesGitSummary | null | undefined;\n /** True only while the initial repository-status overlay is still loading. */\n gitLoading?: boolean | undefined;\n loading: boolean;\n error: Error | null;\n};\n\nexport type SandboxFilesGitSummary = {\n branch: string | null;\n isRepo: boolean;\n repoCount: number;\n ahead: number;\n behind: number;\n dirtyCount: number;\n};\n\nfunction normalizeRoot(root: string): string {\n const slashNormalized = root.replaceAll(\"\\\\\", \"/\").replace(/^\\.\\/+/, \"\");\n if (slashNormalized === \"/\") return \"/\";\n const normalized = slashNormalized.replace(/\\/+$/, \"\");\n return normalized === \".\" ? \"\" : normalized;\n}\n\nfunction isAbsoluteTreePath(path: string): boolean {\n return path.startsWith(\"/\") || /^[A-Za-z]:\\//u.test(path);\n}\n\nfunction joinTreeRoot(root: string, path: string): string {\n if (!root || isAbsoluteTreePath(path)) return path;\n return root === \"/\" ? `/${path}` : `${root}/${path}`;\n}\n\nfunction qualifyStatusPath(root: string, path: string, treeRoot: string): string {\n const normalized = normalizeRoot(root);\n const workspaceRelative = joinTreeRoot(normalized, path);\n return joinTreeRoot(normalizeRoot(treeRoot), workspaceRelative);\n}\n\nfunction summarizeStatuses(\n statuses: Array<{ root: string; status: GitStatusResponse }>,\n): SandboxFilesGitSummary {\n const repositories = statuses.filter(({ status }) => status.isRepo);\n return {\n branch: repositories.length === 1 ? (repositories[0]?.status.head ?? null) : null,\n isRepo: repositories.length > 0,\n repoCount: repositories.length,\n ahead: repositories.reduce((sum, { status }) => sum + status.ahead, 0),\n behind: repositories.reduce((sum, { status }) => sum + status.behind, 0),\n dirtyCount: repositories.reduce((sum, { status }) => sum + status.files.length, 0),\n };\n}\n\n/** The workspace-relative parent directory of a POSIX path (\"\" for a root entry). */\nfunction parentOf(path: string): string {\n const i = path.lastIndexOf(\"/\");\n return i <= 0 ? \"\" : path.slice(0, i);\n}\n\nfunction parentWithinTree(path: string, rootPath: string): string {\n const parent = parentOf(path);\n return parent === \"\" && normalizeRoot(rootPath) === \"/\" && path.startsWith(\"/\") ? \"/\" : parent;\n}\n\n/** The leaf name of a POSIX path. */\nfunction leafOf(path: string): string {\n const i = path.lastIndexOf(\"/\");\n return i < 0 ? path : path.slice(i + 1);\n}\n\n/** Join a parent dir with a leaf name (handles the root \"\" parent). */\n/** Stable sibling ordering: dirs before files, then case-insensitive by name —\n * matches a typical depth-1 list so an optimistic insert lands where a real\n * re-list would put it (no jump when the server reconciles). */\nfunction sortNodes(nodes: FileTreeNode[]): FileTreeNode[] {\n return [...nodes].sort((a, b) => {\n if (a.kind !== b.kind) return a.kind === \"dir\" ? -1 : 1;\n return a.name.localeCompare(b.name, undefined, { sensitivity: \"base\" });\n });\n}\n\nfunction fsNodeToTree(node: FsTreeNode, captureComplete = false): FileTreeNode {\n const kind = node.type === \"dir\" ? \"dir\" : \"file\";\n // Lazy-tree contract: a depth-bounded `fsList` returns each directory at the\n // depth boundary with `children: []` (the dir is listed, but its grandchildren\n // are NOT). An empty array therefore means \"not yet expanded\", NOT \"empty\n // directory\" — so we must map it to `undefined` (the unexpanded marker the\n // FileBrowser keys lazy-expand on). If we kept `[]`, `toggle()`'s\n // `node.children === undefined` guard would never fire and clicking a folder\n // would do nothing (the reported bug). A directory we actually expand has its\n // children spliced in by `replaceChildren` (bypassing this mapper), so a\n // genuinely-empty dir correctly ends up as `[]` AFTER expansion.\n const mappedChildren =\n node.children && node.children.length > 0\n ? node.children.map((child) => fsNodeToTree(child, captureComplete))\n : captureComplete && kind === \"dir\"\n ? []\n : undefined;\n return {\n path: node.path,\n name: node.name,\n kind,\n size: node.sizeBytes,\n ...(kind === \"dir\" ? { children: mappedChildren } : {}),\n // A collapsed residue dir from the capture index — carried through so the\n // tree can show an inline \"contents on machine\" row cold instead of nothing.\n ...(kind === \"dir\" && node.truncated ? { truncated: true } : {}),\n };\n}\n\nconst GIT_STATUS_TO_TREE: Partial<Record<GitFileStatusCode, FileTreeStatus>> = {\n added: \"added\",\n modified: \"modified\",\n deleted: \"deleted\",\n renamed: \"renamed\",\n copied: \"added\",\n untracked: \"untracked\",\n typechange: \"modified\",\n};\n\n/** Replace the children of `targetPath` within the tree (immutably). */\nfunction replaceChildren(\n nodes: FileTreeNode[],\n targetPath: string,\n children: FileTreeNode[],\n): FileTreeNode[] {\n return nodes.map((node) => {\n if (node.path === targetPath) {\n return { ...node, children };\n }\n if (node.kind === \"dir\" && node.children && targetPath.startsWith(`${node.path}/`)) {\n return {\n ...node,\n children: replaceChildren(node.children, targetPath, children),\n };\n }\n return node;\n });\n}\n\n/** Find a node by exact path (depth-first). */\nfunction findNodeByPath(nodes: FileTreeNode[], path: string): FileTreeNode | undefined {\n for (const node of nodes) {\n if (node.path === path) return node;\n if (node.kind === \"dir\" && node.children && path.startsWith(`${node.path}/`)) {\n const hit = findNodeByPath(node.children, path);\n if (hit) return hit;\n }\n }\n return undefined;\n}\n\nconst FS_LIST_BATCH_REQUEST_LIMIT = 16;\n\n/** Repository paths are capability-advertised and therefore safe to use as a\n * bounded initial lazy-tree frontier. Listing their ancestors concurrently with\n * the root avoids a root → repositories → repo remote waterfall. */\nfunction initialDirectoryFrontier(rootPath: string, repoPaths: readonly string[]): string[] {\n const root = normalizeRoot(rootPath);\n const rootParts = root.split(\"/\").filter(Boolean);\n const rootPrefix = root.startsWith(\"//\") ? \"//\" : root.startsWith(\"/\") ? \"/\" : \"\";\n const paths = new Set<string>();\n for (const repoPath of repoPaths) {\n const canonicalRepoPath = joinTreeRoot(root, normalizeRoot(repoPath));\n const parts = canonicalRepoPath.split(\"/\").filter(Boolean);\n if (rootParts.some((part, index) => parts[index] !== part)) continue;\n for (let depth = rootParts.length + 1; depth <= parts.length; depth += 1) {\n const path = parts.slice(0, depth).join(\"/\");\n paths.add(`${rootPrefix}${path}`);\n }\n }\n // A workspace with hundreds of repositories should remain lazy. This still\n // preloads the shared repository container and the first visible roots.\n return [...paths]\n .sort((a, b) => a.split(\"/\").length - b.split(\"/\").length || a.localeCompare(b))\n .slice(0, 8);\n}\n\n// ── In-place (optimistic) tree mutations ────────────────────────────────────\n// The Pierre mutation-handle analogue. These splice a single node in/out/across\n// the immutable tree, PRESERVING every other node's `children` (and therefore the\n// FileBrowser's expansion + selection). The old data flow re-listed the whole\n// root and `setTree(rootChildren)` — that dropped every expanded dir back to the\n// unexpanded marker, which is exactly the \"everything refreshes / collapses to\n// .config\" the user saw. Mutating in place is the fix.\n//\n// `parent === \"\"` targets the root list directly. A parent that isn't present in\n// the (lazily-loaded) tree means it's collapsed/unloaded — the helpers return the\n// tree UNCHANGED in that case (caller treats it as \"nothing visible to update\",\n// which is correct: a collapsed dir re-lists fresh when the user expands it).\n\n/** True when `parent` is the root (\"\") or a dir node that is actually present in\n * the loaded tree (so an insert/remove there would be visible). */\nfunction parentIsLoaded(nodes: FileTreeNode[], parent: string, rootPath = \"\"): boolean {\n if (parent === normalizeRoot(rootPath)) return true;\n const node = findNodeByPath(nodes, parent);\n return Boolean(node && node.kind === \"dir\" && node.children !== undefined);\n}\n\n/** Insert `child` under `parent` (immutably), keeping siblings sorted. A no-op\n * (returns the same array) when the parent isn't a loaded dir or the child\n * already exists. */\nfunction insertNode(\n nodes: FileTreeNode[],\n parent: string,\n child: FileTreeNode,\n rootPath = \"\",\n): FileTreeNode[] {\n if (parent === normalizeRoot(rootPath)) {\n if (nodes.some((n) => n.path === child.path)) return nodes;\n return sortNodes([...nodes, child]);\n }\n return nodes.map((node) => {\n if (node.path === parent) {\n if (node.kind !== \"dir\" || node.children === undefined) return node;\n if (node.children.some((n) => n.path === child.path)) return node;\n return { ...node, children: sortNodes([...node.children, child]) };\n }\n if (node.kind === \"dir\" && node.children && parent.startsWith(`${node.path}/`)) {\n return { ...node, children: insertNode(node.children, parent, child, rootPath) };\n }\n return node;\n });\n}\n\n/** Remove the node at `path` (immutably). No-op when it isn't in the tree. */\nfunction removeNode(nodes: FileTreeNode[], path: string, rootPath = \"\"): FileTreeNode[] {\n const parent = parentWithinTree(path, rootPath);\n if (parent === normalizeRoot(rootPath)) {\n if (!nodes.some((n) => n.path === path)) return nodes;\n return nodes.filter((n) => n.path !== path);\n }\n return nodes.map((node) => {\n if (node.path === parent) {\n if (node.kind !== \"dir\" || node.children === undefined) return node;\n return {\n ...node,\n children: node.children.filter((n) => n.path !== path),\n };\n }\n if (node.kind === \"dir\" && node.children && parent.startsWith(`${node.path}/`)) {\n return { ...node, children: removeNode(node.children, path, rootPath) };\n }\n return node;\n });\n}\n\n/** Reconcile a freshly-listed depth-1 set of children against the CURRENT nodes\n * at the same level, PRESERVING expansion: an existing dir keeps its already-\n * loaded `children` (so its expanded subtree survives), new entries are added,\n * and entries the server no longer returns are dropped. This is the in-place\n * merge a root (\"\") reconcile needs — a blind replace would collapse every\n * expanded top-level dir back to the unexpanded marker (the reported bug). */\n/** Shallow node equality for identity preservation across a reconcile — same\n * path/kind/name/size/status (children handled separately by the caller). */\nfunction sameNodeShallow(a: FileTreeNode, b: FileTreeNode): boolean {\n return (\n a.path === b.path &&\n a.kind === b.kind &&\n a.name === b.name &&\n (a.size ?? null) === (b.size ?? null) &&\n (a.status ?? undefined) === (b.status ?? undefined) &&\n (a.truncated ?? false) === (b.truncated ?? false)\n );\n}\n\nfunction mergeChildren(current: FileTreeNode[], listed: FileTreeNode[]): FileTreeNode[] {\n const byPath = new Map(current.map((n) => [n.path, n] as const));\n const merged = listed.map((next) => {\n const existing = byPath.get(next.path);\n if (!existing) return next; // brand-new entry\n // Keep an already-expanded dir's loaded children; otherwise take the listing's\n // marker (undefined = unexpanded). Carry forward size/status from the listing.\n if (existing.kind === \"dir\" && next.kind === \"dir\" && existing.children !== undefined) {\n const candidate: FileTreeNode = { ...next, children: existing.children };\n // Preserve identity when nothing observable changed — no remount (§12-D1).\n return sameNodeShallow(existing, candidate) ? existing : candidate;\n }\n // A file or an unexpanded dir: preserve identity when the node is unchanged.\n if (existing.children === next.children && sameNodeShallow(existing, next)) {\n return existing;\n }\n return next;\n });\n return sortNodes(merged);\n}\n\n/** Root-level (\"\") reconcile: merge a fresh depth-1 listing into the root list\n * without collapsing expanded top-level dirs. */\nfunction mergeRootChildren(nodes: FileTreeNode[], listed: FileTreeNode[]): FileTreeNode[] {\n return mergeChildren(nodes, listed);\n}\n\n/** Re-path a subtree rooted at `node` from `fromPrefix` to `toPrefix` (so a moved\n * dir's descendants keep correct paths without a re-list). */\nfunction repathNode(node: FileTreeNode, fromPrefix: string, toPrefix: string): FileTreeNode {\n const newPath = toPrefix + node.path.slice(fromPrefix.length);\n const next: FileTreeNode = { ...node, path: newPath, name: leafOf(newPath) };\n if (node.children) next.children = node.children.map((c) => repathNode(c, fromPrefix, toPrefix));\n return next;\n}\n\nfunction decodeBase64Bytes(value: string): Uint8Array {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n\nfunction decodeBase64Text(value: string): string {\n return new TextDecoder().decode(decodeBase64Bytes(value));\n}\n\nfunction encodeBase64Bytes(bytes: Uint8Array): string {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n return btoa(binary);\n}\n\nasync function assertCapturedHash(bytes: Uint8Array, expected: string | null): Promise<void> {\n if (!expected) throw new Error(\"Captured file is missing its integrity hash.\");\n if (!globalThis.crypto?.subtle) {\n throw new Error(\"Captured file integrity verification is unavailable in this browser.\");\n }\n const buffer = new ArrayBuffer(bytes.byteLength);\n new Uint8Array(buffer).set(bytes);\n const digest = new Uint8Array(await globalThis.crypto.subtle.digest(\"SHA-256\", buffer));\n const actual = [...digest].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n if (actual !== expected) throw new Error(\"Captured file content failed its integrity check.\");\n}\n\n/**\n * Project the FileSystem service into a lazy-loaded Pierre tree. The initial\n * list pulls one level (depth 1); `expand(path)` lists a directory's immediate\n * children on demand (the fast lazy-tree UX). A git-status overlay tints\n * modified files. Auto-refreshes when an `fs.changed` / `git.changed` event\n * arrives on the live log.\n */\nexport function useSandboxFiles(\n sessionId: string | null | undefined,\n options: UseSandboxFilesOptions = {},\n): UseSandboxFilesResult {\n const { client, workspaceId } = useOpenGeni(options);\n const enabled = (options.enabled ?? true) && Boolean(sessionId);\n const active = options.active ?? true;\n const rootPath = options.rootPath ?? \"\";\n const routeEpoch = options.route?.epoch ?? null;\n const routeRoot = options.route?.root ?? null;\n const route = useMemo<FileSystemRouteIdentity | undefined>(\n () =>\n routeEpoch !== null && routeRoot !== null\n ? { epoch: routeEpoch, root: routeRoot }\n : undefined,\n [routeEpoch, routeRoot],\n );\n const repoPathsKey = [\n ...new Set((options.repoPaths?.length ? options.repoPaths : [rootPath]).map(normalizeRoot)),\n ].join(\"\\u0000\");\n const repoPaths = useMemo(() => repoPathsKey.split(\"\\u0000\"), [repoPathsKey]);\n const capture = options.capture ?? null;\n const isLive = sandboxAcceptsLiveIo(options.liveness);\n // `liveness` predates this hook option. Preserve legacy embedders that omit it;\n // explicit `null` (negotiating) and lifecycle values require authoritative warm.\n const acceptsEventReads = options.liveness === undefined || isLive;\n const acceptsEventReadsRef = useRef(acceptsEventReads);\n acceptsEventReadsRef.current = acceptsEventReads;\n const hasLiveIoFence = options.liveness !== undefined;\n const identityKey = `${workspaceId}\\u0000${sessionId ?? \"\"}\\u0000${rootPath}\\u0000${repoPathsKey}\\u0000${routeEpoch ?? \"\"}\\u0000${routeRoot ?? \"\"}`;\n\n const [tree, setTree] = useState<FileTreeNode[]>([]);\n // A ref mirror of the current tree — lets the optimistic path snapshot the\n // pre-op tree WITHOUT relying on a `setTree` updater (which StrictMode invokes\n // twice, corrupting an in-closure snapshot). Kept in sync on every set below\n // and in a layout effect for any path that sets `tree` directly.\n const treeRef = useRef<FileTreeNode[]>([]);\n const [loading, setLoading] = useState(false);\n const [expandingPaths, setExpandingPaths] = useState<Set<string>>(new Set());\n const [error, setError] = useState<Error | null>(null);\n const [gitSummary, setGitSummary] = useState<SandboxFilesGitSummary | null>(null);\n const [gitLoading, setGitLoading] = useState(false);\n const [contentRevision, setContentRevision] = useState(0);\n const [stateIdentity, setStateIdentity] = useState(identityKey);\n // Which source the tree currently reflects — \"capture\" (cold paint) or \"live\".\n const [source, setSource] = useState<\"live\" | \"capture\" | null>(null);\n const sourceRef = useRef<\"live\" | \"capture\" | null>(null);\n const statusRef = useRef<Map<string, FileTreeStatus>>(new Map());\n // Async reads, event cursors, and debounced work are scoped to the hook's\n // workspace/session/root identity. These refs are reset/fenced at that boundary.\n const refreshGenerationRef = useRef(0);\n const refreshAbortRef = useRef<AbortController | null>(null);\n const identityAbortRef = useRef(new AbortController());\n const eventReadAbortRef = useRef(new AbortController());\n const identityGenerationRef = useRef(0);\n const lastSeqRef = useRef(0);\n const pendingParentsRef = useRef<Set<string>>(new Set());\n const pendingGitRef = useRef(false);\n const eventReconcileInFlightRef = useRef<Promise<void> | null>(null);\n const eventReconcilePendingRef = useRef(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // ── Self-emitted fs.changed de-dupe ───────────────────────────────────────\n // Every one of OUR mutations emits an `fs.changed` event back on the live log\n // (source:\"write\"). The old flow auto-refreshed on EVERY fs.changed, so each\n // edit self-triggered a full root collapse-reload (~5s, lost expansion). We now\n // (a) ignore fs.changed whose `source === \"write\"` (our own control-plane ops),\n // and (b) belt-and-braces, track the revisions WE caused so even a watch-sourced\n // echo of our own write is suppressed. Only EXTERNAL changes (the agent writing,\n // source:\"agent\"/\"watch\" we didn't cause) drive a targeted reconcile.\n const ownRevisionsRef = useRef<Set<number>>(new Set());\n const onMutationError = options.onMutationError;\n\n // Keep the ref mirror current for the optimistic snapshot path.\n treeRef.current = tree;\n\n // Overlay the git-status tint onto the tree. IDENTITY-PRESERVING: a node whose\n // tint and children are unchanged is returned by reference (not rebuilt), so a\n // re-tint or a cold→warm reconcile does NOT remount unchanged rows — the\n // no-flicker constraint. An empty overlay is still\n // meaningful: it strips stale tints after the repository becomes clean.\n const applyStatus = useCallback((nodes: FileTreeNode[]): FileTreeNode[] => {\n const overlay = statusRef.current;\n const walk = (list: FileTreeNode[]): FileTreeNode[] => {\n let changed = false;\n const out = list.map((node) => {\n const nextChildren = node.children ? walk(node.children) : node.children;\n const wantStatus = node.kind === \"file\" ? overlay.get(node.path) : undefined;\n const childrenChanged = nextChildren !== node.children;\n const statusChanged = (node.status ?? undefined) !== (wantStatus ?? undefined);\n if (!childrenChanged && !statusChanged) return node;\n changed = true;\n const next: FileTreeNode = {\n ...node,\n ...(node.children ? { children: nextChildren } : {}),\n };\n if (wantStatus) next.status = wantStatus;\n else delete next.status;\n return next;\n });\n return changed ? out : list;\n };\n return walk(nodes);\n }, []);\n\n const refresh = useCallback(async () => {\n if (!sessionId) return;\n refreshAbortRef.current?.abort();\n const refreshAbort = new AbortController();\n refreshAbortRef.current = refreshAbort;\n const generation = (refreshGenerationRef.current += 1);\n setLoading(true);\n setGitLoading(true);\n setError(null);\n try {\n // Paint the useful file tree before the optional Git tint. Separate remote\n // requests for one Modal box are deliberately serialized by the API; firing\n // both here only made the Git request contend with the file request during\n // cold starts.\n const frontierPaths = initialDirectoryFrontier(rootPath, repoPaths);\n const listRequests = [rootPath, ...frontierPaths].map((path) => ({\n path,\n depth: 1,\n ...(route ? { route } : {}),\n }));\n // Root plus the bounded repository frontier share one API request, one\n // direct holder, and one provider attach. The old per-directory fan-out\n // paid that fixed control-plane cost up to nine times on every Files open.\n const listedBatch = await client.fsListBatch(\n workspaceId,\n sessionId,\n { requests: listRequests },\n { signal: refreshAbort.signal },\n );\n if (refreshGenerationRef.current !== generation) return;\n const listed = listedBatch.results[0];\n if (!listed) throw new Error(\"Workspace list batch did not return the root result.\");\n const children = (listed.root.children ?? []).map((node) => fsNodeToTree(node));\n // Paint the root and already-returned frontier in one commit so preloaded\n // repository folders never flicker through a collapsed intermediate tree.\n setTree((prev) => {\n let hydrated = prev.length === 0 ? children : mergeRootChildren(prev, children);\n for (const [index, path] of frontierPaths.entries()) {\n const prefetched = listedBatch.results[index + 1];\n if (!prefetched) continue;\n hydrated = replaceChildren(\n hydrated,\n path,\n (prefetched.root.children ?? []).map((node) => fsNodeToTree(node)),\n );\n }\n return applyStatus(hydrated);\n });\n sourceRef.current = \"live\";\n setSource(\"live\");\n setLoading(false);\n\n const statuses =\n repoPaths.length > 0\n ? await client\n .gitReadBatch(\n workspaceId,\n sessionId,\n {\n requests: repoPaths.map((root) => ({\n status: { path: root },\n })),\n },\n { signal: refreshAbort.signal },\n )\n .then((batch) =>\n batch.results.map((result, index) => ({\n root: repoPaths[index] ?? \"\",\n status: result.status,\n })),\n )\n .catch(() => null)\n : [];\n if (refreshGenerationRef.current !== generation) return;\n if (statuses) {\n const overlay = new Map<string, FileTreeStatus>();\n for (const { root, status } of statuses) {\n for (const file of status.files) {\n const code = file.worktree ?? file.index;\n const mapped = code ? GIT_STATUS_TO_TREE[code] : undefined;\n if (mapped) overlay.set(qualifyStatusPath(root, file.path, rootPath), mapped);\n }\n }\n statusRef.current = overlay;\n setGitSummary(summarizeStatuses(statuses));\n } else {\n statusRef.current = new Map();\n setGitSummary(null);\n }\n setGitLoading(false);\n setTree((prev) => applyStatus(prev));\n } catch (cause) {\n if (refreshGenerationRef.current !== generation) return;\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n } finally {\n if (refreshGenerationRef.current === generation) setLoading(false);\n if (refreshGenerationRef.current === generation) setGitLoading(false);\n if (refreshAbortRef.current === refreshAbort) refreshAbortRef.current = null;\n }\n }, [client, workspaceId, sessionId, rootPath, repoPaths, route, applyStatus]);\n\n // Seed (or re-seed) the tree from a turn-end capture — the COLD/offline paint,\n // zero Channel-A calls. The tree index is workspace-relative (`treeIndex`); the\n // tint overlay comes from the capture's changed `files`. Uses the SAME merge as\n // the live reconcile so a re-seed (a newer capture arriving cold) patches deltas\n // in place instead of remounting the tree (§12-D1).\n const seedFromCapture = useCallback(\n (manifest: WorkspaceCaptureManifest) => {\n const overlay = new Map<string, FileTreeStatus>();\n for (const file of manifest.files) {\n if (file.deleted) continue;\n const mapped = GIT_STATUS_TO_TREE[file.status];\n if (mapped) overlay.set(file.path, mapped);\n }\n statusRef.current = overlay;\n // The capture tree is a complete bounded index. Preserve an explicit empty\n // `children: []` as an actually empty directory; the live depth-1 mapper\n // intentionally treats that shape as an unexpanded boundary.\n const children = (manifest.treeIndex.children ?? []).map((node) => fsNodeToTree(node, true));\n setTree((prev) =>\n applyStatus(prev.length === 0 ? children : mergeRootChildren(prev, children)),\n );\n sourceRef.current = \"capture\";\n setSource(\"capture\");\n setGitSummary({\n branch: manifest.repos.length === 1 ? (manifest.repos[0]?.head ?? null) : null,\n isRepo: manifest.repos.length > 0,\n repoCount: manifest.repos.length,\n ahead: manifest.repos.reduce((sum, repo) => sum + repo.ahead, 0),\n behind: manifest.repos.reduce((sum, repo) => sum + repo.behind, 0),\n dirtyCount: manifest.files.length,\n });\n setGitLoading(false);\n setError(null);\n },\n [applyStatus],\n );\n\n const expand = useCallback(\n async (path: string) => {\n if (!sessionId) return;\n // Capture browsing is a durable server-side read surface. Never turn a\n // folder click into a Channel-A list while cold; truncated residue already\n // renders a truthful \"contents on machine\" row.\n if (source === \"capture\" && capture) return;\n const identityGeneration = identityGenerationRef.current;\n const identitySignal = identityAbortRef.current.signal;\n // Mark this node as expanding so the FileBrowser can render a spinner while\n // the (often 2-3s) Channel-A fs/list is in flight — the tree never looks\n // frozen on a click.\n setExpandingPaths((prev) => {\n const next = new Set(prev);\n next.add(path);\n return next;\n });\n try {\n const listed = await client.fsList(\n workspaceId,\n sessionId,\n { path, depth: 1, ...(route ? { route } : {}) },\n { signal: identitySignal },\n );\n if (identityGenerationRef.current !== identityGeneration) return;\n const children = (listed.root.children ?? []).map((node) => fsNodeToTree(node));\n setTree((prev) => applyStatus(replaceChildren(prev, path, children)));\n } catch (cause) {\n if (identityGenerationRef.current !== identityGeneration) return;\n setError(cause instanceof Error ? cause : new Error(String(cause)));\n } finally {\n if (identityGenerationRef.current === identityGeneration) {\n setExpandingPaths((prev) => {\n if (!prev.has(path)) return prev;\n const next = new Set(prev);\n next.delete(path);\n return next;\n });\n }\n }\n },\n [client, workspaceId, sessionId, capture, source, route, applyStatus],\n );\n\n const readFile = useCallback(\n async (path: string, requestOptions: OpenGeniRequestOptions = {}) => {\n if (!sessionId) throw new Error(\"no session\");\n const identitySignal = identityAbortRef.current.signal;\n const signal = requestOptions.signal\n ? AbortSignal.any([identitySignal, requestOptions.signal])\n : identitySignal;\n const captured = capture?.files.find((file) => file.path === path && !file.deleted);\n if (source === \"capture\" && capture) {\n if (!captured) {\n throw new CapturedFileUnavailableError(path, \"not-captured\");\n }\n // A passive review of a turn-touched file must stay entirely server-side:\n // mint/read its captured after-image, verify the content hash, and never\n // wake the sandbox. A URL may expire between mint and GET, so retry once\n // through the authenticated API to obtain a fresh scoped URL.\n for (let attempt = 0; attempt < 2; attempt += 1) {\n const result = await client.getWorkspaceCaptureFile(\n workspaceId,\n sessionId,\n path,\n capture.revision,\n { signal },\n );\n if (result.path !== path || result.revision !== capture.revision) {\n throw new Error(\n \"Captured file identity did not match the requested workspace revision.\",\n );\n }\n if (\n result.hash !== captured.hash ||\n result.sizeBytes !== captured.sizeBytes ||\n result.isBinary !== captured.isBinary ||\n result.tooLarge !== captured.tooLarge\n ) {\n throw new Error(\"Captured file metadata did not match its manifest.\");\n }\n if (result.tooLarge) {\n throw new CapturedFileUnavailableError(path, \"too-large\");\n }\n\n let bytes: Uint8Array;\n let encoding: \"utf8\" | \"base64\";\n let content: string;\n if (result.content !== null && result.encoding !== null) {\n encoding = result.encoding;\n content = result.content;\n bytes =\n encoding === \"base64\"\n ? decodeBase64Bytes(content)\n : new TextEncoder().encode(content);\n } else if (result.contentUrl) {\n const response = await fetch(result.contentUrl.url, {\n credentials: \"omit\",\n cache: \"no-store\",\n referrerPolicy: \"no-referrer\",\n signal: AbortSignal.any([signal, AbortSignal.timeout(30_000)]),\n }).catch(() => null);\n if (!response?.ok) {\n if (\n attempt === 0 &&\n (response === null || response.status === 401 || response.status === 403)\n ) {\n continue;\n }\n throw new Error(\"Captured file download failed.\");\n }\n bytes = new Uint8Array(await response.arrayBuffer());\n encoding = result.isBinary ? \"base64\" : \"utf8\";\n content = result.isBinary ? encodeBase64Bytes(bytes) : new TextDecoder().decode(bytes);\n } else {\n throw new CapturedFileUnavailableError(path, \"content-missing\");\n }\n\n if (bytes.byteLength !== result.sizeBytes) {\n throw new Error(\"Captured file size did not match its manifest.\");\n }\n await assertCapturedHash(bytes, result.hash);\n return {\n path,\n encoding,\n content,\n sizeBytes: result.sizeBytes,\n truncated: false,\n isBinary: result.isBinary,\n revision: result.revision,\n };\n }\n throw new Error(\"Captured file download failed after refreshing its URL.\");\n }\n return await client.fsRead(\n workspaceId,\n sessionId,\n { path, ...(route ? { route } : {}) },\n { signal },\n );\n },\n [client, workspaceId, sessionId, capture, source, route],\n );\n\n // TARGETED reconcile of a single directory — re-list ONE parent at depth 1 and\n // splice its children in place via `replaceChildren`, preserving the rest of the\n // tree's expansion. NEVER falls back to a root refresh (that's the collapse).\n // Used to (a) reconcile an optimistic insert against the server's real\n // size/mtime, and (b) fold an EXTERNAL (agent) change into the tree. A reconcile\n // of a parent that isn't loaded (collapsed/unmounted) is a no-op — there's\n // nothing visible to update, and it re-lists fresh when the user expands it.\n const reconcilePath = useCallback(\n async (path: string, requestSignal?: AbortSignal) => {\n if (!sessionId) return;\n const identityGeneration = identityGenerationRef.current;\n const identitySignal = identityAbortRef.current.signal;\n const signal = requestSignal\n ? AbortSignal.any([identitySignal, requestSignal])\n : identitySignal;\n // Skip parents that aren't currently loaded/expanded in the tree (nothing\n // visible to update; they re-list fresh on the next expand).\n if (!parentIsLoaded(treeRef.current, path, rootPath)) return;\n try {\n const listed = await client.fsList(\n workspaceId,\n sessionId,\n { path, depth: 1, ...(route ? { route } : {}) },\n { signal },\n );\n if (identityGenerationRef.current !== identityGeneration) return;\n const children = (listed.root.children ?? []).map((node) => fsNodeToTree(node));\n if (path === normalizeRoot(rootPath)) {\n setTree((prev) => applyStatus(mergeRootChildren(prev, children)));\n } else\n setTree((prev) => {\n const existing = findNodeByPath(prev, path);\n const merged = existing?.children\n ? mergeChildren(existing.children, children)\n : children;\n return applyStatus(replaceChildren(prev, path, merged));\n });\n } catch {\n // A failed reconcile is non-fatal: the optimistic state stands. We never\n // root-refresh here (that would collapse the tree the user is working in).\n }\n },\n [client, workspaceId, sessionId, rootPath, route, applyStatus],\n );\n\n // Reconcile the visible directory frontier through bounded batch requests.\n // One tool completion can affect several expanded directories; issuing one\n // provider request per directory created a self-inflicted lock convoy.\n const reconcilePaths = useCallback(\n async (requestedPaths: readonly string[], requestSignal?: AbortSignal) => {\n if (!sessionId) return;\n const identityGeneration = identityGenerationRef.current;\n const identitySignal = identityAbortRef.current.signal;\n const signal = requestSignal\n ? AbortSignal.any([identitySignal, requestSignal])\n : identitySignal;\n const paths = [...new Set(requestedPaths)].filter((path) =>\n parentIsLoaded(treeRef.current, path, rootPath),\n );\n for (let offset = 0; offset < paths.length; offset += FS_LIST_BATCH_REQUEST_LIMIT) {\n const chunk = paths.slice(offset, offset + FS_LIST_BATCH_REQUEST_LIMIT);\n try {\n const listed = await client.fsListBatch(\n workspaceId,\n sessionId,\n {\n requests: chunk.map((path) => ({\n path,\n depth: 1,\n ...(route ? { route } : {}),\n })),\n },\n { signal },\n );\n if (identityGenerationRef.current !== identityGeneration) return;\n setTree((previous) => {\n let next = previous;\n for (const [index, path] of chunk.entries()) {\n const result = listed.results[index];\n if (!result) continue;\n const children = (result.root.children ?? []).map((node) => fsNodeToTree(node));\n if (path === normalizeRoot(rootPath)) {\n next = mergeRootChildren(next, children);\n } else {\n const existing = findNodeByPath(next, path);\n const merged = existing?.children\n ? mergeChildren(existing.children, children)\n : children;\n next = replaceChildren(next, path, merged);\n }\n }\n return applyStatus(next);\n });\n } catch {\n // Reconciliation is best-effort. Preserve the current visible tree and\n // let the next real event or explicit refresh reconcile it.\n }\n }\n },\n [client, workspaceId, sessionId, rootPath, route, applyStatus],\n );\n\n // Run a Channel-A op behind an OPTIMISTIC tree edit. `apply` splices the change\n // in immediately (preserving expansion/selection); the op runs in the\n // background; on failure we revert to the pre-op snapshot and surface a toast.\n // On success we keep the optimistic state and (optionally) reconcile the\n // affected parent(s) to pick up the server's real size/revision — NEVER a full\n // refresh. The returned promise resolves/rejects with the op so callers (the\n // editor save, inline rename) can still await it.\n const runOptimistic = useCallback(\n async <T>(\n opName: string,\n apply: (nodes: FileTreeNode[]) => FileTreeNode[],\n op: () => Promise<T>,\n reconcileParents: string[],\n ): Promise<T> => {\n const identityGeneration = identityGenerationRef.current;\n // Snapshot the pre-op tree from the ref (StrictMode-safe — see treeRef).\n const snapshot = treeRef.current;\n setError(null);\n setTree(applyStatus(apply(snapshot)));\n try {\n const res = await op();\n if (identityGenerationRef.current !== identityGeneration) return res;\n // Remember the revision WE caused so the matching fs.changed echo is\n // ignored by the event effect (no self-triggered refresh).\n if (res && typeof res === \"object\" && \"revision\" in res) {\n const rev = (res as { revision?: unknown }).revision;\n if (typeof rev === \"number\") ownRevisionsRef.current.add(rev);\n }\n // Reconcile loaded parents to fold the server's real metadata. Sequential\n // and best-effort — purely cosmetic over the already-correct optimistic UI.\n for (const parent of reconcileParents) {\n if (identityGenerationRef.current !== identityGeneration) return res;\n await reconcilePath(parent);\n }\n return res;\n } catch (cause) {\n const err = cause instanceof Error ? cause : new Error(String(cause));\n if (identityGenerationRef.current !== identityGeneration) throw err;\n // Revert the optimistic edit to the exact pre-op tree.\n setTree(applyStatus(snapshot));\n // An expected-content conflict belongs to the editor's explicit\n // Reload/Overwrite decision surface. Treating it as a broken file tree\n // would also raise a duplicate host toast and leave a stale global error\n // after the user successfully resolves the conflict.\n if (err instanceof FileWriteConflictError) throw err;\n setError(err);\n onMutationError?.(err, opName);\n throw err;\n }\n },\n [applyStatus, reconcilePath, onMutationError],\n );\n\n const writeFile = useCallback(\n async (\n path: string,\n content: string,\n writeOptions: SandboxWriteFileOptions = {},\n ): Promise<FsWriteResponse> => {\n if (!sessionId) throw new Error(\"no session\");\n const identityGeneration = identityGenerationRef.current;\n const identitySignal = identityAbortRef.current.signal;\n const parent = parentWithinTree(path, rootPath);\n // Splice a new file node in immediately ONLY when the path doesn't already\n // exist in a loaded parent (an editor SAVE to an existing file mutates no\n // tree shape — just content — so it needs no optimistic node, no reconcile).\n const exists = Boolean(findNodeByPath(tree, path));\n const node: FileTreeNode = {\n path,\n name: leafOf(path),\n kind: \"file\",\n size: content.length,\n };\n return await runOptimistic(\n \"write\",\n (nodes) => (exists ? nodes : insertNode(nodes, parent, node, rootPath)),\n async () => {\n if (!writeOptions.force && writeOptions.expectedContent !== undefined) {\n const live = await client.fsRead(\n workspaceId,\n sessionId,\n { path, ...(route ? { route } : {}) },\n { signal: identitySignal },\n );\n if (identityGenerationRef.current !== identityGeneration) {\n throw new Error(\"File save cancelled because the workspace changed.\");\n }\n const liveContent =\n live.encoding === \"base64\" ? decodeBase64Text(live.content) : live.content;\n if (live.truncated || live.isBinary || liveContent !== writeOptions.expectedContent) {\n throw new FileWriteConflictError(path, writeOptions.expectedContent, liveContent);\n }\n }\n if (identityGenerationRef.current !== identityGeneration) {\n throw new Error(\"File save cancelled because the workspace changed.\");\n }\n return await client.fsWrite(workspaceId, sessionId, {\n path,\n content,\n overwrite: true,\n ...(route ? { route } : {}),\n });\n },\n exists ? [] : [parent],\n );\n },\n [client, workspaceId, sessionId, tree, rootPath, route, runOptimistic],\n );\n\n const createFile = useCallback(\n async (path: string): Promise<void> => {\n if (!sessionId) throw new Error(\"no session\");\n const parent = parentWithinTree(path, rootPath);\n const node: FileTreeNode = {\n path,\n name: leafOf(path),\n kind: \"file\",\n size: 0,\n };\n await runOptimistic(\n \"create file\",\n (nodes) => insertNode(nodes, parent, node, rootPath),\n () =>\n client.fsWrite(workspaceId, sessionId, {\n path,\n content: \"\",\n overwrite: false,\n ...(route ? { route } : {}),\n }),\n [parent],\n );\n },\n [client, workspaceId, sessionId, rootPath, route, runOptimistic],\n );\n\n const createDir = useCallback(\n async (path: string): Promise<void> => {\n if (!sessionId) throw new Error(\"no session\");\n const parent = parentWithinTree(path, rootPath);\n // A freshly-created dir is empty + expanded: children:[] (not undefined, so\n // it doesn't show the lazy-expand marker over a dir we KNOW is empty).\n const node: FileTreeNode = {\n path,\n name: leafOf(path),\n kind: \"dir\",\n children: [],\n };\n await runOptimistic(\n \"create folder\",\n (nodes) => insertNode(nodes, parent, node, rootPath),\n () =>\n client.fsMkdir(workspaceId, sessionId, {\n path,\n recursive: true,\n ...(route ? { route } : {}),\n }),\n [parent],\n );\n },\n [client, workspaceId, sessionId, rootPath, route, runOptimistic],\n );\n\n const deleteEntry = useCallback(\n async (path: string, recursive = false): Promise<void> => {\n if (!sessionId) throw new Error(\"no session\");\n await runOptimistic(\n \"delete\",\n (nodes) => removeNode(nodes, path, rootPath),\n () =>\n client.fsDelete(workspaceId, sessionId, {\n path,\n recursive,\n ...(route ? { route } : {}),\n }),\n [parentWithinTree(path, rootPath)],\n );\n },\n [client, workspaceId, sessionId, rootPath, route, runOptimistic],\n );\n\n const moveEntry = useCallback(\n async (path: string, newPath: string, opts?: { overwrite?: boolean }): Promise<void> => {\n if (!sessionId) throw new Error(\"no session\");\n const from = parentWithinTree(path, rootPath);\n const to = parentWithinTree(newPath, rootPath);\n await runOptimistic(\n \"move\",\n (nodes) => {\n const moving = findNodeByPath(nodes, path);\n if (!moving) return nodes; // not loaded — let the reconcile pick it up\n // Re-path the moved subtree, drop it from its old parent, splice into new.\n const moved = repathNode(moving, path, newPath);\n return insertNode(removeNode(nodes, path, rootPath), to, moved, rootPath);\n },\n () =>\n client.fsMove(workspaceId, sessionId, {\n path,\n newPath,\n overwrite: opts?.overwrite ?? false,\n ...(route ? { route } : {}),\n }),\n to === from ? [from] : [from, to],\n );\n },\n [client, workspaceId, sessionId, rootPath, route, runOptimistic],\n );\n\n // Initial paint + reset on identity change. Source selection:\n // • any box WITH a capture → paint instantly from the durable capture index;\n // a holder-confirmed warm box then reconciles live in place.\n // • if that live reconciliation fails, keep the capture visible and read-only.\n // • legacy callers that omit liveness and have no capture retain their live\n // fallback; an explicitly cold/draining lease never wakes from a passive mount.\n // Key the seed on the capture's REVISION (a primitive), not the manifest object\n // — a consumer passing a fresh object each render (or a new revision) must not\n // spin the effect. The latest manifest is read from a ref at run time.\n const captureRef = useRef<WorkspaceCaptureManifest | null>(capture);\n captureRef.current = capture;\n const captureRevision = capture?.revision ?? null;\n const previousIdentityRef = useRef(identityKey);\n useEffect(() => {\n // Any source-selection change supersedes an older root refresh. A true data\n // identity change additionally fences all other async tree work and resets\n // event/debounce state before the event-folding effect runs.\n refreshAbortRef.current?.abort();\n refreshAbortRef.current = null;\n refreshGenerationRef.current += 1;\n eventReadAbortRef.current.abort();\n eventReadAbortRef.current = new AbortController();\n const identityChanged = previousIdentityRef.current !== identityKey;\n previousIdentityRef.current = identityKey;\n if (identityChanged || !enabled) {\n if (identityChanged) eventReconcileInFlightRef.current = null;\n identityAbortRef.current.abort();\n identityAbortRef.current = new AbortController();\n identityGenerationRef.current += 1;\n lastSeqRef.current = 0;\n pendingParentsRef.current = new Set();\n pendingGitRef.current = false;\n eventReconcilePendingRef.current = false;\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n ownRevisionsRef.current = new Set();\n statusRef.current = new Map();\n treeRef.current = [];\n setTree([]);\n setStateIdentity(identityKey);\n setExpandingPaths(new Set());\n sourceRef.current = null;\n setSource(null);\n setLoading(false);\n setError(null);\n setGitSummary(null);\n setGitLoading(false);\n setContentRevision(0);\n }\n if (!enabled) {\n return;\n }\n const currentCapture = captureRevision !== null ? captureRef.current : null;\n if (currentCapture && (identityChanged || !isLive || sourceRef.current !== \"live\")) {\n seedFromCapture(currentCapture);\n }\n if (!active) {\n if (!active) {\n setLoading(false);\n setGitLoading(false);\n }\n return;\n }\n if (isLive || (!hasLiveIoFence && !currentCapture)) {\n void refresh();\n }\n return () => {\n refreshAbortRef.current?.abort();\n refreshAbortRef.current = null;\n refreshGenerationRef.current += 1;\n eventReadAbortRef.current.abort();\n eventReconcilePendingRef.current = false;\n };\n }, [\n enabled,\n active,\n isLive,\n hasLiveIoFence,\n captureRevision,\n identityKey,\n refresh,\n seedFromCapture,\n ]);\n\n // Re-pull JUST the git-status overlay and re-tint the existing tree in place —\n // no fs re-list, no collapse. This is all a `git.changed` (commit/stage/checkout)\n // needs: the tree SHAPE is unchanged, only the tints move.\n const refreshGitOverlay = useCallback(\n async (requestSignal?: AbortSignal) => {\n if (!sessionId) return;\n const identityGeneration = identityGenerationRef.current;\n const identitySignal = identityAbortRef.current.signal;\n const signal = requestSignal\n ? AbortSignal.any([identitySignal, requestSignal])\n : identitySignal;\n setGitLoading(true);\n try {\n const batch = await client.gitReadBatch(\n workspaceId,\n sessionId,\n { requests: repoPaths.map((root) => ({ status: { path: root } })) },\n { signal },\n );\n const statuses = batch.results.map((result, index) => ({\n root: repoPaths[index] ?? \"\",\n status: result.status,\n }));\n if (identityGenerationRef.current !== identityGeneration) return;\n const overlay = new Map<string, FileTreeStatus>();\n for (const { root, status } of statuses) {\n for (const file of status.files) {\n const code = file.worktree ?? file.index;\n const mapped = code ? GIT_STATUS_TO_TREE[code] : undefined;\n if (mapped) overlay.set(qualifyStatusPath(root, file.path, rootPath), mapped);\n }\n }\n statusRef.current = overlay;\n setGitSummary(summarizeStatuses(statuses));\n setTree((prev) => applyStatus(prev));\n } catch {\n /* a non-repo box has no overlay — leave the tree untinted */\n } finally {\n if (identityGenerationRef.current === identityGeneration) setGitLoading(false);\n }\n },\n [client, workspaceId, sessionId, repoPaths, rootPath, applyStatus],\n );\n\n const performEventReconcile = useCallback(async () => {\n const parents = pendingParentsRef.current;\n pendingParentsRef.current = new Set();\n const wantGit = pendingGitRef.current;\n pendingGitRef.current = false;\n const signal = eventReadAbortRef.current.signal;\n const paths = [...parents];\n\n // File content is the primary Files-tab result. Reconcile it first, then add\n // the optional Git tint through a second serial request. This matches the\n // API's exact-provider serialization instead of making the two reads contend.\n await reconcilePaths(paths, signal);\n if (wantGit) await refreshGitOverlay(signal);\n }, [reconcilePaths, refreshGitOverlay]);\n const performEventReconcileRef = useRef(performEventReconcile);\n performEventReconcileRef.current = performEventReconcile;\n const reconcilePendingEvents = useCallback(async () => {\n eventReconcilePendingRef.current = true;\n const existing = eventReconcileInFlightRef.current;\n if (existing) return await existing;\n const identityGeneration = identityGenerationRef.current;\n const run = (async () => {\n while (\n eventReconcilePendingRef.current &&\n identityGenerationRef.current === identityGeneration\n ) {\n eventReconcilePendingRef.current = false;\n await performEventReconcileRef.current();\n }\n })();\n eventReconcileInFlightRef.current = run;\n try {\n await run;\n } finally {\n if (eventReconcileInFlightRef.current === run) eventReconcileInFlightRef.current = null;\n }\n }, []);\n\n // Auto-reconcile on fs/git change notifications — TARGETED, never a root\n // collapse-reload, and de-duped against our OWN mutations.\n //\n // • Our own ops (`source:\"write\"`, or a revision WE caused) are IGNORED —\n // the optimistic edit already reflects them, so a refresh here would be the\n // pointless 5s collapse the user reported.\n // • An EXTERNAL fs.changed (the agent writing files: `source:\"agent\"`/`watch`)\n // reconciles ONLY the affected parent directories (in place, expansion\n // preserved). Bursts are debounced into a single reconcile pass.\n // • A git.changed just re-tints (refreshes the status overlay) — no fs re-list.\n // • Generic command/tool output performs no provider reads. The canonical\n // turn-end capture refreshes the root once after the command burst settles.\n const events = options.events;\n\n useEffect(() => {\n if (!enabled || !events) return;\n // An inactive tab or holderless draining/cold lease must not replay the\n // historical log into live provider reads. The capture already includes\n // those events; a later warm transition performs one authoritative refresh.\n if (!active || !acceptsEventReads) {\n for (const event of events) {\n if (event.sequence > lastSeqRef.current) lastSeqRef.current = event.sequence;\n }\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n pendingParentsRef.current = new Set();\n pendingGitRef.current = false;\n eventReconcilePendingRef.current = false;\n return;\n }\n let sawNew = false;\n let contentChanged = false;\n for (const event of events) {\n if (event.sequence <= lastSeqRef.current) continue;\n if (event.type === \"fs.changed\") {\n sawNew = true;\n const payload = event.payload as FsChangedPayload | null;\n if (!payload || typeof payload !== \"object\") continue;\n // Suppress our own writes: the optimistic tree already shows them.\n if (payload.source === \"write\") continue;\n if (typeof payload.revision === \"number\" && ownRevisionsRef.current.has(payload.revision))\n continue;\n contentChanged = true;\n for (const change of payload.changes ?? []) {\n pendingParentsRef.current.add(parentWithinTree(change.path, rootPath));\n if (change.oldPath) {\n pendingParentsRef.current.add(parentWithinTree(change.oldPath, rootPath));\n }\n }\n } else if (event.type === \"git.changed\") {\n sawNew = true;\n const payload = event.payload as GitChangedPayload | null;\n // A git.changed our own write triggered (commit/stage from the agent is\n // external; a checkout we caused isn't — but we don't cause git ops here,\n // so any git.changed is external) → re-tint.\n if (\n payload &&\n typeof payload === \"object\" &&\n typeof payload.revision === \"number\" &&\n ownRevisionsRef.current.has(payload.revision)\n )\n continue;\n pendingGitRef.current = true;\n }\n }\n // Advance the high-water mark past everything we've folded.\n for (const event of events)\n if (event.sequence > lastSeqRef.current) lastSeqRef.current = event.sequence;\n if (!sawNew) return;\n if (contentChanged) setContentRevision((revision) => revision + 1);\n\n if (debounceRef.current) clearTimeout(debounceRef.current);\n const identityGeneration = identityGenerationRef.current;\n debounceRef.current = setTimeout(() => {\n debounceRef.current = null;\n if (identityGenerationRef.current !== identityGeneration) return;\n if (!acceptsEventReadsRef.current) {\n pendingParentsRef.current = new Set();\n pendingGitRef.current = false;\n return;\n }\n void reconcilePendingEvents();\n }, 150);\n }, [enabled, active, acceptsEventReads, events, rootPath, reconcilePendingEvents]);\n\n useEffect(() => {\n if (active && acceptsEventReads) return;\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n debounceRef.current = null;\n }\n pendingParentsRef.current = new Set();\n pendingGitRef.current = false;\n eventReconcilePendingRef.current = false;\n }, [active, acceptsEventReads]);\n\n useEffect(\n () => () => {\n refreshAbortRef.current?.abort();\n identityAbortRef.current.abort();\n eventReadAbortRef.current.abort();\n eventReconcilePendingRef.current = false;\n identityGenerationRef.current += 1;\n if (debounceRef.current) clearTimeout(debounceRef.current);\n },\n [],\n );\n\n const identityMatches = enabled && stateIdentity === identityKey;\n return {\n tree: identityMatches ? tree : [],\n expand,\n expandingPaths: identityMatches ? expandingPaths : new Set<string>(),\n readFile,\n writeFile,\n createFile,\n createDir,\n deleteEntry,\n moveEntry,\n refresh,\n contentRevision: identityMatches ? contentRevision : 0,\n source: identityMatches ? source : null,\n capturedAt: identityMatches && source === \"capture\" ? (capture?.capturedAt ?? null) : null,\n gitSummary: identityMatches ? gitSummary : null,\n gitLoading: identityMatches && gitLoading,\n loading: identityMatches && loading,\n error: identityMatches ? error : null,\n };\n}\n","/**\n * A sandbox is available for new I/O only after a holder has observed `warm`.\n *\n * `draining` means the holder count is zero and teardown owns the provider\n * instance. The provider may disappear before the durable lease reaches `cold`,\n * so treating `draining` as live races capture/termination. Explicit user intent\n * reacquires a holder; only its subsequent `warm` state re-enables live I/O.\n */\nexport function sandboxAcceptsLiveIo(liveness: string | null | undefined): boolean {\n return liveness === \"warm\";\n}\n","import type { FileTreeNode } from \"./hooks/use-sandbox-files\";\n\nexport type FileNodeVisibilityContext = {\n depth: number;\n parent: FileTreeNode | null;\n};\n\n/** Presentation-only predicate. It never changes filesystem authorization. */\nexport type FileNodeVisibilityPredicate = (\n node: FileTreeNode,\n context: FileNodeVisibilityContext,\n) => boolean;\n\nexport type FilePathVisibility = \"visible\" | \"hidden\" | \"unknown\";\n\nfunction pathIsInsideDirectory(path: string, directory: string): boolean {\n if (!path.startsWith(directory) || path === directory) return false;\n if (directory.endsWith(\"/\") || directory.endsWith(\"\\\\\")) return true;\n const boundary = path[directory.length];\n return boundary === \"/\" || boundary === \"\\\\\";\n}\n\n/**\n * Filter an authoritative tree without promoting children of a hidden parent.\n * Undefined children stay undefined so lazy-loading semantics are preserved.\n */\nexport function visibleFileTree(\n nodes: FileTreeNode[],\n predicate?: FileNodeVisibilityPredicate,\n parent: FileTreeNode | null = null,\n depth = 0,\n): FileTreeNode[] {\n if (!predicate) return nodes;\n const visible: FileTreeNode[] = [];\n for (const node of nodes) {\n if (!predicate(node, { depth, parent })) continue;\n visible.push(\n node.children === undefined\n ? node\n : {\n ...node,\n children: visibleFileTree(node.children, predicate, node, depth + 1),\n },\n );\n }\n return visible;\n}\n\n/** Resolve only what the currently loaded tree can prove. */\nexport function filePathVisibility(\n nodes: FileTreeNode[],\n path: string,\n predicate?: FileNodeVisibilityPredicate,\n parent: FileTreeNode | null = null,\n depth = 0,\n): FilePathVisibility {\n if (!predicate) return \"visible\";\n for (const node of nodes) {\n if (node.path !== path && !pathIsInsideDirectory(path, node.path)) continue;\n if (!predicate(node, { depth, parent })) return \"hidden\";\n if (node.path === path) return \"visible\";\n if (node.kind !== \"dir\" || node.children === undefined) return \"unknown\";\n return filePathVisibility(node.children, path, predicate, node, depth + 1);\n }\n return \"unknown\";\n}\n","import { Loader2Icon, SaveIcon } from \"lucide-react\";\nimport {\n type ComponentType,\n type CSSProperties,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../lib/cn\";\n\n// --- Lazy CodeMirror surface ----------------------------------------------\n//\n// CodeMirror 6 (via @uiw/react-codemirror) plus the per-language grammars are a\n// heavy bundle (lezer parsers, the view layer). We keep them OFF the critical\n// path and out of any SSR bundle by lazy-importing only when a file is actually\n// EDITED. The read-only viewer stays Pierre's Shiki `File`; this is the\n// editable complement, mounted on demand.\n\n/** The subset of `@uiw/react-codemirror`'s props we drive. */\ntype ReactCodeMirrorComponent = ComponentType<{\n value?: string;\n height?: string;\n theme?: \"light\" | \"dark\" | \"none\" | unknown;\n editable?: boolean;\n readOnly?: boolean;\n basicSetup?: boolean | Record<string, boolean>;\n extensions?: unknown[];\n onChange?: ((value: string) => void) | undefined;\n className?: string;\n style?: CSSProperties;\n}>;\n\n// Resolved lazily on first edit: the editor component + the keymap/Prec helpers\n// (both re-exported from @uiw/react-codemirror, which re-exports @codemirror/view\n// and @codemirror/state) + the chosen language extension.\ntype EditorBundle = {\n Editor: ReactCodeMirrorComponent;\n saveKeymapExtension: (onSave: () => void) => unknown;\n languageExtension: unknown | null;\n};\n\n/** Language grammar loaders, keyed by the extension class we infer from the path. */\nconst LANGUAGE_LOADERS: Record<string, () => Promise<unknown>> = {\n javascript: async () =>\n (await import(\"@codemirror/lang-javascript\")).javascript({ jsx: true, typescript: true }),\n json: async () => (await import(\"@codemirror/lang-json\")).json(),\n python: async () => (await import(\"@codemirror/lang-python\")).python(),\n markdown: async () => (await import(\"@codemirror/lang-markdown\")).markdown(),\n css: async () => (await import(\"@codemirror/lang-css\")).css(),\n html: async () => (await import(\"@codemirror/lang-html\")).html(),\n};\n\n/** Map a filename to a grammar key (or null for plain text — still fully editable). */\nexport function languageForPath(path: string): keyof typeof LANGUAGE_LOADERS | null {\n const name = path.split(\"/\").pop() ?? path;\n const ext = name.includes(\".\") ? (name.split(\".\").pop() ?? \"\").toLowerCase() : \"\";\n switch (ext) {\n case \"js\":\n case \"jsx\":\n case \"ts\":\n case \"tsx\":\n case \"mjs\":\n case \"cjs\":\n return \"javascript\";\n case \"json\":\n case \"jsonc\":\n return \"json\";\n case \"py\":\n case \"pyi\":\n return \"python\";\n case \"md\":\n case \"markdown\":\n case \"mdx\":\n return \"markdown\";\n case \"css\":\n case \"scss\":\n case \"less\":\n return \"css\";\n case \"html\":\n case \"htm\":\n case \"xml\":\n case \"svg\":\n case \"vue\":\n return \"html\";\n default:\n return null;\n }\n}\n\nexport type CodeEditorProps = {\n /** Workspace-relative path — drives language inference (and the save target upstream). */\n path: string;\n /** The decoded text contents to seed the editor with. */\n initialContents: string;\n /**\n * Persist the current buffer against the exact contents it was edited from.\n * The second argument is the immutable compare-and-swap baseline; hosts must\n * not replace it with a newer remote snapshot or concurrent writes can be\n * silently overwritten.\n */\n onSave: (contents: string, expectedContents: string) => Promise<unknown>;\n /** Explicitly overwrite after a visible expected-content conflict. */\n onOverwrite?: ((contents: string) => Promise<unknown>) | undefined;\n /** Re-read the selected file after a visible save conflict. */\n onReload?: (() => void) | undefined;\n /** Fired once when the buffer FIRST diverges from its baseline (the first real\n * keystroke) — the wake-on-edit intent. The host warms the box on this so the\n * eventual save lands fast; merely opening the file for reading never fires it. */\n onEditIntent?: (() => void) | undefined;\n /** Read-only mode (e.g. a truncated/too-large file shown for reference only). */\n readOnly?: boolean | undefined;\n themeType?: \"dark\" | \"light\" | undefined;\n /** Rendered while the (lazy) CodeMirror bundle loads. */\n loading?: ReactNode | undefined;\n /** Rendered if `@uiw/react-codemirror` is not installed / fails to import. */\n fallback?: ReactNode | undefined;\n className?: string | undefined;\n};\n\nexport type EditorBufferState = {\n path: string;\n value: string;\n baseline: string;\n};\n\n/**\n * Reconcile a remote file snapshot without destroying unsaved local work.\n *\n * A different path is a new document and always resets. For the same path, a\n * clean editor follows the remote snapshot while a dirty editor retains both\n * its local value and the original CAS baseline. The eventual save will then\n * either succeed against that baseline or surface a typed conflict.\n */\nexport function reconcileEditorBuffer(\n current: EditorBufferState,\n incoming: { path: string; contents: string },\n): EditorBufferState {\n if (current.path === incoming.path && current.value !== current.baseline) {\n return current;\n }\n if (\n current.path === incoming.path &&\n current.value === incoming.contents &&\n current.baseline === incoming.contents\n ) {\n return current;\n }\n return {\n path: incoming.path,\n value: incoming.contents,\n baseline: incoming.contents,\n };\n}\n\n/**\n * The EDITABLE single-file pane: CodeMirror 6 with a per-language grammar chosen\n * from the filename, og-* themed, with dirty tracking and a save path wired to\n * `Cmd/Ctrl+S` *and* an explicit Save button. The viewer (Pierre `File`) stays\n * the read-only complement — this is only mounted when the user opts to edit.\n *\n * Save semantics: the buffer is \"dirty\" the moment it diverges from the last\n * saved baseline; a successful `onSave` clears dirty and re-baselines. A failed\n * save keeps the buffer dirty (nothing is lost) and surfaces the error inline.\n * `readOnly` suppresses every mutation path so a truncated/binary file can never\n * be saved back (which would corrupt it by writing the truncated prefix).\n */\nexport function CodeEditor({\n path,\n initialContents,\n onSave,\n onOverwrite,\n onReload,\n onEditIntent,\n readOnly = false,\n themeType = \"dark\",\n loading,\n fallback,\n className,\n}: CodeEditorProps) {\n const [failed, setFailed] = useState(false);\n const [bundle, setBundle] = useState<EditorBundle | null>(null);\n\n // The live buffer and its compare-and-swap baseline are one state value so a\n // remote refresh cannot update one without the other.\n const [buffer, setBuffer] = useState<EditorBufferState>(() => ({\n path,\n value: initialContents,\n baseline: initialContents,\n }));\n const { value, baseline } = buffer;\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<Error | null>(null);\n const [savedTick, setSavedTick] = useState(false);\n const saveInFlightRef = useRef(false);\n\n const dirty = value !== baseline;\n const saveConflict =\n saveError !== null && (saveError as Error & { code?: unknown }).code === \"file_write_conflict\";\n\n // Follow path changes and clean same-file refreshes. Dirty same-file buffers\n // intentionally ignore remote snapshots: the original baseline must survive\n // until guarded save, explicit reload, or navigation.\n const editIntentFiredRef = useRef(false);\n useEffect(() => {\n setBuffer((current) => reconcileEditorBuffer(current, { path, contents: initialContents }));\n }, [path, initialContents]);\n\n // A new document is a new edit-intent/error lifecycle. The normal\n // SandboxFiles host also keys the component by path; this keeps standalone\n // consumers correct without relying on that implementation detail.\n useEffect(() => {\n editIntentFiredRef.current = false;\n setSaveError(null);\n setSavedTick(false);\n }, [path]);\n\n // Record a buffer change: the FIRST divergence from the baseline is the edit\n // intent that warms the box (idempotent — latched per opened file).\n const noteEdit = useCallback(\n (next: string) => {\n setBuffer((current) => ({ ...current, value: next }));\n setSavedTick(false);\n if (!editIntentFiredRef.current && next !== baseline) {\n editIntentFiredRef.current = true;\n onEditIntent?.();\n }\n },\n [baseline, onEditIntent],\n );\n\n // Resolve the lazy bundle (editor + keymap/Prec helpers + language grammar)\n // once, re-resolving the grammar when the file's language class changes.\n const langKey = useMemo(() => languageForPath(path), [path]);\n useEffect(() => {\n let cancelled = false;\n void (async () => {\n try {\n const cmMod = (await import(\"@uiw/react-codemirror\")) as unknown as {\n default: ReactCodeMirrorComponent;\n keymap: { of: (binds: unknown[]) => unknown };\n Prec: { highest: (ext: unknown) => unknown };\n };\n // Language peers are optional. A missing grammar must degrade to a plain\n // CodeMirror document, not throw the entire editor down to textarea.\n let languageExtension: unknown | null = null;\n if (langKey) {\n try {\n languageExtension = (await LANGUAGE_LOADERS[langKey]?.()) ?? null;\n } catch {\n languageExtension = null;\n }\n }\n if (cancelled) return;\n // A high-precedence Cmd/Ctrl-S keymap that calls back into the latest\n // save handler (kept fresh via a ref) and swallows the browser's\n // \"save page\" default.\n const saveKeymapExtension = (run: () => void) =>\n cmMod.Prec.highest(\n cmMod.keymap.of([\n {\n key: \"Mod-s\",\n preventDefault: true,\n run: () => {\n run();\n return true;\n },\n },\n ]),\n );\n setBundle({\n Editor: cmMod.default,\n saveKeymapExtension,\n languageExtension,\n });\n setFailed(false);\n } catch {\n if (!cancelled) setFailed(true);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [langKey]);\n\n // Keep the freshest save closure reachable from the (stable) keymap binding.\n const saveRef = useRef<() => void>(() => {});\n\n const save = useCallback(async () => {\n if (readOnly || saveInFlightRef.current) return;\n // Snapshot the buffer at call time so an in-flight edit can't race the write.\n const snapshot = value;\n if (snapshot === baseline) return; // nothing to persist\n saveInFlightRef.current = true;\n setSaving(true);\n setSaveError(null);\n setSavedTick(false);\n try {\n await onSave(snapshot, baseline);\n setBuffer((current) =>\n current.path === path ? { ...current, baseline: snapshot } : current,\n );\n setSavedTick(true);\n } catch (cause) {\n setSaveError(cause instanceof Error ? cause : new Error(String(cause)));\n } finally {\n saveInFlightRef.current = false;\n setSaving(false);\n }\n }, [readOnly, value, baseline, onSave, path]);\n\n const overwrite = useCallback(async () => {\n if (readOnly || !onOverwrite || saveInFlightRef.current) return;\n const snapshot = value;\n if (snapshot === baseline) return;\n saveInFlightRef.current = true;\n setSaving(true);\n setSaveError(null);\n setSavedTick(false);\n try {\n await onOverwrite(snapshot);\n setBuffer((current) =>\n current.path === path ? { ...current, baseline: snapshot } : current,\n );\n setSavedTick(true);\n } catch (cause) {\n setSaveError(cause instanceof Error ? cause : new Error(String(cause)));\n } finally {\n saveInFlightRef.current = false;\n setSaving(false);\n }\n }, [readOnly, onOverwrite, value, baseline, path]);\n\n saveRef.current = () => {\n void save();\n };\n\n // A brief \"Saved\" affordance after a successful write, cleared on the next edit.\n useEffect(() => {\n if (!savedTick) return;\n const t = setTimeout(() => setSavedTick(false), 1800);\n return () => clearTimeout(t);\n }, [savedTick]);\n\n const fileName = path.split(\"/\").filter(Boolean).pop() ?? path;\n\n const cmExtensions = useMemo(() => {\n if (!bundle) return [] as unknown[];\n const exts: unknown[] = [bundle.saveKeymapExtension(() => saveRef.current())];\n if (bundle.languageExtension) exts.push(bundle.languageExtension);\n return exts;\n }, [bundle]);\n\n const Editor = bundle?.Editor;\n\n const reload = useCallback(() => {\n setBuffer({ path, value: initialContents, baseline: initialContents });\n editIntentFiredRef.current = false;\n setSaveError(null);\n setSavedTick(false);\n onReload?.();\n }, [initialContents, onReload, path]);\n\n return (\n <div\n className={cn(\"flex h-full min-h-0 flex-col\", className)}\n data-opengeni-code-editor\n data-opengeni-editor-dirty={dirty ? \"true\" : \"false\"}\n style={editorVars}\n >\n {/* Save bar: dirty indicator + status + the explicit Save button. */}\n <div className=\"flex min-h-9 shrink-0 items-center gap-2 border-b border-og-border bg-og-surface-1 px-2 py-1\">\n <span\n className={cn(\n \"size-1.5 shrink-0 rounded-full transition-colors\",\n readOnly ? \"bg-transparent\" : dirty ? \"bg-og-status-running\" : \"bg-og-status-idle\",\n )}\n title={readOnly ? \"read-only\" : dirty ? \"unsaved changes\" : \"saved\"}\n />\n <span className=\"truncate font-og-mono text-og-xs text-og-fg-muted\">\n {fileName}\n {dirty && !readOnly ? \" •\" : \"\"}\n </span>\n <div className=\"ml-auto flex shrink-0 items-center gap-2\">\n {saveError && !saveConflict && (\n <span\n className=\"max-w-[220px] truncate text-og-xs text-og-status-failed\"\n title={saveError.message}\n >\n {saveError.message}\n </span>\n )}\n {!saveError && savedTick && !dirty && (\n <span className=\"text-og-xs text-og-status-idle\">Saved</span>\n )}\n {readOnly ? (\n <span className=\"text-og-xs uppercase tracking-wide text-og-fg-subtle\">Read-only</span>\n ) : !saveConflict ? (\n <button\n type=\"button\"\n onClick={() => void save()}\n disabled={saving || !dirty}\n className={cn(\n \"flex items-center gap-1 rounded-og-sm border border-og-border px-1.5 py-0.5 text-og-xs pointer-coarse:min-h-11\",\n saving || !dirty\n ? \"cursor-default text-og-fg-subtle opacity-60\"\n : \"text-og-fg hover:bg-og-accent-soft\",\n )}\n title=\"Save (⌘/Ctrl+S)\"\n >\n {saving ? (\n <Loader2Icon className=\"size-3 animate-spin\" />\n ) : (\n <SaveIcon className=\"size-3\" />\n )}\n Save\n </button>\n ) : null}\n </div>\n </div>\n\n {saveConflict ? (\n <div\n className=\"flex shrink-0 flex-wrap items-center gap-x-3 gap-y-2 border-b border-og-status-failed/25 bg-og-status-failed/8 px-2 py-2\"\n role=\"alert\"\n >\n <div className=\"min-w-[12rem] flex-1 text-og-xs text-og-fg-muted\">\n <span className=\"font-medium text-og-status-failed\">File changed on machine.</span>{\" \"}\n Reloading discards your edits; overwriting replaces the live version.\n </div>\n <div className=\"ml-auto flex shrink-0 items-center gap-1.5\">\n {onReload ? (\n <button\n type=\"button\"\n onClick={() => {\n reload();\n }}\n className=\"min-h-8 rounded-og-sm border border-og-border bg-og-surface-1 px-2 text-og-xs font-medium text-og-fg hover:bg-og-surface-2 pointer-coarse:min-h-11\"\n >\n Reload live\n </button>\n ) : null}\n {onOverwrite ? (\n <button\n type=\"button\"\n onClick={() => void overwrite()}\n disabled={saving}\n className=\"min-h-8 rounded-og-sm border border-og-status-failed/40 px-2 text-og-xs font-medium text-og-status-failed hover:bg-og-status-failed/10 disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n Overwrite\n </button>\n ) : null}\n </div>\n </div>\n ) : null}\n\n {/* The editor surface. */}\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {failed ? (\n (fallback ?? (\n <PlainTextarea\n value={value}\n readOnly={readOnly}\n onChange={noteEdit}\n onSave={() => void save()}\n />\n ))\n ) : Editor ? (\n <Editor\n value={value}\n theme={themeType === \"light\" ? \"light\" : \"dark\"}\n editable={!readOnly}\n readOnly={readOnly}\n basicSetup={true}\n extensions={cmExtensions}\n height=\"100%\"\n className=\"og-cm-editor min-h-full text-og-sm\"\n onChange={readOnly ? undefined : noteEdit}\n />\n ) : (\n (loading ?? <EditorSkeleton />)\n )}\n </div>\n </div>\n );\n}\n\n/** og-* themed CSS-var overrides handed to CodeMirror's container. */\nconst editorVars = {\n \"--og-cm-bg\": \"var(--og-color-bg)\",\n fontFamily: \"var(--og-font-mono)\",\n} as CSSProperties;\n\nfunction PlainTextarea({\n value,\n readOnly,\n onChange,\n onSave,\n}: {\n value: string;\n readOnly: boolean;\n onChange: (value: string) => void;\n onSave: () => void;\n}) {\n return (\n <textarea\n value={value}\n readOnly={readOnly}\n spellCheck={false}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"s\") {\n event.preventDefault();\n onSave();\n }\n }}\n aria-label=\"Plain text file editor\"\n className=\"h-full w-full resize-none bg-transparent p-2 font-og-mono text-og-sm text-og-fg outline-hidden\"\n />\n );\n}\n\nfunction EditorSkeleton() {\n return <div className=\"p-3 text-og-sm text-og-fg-subtle\">Loading editor…</div>;\n}\n","import {\n ChevronRightIcon,\n FileIcon,\n FilePlusIcon,\n FolderIcon,\n FolderPlusIcon,\n PencilIcon,\n RefreshCwIcon,\n TriangleAlertIcon,\n Trash2Icon,\n} from \"lucide-react\";\nimport {\n type KeyboardEvent as ReactKeyboardEvent,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { AlertDialog } from \"radix-ui\";\nimport { VList, type VListHandle } from \"virtua\";\nimport { cn } from \"../lib/cn\";\nimport { MENU_BUTTON_CLASS, MENU_SEPARATOR_CLASS, MENU_SURFACE_CLASS } from \"../lib/menu-styles\";\nimport {\n type PortalTokenStyle,\n usePortalTokenSource,\n usePortalTokenStyle,\n} from \"../lib/use-portal-token-style\";\nimport { useUnicodeFallbackFonts } from \"../lib/use-unicode-fonts\";\nimport type { FileTreeNode, UseSandboxFilesResult } from \"../hooks/use-sandbox-files\";\nimport { visibleFileTree, type FileNodeVisibilityPredicate } from \"../file-node-visibility\";\n\nexport type FileBrowserProps = {\n /** From `useSandboxFiles(...)`. */\n result: UseSandboxFilesResult;\n /**\n * Rendered instead of the built-in tree when the file surface is unavailable\n * (e.g. a `FileSystem.available === false` capability). Default: a quiet notice.\n */\n fallback?: ReactNode | undefined;\n /** Selection callback for the preview pane. */\n onSelectFile?: ((path: string) => void) | undefined;\n selectedPath?: string | undefined;\n /** Presentation-only node filter. Hidden parents never expose their children. */\n isNodeVisible?: FileNodeVisibilityPredicate | undefined;\n /** Deliberately reveal this selected path by lazily opening every loaded\n * ancestor and scrolling its row into view. The path is opaque and is never\n * normalized or re-rooted here. */\n revealPath?: string | undefined;\n /** Increment/change to reveal the same path again after a user collapses it. */\n revealPathRequestId?: string | number | undefined;\n /** Render-prop to theme/replace a row entirely (the Pierre-swap escape hatch). */\n renderNode?: ((node: FileTreeNode, depth: number, expanded: boolean) => ReactNode) | undefined;\n /** Shown when the tree is empty (no files / not loaded yet). */\n emptyState?: ReactNode | undefined;\n /**\n * Enable the file-manager affordances (toolbar, context menu, drag-drop move,\n * inline rename, delete, new file/folder). Defaults to `true` when the hook\n * exposes the mutation methods; pass `false` for a strictly read-only tree.\n */\n editable?: boolean | undefined;\n /**\n * Confirm a (recursive) delete before it runs. Return `false` to cancel.\n * The default is an accessible, non-blocking confirmation dialog. Supply this\n * callback to delegate confirmation to a host-owned dialog.\n */\n confirmDelete?: ((node: FileTreeNode) => boolean | Promise<boolean>) | undefined;\n className?: string | undefined;\n};\n\nconst STATUS_TINT: Record<NonNullable<FileTreeNode[\"status\"]>, string> = {\n added: \"text-og-status-idle\",\n modified: \"text-og-status-running\",\n deleted: \"text-og-status-failed line-through\",\n renamed: \"text-og-accent\",\n untracked: \"text-og-fg-subtle\",\n};\nconst useBrowserLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\n/** Parent dir of a workspace-relative POSIX path (\"\" for a root entry). */\nfunction parentOf(path: string): string {\n const i = path.lastIndexOf(\"/\");\n return i <= 0 ? \"\" : path.slice(0, i);\n}\n\n/** Join a parent dir with a leaf name (handles the root \"\" parent). */\nfunction joinPath(parent: string, name: string): string {\n return parent ? `${parent}/${name}` : name;\n}\n\n/** A stable React key for a flat render item. */\nfunction itemKey(item: RenderItem): string {\n switch (item.type) {\n case \"node\":\n return item.node.path;\n case \"create\":\n return `create:${item.parent}`;\n case \"skeleton\":\n return `skeleton:${item.path}`;\n case \"residue\":\n return `residue:${item.path}`;\n }\n}\n\nfunction pathIsInsideDirectory(path: string, directory: string): boolean {\n if (!path.startsWith(directory) || path === directory) return false;\n if (directory.endsWith(\"/\") || directory.endsWith(\"\\\\\")) return true;\n const boundary = path[directory.length];\n return boundary === \"/\" || boundary === \"\\\\\";\n}\n\n/** Walk the authoritative tree without assuming its target-owned separator. */\nfunction findNode(nodes: FileTreeNode[], path: string): FileTreeNode | undefined {\n for (const node of nodes) {\n if (node.path === path) return node;\n if (node.kind === \"dir\" && node.children && pathIsInsideDirectory(path, node.path)) {\n const hit = findNode(node.children, path);\n if (hit) return hit;\n }\n }\n return undefined;\n}\n\ntype RevealTrace = {\n directories: string[];\n frontier: string | null;\n};\n\n/** Follow only paths already named by the authoritative tree. This deliberately\n * avoids manufacturing ancestors from a platform-specific path string. */\nfunction traceRevealPath(nodes: FileTreeNode[], targetPath: string): RevealTrace {\n for (const node of nodes) {\n if (node.path === targetPath) {\n return {\n directories: node.kind === \"dir\" ? [node.path] : [],\n frontier: node.kind === \"dir\" && node.children === undefined ? node.path : null,\n };\n }\n if (node.kind !== \"dir\" || !pathIsInsideDirectory(targetPath, node.path)) continue;\n if (node.children === undefined) {\n return { directories: [node.path], frontier: node.path };\n }\n const child = traceRevealPath(node.children, targetPath);\n return {\n directories: [node.path, ...child.directories],\n frontier: child.frontier,\n };\n }\n return { directories: [], frontier: null };\n}\n\n/** A pending inline-create: a phantom input row under `parent`. */\ntype DraftCreate = { parent: string; kind: \"file\" | \"dir\" };\n/** A pending inline-rename of an existing node. */\ntype DraftRename = { path: string };\ntype ContextMenuState = { node: FileTreeNode | null; x: number; y: number };\n\n/** One virtualized row. Nodes plus the synthetic rows the recursive renderer\n * used to nest inline. */\ntype RenderItem =\n | { type: \"node\"; node: FileTreeNode; depth: number }\n | { type: \"create\"; parent: string; kind: \"file\" | \"dir\"; depth: number }\n | { type: \"skeleton\"; path: string; depth: number }\n | { type: \"residue\"; path: string; depth: number };\n\n/**\n * The file MANAGER, fed by the FileSystem service via `useSandboxFiles`. This is\n * a first-class editable tree (not a render-only view): lazy-expand with a\n * spinner on the in-flight node, git-status tinting, full keyboard navigation,\n * selection, and the mutating affordances wired straight to the hook —\n *\n * • drag-and-drop MOVE → `moveEntry(from, to)`\n * • inline RENAME → `moveEntry(path, newPath)` (F2 / double-click / menu)\n * • DELETE → `deleteEntry(path, recursive)` (Del / menu, confirmed)\n * • NEW FILE / FOLDER → `createFile` / `createDir` (toolbar + menu), then open\n * • right-click CONTEXT MENU\n *\n * `renderNode` is still honoured as the Pierre-swap escape hatch for the row\n * chrome; the manager scaffolding (toolbar, dnd, menu, inline inputs) wraps it.\n */\nexport function FileBrowser({\n result,\n fallback,\n onSelectFile,\n selectedPath,\n isNodeVisible,\n revealPath,\n revealPathRequestId,\n renderNode,\n emptyState,\n editable = true,\n confirmDelete,\n className,\n}: FileBrowserProps) {\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n const [loadingPaths, setLoadingPaths] = useState<Set<string>>(new Set());\n const [active, setActive] = useState<string | null>(null);\n const [draftCreate, setDraftCreate] = useState<DraftCreate | null>(null);\n const [draftRename, setDraftRename] = useState<DraftRename | null>(null);\n const [dragOver, setDragOver] = useState<string | null>(null);\n const [menu, setMenu] = useState<ContextMenuState | null>(null);\n const [pendingDelete, setPendingDelete] = useState<FileTreeNode | null>(null);\n const [busy, setBusy] = useState(false);\n const [coarsePointer, setCoarsePointer] = useState(false);\n const [revealRequest, setRevealRequest] = useState<{\n path: string;\n requestId: string | number;\n } | null>(null);\n const handledRevealRequestRef = useRef<{\n path: string;\n requestId: string | number;\n } | null>(null);\n const attemptedRevealPathsRef = useRef<Set<string>>(new Set());\n const treeId = useId();\n const container = usePortalTokenSource<HTMLDivElement>();\n const containerRef = container.currentRef;\n const deleteReturnFocusRef = useRef<HTMLElement | null>(null);\n const vlistRef = useRef<VListHandle>(null);\n const portalTokenStyle = usePortalTokenStyle(container.source);\n const getTreeElement = useCallback(\n () => (typeof document === \"undefined\" ? null : document.getElementById(treeId)),\n [treeId],\n );\n const visibleTree = useMemo(\n () => visibleFileTree(result.tree, isNodeVisible),\n [isNodeVisible, result.tree],\n );\n\n useBrowserLayoutEffect(() => {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return;\n const query = window.matchMedia(\"(pointer: coarse)\");\n const update = () => setCoarsePointer(query.matches);\n update();\n if (typeof query.addEventListener === \"function\") {\n query.addEventListener(\"change\", update);\n return () => query.removeEventListener(\"change\", update);\n }\n if (typeof query.addListener === \"function\") {\n query.addListener(update);\n return () => query.removeListener(update);\n }\n }, []);\n\n const effectiveRevealRequestId = revealPath ? (revealPathRequestId ?? revealPath) : null;\n useEffect(() => {\n if (!revealPath || effectiveRevealRequestId === null) {\n setRevealRequest(null);\n return;\n }\n const handled = handledRevealRequestRef.current;\n if (handled?.path === revealPath && handled.requestId === effectiveRevealRequestId) return;\n handledRevealRequestRef.current = {\n path: revealPath,\n requestId: effectiveRevealRequestId,\n };\n attemptedRevealPathsRef.current = new Set();\n setActive(null);\n setRevealRequest({ path: revealPath, requestId: effectiveRevealRequestId });\n }, [effectiveRevealRequestId, revealPath]);\n\n // The keyboard cursor: an explicitly-navigated node falls back to the\n // externally-selected file so arrow keys pick up where the preview pane is.\n const visibleActive = active && findNode(visibleTree, active) ? active : null;\n const cursor =\n visibleActive ?? (selectedPath && findNode(visibleTree, selectedPath) ? selectedPath : null);\n useEffect(() => {\n if (active !== null && visibleActive === null) setActive(null);\n }, [active, visibleActive]);\n\n const expand = useCallback(\n async (path: string) => {\n const node = findNode(visibleTree, path);\n if (node && node.kind === \"dir\" && node.children === undefined) {\n setLoadingPaths((prev) => new Set(prev).add(path));\n try {\n await result.expand(path);\n } finally {\n setLoadingPaths((prev) => {\n const next = new Set(prev);\n next.delete(path);\n return next;\n });\n }\n }\n },\n [result, visibleTree],\n );\n\n const open = useCallback(\n (path: string) => {\n setExpanded((prev) => new Set(prev).add(path));\n void expand(path);\n },\n [expand],\n );\n\n useEffect(() => {\n if (!revealRequest) return;\n const trace = traceRevealPath(visibleTree, revealRequest.path);\n if (trace.directories.length > 0) {\n setExpanded((previous) => {\n const next = new Set(previous);\n let changed = false;\n for (const path of trace.directories) {\n if (next.has(path)) continue;\n next.add(path);\n changed = true;\n }\n return changed ? next : previous;\n });\n }\n const frontier = trace.frontier;\n if (\n !frontier ||\n attemptedRevealPathsRef.current.has(frontier) ||\n loadingPaths.has(frontier) ||\n result.expandingPaths.has(frontier)\n ) {\n return;\n }\n attemptedRevealPathsRef.current.add(frontier);\n void expand(frontier);\n }, [expand, loadingPaths, result.expandingPaths, revealRequest, visibleTree]);\n\n const toggle = useCallback(\n async (node: FileTreeNode) => {\n if (node.kind !== \"dir\") return;\n const isOpen = expanded.has(node.path);\n setExpanded((prev) => {\n const next = new Set(prev);\n if (isOpen) next.delete(node.path);\n else next.add(node.path);\n return next;\n });\n if (!isOpen) await expand(node.path);\n },\n [expanded, expand],\n );\n\n // Flatten the VISIBLE (expanded) tree into a single ordered render list — the\n // input to the virtualizer. Interleaves the synthetic rows the recursive\n // renderer used to nest (inline create input, lazy-expand skeleton, and the\n // cold residue \"contents on machine\" row) so every visual row is one list item.\n const cold = result.source !== \"live\";\n const renderItems = useMemo(() => {\n const items: RenderItem[] = [];\n if (draftCreate && draftCreate.parent === \"\") {\n items.push({ type: \"create\", parent: \"\", kind: draftCreate.kind, depth: 0 });\n }\n const walk = (nodes: FileTreeNode[], depth: number) => {\n for (const node of nodes) {\n items.push({ type: \"node\", node, depth });\n if (node.kind !== \"dir\" || !expanded.has(node.path)) continue;\n if (draftCreate && draftCreate.parent === node.path) {\n items.push({\n type: \"create\",\n parent: node.path,\n kind: draftCreate.kind,\n depth: depth + 1,\n });\n }\n const childless = node.children === undefined || node.children.length === 0;\n const isLoading = loadingPaths.has(node.path) || result.expandingPaths.has(node.path);\n // A collapsed residue dir (node_modules, .git, …) can't list children from\n // the cold capture — offer to open it live rather than a dead skeleton.\n if (node.truncated && childless && cold && !isLoading) {\n items.push({ type: \"residue\", path: node.path, depth: depth + 1 });\n } else if (node.children && node.children.length > 0) {\n walk(node.children, depth + 1);\n } else if (isLoading && childless) {\n items.push({ type: \"skeleton\", path: node.path, depth: depth + 1 });\n }\n }\n };\n walk(visibleTree, 0);\n return items;\n }, [visibleTree, expanded, draftCreate, loadingPaths, result.expandingPaths, cold]);\n const unicodeFontPaths = useMemo(\n () => renderItems.flatMap((item) => (item.type === \"node\" ? [item.node.path] : [])),\n [renderItems],\n );\n useUnicodeFallbackFonts(unicodeFontPaths);\n\n // The visible NODE rows in order — drives keyboard up/down navigation.\n const flatRows = useMemo(\n () =>\n renderItems.flatMap((item) =>\n item.type === \"node\" ? [{ node: item.node, depth: item.depth }] : [],\n ),\n [renderItems],\n );\n const rowIndexByPath = useMemo(\n () => new Map(flatRows.map((row, index) => [row.node.path, index] as const)),\n [flatRows],\n );\n const treePositionByPath = useMemo(() => {\n const positions = new Map<string, { position: number; setSize: number }>();\n const visit = (nodes: FileTreeNode[]) => {\n nodes.forEach((node, index) => {\n positions.set(node.path, { position: index + 1, setSize: nodes.length });\n if (node.children) visit(node.children);\n });\n };\n visit(visibleTree);\n return positions;\n }, [visibleTree]);\n const cursorIndex = cursor ? (rowIndexByPath.get(cursor) ?? -1) : -1;\n const activeDescendantId = cursorIndex >= 0 ? `${treeId}-item-${cursorIndex}` : undefined;\n\n // A capture is immutable review data even if a stale capability document still\n // says the machine is writable. Mutations become available only after a live\n // reconciliation has actually succeeded.\n const supportsMutation =\n editable && result.source === \"live\" && result.error === null && !result.loading;\n\n const performDelete = useCallback(\n async (node: FileTreeNode) => {\n if (!supportsMutation) return;\n const recursive = node.kind === \"dir\";\n setBusy(true);\n try {\n await result.deleteEntry(node.path, recursive);\n } catch {\n // The hook surfaces the error on `result.error`; the panel renders it.\n } finally {\n setBusy(false);\n }\n },\n [supportsMutation, result],\n );\n\n const runDelete = useCallback(\n async (node: FileTreeNode, returnFocus?: HTMLElement) => {\n if (!supportsMutation) return;\n setMenu(null);\n if (!confirmDelete) {\n deleteReturnFocusRef.current =\n returnFocus ??\n (typeof document !== \"undefined\" && document.activeElement instanceof HTMLElement\n ? document.activeElement\n : null);\n setPendingDelete(node);\n return;\n }\n if (await confirmDelete(node)) await performDelete(node);\n },\n [supportsMutation, confirmDelete, performDelete],\n );\n\n const closePendingDelete = useCallback(\n (restoreTrigger: boolean) => {\n const returnTarget = restoreTrigger ? deleteReturnFocusRef.current : getTreeElement();\n deleteReturnFocusRef.current = null;\n setPendingDelete(null);\n if (typeof window !== \"undefined\") {\n window.requestAnimationFrame(() => {\n const target = returnTarget?.isConnected ? returnTarget : getTreeElement();\n target?.focus();\n });\n }\n },\n [getTreeElement],\n );\n\n const commitCreate = useCallback(\n async (name: string) => {\n const draft = draftCreate;\n setDraftCreate(null);\n if (!draft || !supportsMutation) return;\n const trimmed = name.trim().replace(/\\/+$/, \"\");\n if (!trimmed) return;\n const path = joinPath(draft.parent, trimmed);\n setBusy(true);\n try {\n if (draft.kind === \"dir\") {\n await result.createDir(path);\n open(path);\n } else {\n await result.createFile(path);\n // Open the freshly-created file in the preview/editor pane.\n setActive(path);\n onSelectFile?.(path);\n }\n } catch {\n /* error surfaced via result.error */\n } finally {\n setBusy(false);\n }\n },\n [draftCreate, supportsMutation, result, open, onSelectFile],\n );\n\n const commitRename = useCallback(\n async (name: string) => {\n const draft = draftRename;\n setDraftRename(null);\n if (!draft || !supportsMutation) return;\n const node = findNode(visibleTree, draft.path);\n const trimmed = name.trim().replace(/\\/+$/, \"\");\n if (!node || !trimmed || trimmed === node.name) return;\n const newPath = joinPath(parentOf(draft.path), trimmed);\n setBusy(true);\n try {\n await result.moveEntry(draft.path, newPath);\n if (node.kind === \"file\" && (selectedPath === draft.path || active === draft.path)) {\n setActive(newPath);\n onSelectFile?.(newPath);\n }\n } catch {\n /* error surfaced via result.error */\n } finally {\n setBusy(false);\n }\n },\n [draftRename, supportsMutation, result, selectedPath, active, onSelectFile, visibleTree],\n );\n\n // Begin a new file/folder under the active node's directory (or root).\n const startCreate = useCallback(\n (kind: \"file\" | \"dir\") => {\n if (!supportsMutation) return;\n const anchor = cursor ? findNode(visibleTree, cursor) : undefined;\n const parent = anchor ? (anchor.kind === \"dir\" ? anchor.path : parentOf(anchor.path)) : \"\";\n if (parent) open(parent);\n setDraftRename(null);\n setMenu(null);\n setDraftCreate({ parent, kind });\n },\n [supportsMutation, cursor, open, visibleTree],\n );\n\n const startRename = useCallback(\n (node: FileTreeNode) => {\n if (!supportsMutation) return;\n setDraftCreate(null);\n setMenu(null);\n setDraftRename({ path: node.path });\n },\n [supportsMutation],\n );\n\n // Drag-drop move: drop a node onto a directory (or the root) → moveEntry.\n const onDropOnto = useCallback(\n async (targetDir: string, sourcePath: string) => {\n setDragOver(null);\n if (!supportsMutation || !sourcePath) return;\n const src = findNode(visibleTree, sourcePath);\n if (!src) return;\n // No-op drops: onto its own current parent, onto itself, or into its own subtree.\n if (parentOf(sourcePath) === targetDir) return;\n if (targetDir === sourcePath || targetDir.startsWith(`${sourcePath}/`)) return;\n const newPath = joinPath(targetDir, src.name);\n if (newPath === sourcePath) return;\n setBusy(true);\n try {\n await result.moveEntry(sourcePath, newPath);\n if (src.kind === \"file\" && (selectedPath === sourcePath || active === sourcePath)) {\n setActive(newPath);\n onSelectFile?.(newPath);\n }\n } catch {\n /* 409/collision etc. surfaced via result.error */\n } finally {\n setBusy(false);\n }\n },\n [supportsMutation, result, selectedPath, active, onSelectFile, visibleTree],\n );\n\n const onKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLDivElement>) => {\n if (draftCreate || draftRename) return; // inline input owns the keyboard\n if (flatRows.length === 0) return;\n const idx = flatRows.findIndex((r) => r.node.path === cursor);\n const move = (next: number) => {\n const clamped = Math.max(0, Math.min(flatRows.length - 1, next));\n const row = flatRows[clamped];\n if (row) setActive(row.node.path);\n e.preventDefault();\n };\n const cur = idx >= 0 ? flatRows[idx] : undefined;\n switch (e.key) {\n case \"ArrowDown\":\n move(idx < 0 ? 0 : idx + 1);\n break;\n case \"ArrowUp\":\n move(idx < 0 ? 0 : idx - 1);\n break;\n case \"Home\":\n move(0);\n break;\n case \"End\":\n move(flatRows.length - 1);\n break;\n case \"PageDown\": {\n const pageSize = Math.max(\n 1,\n Math.floor((containerRef.current?.clientHeight || 280) / (coarsePointer ? 44 : 28)) - 1,\n );\n move((idx < 0 ? 0 : idx) + pageSize);\n break;\n }\n case \"PageUp\": {\n const pageSize = Math.max(\n 1,\n Math.floor((containerRef.current?.clientHeight || 280) / (coarsePointer ? 44 : 28)) - 1,\n );\n move((idx < 0 ? 0 : idx) - pageSize);\n break;\n }\n case \"ArrowRight\":\n if (cur?.node.kind === \"dir\") {\n if (!expanded.has(cur.node.path)) open(cur.node.path);\n else move(idx + 1);\n e.preventDefault();\n }\n break;\n case \"ArrowLeft\":\n if (cur) {\n if (cur.node.kind === \"dir\" && expanded.has(cur.node.path)) {\n setExpanded((prev) => {\n const n = new Set(prev);\n n.delete(cur.node.path);\n return n;\n });\n } else {\n const parent = parentOf(cur.node.path);\n if (parent) setActive(parent);\n }\n e.preventDefault();\n }\n break;\n case \"Enter\":\n if (cur) {\n if (cur.node.kind === \"dir\") void toggle(cur.node);\n else onSelectFile?.(cur.node.path);\n e.preventDefault();\n }\n break;\n case \"ContextMenu\":\n case \"F10\":\n if (cur && supportsMutation && (e.key === \"ContextMenu\" || e.shiftKey)) {\n const rowIndex = rowIndexByPath.get(cur.node.path) ?? 0;\n const row = document.getElementById(`${treeId}-item-${rowIndex}`);\n const rect = row?.getBoundingClientRect();\n setMenu({\n node: cur.node,\n x: rect ? rect.left + Math.min(32, rect.width / 2) : 8,\n y: rect ? rect.bottom : 8,\n });\n e.preventDefault();\n } else if (e.key === \"F10\") {\n break;\n }\n break;\n case \"F2\":\n if (cur) {\n startRename(cur.node);\n e.preventDefault();\n }\n break;\n case \"Delete\":\n case \"Backspace\":\n if (cur && supportsMutation) {\n void runDelete(cur.node);\n e.preventDefault();\n }\n break;\n }\n },\n [\n draftCreate,\n draftRename,\n flatRows,\n cursor,\n expanded,\n open,\n toggle,\n onSelectFile,\n startRename,\n runDelete,\n supportsMutation,\n coarsePointer,\n containerRef,\n rowIndexByPath,\n treeId,\n ],\n );\n\n // Close the context menu on any outside interaction.\n useEffect(() => {\n if (!menu) return;\n const close = () => setMenu(null);\n window.addEventListener(\"click\", close);\n window.addEventListener(\"scroll\", close, true);\n window.addEventListener(\"resize\", close);\n return () => {\n window.removeEventListener(\"click\", close);\n window.removeEventListener(\"scroll\", close, true);\n window.removeEventListener(\"resize\", close);\n };\n }, [menu]);\n\n const showErrorEmpty = result.error && visibleTree.length === 0 && !draftCreate;\n const showDegradedTree = result.error && visibleTree.length > 0;\n const showEmpty = !result.loading && visibleTree.length === 0 && !draftCreate;\n // Retry lives next to the state it explains (the degraded/empty notice), so do\n // not render a second toolbar retry for the same failure.\n const showToolbar = supportsMutation || result.loading;\n // Virtua caches the previous visible range when a lazy-expanded subtree is\n // inserted in the middle of a short list. The spacer grows but later root\n // siblings can remain unmounted until a scroll/resize (for example,\n // `.bash_history` vanished after expanding `repositories/<repo>`). Small\n // trees do not benefit from virtualization, so render them directly and keep\n // Virtua only for genuinely large workspaces.\n const usesVirtualTree = !showErrorEmpty && !showEmpty && renderItems.length > 500;\n\n // Render a SINGLE node row (no recursion — children are separate flat items the\n // virtualizer renders). Returns the row element; the caller assigns the key.\n const renderNodeRow = (node: FileTreeNode, depth: number): ReactNode => {\n const isOpen = expanded.has(node.path);\n if (renderNode) {\n return <div>{renderNode(node, depth, isOpen)}</div>;\n }\n const isDir = node.kind === \"dir\";\n const isSelected = node.path === selectedPath || node.path === active;\n const isCursor = node.path === cursor;\n const isLoading = loadingPaths.has(node.path) || result.expandingPaths.has(node.path);\n const isRenaming = draftRename?.path === node.path;\n const isDropTarget = dragOver === (isDir ? node.path : parentOf(node.path));\n const dropDir = isDir ? node.path : parentOf(node.path);\n const treePosition = treePositionByPath.get(node.path);\n\n return (\n <div\n id={`${treeId}-item-${rowIndexByPath.get(node.path) ?? 0}`}\n role=\"treeitem\"\n aria-level={depth + 1}\n aria-posinset={treePosition?.position}\n aria-setsize={treePosition?.setSize}\n aria-expanded={isDir ? isOpen : undefined}\n aria-selected={isCursor || undefined}\n aria-busy={isLoading || undefined}\n onDragOver={\n supportsMutation\n ? (e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n setDragOver(dropDir);\n }\n : undefined\n }\n onDragLeave={\n supportsMutation\n ? (e) => {\n e.stopPropagation();\n setDragOver((cur) => (cur === dropDir ? null : cur));\n }\n : undefined\n }\n onDrop={\n supportsMutation\n ? (e) => {\n e.preventDefault();\n e.stopPropagation();\n const src = e.dataTransfer.getData(\"text/og-path\");\n void onDropOnto(dropDir, src);\n }\n : undefined\n }\n >\n {isRenaming ? (\n <InlineInput\n depth={depth}\n kind={node.kind}\n initialValue={node.name}\n onCommit={(name) => void commitRename(name)}\n onCancel={() => setDraftRename(null)}\n />\n ) : (\n <button\n type=\"button\"\n tabIndex={-1}\n draggable={supportsMutation || undefined}\n onDragStart={\n supportsMutation\n ? (e) => {\n e.dataTransfer.setData(\"text/og-path\", node.path);\n e.dataTransfer.effectAllowed = \"move\";\n }\n : undefined\n }\n onClick={() => {\n setActive(node.path);\n if (isDir) void toggle(node);\n else onSelectFile?.(node.path);\n }}\n onDoubleClick={() => supportsMutation && startRename(node)}\n onContextMenu={(e) => {\n if (!supportsMutation) return;\n e.preventDefault();\n setActive(node.path);\n setMenu({ node, x: e.clientX, y: e.clientY });\n }}\n className={cn(\n \"group relative flex min-h-7 w-full items-center gap-1 truncate rounded-og-sm px-1 py-0.5 text-left text-og-sm pointer-coarse:min-h-11\",\n \"hover:bg-og-surface-2\",\n isSelected && \"bg-og-surface-2\",\n isCursor && \"outline outline-1 -outline-offset-1 outline-og-accent\",\n isDropTarget && \"bg-og-accent-soft ring-1 ring-inset ring-og-accent\",\n // A thin progress shimmer on the expanding row — no per-node spinner.\n isLoading &&\n \"after:pointer-events-none after:absolute after:inset-x-1 after:bottom-0 after:h-px after:animate-pulse after:rounded-full after:bg-og-accent-soft\",\n node.status ? STATUS_TINT[node.status] : undefined,\n )}\n style={{ paddingLeft: `${depth * 12 + 4}px` }}\n >\n {isDir ? (\n <ChevronRightIcon\n className={cn(\n \"size-3 shrink-0 transition-transform\",\n isOpen && \"rotate-90\",\n isLoading && \"text-og-accent\",\n )}\n />\n ) : (\n <span className=\"inline-block w-3 shrink-0\" />\n )}\n {isDir ? (\n <FolderIcon className=\"size-3.5 shrink-0\" />\n ) : (\n <FileIcon className=\"size-3.5 shrink-0\" />\n )}\n <span className=\"truncate\">{node.name}</span>\n {supportsMutation && (\n <span\n role=\"button\"\n tabIndex={-1}\n aria-label=\"More actions\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setActive(node.path);\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n setMenu({ node, x: rect.right, y: rect.bottom });\n }}\n className=\"ml-auto hidden shrink-0 px-1 text-og-fg-subtle hover:text-og-fg group-hover:inline\"\n >\n ⋯\n </span>\n )}\n </button>\n )}\n </div>\n );\n };\n\n // Render one flat list item (node row or a synthetic create/skeleton/residue row).\n const renderItem = (item: RenderItem): ReactNode => {\n switch (item.type) {\n case \"node\":\n return renderNodeRow(item.node, item.depth);\n case \"create\":\n return (\n <InlineInput\n depth={item.depth}\n kind={item.kind}\n initialValue=\"\"\n onCommit={(name) => void commitCreate(name)}\n onCancel={() => setDraftCreate(null)}\n />\n );\n case \"skeleton\":\n return (\n <div\n role=\"group\"\n aria-hidden\n style={{ paddingLeft: `${item.depth * 12 + 4}px` }}\n className=\"space-y-1 py-1\"\n >\n {[0, 1, 2].map((i) => (\n <div\n key={i}\n className=\"h-2.5 animate-pulse rounded-og-sm bg-og-surface-2\"\n style={{ width: `${70 - i * 12}%` }}\n />\n ))}\n </div>\n );\n case \"residue\":\n return (\n <div\n style={{ paddingLeft: `${item.depth * 12 + 4}px` }}\n className=\"flex items-center gap-1.5 py-0.5 pr-1 text-og-xs italic text-og-fg-subtle\"\n >\n <span className=\"inline-block w-3 shrink-0\" />\n <span className=\"min-w-0 truncate\">contents on machine — open when live</span>\n </div>\n );\n }\n };\n\n // Keep the keyboard cursor's row on screen even though off-screen rows unmount.\n useEffect(() => {\n if (!cursor) return;\n const index = renderItems.findIndex((it) => it.type === \"node\" && it.node.path === cursor);\n if (index >= 0) vlistRef.current?.scrollToIndex(index);\n }, [cursor, renderItems]);\n\n useEffect(() => {\n if (!revealRequest) return;\n const index = renderItems.findIndex(\n (item) => item.type === \"node\" && item.node.path === revealRequest.path,\n );\n if (index < 0) return;\n if (usesVirtualTree) {\n vlistRef.current?.scrollToIndex(index);\n } else {\n document.getElementById(`${treeId}-item-${index}`)?.scrollIntoView?.({ block: \"nearest\" });\n }\n setRevealRequest((current) =>\n current?.path === revealRequest.path && current.requestId === revealRequest.requestId\n ? null\n : current,\n );\n }, [renderItems, revealRequest, treeId, usesVirtualTree]);\n\n return (\n <div className={cn(\"flex min-h-0 min-w-0 flex-col\", className)}>\n {showToolbar && (\n <div\n role=\"toolbar\"\n aria-label=\"File actions\"\n className=\"flex shrink-0 flex-wrap items-center gap-0.5 border-b border-og-border px-1 py-1\"\n >\n {supportsMutation ? (\n <>\n <ToolbarButton label=\"New file\" onClick={() => startCreate(\"file\")} disabled={busy}>\n <FilePlusIcon className=\"size-3.5\" />\n </ToolbarButton>\n <ToolbarButton label=\"New folder\" onClick={() => startCreate(\"dir\")} disabled={busy}>\n <FolderPlusIcon className=\"size-3.5\" />\n </ToolbarButton>\n <ToolbarButton\n label=\"Rename\"\n onClick={() => {\n const node = cursor ? findNode(visibleTree, cursor) : undefined;\n if (node) startRename(node);\n }}\n disabled={busy || !cursor}\n >\n <PencilIcon className=\"size-3.5\" />\n </ToolbarButton>\n <ToolbarButton\n label=\"Delete\"\n onClick={(event) => {\n const node = cursor ? findNode(visibleTree, cursor) : undefined;\n if (node) void runDelete(node, event.currentTarget);\n }}\n disabled={busy || !cursor}\n >\n <Trash2Icon className=\"size-3.5\" />\n </ToolbarButton>\n </>\n ) : null}\n <span className=\"ml-auto\" />\n <ToolbarButton\n label=\"Refresh\"\n onClick={() => void result.refresh()}\n disabled={busy || result.loading}\n >\n <RefreshCwIcon className={cn(\"size-3.5\", result.loading && \"animate-spin\")} />\n </ToolbarButton>\n </div>\n )}\n\n {showDegradedTree ? (\n <div\n role=\"status\"\n aria-live=\"polite\"\n data-opengeni-files-degraded\n className=\"flex shrink-0 items-center gap-2 border-b border-og-status-running/30 bg-og-status-running/10 px-2 py-1.5 text-og-xs text-og-fg-muted\"\n >\n <TriangleAlertIcon className=\"size-3.5 shrink-0 text-og-status-running\" aria-hidden />\n <span className=\"min-w-0 flex-1\">\n {result.source === \"capture\"\n ? \"Live files are temporarily unavailable. Showing the latest captured revision.\"\n : \"Live refresh failed. Showing the last loaded files.\"}\n </span>\n <button\n type=\"button\"\n onClick={() => void result.refresh()}\n disabled={result.loading}\n className=\"inline-flex min-h-7 shrink-0 items-center gap-1 rounded-og-sm border border-og-border bg-og-surface-1 px-2 font-medium text-og-fg transition-colors hover:border-og-border-strong focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n <RefreshCwIcon\n className={cn(\"size-3\", result.loading && \"animate-spin motion-reduce:animate-none\")}\n aria-hidden\n />\n Retry\n </button>\n </div>\n ) : null}\n\n {/* The tree itself. The root is a drop target so a node can be moved to \"\". */}\n {/* biome-ignore lint/a11y/noNoninteractiveTabindex: the tree owns keyboard nav */}\n <div\n ref={container.ref}\n onFocus={(event) => {\n if ((event.target as HTMLElement).id === treeId && cursorIndex < 0) {\n const first = flatRows[0];\n if (first) setActive(first.node.path);\n }\n }}\n onKeyDown={onKeyDown}\n onDragOver={\n supportsMutation\n ? (e) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n setDragOver(\"\");\n }\n : undefined\n }\n onDrop={\n supportsMutation\n ? (e) => {\n e.preventDefault();\n const src = e.dataTransfer.getData(\"text/og-path\");\n void onDropOnto(\"\", src);\n }\n : undefined\n }\n className={cn(\n \"flex min-h-0 min-w-0 flex-1 flex-col p-1\",\n dragOver === \"\" && \"ring-1 ring-inset ring-og-accent\",\n )}\n data-opengeni-file-tree\n >\n {showErrorEmpty ? (\n <div className=\"flex flex-col items-start gap-2 p-2 text-og-sm text-og-fg-subtle\">\n <div>\n {fallback ??\n `Could not load files: ${result.error?.message ?? \"refresh the file list to try again\"}`}\n </div>\n <button\n type=\"button\"\n onClick={() => void result.refresh()}\n disabled={result.loading}\n className=\"inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2 py-1 text-og-xs font-medium text-og-fg-muted transition-colors hover:border-og-border-strong hover:text-og-fg disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n <RefreshCwIcon\n className={cn(\"size-3.5\", result.loading && \"animate-spin\")}\n aria-hidden\n />\n Retry\n </button>\n </div>\n ) : showEmpty ? (\n <div className=\"p-2 text-og-sm text-og-fg-subtle\">\n {emptyState ?? \"This directory is empty\"}\n </div>\n ) : !usesVirtualTree ? (\n <div\n id={treeId}\n role=\"tree\"\n aria-label=\"Workspace files\"\n aria-activedescendant={activeDescendantId}\n aria-multiselectable={false}\n tabIndex={0}\n className=\"min-h-0 min-w-0 flex-1 overflow-auto outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent\"\n >\n {renderItems.map((item) => (\n <div key={itemKey(item)} className=\"min-w-0\">\n {renderItem(item)}\n </div>\n ))}\n </div>\n ) : (\n // Virtualized: only the rows in/near the viewport mount, so a 3k-node\n // tree stays responsive. The flat item list already carries the\n // expanded subtree + synthetic (create/skeleton/residue) rows.\n <VList\n ref={vlistRef}\n id={treeId}\n role=\"tree\"\n aria-label=\"Workspace files\"\n aria-activedescendant={activeDescendantId}\n aria-multiselectable={false}\n tabIndex={0}\n className=\"min-h-0 flex-1 outline-hidden focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent\"\n itemSize={coarsePointer ? 44 : 28}\n ssrCount={Math.min(32, renderItems.length)}\n >\n {renderItems.map((item) => (\n <div key={itemKey(item)} className=\"min-w-0\">\n {renderItem(item)}\n </div>\n ))}\n </VList>\n )}\n </div>\n\n {menu && menu.node && (\n <ContextMenu\n node={menu.node}\n x={menu.x}\n y={menu.y}\n onRename={() => menu.node && startRename(menu.node)}\n onDelete={() => menu.node && void runDelete(menu.node)}\n onNewFile={() => startCreate(\"file\")}\n onNewFolder={() => startCreate(\"dir\")}\n onClose={() => {\n setMenu(null);\n window.requestAnimationFrame(() => getTreeElement()?.focus());\n }}\n />\n )}\n {pendingDelete ? (\n <DeleteDialog\n node={pendingDelete}\n busy={busy}\n portalTokenStyle={portalTokenStyle}\n onCancel={() => closePendingDelete(true)}\n onConfirm={() => {\n const node = pendingDelete;\n closePendingDelete(false);\n void performDelete(node);\n }}\n />\n ) : null}\n </div>\n );\n}\n\nfunction DeleteDialog({\n node,\n busy,\n portalTokenStyle,\n onCancel,\n onConfirm,\n}: {\n node: FileTreeNode;\n busy: boolean;\n portalTokenStyle: PortalTokenStyle;\n onCancel: () => void;\n onConfirm: () => void;\n}) {\n const cancelRef = useRef<HTMLButtonElement | null>(null);\n const [open, setOpen] = useState(true);\n const closeIntentRef = useRef<\"cancel\" | \"confirm\">(\"cancel\");\n const settledRef = useRef(false);\n const settleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const settle = () => {\n if (settledRef.current) return;\n settledRef.current = true;\n if (closeIntentRef.current === \"confirm\") {\n onConfirm();\n } else {\n onCancel();\n }\n };\n\n const scheduleSettle = () => {\n if (settleTimerRef.current !== null) return;\n settleTimerRef.current = setTimeout(() => {\n settleTimerRef.current = null;\n settle();\n }, 0);\n };\n\n useEffect(\n () => () => {\n if (settleTimerRef.current !== null) clearTimeout(settleTimerRef.current);\n },\n [],\n );\n\n return (\n <AlertDialog.Root\n open={open}\n onOpenChange={(nextOpen) => {\n if (!nextOpen && !busy) {\n setOpen(false);\n scheduleSettle();\n }\n }}\n >\n <AlertDialog.Portal container={typeof document === \"undefined\" ? null : document.body}>\n <AlertDialog.Overlay className=\"og-root fixed inset-0 z-[100] bg-black/45 backdrop-blur-[2px]\" />\n <AlertDialog.Content\n className=\"og-root fixed left-1/2 top-1/2 z-[101] max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] max-w-sm -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-og-lg border border-og-border-strong bg-og-surface-1 p-4 text-og-fg shadow-2xl outline-hidden\"\n style={portalTokenStyle}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n cancelRef.current?.focus();\n }}\n onCloseAutoFocus={(event) => {\n event.preventDefault();\n scheduleSettle();\n }}\n onEscapeKeyDown={(event) => {\n event.stopPropagation();\n if (busy) {\n event.preventDefault();\n } else {\n closeIntentRef.current = \"cancel\";\n }\n }}\n >\n <div className=\"flex items-start gap-3\">\n <span className=\"flex size-9 shrink-0 items-center justify-center rounded-full bg-og-status-failed/12 text-og-status-failed\">\n <Trash2Icon className=\"size-4\" aria-hidden />\n </span>\n <div className=\"min-w-0\">\n <AlertDialog.Title className=\"text-og-sm font-semibold\">\n Delete {node.kind === \"dir\" ? \"folder\" : \"file\"}?\n </AlertDialog.Title>\n <AlertDialog.Description className=\"mt-1 text-og-sm leading-relaxed text-og-fg-muted\">\n <span className=\"break-all font-og-mono text-og-fg\">{node.path}</span>\n {node.kind === \"dir\"\n ? \" and everything inside it will be permanently removed.\"\n : \" will be permanently removed.\"}\n </AlertDialog.Description>\n </div>\n </div>\n <div className=\"mt-4 flex justify-end gap-2\">\n <AlertDialog.Cancel asChild>\n <button\n ref={cancelRef}\n type=\"button\"\n onClick={() => {\n closeIntentRef.current = \"cancel\";\n }}\n disabled={busy}\n className=\"min-h-9 rounded-og-md border border-og-border px-3 text-og-sm font-medium text-og-fg hover:bg-og-surface-2 disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n Cancel\n </button>\n </AlertDialog.Cancel>\n <AlertDialog.Action asChild>\n <button\n type=\"button\"\n onClick={() => {\n closeIntentRef.current = \"confirm\";\n }}\n disabled={busy}\n className=\"min-h-9 rounded-og-md bg-og-danger-fill px-3 text-og-sm font-semibold text-og-danger-fg shadow-sm hover:brightness-110 disabled:opacity-50 pointer-coarse:min-h-11\"\n >\n Delete permanently\n </button>\n </AlertDialog.Action>\n </div>\n </AlertDialog.Content>\n </AlertDialog.Portal>\n </AlertDialog.Root>\n );\n}\n\nfunction ToolbarButton({\n label,\n onClick,\n disabled,\n children,\n}: {\n label: string;\n onClick: (event: ReactMouseEvent<HTMLButtonElement>) => void;\n disabled?: boolean;\n children: ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n title={label}\n aria-label={label}\n onClick={onClick}\n disabled={disabled}\n className={cn(\n \"inline-flex size-7 items-center justify-center rounded-og-sm p-1 text-og-fg-muted max-[1023px]:size-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11\",\n \"hover:bg-og-surface-2 hover:text-og-fg\",\n \"disabled:cursor-not-allowed disabled:opacity-40\",\n )}\n >\n {children}\n </button>\n );\n}\n\n/** An inline text input for create / rename, indented to match its row depth. */\nfunction InlineInput({\n depth,\n kind,\n initialValue,\n onCommit,\n onCancel,\n}: {\n depth: number;\n kind: \"file\" | \"dir\";\n initialValue: string;\n onCommit: (value: string) => void;\n onCancel: () => void;\n}) {\n const [value, setValue] = useState(initialValue);\n const ref = useRef<HTMLInputElement | null>(null);\n // Track whether we've already resolved so a blur after Enter/Escape is a no-op.\n const doneRef = useRef(false);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.focus();\n // Select the basename (excluding any extension) for a rename, like an IDE.\n const dot = initialValue.lastIndexOf(\".\");\n if (initialValue && dot > 0) el.setSelectionRange(0, dot);\n else el.select();\n }, [initialValue]);\n\n const finish = (commit: boolean) => {\n if (doneRef.current) return;\n doneRef.current = true;\n if (commit) onCommit(value);\n else onCancel();\n };\n\n return (\n <div\n className=\"flex items-center gap-1 px-1 py-0.5\"\n style={{ paddingLeft: `${depth * 12 + 4}px` }}\n >\n <span className=\"inline-block w-3 shrink-0\" />\n {kind === \"dir\" ? (\n <FolderIcon className=\"size-3.5 shrink-0\" />\n ) : (\n <FileIcon className=\"size-3.5 shrink-0\" />\n )}\n <input\n ref={ref}\n value={value}\n spellCheck={false}\n autoComplete=\"off\"\n aria-label={kind === \"dir\" ? \"Folder name\" : \"File name\"}\n onChange={(e) => setValue(e.target.value)}\n onBlur={() => finish(true)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n finish(true);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n finish(false);\n }\n e.stopPropagation();\n }}\n className={cn(\n \"min-w-0 flex-1 rounded-og-sm border bg-og-bg px-1 py-0 text-og-sm\",\n \"border-og-accent text-og-fg\",\n \"outline-hidden\",\n )}\n />\n </div>\n );\n}\n\n/** The right-click / kebab context menu, positioned at the click point. */\nfunction ContextMenu({\n node,\n x,\n y,\n onRename,\n onDelete,\n onNewFile,\n onNewFolder,\n onClose,\n}: {\n node: FileTreeNode;\n x: number;\n y: number;\n onRename: () => void;\n onDelete: () => void;\n onNewFile: () => void;\n onNewFolder: () => void;\n onClose: () => void;\n}) {\n const isDir = node.kind === \"dir\";\n const menuRef = useRef<HTMLDivElement | null>(null);\n // Keep the menu on-screen when opened near the viewport edge.\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 9999;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 9999;\n const left = Math.max(4, Math.min(x, vw - 180));\n const top = Math.max(4, Math.min(y, vh - 160));\n\n useEffect(() => {\n menuRef.current?.querySelector<HTMLButtonElement>('[role=\"menuitem\"]')?.focus();\n }, []);\n\n const onKeyDown = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n const items = Array.from(\n menuRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"menuitem\"]') ?? [],\n );\n if (items.length === 0) return;\n const current = items.findIndex((item) => item === document.activeElement);\n let next: number | null = null;\n if (event.key === \"ArrowDown\") next = (current + 1 + items.length) % items.length;\n else if (event.key === \"ArrowUp\") next = (current - 1 + items.length) % items.length;\n else if (event.key === \"Home\") next = 0;\n else if (event.key === \"End\") next = items.length - 1;\n else if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n onClose();\n return;\n }\n if (next === null) return;\n event.preventDefault();\n event.stopPropagation();\n items[next]?.focus();\n };\n\n const item = (label: string, icon: ReactNode, onClick: () => void, danger?: boolean) => (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={(e) => {\n e.stopPropagation();\n onClick();\n }}\n className={cn(\n MENU_BUTTON_CLASS,\n danger && \"text-og-status-failed [&_svg]:text-og-status-failed!\",\n )}\n >\n {icon}\n {label}\n </button>\n );\n\n return (\n <div\n ref={menuRef}\n role=\"menu\"\n aria-label={`Actions for ${node.name}`}\n onKeyDown={onKeyDown}\n onClick={(e) => e.stopPropagation()}\n style={{ left, top }}\n className={cn(MENU_SURFACE_CLASS, \"fixed z-50 min-w-[180px] overflow-hidden\")}\n >\n {isDir && (\n <>\n {item(\"New file\", <FilePlusIcon />, onNewFile)}\n {item(\"New folder\", <FolderPlusIcon />, onNewFolder)}\n <div role=\"separator\" className={MENU_SEPARATOR_CLASS} />\n </>\n )}\n {item(\"Rename\", <PencilIcon />, onRename)}\n {item(\"Delete\", <Trash2Icon />, onDelete, true)}\n </div>\n );\n}\n","import { useEffect, useMemo } from \"react\";\n\nexport type UnicodeFontNeeds = {\n japanese: boolean;\n arabic: boolean;\n};\n\nconst japaneseScript = /[\\u3040-\\u30ff\\u3400-\\u4dbf\\u4e00-\\u9fff\\uf900-\\ufaff]/u;\nconst arabicScript = /[\\u0600-\\u06ff\\u0750-\\u077f\\u0870-\\u08ff\\ufb50-\\ufdff\\ufe70-\\ufefc]/u;\n\nexport function detectUnicodeFontNeeds(values: Iterable<string>): UnicodeFontNeeds {\n let japanese = false;\n let arabic = false;\n for (const value of values) {\n japanese ||= japaneseScript.test(value);\n arabic ||= arabicScript.test(value);\n if (japanese && arabic) break;\n }\n return { japanese, arabic };\n}\n\n/**\n * Load large script-specific font manifests only when visible workspace content\n * needs them. Fontsource splits the actual glyphs by unicode-range, so Chromium\n * then fetches only the small shards used by the path instead of charging every\n * Latin-only session for the complete font.\n */\nexport function useUnicodeFallbackFonts(values: readonly string[]): void {\n const content = useMemo(() => collectUnicodeContent(values), [values]);\n useEffect(() => {\n if (content.japanese) {\n void import(\"./noto-sans-jp-loader.generated\")\n .then(({ loadNotoSansJp }) => loadNotoSansJp(content.japanese))\n .catch(() => undefined);\n }\n if (content.arabic) {\n void import(\"./noto-sans-arabic-loader\")\n .then(({ loadNotoSansArabic }) => loadNotoSansArabic())\n .catch(() => undefined);\n }\n }, [content.arabic, content.japanese]);\n}\n\nfunction collectUnicodeContent(values: Iterable<string>): {\n japanese: string;\n arabic: string;\n} {\n const japanese = new Set<string>();\n const arabic = new Set<string>();\n for (const value of values) {\n for (const character of value) {\n if (japaneseScript.test(character)) japanese.add(character);\n if (arabicScript.test(character)) arabic.add(character);\n }\n }\n return { japanese: [...japanese].join(\"\"), arabic: [...arabic].join(\"\") };\n}\n","import {\n type ComponentType,\n type CSSProperties,\n type ReactNode,\n lazy,\n Suspense,\n useEffect,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n loadPierreDiffs,\n pierreDiffsRevision,\n subscribePierreDiffs,\n} from \"../lib/pierre-diffs-loader\";\n\n/** Pierre `File` props subset we drive — the single-file, syntax-highlighted view\n * (Shiki), the read counterpart of `PatchDiff`. */\ntype FileComponent = ComponentType<{\n file: { name: string; contents: string; lang?: string };\n options?: {\n theme?: string | { dark: string; light: string };\n themeType?: \"dark\" | \"light\";\n overflow?: \"scroll\" | \"wrap\";\n stickyHeader?: boolean;\n showLineNumbers?: boolean;\n };\n disableWorkerPool?: boolean;\n className?: string;\n}>;\n\nexport type PierreFileProps = {\n /** Target path (used for the header + language inference). */\n path: string;\n /** The decoded text contents. */\n contents: string;\n themeType?: \"dark\" | \"light\" | undefined;\n /** Shiki bundled theme names (dark/light) — derived from the host palette. */\n theme?: { dark: string; light: string } | undefined;\n /** Disable Pierre's worker pool if its worker bundling fights the host bundler. */\n disableWorkerPool?: boolean | undefined;\n /** Rendered while the (lazy) Pierre bundle loads. */\n loading?: ReactNode | undefined;\n /** Rendered if `@pierre/diffs/react` is not installed / fails to import. */\n fallback?: ReactNode | undefined;\n className?: string | undefined;\n};\n\n// Lazy-load `@pierre/diffs/react`'s `File` so Shiki + the worker pool stay off the\n// critical path (and out of an SSR bundle) until a file is actually viewed.\nconst LazyFile = lazy(async () => {\n const mod = (await loadPierreDiffs()) as { File: FileComponent };\n return { default: mod.File };\n});\n\n/**\n * The Pierre-backed single-file VIEWER: Shiki-highlighted, language inferred from\n * the filename — the read complement of `PierreDiff`. Wired to `fs.read` so\n * clicking any file in the tree shows its contents (NOT a diff; no repo needed).\n * Falls back to a plain `<pre>` when `@pierre/diffs` is absent / fails to import.\n */\nexport function PierreFile({\n path,\n contents,\n themeType,\n theme,\n disableWorkerPool,\n loading,\n fallback,\n className,\n}: PierreFileProps) {\n const [failed, setFailed] = useState(false);\n const [ready, setReady] = useState(false);\n\n // Probe the import once so a hard failure (peer missing) shows `fallback`\n // rather than a Suspense boundary that never resolves.\n const loaderRevision = useSyncExternalStore(\n subscribePierreDiffs,\n pierreDiffsRevision,\n pierreDiffsRevision,\n );\n useEffect(() => {\n let cancelled = false;\n setFailed(false);\n loadPierreDiffs().then(\n () => {\n if (!cancelled) setReady(true);\n },\n () => {\n if (!cancelled) setFailed(true);\n },\n );\n return () => {\n cancelled = true;\n };\n }, [loaderRevision]);\n\n const name = path.split(\"/\").filter(Boolean).pop() ?? path;\n\n if (failed) {\n return (\n <div className={className}>{fallback ?? <PlainFile name={name} contents={contents} />}</div>\n );\n }\n\n const options = {\n overflow: \"scroll\" as const,\n stickyHeader: true,\n showLineNumbers: true,\n ...(theme\n ? { theme }\n : {\n theme: {\n dark: \"github-dark-high-contrast\",\n light: \"github-light-high-contrast\",\n },\n }),\n themeType: themeType ?? \"dark\",\n };\n\n // Same shadow-DOM override vars as PierreDiff: pin the base background to the\n // dock surface so the viewer reads as part of the panel, not a black seam.\n const pierreVars = {\n \"--diffs-dark-bg\": \"var(--og-color-bg)\",\n \"--diffs-light-bg\": \"var(--og-color-bg)\",\n \"--diffs-bg-buffer-override\": \"var(--og-color-surface-1)\",\n \"--diffs-bg-separator-override\": \"var(--og-color-surface-1)\",\n // Pierre's default (fg mixed 65% into bg) falls under 4.5:1 on the lifted\n // graphite separator; quiet meta text keeps AA on every diff surface.\n \"--diffs-fg-number-override\": \"var(--og-color-fg-subtle)\",\n \"--diffs-font-size\": \"var(--og-code-font-size)\",\n \"--diffs-line-height\": \"var(--og-code-line-height)\",\n } as CSSProperties;\n\n return (\n <div className={cn(\"min-w-0\", className)} data-opengeni-pierre-file style={pierreVars}>\n <Suspense fallback={loading ?? <FileSkeleton />}>\n {/* `cacheKey` keys Pierre's worker-pool highlight cache on path+size so a\n re-select of the same file is instant but an edited file re-highlights. */}\n {ready ? (\n <LazyFile\n file={{ name, contents }}\n options={options}\n {...(disableWorkerPool !== undefined ? { disableWorkerPool } : {})}\n />\n ) : (\n (loading ?? <FileSkeleton />)\n )}\n </Suspense>\n </div>\n );\n}\n\nfunction PlainFile({ name, contents }: { name: string; contents: string }) {\n return (\n <pre\n className=\"overflow-auto whitespace-pre p-2 font-og-mono text-og-sm text-og-fg\"\n data-file={name}\n >\n {contents}\n </pre>\n );\n}\n\nfunction FileSkeleton() {\n return <div className=\"p-3 text-og-sm text-og-fg-subtle\">Loading file…</div>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe,iBAAiB,wBAAwB;AACjE,SAAyB,eAAAA,cAAa,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AACzE,SAAS,OAAO,OAAO,iBAAiB;;;ACYxC,SAAS,aAAa,WAAW,SAAS,QAAQ,gBAAgB;;;ACN3D,SAAS,qBAAqB,UAA8C;AACjF,SAAO,aAAa;AACtB;;;ADgBO,IAAM,+BAAN,cAA2C,MAAM;AAAA,EAGtD,YACW,MACA,QACT;AACA;AAAA,MACE,WAAW,cACP,GAAG,IAAI,yCACP,WAAW,oBACT,GAAG,IAAI,6CACP,GAAG,IAAI;AAAA,IACf;AATS;AACA;AAST,SAAK,OAAO;AAAA,EACd;AAAA,EAdS,OAAO;AAelB;AAEO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAGhD,YACW,MACA,iBACA,aACT;AACA,UAAM,GAAG,IAAI,8EAA8E;AAJlF;AACA;AACA;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EATS,OAAO;AAUlB;AAiHA,SAAS,cAAc,MAAsB;AAC3C,QAAM,kBAAkB,KAAK,WAAW,MAAM,GAAG,EAAE,QAAQ,UAAU,EAAE;AACvE,MAAI,oBAAoB,IAAK,QAAO;AACpC,QAAM,aAAa,gBAAgB,QAAQ,QAAQ,EAAE;AACrD,SAAO,eAAe,MAAM,KAAK;AACnC;AAEA,SAAS,mBAAmB,MAAuB;AACjD,SAAO,KAAK,WAAW,GAAG,KAAK,gBAAgB,KAAK,IAAI;AAC1D;AAEA,SAAS,aAAa,MAAc,MAAsB;AACxD,MAAI,CAAC,QAAQ,mBAAmB,IAAI,EAAG,QAAO;AAC9C,SAAO,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,IAAI;AACpD;AAEA,SAAS,kBAAkB,MAAc,MAAc,UAA0B;AAC/E,QAAM,aAAa,cAAc,IAAI;AACrC,QAAM,oBAAoB,aAAa,YAAY,IAAI;AACvD,SAAO,aAAa,cAAc,QAAQ,GAAG,iBAAiB;AAChE;AAEA,SAAS,kBACP,UACwB;AACxB,QAAM,eAAe,SAAS,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,MAAM;AAClE,SAAO;AAAA,IACL,QAAQ,aAAa,WAAW,IAAK,aAAa,CAAC,GAAG,OAAO,QAAQ,OAAQ;AAAA,IAC7E,QAAQ,aAAa,SAAS;AAAA,IAC9B,WAAW,aAAa;AAAA,IACxB,OAAO,aAAa,OAAO,CAAC,KAAK,EAAE,OAAO,MAAM,MAAM,OAAO,OAAO,CAAC;AAAA,IACrE,QAAQ,aAAa,OAAO,CAAC,KAAK,EAAE,OAAO,MAAM,MAAM,OAAO,QAAQ,CAAC;AAAA,IACvE,YAAY,aAAa,OAAO,CAAC,KAAK,EAAE,OAAO,MAAM,MAAM,OAAO,MAAM,QAAQ,CAAC;AAAA,EACnF;AACF;AAGA,SAAS,SAAS,MAAsB;AACtC,QAAM,IAAI,KAAK,YAAY,GAAG;AAC9B,SAAO,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG,CAAC;AACtC;AAEA,SAAS,iBAAiB,MAAc,UAA0B;AAChE,QAAM,SAAS,SAAS,IAAI;AAC5B,SAAO,WAAW,MAAM,cAAc,QAAQ,MAAM,OAAO,KAAK,WAAW,GAAG,IAAI,MAAM;AAC1F;AAGA,SAAS,OAAO,MAAsB;AACpC,QAAM,IAAI,KAAK,YAAY,GAAG;AAC9B,SAAO,IAAI,IAAI,OAAO,KAAK,MAAM,IAAI,CAAC;AACxC;AAMA,SAAS,UAAU,OAAuC;AACxD,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/B,QAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,SAAS,QAAQ,KAAK;AACtD,WAAO,EAAE,KAAK,cAAc,EAAE,MAAM,QAAW,EAAE,aAAa,OAAO,CAAC;AAAA,EACxE,CAAC;AACH;AAEA,SAAS,aAAa,MAAkB,kBAAkB,OAAqB;AAC7E,QAAM,OAAO,KAAK,SAAS,QAAQ,QAAQ;AAU3C,QAAM,iBACJ,KAAK,YAAY,KAAK,SAAS,SAAS,IACpC,KAAK,SAAS,IAAI,CAAC,UAAU,aAAa,OAAO,eAAe,CAAC,IACjE,mBAAmB,SAAS,QAC1B,CAAC,IACD;AACR,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA,IACX;AAAA,IACA,MAAM,KAAK;AAAA,IACX,GAAI,SAAS,QAAQ,EAAE,UAAU,eAAe,IAAI,CAAC;AAAA;AAAA;AAAA,IAGrD,GAAI,SAAS,SAAS,KAAK,YAAY,EAAE,WAAW,KAAK,IAAI,CAAC;AAAA,EAChE;AACF;AAEA,IAAM,qBAAyE;AAAA,EAC7E,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AACd;AAGA,SAAS,gBACP,OACA,YACA,UACgB;AAChB,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,QAAI,KAAK,SAAS,YAAY;AAC5B,aAAO,EAAE,GAAG,MAAM,SAAS;AAAA,IAC7B;AACA,QAAI,KAAK,SAAS,SAAS,KAAK,YAAY,WAAW,WAAW,GAAG,KAAK,IAAI,GAAG,GAAG;AAClF,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU,gBAAgB,KAAK,UAAU,YAAY,QAAQ;AAAA,MAC/D;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAGA,SAAS,eAAe,OAAuB,MAAwC;AACrF,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,KAAM,QAAO;AAC/B,QAAI,KAAK,SAAS,SAAS,KAAK,YAAY,KAAK,WAAW,GAAG,KAAK,IAAI,GAAG,GAAG;AAC5E,YAAM,MAAM,eAAe,KAAK,UAAU,IAAI;AAC9C,UAAI,IAAK,QAAO;AAAA,IAClB;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,8BAA8B;AAKpC,SAAS,yBAAyB,UAAkB,WAAwC;AAC1F,QAAM,OAAO,cAAc,QAAQ;AACnC,QAAM,YAAY,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAChD,QAAM,aAAa,KAAK,WAAW,IAAI,IAAI,OAAO,KAAK,WAAW,GAAG,IAAI,MAAM;AAC/E,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,YAAY,WAAW;AAChC,UAAM,oBAAoB,aAAa,MAAM,cAAc,QAAQ,CAAC;AACpE,UAAM,QAAQ,kBAAkB,MAAM,GAAG,EAAE,OAAO,OAAO;AACzD,QAAI,UAAU,KAAK,CAAC,MAAM,UAAU,MAAM,KAAK,MAAM,IAAI,EAAG;AAC5D,aAAS,QAAQ,UAAU,SAAS,GAAG,SAAS,MAAM,QAAQ,SAAS,GAAG;AACxE,YAAM,OAAO,MAAM,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG;AAC3C,YAAM,IAAI,GAAG,UAAU,GAAG,IAAI,EAAE;AAAA,IAClC;AAAA,EACF;AAGA,SAAO,CAAC,GAAG,KAAK,EACb,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,EAC9E,MAAM,GAAG,CAAC;AACf;AAiBA,SAAS,eAAe,OAAuB,QAAgB,WAAW,IAAa;AACrF,MAAI,WAAW,cAAc,QAAQ,EAAG,QAAO;AAC/C,QAAM,OAAO,eAAe,OAAO,MAAM;AACzC,SAAO,QAAQ,QAAQ,KAAK,SAAS,SAAS,KAAK,aAAa,MAAS;AAC3E;AAKA,SAAS,WACP,OACA,QACA,OACA,WAAW,IACK;AAChB,MAAI,WAAW,cAAc,QAAQ,GAAG;AACtC,QAAI,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,IAAI,EAAG,QAAO;AACrD,WAAO,UAAU,CAAC,GAAG,OAAO,KAAK,CAAC;AAAA,EACpC;AACA,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,QAAI,KAAK,SAAS,QAAQ;AACxB,UAAI,KAAK,SAAS,SAAS,KAAK,aAAa,OAAW,QAAO;AAC/D,UAAI,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,IAAI,EAAG,QAAO;AAC7D,aAAO,EAAE,GAAG,MAAM,UAAU,UAAU,CAAC,GAAG,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,IACnE;AACA,QAAI,KAAK,SAAS,SAAS,KAAK,YAAY,OAAO,WAAW,GAAG,KAAK,IAAI,GAAG,GAAG;AAC9E,aAAO,EAAE,GAAG,MAAM,UAAU,WAAW,KAAK,UAAU,QAAQ,OAAO,QAAQ,EAAE;AAAA,IACjF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAGA,SAAS,WAAW,OAAuB,MAAc,WAAW,IAAoB;AACtF,QAAM,SAAS,iBAAiB,MAAM,QAAQ;AAC9C,MAAI,WAAW,cAAc,QAAQ,GAAG;AACtC,QAAI,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,EAAG,QAAO;AAChD,WAAO,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,EAC5C;AACA,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,QAAI,KAAK,SAAS,QAAQ;AACxB,UAAI,KAAK,SAAS,SAAS,KAAK,aAAa,OAAW,QAAO;AAC/D,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU,KAAK,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,MACvD;AAAA,IACF;AACA,QAAI,KAAK,SAAS,SAAS,KAAK,YAAY,OAAO,WAAW,GAAG,KAAK,IAAI,GAAG,GAAG;AAC9E,aAAO,EAAE,GAAG,MAAM,UAAU,WAAW,KAAK,UAAU,MAAM,QAAQ,EAAE;AAAA,IACxE;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAUA,SAAS,gBAAgB,GAAiB,GAA0B;AAClE,SACE,EAAE,SAAS,EAAE,QACb,EAAE,SAAS,EAAE,QACb,EAAE,SAAS,EAAE,SACZ,EAAE,QAAQ,WAAW,EAAE,QAAQ,UAC/B,EAAE,UAAU,aAAgB,EAAE,UAAU,YACxC,EAAE,aAAa,YAAY,EAAE,aAAa;AAE/C;AAEA,SAAS,cAAc,SAAyB,QAAwC;AACtF,QAAM,SAAS,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAU,CAAC;AAC/D,QAAM,SAAS,OAAO,IAAI,CAAC,SAAS;AAClC,UAAM,WAAW,OAAO,IAAI,KAAK,IAAI;AACrC,QAAI,CAAC,SAAU,QAAO;AAGtB,QAAI,SAAS,SAAS,SAAS,KAAK,SAAS,SAAS,SAAS,aAAa,QAAW;AACrF,YAAM,YAA0B,EAAE,GAAG,MAAM,UAAU,SAAS,SAAS;AAEvE,aAAO,gBAAgB,UAAU,SAAS,IAAI,WAAW;AAAA,IAC3D;AAEA,QAAI,SAAS,aAAa,KAAK,YAAY,gBAAgB,UAAU,IAAI,GAAG;AAC1E,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AACD,SAAO,UAAU,MAAM;AACzB;AAIA,SAAS,kBAAkB,OAAuB,QAAwC;AACxF,SAAO,cAAc,OAAO,MAAM;AACpC;AAIA,SAAS,WAAW,MAAoB,YAAoB,UAAgC;AAC1F,QAAM,UAAU,WAAW,KAAK,KAAK,MAAM,WAAW,MAAM;AAC5D,QAAM,OAAqB,EAAE,GAAG,MAAM,MAAM,SAAS,MAAM,OAAO,OAAO,EAAE;AAC3E,MAAI,KAAK,SAAU,MAAK,WAAW,KAAK,SAAS,IAAI,CAAC,MAAM,WAAW,GAAG,YAAY,QAAQ,CAAC;AAC/F,SAAO;AACT;AAEA,SAAS,kBAAkB,OAA2B;AACpD,QAAM,SAAS,KAAK,KAAK;AACzB,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,UAAM,KAAK,IAAI,OAAO,WAAW,KAAK;AAAA,EACxC;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,OAAuB;AAC/C,SAAO,IAAI,YAAY,EAAE,OAAO,kBAAkB,KAAK,CAAC;AAC1D;AAEA,SAAS,kBAAkB,OAA2B;AACpD,MAAI,SAAS;AACb,QAAM,YAAY;AAClB,WAAS,SAAS,GAAG,SAAS,MAAM,QAAQ,UAAU,WAAW;AAC/D,cAAU,OAAO,aAAa,GAAG,MAAM,SAAS,QAAQ,SAAS,SAAS,CAAC;AAAA,EAC7E;AACA,SAAO,KAAK,MAAM;AACpB;AAEA,eAAe,mBAAmB,OAAmB,UAAwC;AAC3F,MAAI,CAAC,SAAU,OAAM,IAAI,MAAM,8CAA8C;AAC7E,MAAI,CAAC,WAAW,QAAQ,QAAQ;AAC9B,UAAM,IAAI,MAAM,sEAAsE;AAAA,EACxF;AACA,QAAM,SAAS,IAAI,YAAY,MAAM,UAAU;AAC/C,MAAI,WAAW,MAAM,EAAE,IAAI,KAAK;AAChC,QAAM,SAAS,IAAI,WAAW,MAAM,WAAW,OAAO,OAAO,OAAO,WAAW,MAAM,CAAC;AACtF,QAAM,SAAS,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACpF,MAAI,WAAW,SAAU,OAAM,IAAI,MAAM,mDAAmD;AAC9F;AASO,SAAS,gBACd,WACA,UAAkC,CAAC,GACZ;AACvB,QAAM,EAAE,QAAQ,YAAY,IAAI,YAAY,OAAO;AACnD,QAAM,WAAW,QAAQ,WAAW,SAAS,QAAQ,SAAS;AAC9D,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,aAAa,QAAQ,OAAO,SAAS;AAC3C,QAAM,YAAY,QAAQ,OAAO,QAAQ;AACzC,QAAM,QAAQ;AAAA,IACZ,MACE,eAAe,QAAQ,cAAc,OACjC,EAAE,OAAO,YAAY,MAAM,UAAU,IACrC;AAAA,IACN,CAAC,YAAY,SAAS;AAAA,EACxB;AACA,QAAM,eAAe;AAAA,IACnB,GAAG,IAAI,KAAK,QAAQ,WAAW,SAAS,QAAQ,YAAY,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC;AAAA,EAC5F,EAAE,KAAK,IAAQ;AACf,QAAM,YAAY,QAAQ,MAAM,aAAa,MAAM,IAAQ,GAAG,CAAC,YAAY,CAAC;AAC5E,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,SAAS,qBAAqB,QAAQ,QAAQ;AAGpD,QAAM,oBAAoB,QAAQ,aAAa,UAAa;AAC5D,QAAM,uBAAuB,OAAO,iBAAiB;AACrD,uBAAqB,UAAU;AAC/B,QAAM,iBAAiB,QAAQ,aAAa;AAC5C,QAAM,cAAc,GAAG,WAAW,KAAS,aAAa,EAAE,KAAS,QAAQ,KAAS,YAAY,KAAS,cAAc,EAAE,KAAS,aAAa,EAAE;AAEjJ,QAAM,CAAC,MAAM,OAAO,IAAI,SAAyB,CAAC,CAAC;AAKnD,QAAM,UAAU,OAAuB,CAAC,CAAC;AACzC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAsB,oBAAI,IAAI,CAAC;AAC3E,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AACrD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwC,IAAI;AAChF,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAS,CAAC;AACxD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,WAAW;AAE9D,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAoC,IAAI;AACpE,QAAM,YAAY,OAAkC,IAAI;AACxD,QAAM,YAAY,OAAoC,oBAAI,IAAI,CAAC;AAG/D,QAAM,uBAAuB,OAAO,CAAC;AACrC,QAAM,kBAAkB,OAA+B,IAAI;AAC3D,QAAM,mBAAmB,OAAO,IAAI,gBAAgB,CAAC;AACrD,QAAM,oBAAoB,OAAO,IAAI,gBAAgB,CAAC;AACtD,QAAM,wBAAwB,OAAO,CAAC;AACtC,QAAM,aAAa,OAAO,CAAC;AAC3B,QAAM,oBAAoB,OAAoB,oBAAI,IAAI,CAAC;AACvD,QAAM,gBAAgB,OAAO,KAAK;AAClC,QAAM,4BAA4B,OAA6B,IAAI;AACnE,QAAM,2BAA2B,OAAO,KAAK;AAC7C,QAAM,cAAc,OAA6C,IAAI;AAUrE,QAAM,kBAAkB,OAAoB,oBAAI,IAAI,CAAC;AACrD,QAAM,kBAAkB,QAAQ;AAGhC,UAAQ,UAAU;AAOlB,QAAM,cAAc,YAAY,CAAC,UAA0C;AACzE,UAAM,UAAU,UAAU;AAC1B,UAAM,OAAO,CAAC,SAAyC;AACrD,UAAI,UAAU;AACd,YAAM,MAAM,KAAK,IAAI,CAAC,SAAS;AAC7B,cAAM,eAAe,KAAK,WAAW,KAAK,KAAK,QAAQ,IAAI,KAAK;AAChE,cAAM,aAAa,KAAK,SAAS,SAAS,QAAQ,IAAI,KAAK,IAAI,IAAI;AACnE,cAAM,kBAAkB,iBAAiB,KAAK;AAC9C,cAAM,iBAAiB,KAAK,UAAU,aAAgB,cAAc;AACpE,YAAI,CAAC,mBAAmB,CAAC,cAAe,QAAO;AAC/C,kBAAU;AACV,cAAM,OAAqB;AAAA,UACzB,GAAG;AAAA,UACH,GAAI,KAAK,WAAW,EAAE,UAAU,aAAa,IAAI,CAAC;AAAA,QACpD;AACA,YAAI,WAAY,MAAK,SAAS;AAAA,YACzB,QAAO,KAAK;AACjB,eAAO;AAAA,MACT,CAAC;AACD,aAAO,UAAU,MAAM;AAAA,IACzB;AACA,WAAO,KAAK,KAAK;AAAA,EACnB,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,YAAY,YAAY;AACtC,QAAI,CAAC,UAAW;AAChB,oBAAgB,SAAS,MAAM;AAC/B,UAAM,eAAe,IAAI,gBAAgB;AACzC,oBAAgB,UAAU;AAC1B,UAAM,aAAc,qBAAqB,WAAW;AACpD,eAAW,IAAI;AACf,kBAAc,IAAI;AAClB,aAAS,IAAI;AACb,QAAI;AAKF,YAAM,gBAAgB,yBAAyB,UAAU,SAAS;AAClE,YAAM,eAAe,CAAC,UAAU,GAAG,aAAa,EAAE,IAAI,CAAC,UAAU;AAAA,QAC/D;AAAA,QACA,OAAO;AAAA,QACP,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MAC3B,EAAE;AAIF,YAAM,cAAc,MAAM,OAAO;AAAA,QAC/B;AAAA,QACA;AAAA,QACA,EAAE,UAAU,aAAa;AAAA,QACzB,EAAE,QAAQ,aAAa,OAAO;AAAA,MAChC;AACA,UAAI,qBAAqB,YAAY,WAAY;AACjD,YAAM,SAAS,YAAY,QAAQ,CAAC;AACpC,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sDAAsD;AACnF,YAAM,YAAY,OAAO,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAG9E,cAAQ,CAAC,SAAS;AAChB,YAAI,WAAW,KAAK,WAAW,IAAI,WAAW,kBAAkB,MAAM,QAAQ;AAC9E,mBAAW,CAAC,OAAO,IAAI,KAAK,cAAc,QAAQ,GAAG;AACnD,gBAAM,aAAa,YAAY,QAAQ,QAAQ,CAAC;AAChD,cAAI,CAAC,WAAY;AACjB,qBAAW;AAAA,YACT;AAAA,YACA;AAAA,aACC,WAAW,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAAA,UACnE;AAAA,QACF;AACA,eAAO,YAAY,QAAQ;AAAA,MAC7B,CAAC;AACD,gBAAU,UAAU;AACpB,gBAAU,MAAM;AAChB,iBAAW,KAAK;AAEhB,YAAM,WACJ,UAAU,SAAS,IACf,MAAM,OACH;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,UACE,UAAU,UAAU,IAAI,CAAC,UAAU;AAAA,YACjC,QAAQ,EAAE,MAAM,KAAK;AAAA,UACvB,EAAE;AAAA,QACJ;AAAA,QACA,EAAE,QAAQ,aAAa,OAAO;AAAA,MAChC,EACC;AAAA,QAAK,CAAC,UACL,MAAM,QAAQ,IAAI,CAAC,QAAQ,WAAW;AAAA,UACpC,MAAM,UAAU,KAAK,KAAK;AAAA,UAC1B,QAAQ,OAAO;AAAA,QACjB,EAAE;AAAA,MACJ,EACC,MAAM,MAAM,IAAI,IACnB,CAAC;AACP,UAAI,qBAAqB,YAAY,WAAY;AACjD,UAAI,UAAU;AACZ,cAAM,UAAU,oBAAI,IAA4B;AAChD,mBAAW,EAAE,MAAM,OAAO,KAAK,UAAU;AACvC,qBAAW,QAAQ,OAAO,OAAO;AAC/B,kBAAM,OAAO,KAAK,YAAY,KAAK;AACnC,kBAAM,SAAS,OAAO,mBAAmB,IAAI,IAAI;AACjD,gBAAI,OAAQ,SAAQ,IAAI,kBAAkB,MAAM,KAAK,MAAM,QAAQ,GAAG,MAAM;AAAA,UAC9E;AAAA,QACF;AACA,kBAAU,UAAU;AACpB,sBAAc,kBAAkB,QAAQ,CAAC;AAAA,MAC3C,OAAO;AACL,kBAAU,UAAU,oBAAI,IAAI;AAC5B,sBAAc,IAAI;AAAA,MACpB;AACA,oBAAc,KAAK;AACnB,cAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AAAA,IACrC,SAAS,OAAO;AACd,UAAI,qBAAqB,YAAY,WAAY;AACjD,eAAS,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACpE,UAAE;AACA,UAAI,qBAAqB,YAAY,WAAY,YAAW,KAAK;AACjE,UAAI,qBAAqB,YAAY,WAAY,eAAc,KAAK;AACpE,UAAI,gBAAgB,YAAY,aAAc,iBAAgB,UAAU;AAAA,IAC1E;AAAA,EACF,GAAG,CAAC,QAAQ,aAAa,WAAW,UAAU,WAAW,OAAO,WAAW,CAAC;AAO5E,QAAM,kBAAkB;AAAA,IACtB,CAAC,aAAuC;AACtC,YAAM,UAAU,oBAAI,IAA4B;AAChD,iBAAW,QAAQ,SAAS,OAAO;AACjC,YAAI,KAAK,QAAS;AAClB,cAAM,SAAS,mBAAmB,KAAK,MAAM;AAC7C,YAAI,OAAQ,SAAQ,IAAI,KAAK,MAAM,MAAM;AAAA,MAC3C;AACA,gBAAU,UAAU;AAIpB,YAAM,YAAY,SAAS,UAAU,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,MAAM,IAAI,CAAC;AAC3F;AAAA,QAAQ,CAAC,SACP,YAAY,KAAK,WAAW,IAAI,WAAW,kBAAkB,MAAM,QAAQ,CAAC;AAAA,MAC9E;AACA,gBAAU,UAAU;AACpB,gBAAU,SAAS;AACnB,oBAAc;AAAA,QACZ,QAAQ,SAAS,MAAM,WAAW,IAAK,SAAS,MAAM,CAAC,GAAG,QAAQ,OAAQ;AAAA,QAC1E,QAAQ,SAAS,MAAM,SAAS;AAAA,QAChC,WAAW,SAAS,MAAM;AAAA,QAC1B,OAAO,SAAS,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,OAAO,CAAC;AAAA,QAC/D,QAAQ,SAAS,MAAM,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,QAAQ,CAAC;AAAA,QACjE,YAAY,SAAS,MAAM;AAAA,MAC7B,CAAC;AACD,oBAAc,KAAK;AACnB,eAAS,IAAI;AAAA,IACf;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,SAAS;AAAA,IACb,OAAO,SAAiB;AACtB,UAAI,CAAC,UAAW;AAIhB,UAAI,WAAW,aAAa,QAAS;AACrC,YAAM,qBAAqB,sBAAsB;AACjD,YAAM,iBAAiB,iBAAiB,QAAQ;AAIhD,wBAAkB,CAAC,SAAS;AAC1B,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,aAAK,IAAI,IAAI;AACb,eAAO;AAAA,MACT,CAAC;AACD,UAAI;AACF,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B;AAAA,UACA;AAAA,UACA,EAAE,MAAM,OAAO,GAAG,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,UAC9C,EAAE,QAAQ,eAAe;AAAA,QAC3B;AACA,YAAI,sBAAsB,YAAY,mBAAoB;AAC1D,cAAM,YAAY,OAAO,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAC9E,gBAAQ,CAAC,SAAS,YAAY,gBAAgB,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,MACtE,SAAS,OAAO;AACd,YAAI,sBAAsB,YAAY,mBAAoB;AAC1D,iBAAS,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,MACpE,UAAE;AACA,YAAI,sBAAsB,YAAY,oBAAoB;AACxD,4BAAkB,CAAC,SAAS;AAC1B,gBAAI,CAAC,KAAK,IAAI,IAAI,EAAG,QAAO;AAC5B,kBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,iBAAK,OAAO,IAAI;AAChB,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,SAAS,QAAQ,OAAO,WAAW;AAAA,EACtE;AAEA,QAAM,WAAW;AAAA,IACf,OAAO,MAAc,iBAAyC,CAAC,MAAM;AACnE,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,YAAY;AAC5C,YAAM,iBAAiB,iBAAiB,QAAQ;AAChD,YAAM,SAAS,eAAe,SAC1B,YAAY,IAAI,CAAC,gBAAgB,eAAe,MAAM,CAAC,IACvD;AACJ,YAAM,WAAW,SAAS,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,QAAQ,CAAC,KAAK,OAAO;AAClF,UAAI,WAAW,aAAa,SAAS;AACnC,YAAI,CAAC,UAAU;AACb,gBAAM,IAAI,6BAA6B,MAAM,cAAc;AAAA,QAC7D;AAKA,iBAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,gBAAM,SAAS,MAAM,OAAO;AAAA,YAC1B;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR,EAAE,OAAO;AAAA,UACX;AACA,cAAI,OAAO,SAAS,QAAQ,OAAO,aAAa,QAAQ,UAAU;AAChE,kBAAM,IAAI;AAAA,cACR;AAAA,YACF;AAAA,UACF;AACA,cACE,OAAO,SAAS,SAAS,QACzB,OAAO,cAAc,SAAS,aAC9B,OAAO,aAAa,SAAS,YAC7B,OAAO,aAAa,SAAS,UAC7B;AACA,kBAAM,IAAI,MAAM,oDAAoD;AAAA,UACtE;AACA,cAAI,OAAO,UAAU;AACnB,kBAAM,IAAI,6BAA6B,MAAM,WAAW;AAAA,UAC1D;AAEA,cAAI;AACJ,cAAI;AACJ,cAAI;AACJ,cAAI,OAAO,YAAY,QAAQ,OAAO,aAAa,MAAM;AACvD,uBAAW,OAAO;AAClB,sBAAU,OAAO;AACjB,oBACE,aAAa,WACT,kBAAkB,OAAO,IACzB,IAAI,YAAY,EAAE,OAAO,OAAO;AAAA,UACxC,WAAW,OAAO,YAAY;AAC5B,kBAAM,WAAW,MAAM,MAAM,OAAO,WAAW,KAAK;AAAA,cAClD,aAAa;AAAA,cACb,OAAO;AAAA,cACP,gBAAgB;AAAA,cAChB,QAAQ,YAAY,IAAI,CAAC,QAAQ,YAAY,QAAQ,GAAM,CAAC,CAAC;AAAA,YAC/D,CAAC,EAAE,MAAM,MAAM,IAAI;AACnB,gBAAI,CAAC,UAAU,IAAI;AACjB,kBACE,YAAY,MACX,aAAa,QAAQ,SAAS,WAAW,OAAO,SAAS,WAAW,MACrE;AACA;AAAA,cACF;AACA,oBAAM,IAAI,MAAM,gCAAgC;AAAA,YAClD;AACA,oBAAQ,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AACnD,uBAAW,OAAO,WAAW,WAAW;AACxC,sBAAU,OAAO,WAAW,kBAAkB,KAAK,IAAI,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,UACvF,OAAO;AACL,kBAAM,IAAI,6BAA6B,MAAM,iBAAiB;AAAA,UAChE;AAEA,cAAI,MAAM,eAAe,OAAO,WAAW;AACzC,kBAAM,IAAI,MAAM,gDAAgD;AAAA,UAClE;AACA,gBAAM,mBAAmB,OAAO,OAAO,IAAI;AAC3C,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA,WAAW,OAAO;AAAA,YAClB,WAAW;AAAA,YACX,UAAU,OAAO;AAAA,YACjB,UAAU,OAAO;AAAA,UACnB;AAAA,QACF;AACA,cAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AACA,aAAO,MAAM,OAAO;AAAA,QAClB;AAAA,QACA;AAAA,QACA,EAAE,MAAM,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,QACpC,EAAE,OAAO;AAAA,MACX;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,SAAS,QAAQ,KAAK;AAAA,EACzD;AASA,QAAM,gBAAgB;AAAA,IACpB,OAAO,MAAc,kBAAgC;AACnD,UAAI,CAAC,UAAW;AAChB,YAAM,qBAAqB,sBAAsB;AACjD,YAAM,iBAAiB,iBAAiB,QAAQ;AAChD,YAAM,SAAS,gBACX,YAAY,IAAI,CAAC,gBAAgB,aAAa,CAAC,IAC/C;AAGJ,UAAI,CAAC,eAAe,QAAQ,SAAS,MAAM,QAAQ,EAAG;AACtD,UAAI;AACF,cAAM,SAAS,MAAM,OAAO;AAAA,UAC1B;AAAA,UACA;AAAA,UACA,EAAE,MAAM,OAAO,GAAG,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,UAC9C,EAAE,OAAO;AAAA,QACX;AACA,YAAI,sBAAsB,YAAY,mBAAoB;AAC1D,cAAM,YAAY,OAAO,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAC9E,YAAI,SAAS,cAAc,QAAQ,GAAG;AACpC,kBAAQ,CAAC,SAAS,YAAY,kBAAkB,MAAM,QAAQ,CAAC,CAAC;AAAA,QAClE;AACE,kBAAQ,CAAC,SAAS;AAChB,kBAAM,WAAW,eAAe,MAAM,IAAI;AAC1C,kBAAM,SAAS,UAAU,WACrB,cAAc,SAAS,UAAU,QAAQ,IACzC;AACJ,mBAAO,YAAY,gBAAgB,MAAM,MAAM,MAAM,CAAC;AAAA,UACxD,CAAC;AAAA,MACL,QAAQ;AAAA,MAGR;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,UAAU,OAAO,WAAW;AAAA,EAC/D;AAKA,QAAM,iBAAiB;AAAA,IACrB,OAAO,gBAAmC,kBAAgC;AACxE,UAAI,CAAC,UAAW;AAChB,YAAM,qBAAqB,sBAAsB;AACjD,YAAM,iBAAiB,iBAAiB,QAAQ;AAChD,YAAM,SAAS,gBACX,YAAY,IAAI,CAAC,gBAAgB,aAAa,CAAC,IAC/C;AACJ,YAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,cAAc,CAAC,EAAE;AAAA,QAAO,CAAC,SACjD,eAAe,QAAQ,SAAS,MAAM,QAAQ;AAAA,MAChD;AACA,eAAS,SAAS,GAAG,SAAS,MAAM,QAAQ,UAAU,6BAA6B;AACjF,cAAM,QAAQ,MAAM,MAAM,QAAQ,SAAS,2BAA2B;AACtE,YAAI;AACF,gBAAM,SAAS,MAAM,OAAO;AAAA,YAC1B;AAAA,YACA;AAAA,YACA;AAAA,cACE,UAAU,MAAM,IAAI,CAAC,UAAU;AAAA,gBAC7B;AAAA,gBACA,OAAO;AAAA,gBACP,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,cAC3B,EAAE;AAAA,YACJ;AAAA,YACA,EAAE,OAAO;AAAA,UACX;AACA,cAAI,sBAAsB,YAAY,mBAAoB;AAC1D,kBAAQ,CAAC,aAAa;AACpB,gBAAI,OAAO;AACX,uBAAW,CAAC,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC3C,oBAAM,SAAS,OAAO,QAAQ,KAAK;AACnC,kBAAI,CAAC,OAAQ;AACb,oBAAM,YAAY,OAAO,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAC9E,kBAAI,SAAS,cAAc,QAAQ,GAAG;AACpC,uBAAO,kBAAkB,MAAM,QAAQ;AAAA,cACzC,OAAO;AACL,sBAAM,WAAW,eAAe,MAAM,IAAI;AAC1C,sBAAM,SAAS,UAAU,WACrB,cAAc,SAAS,UAAU,QAAQ,IACzC;AACJ,uBAAO,gBAAgB,MAAM,MAAM,MAAM;AAAA,cAC3C;AAAA,YACF;AACA,mBAAO,YAAY,IAAI;AAAA,UACzB,CAAC;AAAA,QACH,QAAQ;AAAA,QAGR;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,UAAU,OAAO,WAAW;AAAA,EAC/D;AASA,QAAM,gBAAgB;AAAA,IACpB,OACE,QACA,OACA,IACA,qBACe;AACf,YAAM,qBAAqB,sBAAsB;AAEjD,YAAM,WAAW,QAAQ;AACzB,eAAS,IAAI;AACb,cAAQ,YAAY,MAAM,QAAQ,CAAC,CAAC;AACpC,UAAI;AACF,cAAM,MAAM,MAAM,GAAG;AACrB,YAAI,sBAAsB,YAAY,mBAAoB,QAAO;AAGjE,YAAI,OAAO,OAAO,QAAQ,YAAY,cAAc,KAAK;AACvD,gBAAM,MAAO,IAA+B;AAC5C,cAAI,OAAO,QAAQ,SAAU,iBAAgB,QAAQ,IAAI,GAAG;AAAA,QAC9D;AAGA,mBAAW,UAAU,kBAAkB;AACrC,cAAI,sBAAsB,YAAY,mBAAoB,QAAO;AACjE,gBAAM,cAAc,MAAM;AAAA,QAC5B;AACA,eAAO;AAAA,MACT,SAAS,OAAO;AACd,cAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,YAAI,sBAAsB,YAAY,mBAAoB,OAAM;AAEhE,gBAAQ,YAAY,QAAQ,CAAC;AAK7B,YAAI,eAAe,uBAAwB,OAAM;AACjD,iBAAS,GAAG;AACZ,0BAAkB,KAAK,MAAM;AAC7B,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,aAAa,eAAe,eAAe;AAAA,EAC9C;AAEA,QAAM,YAAY;AAAA,IAChB,OACE,MACA,SACA,eAAwC,CAAC,MACZ;AAC7B,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,YAAY;AAC5C,YAAM,qBAAqB,sBAAsB;AACjD,YAAM,iBAAiB,iBAAiB,QAAQ;AAChD,YAAM,SAAS,iBAAiB,MAAM,QAAQ;AAI9C,YAAM,SAAS,QAAQ,eAAe,MAAM,IAAI,CAAC;AACjD,YAAM,OAAqB;AAAA,QACzB;AAAA,QACA,MAAM,OAAO,IAAI;AAAA,QACjB,MAAM;AAAA,QACN,MAAM,QAAQ;AAAA,MAChB;AACA,aAAO,MAAM;AAAA,QACX;AAAA,QACA,CAAC,UAAW,SAAS,QAAQ,WAAW,OAAO,QAAQ,MAAM,QAAQ;AAAA,QACrE,YAAY;AACV,cAAI,CAAC,aAAa,SAAS,aAAa,oBAAoB,QAAW;AACrE,kBAAM,OAAO,MAAM,OAAO;AAAA,cACxB;AAAA,cACA;AAAA,cACA,EAAE,MAAM,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AAAA,cACpC,EAAE,QAAQ,eAAe;AAAA,YAC3B;AACA,gBAAI,sBAAsB,YAAY,oBAAoB;AACxD,oBAAM,IAAI,MAAM,oDAAoD;AAAA,YACtE;AACA,kBAAM,cACJ,KAAK,aAAa,WAAW,iBAAiB,KAAK,OAAO,IAAI,KAAK;AACrE,gBAAI,KAAK,aAAa,KAAK,YAAY,gBAAgB,aAAa,iBAAiB;AACnF,oBAAM,IAAI,uBAAuB,MAAM,aAAa,iBAAiB,WAAW;AAAA,YAClF;AAAA,UACF;AACA,cAAI,sBAAsB,YAAY,oBAAoB;AACxD,kBAAM,IAAI,MAAM,oDAAoD;AAAA,UACtE;AACA,iBAAO,MAAM,OAAO,QAAQ,aAAa,WAAW;AAAA,YAClD;AAAA,YACA;AAAA,YACA,WAAW;AAAA,YACX,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,UAC3B,CAAC;AAAA,QACH;AAAA,QACA,SAAS,CAAC,IAAI,CAAC,MAAM;AAAA,MACvB;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,MAAM,UAAU,OAAO,aAAa;AAAA,EACvE;AAEA,QAAM,aAAa;AAAA,IACjB,OAAO,SAAgC;AACrC,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,YAAY;AAC5C,YAAM,SAAS,iBAAiB,MAAM,QAAQ;AAC9C,YAAM,OAAqB;AAAA,QACzB;AAAA,QACA,MAAM,OAAO,IAAI;AAAA,QACjB,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AACA,YAAM;AAAA,QACJ;AAAA,QACA,CAAC,UAAU,WAAW,OAAO,QAAQ,MAAM,QAAQ;AAAA,QACnD,MACE,OAAO,QAAQ,aAAa,WAAW;AAAA,UACrC;AAAA,UACA,SAAS;AAAA,UACT,WAAW;AAAA,UACX,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,QAC3B,CAAC;AAAA,QACH,CAAC,MAAM;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,UAAU,OAAO,aAAa;AAAA,EACjE;AAEA,QAAM,YAAY;AAAA,IAChB,OAAO,SAAgC;AACrC,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,YAAY;AAC5C,YAAM,SAAS,iBAAiB,MAAM,QAAQ;AAG9C,YAAM,OAAqB;AAAA,QACzB;AAAA,QACA,MAAM,OAAO,IAAI;AAAA,QACjB,MAAM;AAAA,QACN,UAAU,CAAC;AAAA,MACb;AACA,YAAM;AAAA,QACJ;AAAA,QACA,CAAC,UAAU,WAAW,OAAO,QAAQ,MAAM,QAAQ;AAAA,QACnD,MACE,OAAO,QAAQ,aAAa,WAAW;AAAA,UACrC;AAAA,UACA,WAAW;AAAA,UACX,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,QAC3B,CAAC;AAAA,QACH,CAAC,MAAM;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,UAAU,OAAO,aAAa;AAAA,EACjE;AAEA,QAAM,cAAc;AAAA,IAClB,OAAO,MAAc,YAAY,UAAyB;AACxD,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,YAAY;AAC5C,YAAM;AAAA,QACJ;AAAA,QACA,CAAC,UAAU,WAAW,OAAO,MAAM,QAAQ;AAAA,QAC3C,MACE,OAAO,SAAS,aAAa,WAAW;AAAA,UACtC;AAAA,UACA;AAAA,UACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,QAC3B,CAAC;AAAA,QACH,CAAC,iBAAiB,MAAM,QAAQ,CAAC;AAAA,MACnC;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,UAAU,OAAO,aAAa;AAAA,EACjE;AAEA,QAAM,YAAY;AAAA,IAChB,OAAO,MAAc,SAAiB,SAAkD;AACtF,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,YAAY;AAC5C,YAAM,OAAO,iBAAiB,MAAM,QAAQ;AAC5C,YAAM,KAAK,iBAAiB,SAAS,QAAQ;AAC7C,YAAM;AAAA,QACJ;AAAA,QACA,CAAC,UAAU;AACT,gBAAM,SAAS,eAAe,OAAO,IAAI;AACzC,cAAI,CAAC,OAAQ,QAAO;AAEpB,gBAAM,QAAQ,WAAW,QAAQ,MAAM,OAAO;AAC9C,iBAAO,WAAW,WAAW,OAAO,MAAM,QAAQ,GAAG,IAAI,OAAO,QAAQ;AAAA,QAC1E;AAAA,QACA,MACE,OAAO,OAAO,aAAa,WAAW;AAAA,UACpC;AAAA,UACA;AAAA,UACA,WAAW,MAAM,aAAa;AAAA,UAC9B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,QAC3B,CAAC;AAAA,QACH,OAAO,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;AAAA,MAClC;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,UAAU,OAAO,aAAa;AAAA,EACjE;AAWA,QAAM,aAAa,OAAwC,OAAO;AAClE,aAAW,UAAU;AACrB,QAAM,kBAAkB,SAAS,YAAY;AAC7C,QAAM,sBAAsB,OAAO,WAAW;AAC9C,YAAU,MAAM;AAId,oBAAgB,SAAS,MAAM;AAC/B,oBAAgB,UAAU;AAC1B,yBAAqB,WAAW;AAChC,sBAAkB,QAAQ,MAAM;AAChC,sBAAkB,UAAU,IAAI,gBAAgB;AAChD,UAAM,kBAAkB,oBAAoB,YAAY;AACxD,wBAAoB,UAAU;AAC9B,QAAI,mBAAmB,CAAC,SAAS;AAC/B,UAAI,gBAAiB,2BAA0B,UAAU;AACzD,uBAAiB,QAAQ,MAAM;AAC/B,uBAAiB,UAAU,IAAI,gBAAgB;AAC/C,4BAAsB,WAAW;AACjC,iBAAW,UAAU;AACrB,wBAAkB,UAAU,oBAAI,IAAI;AACpC,oBAAc,UAAU;AACxB,+BAAyB,UAAU;AACnC,UAAI,YAAY,SAAS;AACvB,qBAAa,YAAY,OAAO;AAChC,oBAAY,UAAU;AAAA,MACxB;AACA,sBAAgB,UAAU,oBAAI,IAAI;AAClC,gBAAU,UAAU,oBAAI,IAAI;AAC5B,cAAQ,UAAU,CAAC;AACnB,cAAQ,CAAC,CAAC;AACV,uBAAiB,WAAW;AAC5B,wBAAkB,oBAAI,IAAI,CAAC;AAC3B,gBAAU,UAAU;AACpB,gBAAU,IAAI;AACd,iBAAW,KAAK;AAChB,eAAS,IAAI;AACb,oBAAc,IAAI;AAClB,oBAAc,KAAK;AACnB,yBAAmB,CAAC;AAAA,IACtB;AACA,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,UAAM,iBAAiB,oBAAoB,OAAO,WAAW,UAAU;AACvE,QAAI,mBAAmB,mBAAmB,CAAC,UAAU,UAAU,YAAY,SAAS;AAClF,sBAAgB,cAAc;AAAA,IAChC;AACA,QAAI,CAAC,QAAQ;AACX,UAAI,CAAC,QAAQ;AACX,mBAAW,KAAK;AAChB,sBAAc,KAAK;AAAA,MACrB;AACA;AAAA,IACF;AACA,QAAI,UAAW,CAAC,kBAAkB,CAAC,gBAAiB;AAClD,WAAK,QAAQ;AAAA,IACf;AACA,WAAO,MAAM;AACX,sBAAgB,SAAS,MAAM;AAC/B,sBAAgB,UAAU;AAC1B,2BAAqB,WAAW;AAChC,wBAAkB,QAAQ,MAAM;AAChC,+BAAyB,UAAU;AAAA,IACrC;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAKD,QAAM,oBAAoB;AAAA,IACxB,OAAO,kBAAgC;AACrC,UAAI,CAAC,UAAW;AAChB,YAAM,qBAAqB,sBAAsB;AACjD,YAAM,iBAAiB,iBAAiB,QAAQ;AAChD,YAAM,SAAS,gBACX,YAAY,IAAI,CAAC,gBAAgB,aAAa,CAAC,IAC/C;AACJ,oBAAc,IAAI;AAClB,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,UACA,EAAE,UAAU,UAAU,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,EAAE,EAAE,EAAE;AAAA,UAClE,EAAE,OAAO;AAAA,QACX;AACA,cAAM,WAAW,MAAM,QAAQ,IAAI,CAAC,QAAQ,WAAW;AAAA,UACrD,MAAM,UAAU,KAAK,KAAK;AAAA,UAC1B,QAAQ,OAAO;AAAA,QACjB,EAAE;AACF,YAAI,sBAAsB,YAAY,mBAAoB;AAC1D,cAAM,UAAU,oBAAI,IAA4B;AAChD,mBAAW,EAAE,MAAM,OAAO,KAAK,UAAU;AACvC,qBAAW,QAAQ,OAAO,OAAO;AAC/B,kBAAM,OAAO,KAAK,YAAY,KAAK;AACnC,kBAAM,SAAS,OAAO,mBAAmB,IAAI,IAAI;AACjD,gBAAI,OAAQ,SAAQ,IAAI,kBAAkB,MAAM,KAAK,MAAM,QAAQ,GAAG,MAAM;AAAA,UAC9E;AAAA,QACF;AACA,kBAAU,UAAU;AACpB,sBAAc,kBAAkB,QAAQ,CAAC;AACzC,gBAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AAAA,MACrC,QAAQ;AAAA,MAER,UAAE;AACA,YAAI,sBAAsB,YAAY,mBAAoB,eAAc,KAAK;AAAA,MAC/E;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,aAAa,WAAW,WAAW,UAAU,WAAW;AAAA,EACnE;AAEA,QAAM,wBAAwB,YAAY,YAAY;AACpD,UAAM,UAAU,kBAAkB;AAClC,sBAAkB,UAAU,oBAAI,IAAI;AACpC,UAAM,UAAU,cAAc;AAC9B,kBAAc,UAAU;AACxB,UAAM,SAAS,kBAAkB,QAAQ;AACzC,UAAM,QAAQ,CAAC,GAAG,OAAO;AAKzB,UAAM,eAAe,OAAO,MAAM;AAClC,QAAI,QAAS,OAAM,kBAAkB,MAAM;AAAA,EAC7C,GAAG,CAAC,gBAAgB,iBAAiB,CAAC;AACtC,QAAM,2BAA2B,OAAO,qBAAqB;AAC7D,2BAAyB,UAAU;AACnC,QAAM,yBAAyB,YAAY,YAAY;AACrD,6BAAyB,UAAU;AACnC,UAAM,WAAW,0BAA0B;AAC3C,QAAI,SAAU,QAAO,MAAM;AAC3B,UAAM,qBAAqB,sBAAsB;AACjD,UAAM,OAAO,YAAY;AACvB,aACE,yBAAyB,WACzB,sBAAsB,YAAY,oBAClC;AACA,iCAAyB,UAAU;AACnC,cAAM,yBAAyB,QAAQ;AAAA,MACzC;AAAA,IACF,GAAG;AACH,8BAA0B,UAAU;AACpC,QAAI;AACF,YAAM;AAAA,IACR,UAAE;AACA,UAAI,0BAA0B,YAAY,IAAK,2BAA0B,UAAU;AAAA,IACrF;AAAA,EACF,GAAG,CAAC,CAAC;AAcL,QAAM,SAAS,QAAQ;AAEvB,YAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,OAAQ;AAIzB,QAAI,CAAC,UAAU,CAAC,mBAAmB;AACjC,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,WAAW,WAAW,QAAS,YAAW,UAAU,MAAM;AAAA,MACtE;AACA,UAAI,YAAY,SAAS;AACvB,qBAAa,YAAY,OAAO;AAChC,oBAAY,UAAU;AAAA,MACxB;AACA,wBAAkB,UAAU,oBAAI,IAAI;AACpC,oBAAc,UAAU;AACxB,+BAAyB,UAAU;AACnC;AAAA,IACF;AACA,QAAI,SAAS;AACb,QAAI,iBAAiB;AACrB,eAAW,SAAS,QAAQ;AAC1B,UAAI,MAAM,YAAY,WAAW,QAAS;AAC1C,UAAI,MAAM,SAAS,cAAc;AAC/B,iBAAS;AACT,cAAM,UAAU,MAAM;AACtB,YAAI,CAAC,WAAW,OAAO,YAAY,SAAU;AAE7C,YAAI,QAAQ,WAAW,QAAS;AAChC,YAAI,OAAO,QAAQ,aAAa,YAAY,gBAAgB,QAAQ,IAAI,QAAQ,QAAQ;AACtF;AACF,yBAAiB;AACjB,mBAAW,UAAU,QAAQ,WAAW,CAAC,GAAG;AAC1C,4BAAkB,QAAQ,IAAI,iBAAiB,OAAO,MAAM,QAAQ,CAAC;AACrE,cAAI,OAAO,SAAS;AAClB,8BAAkB,QAAQ,IAAI,iBAAiB,OAAO,SAAS,QAAQ,CAAC;AAAA,UAC1E;AAAA,QACF;AAAA,MACF,WAAW,MAAM,SAAS,eAAe;AACvC,iBAAS;AACT,cAAM,UAAU,MAAM;AAItB,YACE,WACA,OAAO,YAAY,YACnB,OAAO,QAAQ,aAAa,YAC5B,gBAAgB,QAAQ,IAAI,QAAQ,QAAQ;AAE5C;AACF,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAEA,eAAW,SAAS;AAClB,UAAI,MAAM,WAAW,WAAW,QAAS,YAAW,UAAU,MAAM;AACtE,QAAI,CAAC,OAAQ;AACb,QAAI,eAAgB,oBAAmB,CAAC,aAAa,WAAW,CAAC;AAEjE,QAAI,YAAY,QAAS,cAAa,YAAY,OAAO;AACzD,UAAM,qBAAqB,sBAAsB;AACjD,gBAAY,UAAU,WAAW,MAAM;AACrC,kBAAY,UAAU;AACtB,UAAI,sBAAsB,YAAY,mBAAoB;AAC1D,UAAI,CAAC,qBAAqB,SAAS;AACjC,0BAAkB,UAAU,oBAAI,IAAI;AACpC,sBAAc,UAAU;AACxB;AAAA,MACF;AACA,WAAK,uBAAuB;AAAA,IAC9B,GAAG,GAAG;AAAA,EACR,GAAG,CAAC,SAAS,QAAQ,mBAAmB,QAAQ,UAAU,sBAAsB,CAAC;AAEjF,YAAU,MAAM;AACd,QAAI,UAAU,kBAAmB;AACjC,QAAI,YAAY,SAAS;AACvB,mBAAa,YAAY,OAAO;AAChC,kBAAY,UAAU;AAAA,IACxB;AACA,sBAAkB,UAAU,oBAAI,IAAI;AACpC,kBAAc,UAAU;AACxB,6BAAyB,UAAU;AAAA,EACrC,GAAG,CAAC,QAAQ,iBAAiB,CAAC;AAE9B;AAAA,IACE,MAAM,MAAM;AACV,sBAAgB,SAAS,MAAM;AAC/B,uBAAiB,QAAQ,MAAM;AAC/B,wBAAkB,QAAQ,MAAM;AAChC,+BAAyB,UAAU;AACnC,4BAAsB,WAAW;AACjC,UAAI,YAAY,QAAS,cAAa,YAAY,OAAO;AAAA,IAC3D;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,kBAAkB,WAAW,kBAAkB;AACrD,SAAO;AAAA,IACL,MAAM,kBAAkB,OAAO,CAAC;AAAA,IAChC;AAAA,IACA,gBAAgB,kBAAkB,iBAAiB,oBAAI,IAAY;AAAA,IACnE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,kBAAkB,kBAAkB;AAAA,IACrD,QAAQ,kBAAkB,SAAS;AAAA,IACnC,YAAY,mBAAmB,WAAW,YAAa,SAAS,cAAc,OAAQ;AAAA,IACtF,YAAY,kBAAkB,aAAa;AAAA,IAC3C,YAAY,mBAAmB;AAAA,IAC/B,SAAS,mBAAmB;AAAA,IAC5B,OAAO,kBAAkB,QAAQ;AAAA,EACnC;AACF;;;AEj8CA,SAAS,sBAAsB,MAAc,WAA4B;AACvE,MAAI,CAAC,KAAK,WAAW,SAAS,KAAK,SAAS,UAAW,QAAO;AAC9D,MAAI,UAAU,SAAS,GAAG,KAAK,UAAU,SAAS,IAAI,EAAG,QAAO;AAChE,QAAM,WAAW,KAAK,UAAU,MAAM;AACtC,SAAO,aAAa,OAAO,aAAa;AAC1C;AAMO,SAAS,gBACd,OACA,WACA,SAA8B,MAC9B,QAAQ,GACQ;AAChB,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,UAA0B,CAAC;AACjC,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,UAAU,MAAM,EAAE,OAAO,OAAO,CAAC,EAAG;AACzC,YAAQ;AAAA,MACN,KAAK,aAAa,SACd,OACA;AAAA,QACE,GAAG;AAAA,QACH,UAAU,gBAAgB,KAAK,UAAU,WAAW,MAAM,QAAQ,CAAC;AAAA,MACrE;AAAA,IACN;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,mBACd,OACA,MACA,WACA,SAA8B,MAC9B,QAAQ,GACY;AACpB,MAAI,CAAC,UAAW,QAAO;AACvB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,QAAQ,CAAC,sBAAsB,MAAM,KAAK,IAAI,EAAG;AACnE,QAAI,CAAC,UAAU,MAAM,EAAE,OAAO,OAAO,CAAC,EAAG,QAAO;AAChD,QAAI,KAAK,SAAS,KAAM,QAAO;AAC/B,QAAI,KAAK,SAAS,SAAS,KAAK,aAAa,OAAW,QAAO;AAC/D,WAAO,mBAAmB,KAAK,UAAU,MAAM,WAAW,MAAM,QAAQ,CAAC;AAAA,EAC3E;AACA,SAAO;AACT;;;ACjEA,SAAS,aAAa,gBAAgB;AACtC;AAAA,EAIE,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AA4WC,cAOA,YAPA;AAzUR,IAAM,mBAA2D;AAAA,EAC/D,YAAY,aACT,MAAM,OAAO,6BAA6B,GAAG,WAAW,EAAE,KAAK,MAAM,YAAY,KAAK,CAAC;AAAA,EAC1F,MAAM,aAAa,MAAM,OAAO,uBAAuB,GAAG,KAAK;AAAA,EAC/D,QAAQ,aAAa,MAAM,OAAO,yBAAyB,GAAG,OAAO;AAAA,EACrE,UAAU,aAAa,MAAM,OAAO,2BAA2B,GAAG,SAAS;AAAA,EAC3E,KAAK,aAAa,MAAM,OAAO,sBAAsB,GAAG,IAAI;AAAA,EAC5D,MAAM,aAAa,MAAM,OAAO,uBAAuB,GAAG,KAAK;AACjE;AAGO,SAAS,gBAAgB,MAAoD;AAClF,QAAM,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK;AACtC,QAAM,MAAM,KAAK,SAAS,GAAG,KAAK,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,IAAI,YAAY,IAAI;AAC/E,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AA8CO,SAAS,sBACd,SACA,UACmB;AACnB,MAAI,QAAQ,SAAS,SAAS,QAAQ,QAAQ,UAAU,QAAQ,UAAU;AACxE,WAAO;AAAA,EACT;AACA,MACE,QAAQ,SAAS,SAAS,QAC1B,QAAQ,UAAU,SAAS,YAC3B,QAAQ,aAAa,SAAS,UAC9B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf,OAAO,SAAS;AAAA,IAChB,UAAU,SAAS;AAAA,EACrB;AACF;AAcO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAC1C,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAA8B,IAAI;AAI9D,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAA4B,OAAO;AAAA,IAC7D;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,EAAE;AACF,QAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAuB,IAAI;AAC7D,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,kBAAkBC,QAAO,KAAK;AAEpC,QAAM,QAAQ,UAAU;AACxB,QAAM,eACJ,cAAc,QAAS,UAAyC,SAAS;AAK3E,QAAM,qBAAqBA,QAAO,KAAK;AACvC,EAAAC,WAAU,MAAM;AACd,cAAU,CAAC,YAAY,sBAAsB,SAAS,EAAE,MAAM,UAAU,gBAAgB,CAAC,CAAC;AAAA,EAC5F,GAAG,CAAC,MAAM,eAAe,CAAC;AAK1B,EAAAA,WAAU,MAAM;AACd,uBAAmB,UAAU;AAC7B,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAAA,EACpB,GAAG,CAAC,IAAI,CAAC;AAIT,QAAM,WAAWC;AAAA,IACf,CAAC,SAAiB;AAChB,gBAAU,CAAC,aAAa,EAAE,GAAG,SAAS,OAAO,KAAK,EAAE;AACpD,mBAAa,KAAK;AAClB,UAAI,CAAC,mBAAmB,WAAW,SAAS,UAAU;AACpD,2BAAmB,UAAU;AAC7B,uBAAe;AAAA,MACjB;AAAA,IACF;AAAA,IACA,CAAC,UAAU,YAAY;AAAA,EACzB;AAIA,QAAM,UAAUC,SAAQ,MAAM,gBAAgB,IAAI,GAAG,CAAC,IAAI,CAAC;AAC3D,EAAAF,WAAU,MAAM;AACd,QAAI,YAAY;AAChB,UAAM,YAAY;AAChB,UAAI;AACF,cAAM,QAAS,MAAM,OAAO,uBAAuB;AAOnD,YAAI,oBAAoC;AACxC,YAAI,SAAS;AACX,cAAI;AACF,gCAAqB,MAAM,iBAAiB,OAAO,IAAI,KAAM;AAAA,UAC/D,QAAQ;AACN,gCAAoB;AAAA,UACtB;AAAA,QACF;AACA,YAAI,UAAW;AAIf,cAAM,sBAAsB,CAAC,QAC3B,MAAM,KAAK;AAAA,UACT,MAAM,OAAO,GAAG;AAAA,YACd;AAAA,cACE,KAAK;AAAA,cACL,gBAAgB;AAAA,cAChB,KAAK,MAAM;AACT,oBAAI;AACJ,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AACF,kBAAU;AAAA,UACR,QAAQ,MAAM;AAAA,UACd;AAAA,UACA;AAAA,QACF,CAAC;AACD,kBAAU,KAAK;AAAA,MACjB,QAAQ;AACN,YAAI,CAAC,UAAW,WAAU,IAAI;AAAA,MAChC;AAAA,IACF,GAAG;AACH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAGZ,QAAM,UAAUD,QAAmB,MAAM;AAAA,EAAC,CAAC;AAE3C,QAAM,OAAOE,aAAY,YAAY;AACnC,QAAI,YAAY,gBAAgB,QAAS;AAEzC,UAAM,WAAW;AACjB,QAAI,aAAa,SAAU;AAC3B,oBAAgB,UAAU;AAC1B,cAAU,IAAI;AACd,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAClB,QAAI;AACF,YAAM,OAAO,UAAU,QAAQ;AAC/B;AAAA,QAAU,CAAC,YACT,QAAQ,SAAS,OAAO,EAAE,GAAG,SAAS,UAAU,SAAS,IAAI;AAAA,MAC/D;AACA,mBAAa,IAAI;AAAA,IACnB,SAAS,OAAO;AACd,mBAAa,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACxE,UAAE;AACA,sBAAgB,UAAU;AAC1B,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,UAAU,OAAO,UAAU,QAAQ,IAAI,CAAC;AAE5C,QAAM,YAAYA,aAAY,YAAY;AACxC,QAAI,YAAY,CAAC,eAAe,gBAAgB,QAAS;AACzD,UAAM,WAAW;AACjB,QAAI,aAAa,SAAU;AAC3B,oBAAgB,UAAU;AAC1B,cAAU,IAAI;AACd,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAClB,QAAI;AACF,YAAM,YAAY,QAAQ;AAC1B;AAAA,QAAU,CAAC,YACT,QAAQ,SAAS,OAAO,EAAE,GAAG,SAAS,UAAU,SAAS,IAAI;AAAA,MAC/D;AACA,mBAAa,IAAI;AAAA,IACnB,SAAS,OAAO;AACd,mBAAa,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IACxE,UAAE;AACA,sBAAgB,UAAU;AAC1B,gBAAU,KAAK;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,UAAU,aAAa,OAAO,UAAU,IAAI,CAAC;AAEjD,UAAQ,UAAU,MAAM;AACtB,SAAK,KAAK;AAAA,EACZ;AAGA,EAAAD,WAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAChB,UAAM,IAAI,WAAW,MAAM,aAAa,KAAK,GAAG,IAAI;AACpD,WAAO,MAAM,aAAa,CAAC;AAAA,EAC7B,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,WAAW,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK;AAE1D,QAAM,eAAeE,SAAQ,MAAM;AACjC,QAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,UAAM,OAAkB,CAAC,OAAO,oBAAoB,MAAM,QAAQ,QAAQ,CAAC,CAAC;AAC5E,QAAI,OAAO,kBAAmB,MAAK,KAAK,OAAO,iBAAiB;AAChE,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,SAAS,QAAQ;AAEvB,QAAM,SAASD,aAAY,MAAM;AAC/B,cAAU,EAAE,MAAM,OAAO,iBAAiB,UAAU,gBAAgB,CAAC;AACrE,uBAAmB,UAAU;AAC7B,iBAAa,IAAI;AACjB,iBAAa,KAAK;AAClB,eAAW;AAAA,EACb,GAAG,CAAC,iBAAiB,UAAU,IAAI,CAAC;AAEpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,gCAAgC,SAAS;AAAA,MACvD,6BAAyB;AAAA,MACzB,8BAA4B,QAAQ,SAAS;AAAA,MAC7C,OAAO;AAAA,MAGP;AAAA,6BAAC,SAAI,WAAU,gGACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,WAAW,mBAAmB,QAAQ,yBAAyB;AAAA,cACjE;AAAA,cACA,OAAO,WAAW,cAAc,QAAQ,oBAAoB;AAAA;AAAA,UAC9D;AAAA,UACA,qBAAC,UAAK,WAAU,qDACb;AAAA;AAAA,YACA,SAAS,CAAC,WAAW,YAAO;AAAA,aAC/B;AAAA,UACA,qBAAC,SAAI,WAAU,4CACZ;AAAA,yBAAa,CAAC,gBACb;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,UAAU;AAAA,gBAEhB,oBAAU;AAAA;AAAA,YACb;AAAA,YAED,CAAC,aAAa,aAAa,CAAC,SAC3B,oBAAC,UAAK,WAAU,kCAAiC,mBAAK;AAAA,YAEvD,WACC,oBAAC,UAAK,WAAU,wDAAuD,uBAAS,IAC9E,CAAC,eACH;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,MAAM,KAAK,KAAK;AAAA,gBACzB,UAAU,UAAU,CAAC;AAAA,gBACrB,WAAW;AAAA,kBACT;AAAA,kBACA,UAAU,CAAC,QACP,gDACA;AAAA,gBACN;AAAA,gBACA,OAAM;AAAA,gBAEL;AAAA,2BACC,oBAAC,eAAY,WAAU,uBAAsB,IAE7C,oBAAC,YAAS,WAAU,UAAS;AAAA,kBAC7B;AAAA;AAAA;AAAA,YAEJ,IACE;AAAA,aACN;AAAA,WACF;AAAA,QAEC,eACC;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YAEL;AAAA,mCAAC,SAAI,WAAU,oDACb;AAAA,oCAAC,UAAK,WAAU,qCAAoC,sCAAwB;AAAA,gBAAQ;AAAA,gBAAI;AAAA,iBAE1F;AAAA,cACA,qBAAC,SAAI,WAAU,8CACZ;AAAA,2BACC;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS,MAAM;AACb,6BAAO;AAAA,oBACT;AAAA,oBACA,WAAU;AAAA,oBACX;AAAA;AAAA,gBAED,IACE;AAAA,gBACH,cACC;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS,MAAM,KAAK,UAAU;AAAA,oBAC9B,UAAU;AAAA,oBACV,WAAU;AAAA,oBACX;AAAA;AAAA,gBAED,IACE;AAAA,iBACN;AAAA;AAAA;AAAA,QACF,IACE;AAAA,QAGJ,oBAAC,SAAI,WAAU,gCACZ,mBACE,YACC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV,QAAQ,MAAM,KAAK,KAAK;AAAA;AAAA,QAC1B,IAEA,SACF;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAO,cAAc,UAAU,UAAU;AAAA,YACzC,UAAU,CAAC;AAAA,YACX;AAAA,YACA,YAAY;AAAA,YACZ,YAAY;AAAA,YACZ,QAAO;AAAA,YACP,WAAU;AAAA,YACV,UAAU,WAAW,SAAY;AAAA;AAAA,QACnC,IAEC,WAAW,oBAAC,kBAAe,GAEhC;AAAA;AAAA;AAAA,EACF;AAEJ;AAGA,IAAM,aAAa;AAAA,EACjB,cAAc;AAAA,EACd,YAAY;AACd;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,MACxC,WAAW,CAAC,UAAU;AACpB,aAAK,MAAM,WAAW,MAAM,YAAY,MAAM,IAAI,YAAY,MAAM,KAAK;AACvE,gBAAM,eAAe;AACrB,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,cAAW;AAAA,MACX,WAAU;AAAA;AAAA,EACZ;AAEJ;AAEA,SAAS,iBAAiB;AACxB,SAAO,oBAAC,SAAI,WAAU,oCAAmC,kCAAe;AAC1E;;;AC9gBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EAIE,eAAAE;AAAA,EACA,aAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,aAA+B;;;ACxBxC,SAAS,aAAAC,YAAW,WAAAC,gBAAe;AAOnC,IAAM,iBAAiB;AACvB,IAAM,eAAe;AAmBd,SAAS,wBAAwB,QAAiC;AACvE,QAAM,UAAUC,SAAQ,MAAM,sBAAsB,MAAM,GAAG,CAAC,MAAM,CAAC;AACrE,EAAAC,WAAU,MAAM;AACd,QAAI,QAAQ,UAAU;AACpB,WAAK,OAAO,6CAAiC,EAC1C,KAAK,CAAC,EAAE,eAAe,MAAM,eAAe,QAAQ,QAAQ,CAAC,EAC7D,MAAM,MAAM,MAAS;AAAA,IAC1B;AACA,QAAI,QAAQ,QAAQ;AAClB,WAAK,OAAO,uCAA2B,EACpC,KAAK,CAAC,EAAE,mBAAmB,MAAM,mBAAmB,CAAC,EACrD,MAAM,MAAM,MAAS;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,QAAQ,QAAQ,CAAC;AACvC;AAEA,SAAS,sBAAsB,QAG7B;AACA,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,SAAS,oBAAI,IAAY;AAC/B,aAAW,SAAS,QAAQ;AAC1B,eAAW,aAAa,OAAO;AAC7B,UAAI,eAAe,KAAK,SAAS,EAAG,UAAS,IAAI,SAAS;AAC1D,UAAI,aAAa,KAAK,SAAS,EAAG,QAAO,IAAI,SAAS;AAAA,IACxD;AAAA,EACF;AACA,SAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;AAC1E;;;AD8pBa,SAsND,UAtNC,OAAAC,MA0DH,QAAAC,aA1DG;AA5oBb,IAAM,cAAmE;AAAA,EACvE,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AACb;AACA,IAAM,yBAAyB,OAAO,WAAW,cAAcC,aAAY;AAG3E,SAASC,UAAS,MAAsB;AACtC,QAAM,IAAI,KAAK,YAAY,GAAG;AAC9B,SAAO,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG,CAAC;AACtC;AAGA,SAAS,SAAS,QAAgB,MAAsB;AACtD,SAAO,SAAS,GAAG,MAAM,IAAI,IAAI,KAAK;AACxC;AAGA,SAAS,QAAQ,MAA0B;AACzC,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,KAAK,KAAK;AAAA,IACnB,KAAK;AACH,aAAO,UAAU,KAAK,MAAM;AAAA,IAC9B,KAAK;AACH,aAAO,YAAY,KAAK,IAAI;AAAA,IAC9B,KAAK;AACH,aAAO,WAAW,KAAK,IAAI;AAAA,EAC/B;AACF;AAEA,SAASC,uBAAsB,MAAc,WAA4B;AACvE,MAAI,CAAC,KAAK,WAAW,SAAS,KAAK,SAAS,UAAW,QAAO;AAC9D,MAAI,UAAU,SAAS,GAAG,KAAK,UAAU,SAAS,IAAI,EAAG,QAAO;AAChE,QAAM,WAAW,KAAK,UAAU,MAAM;AACtC,SAAO,aAAa,OAAO,aAAa;AAC1C;AAGA,SAAS,SAAS,OAAuB,MAAwC;AAC/E,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,KAAM,QAAO;AAC/B,QAAI,KAAK,SAAS,SAAS,KAAK,YAAYA,uBAAsB,MAAM,KAAK,IAAI,GAAG;AAClF,YAAM,MAAM,SAAS,KAAK,UAAU,IAAI;AACxC,UAAI,IAAK,QAAO;AAAA,IAClB;AAAA,EACF;AACA,SAAO;AACT;AASA,SAAS,gBAAgB,OAAuB,YAAiC;AAC/E,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,YAAY;AAC5B,aAAO;AAAA,QACL,aAAa,KAAK,SAAS,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC;AAAA,QAClD,UAAU,KAAK,SAAS,SAAS,KAAK,aAAa,SAAY,KAAK,OAAO;AAAA,MAC7E;AAAA,IACF;AACA,QAAI,KAAK,SAAS,SAAS,CAACA,uBAAsB,YAAY,KAAK,IAAI,EAAG;AAC1E,QAAI,KAAK,aAAa,QAAW;AAC/B,aAAO,EAAE,aAAa,CAAC,KAAK,IAAI,GAAG,UAAU,KAAK,KAAK;AAAA,IACzD;AACA,UAAM,QAAQ,gBAAgB,KAAK,UAAU,UAAU;AACvD,WAAO;AAAA,MACL,aAAa,CAAC,KAAK,MAAM,GAAG,MAAM,WAAW;AAAA,MAC7C,UAAU,MAAM;AAAA,IAClB;AAAA,EACF;AACA,SAAO,EAAE,aAAa,CAAC,GAAG,UAAU,KAAK;AAC3C;AA+BO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,CAAC,UAAU,WAAW,IAAIC,UAAsB,oBAAI,IAAI,CAAC;AAC/D,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAsB,oBAAI,IAAI,CAAC;AACvE,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAwB,IAAI;AACxD,QAAM,CAAC,aAAa,cAAc,IAAIA,UAA6B,IAAI;AACvE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAA6B,IAAI;AACvE,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAwB,IAAI;AAC5D,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAkC,IAAI;AAC9D,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAA8B,IAAI;AAC5E,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAS,KAAK;AACtC,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,KAAK;AACxD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAGhC,IAAI;AACd,QAAM,0BAA0BC,QAGtB,IAAI;AACd,QAAM,0BAA0BA,QAAoB,oBAAI,IAAI,CAAC;AAC7D,QAAM,SAAS,MAAM;AACrB,QAAM,YAAY,qBAAqC;AACvD,QAAM,eAAe,UAAU;AAC/B,QAAM,uBAAuBA,QAA2B,IAAI;AAC5D,QAAM,WAAWA,QAAoB,IAAI;AACzC,QAAM,mBAAmB,oBAAoB,UAAU,MAAM;AAC7D,QAAM,iBAAiBC;AAAA,IACrB,MAAO,OAAO,aAAa,cAAc,OAAO,SAAS,eAAe,MAAM;AAAA,IAC9E,CAAC,MAAM;AAAA,EACT;AACA,QAAM,cAAcC;AAAA,IAClB,MAAM,gBAAgB,OAAO,MAAM,aAAa;AAAA,IAChD,CAAC,eAAe,OAAO,IAAI;AAAA,EAC7B;AAEA,yBAAuB,MAAM;AAC3B,QAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,WAAY;AAC9E,UAAM,QAAQ,OAAO,WAAW,mBAAmB;AACnD,UAAM,SAAS,MAAM,iBAAiB,MAAM,OAAO;AACnD,WAAO;AACP,QAAI,OAAO,MAAM,qBAAqB,YAAY;AAChD,YAAM,iBAAiB,UAAU,MAAM;AACvC,aAAO,MAAM,MAAM,oBAAoB,UAAU,MAAM;AAAA,IACzD;AACA,QAAI,OAAO,MAAM,gBAAgB,YAAY;AAC3C,YAAM,YAAY,MAAM;AACxB,aAAO,MAAM,MAAM,eAAe,MAAM;AAAA,IAC1C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,2BAA2B,aAAc,uBAAuB,aAAc;AACpF,EAAAN,WAAU,MAAM;AACd,QAAI,CAAC,cAAc,6BAA6B,MAAM;AACpD,uBAAiB,IAAI;AACrB;AAAA,IACF;AACA,UAAM,UAAU,wBAAwB;AACxC,QAAI,SAAS,SAAS,cAAc,QAAQ,cAAc,yBAA0B;AACpF,4BAAwB,UAAU;AAAA,MAChC,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AACA,4BAAwB,UAAU,oBAAI,IAAI;AAC1C,cAAU,IAAI;AACd,qBAAiB,EAAE,MAAM,YAAY,WAAW,yBAAyB,CAAC;AAAA,EAC5E,GAAG,CAAC,0BAA0B,UAAU,CAAC;AAIzC,QAAM,gBAAgB,UAAU,SAAS,aAAa,MAAM,IAAI,SAAS;AACzE,QAAM,SACJ,kBAAkB,gBAAgB,SAAS,aAAa,YAAY,IAAI,eAAe;AACzF,EAAAA,WAAU,MAAM;AACd,QAAI,WAAW,QAAQ,kBAAkB,KAAM,WAAU,IAAI;AAAA,EAC/D,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,QAAM,SAASK;AAAA,IACb,OAAO,SAAiB;AACtB,YAAM,OAAO,SAAS,aAAa,IAAI;AACvC,UAAI,QAAQ,KAAK,SAAS,SAAS,KAAK,aAAa,QAAW;AAC9D,wBAAgB,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC;AACjD,YAAI;AACF,gBAAM,OAAO,OAAO,IAAI;AAAA,QAC1B,UAAE;AACA,0BAAgB,CAAC,SAAS;AACxB,kBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,iBAAK,OAAO,IAAI;AAChB,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EACtB;AAEA,QAAM,OAAOA;AAAA,IACX,CAAC,SAAiB;AAChB,kBAAY,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC;AAC7C,WAAK,OAAO,IAAI;AAAA,IAClB;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,EAAAL,WAAU,MAAM;AACd,QAAI,CAAC,cAAe;AACpB,UAAM,QAAQ,gBAAgB,aAAa,cAAc,IAAI;AAC7D,QAAI,MAAM,YAAY,SAAS,GAAG;AAChC,kBAAY,CAAC,aAAa;AACxB,cAAM,OAAO,IAAI,IAAI,QAAQ;AAC7B,YAAI,UAAU;AACd,mBAAW,QAAQ,MAAM,aAAa;AACpC,cAAI,KAAK,IAAI,IAAI,EAAG;AACpB,eAAK,IAAI,IAAI;AACb,oBAAU;AAAA,QACZ;AACA,eAAO,UAAU,OAAO;AAAA,MAC1B,CAAC;AAAA,IACH;AACA,UAAM,WAAW,MAAM;AACvB,QACE,CAAC,YACD,wBAAwB,QAAQ,IAAI,QAAQ,KAC5C,aAAa,IAAI,QAAQ,KACzB,OAAO,eAAe,IAAI,QAAQ,GAClC;AACA;AAAA,IACF;AACA,4BAAwB,QAAQ,IAAI,QAAQ;AAC5C,SAAK,OAAO,QAAQ;AAAA,EACtB,GAAG,CAAC,QAAQ,cAAc,OAAO,gBAAgB,eAAe,WAAW,CAAC;AAE5E,QAAM,SAASK;AAAA,IACb,OAAO,SAAuB;AAC5B,UAAI,KAAK,SAAS,MAAO;AACzB,YAAM,SAAS,SAAS,IAAI,KAAK,IAAI;AACrC,kBAAY,CAAC,SAAS;AACpB,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,YAAI,OAAQ,MAAK,OAAO,KAAK,IAAI;AAAA,YAC5B,MAAK,IAAI,KAAK,IAAI;AACvB,eAAO;AAAA,MACT,CAAC;AACD,UAAI,CAAC,OAAQ,OAAM,OAAO,KAAK,IAAI;AAAA,IACrC;AAAA,IACA,CAAC,UAAU,MAAM;AAAA,EACnB;AAMA,QAAM,OAAO,OAAO,WAAW;AAC/B,QAAM,cAAcC,SAAQ,MAAM;AAChC,UAAM,QAAsB,CAAC;AAC7B,QAAI,eAAe,YAAY,WAAW,IAAI;AAC5C,YAAM,KAAK,EAAE,MAAM,UAAU,QAAQ,IAAI,MAAM,YAAY,MAAM,OAAO,EAAE,CAAC;AAAA,IAC7E;AACA,UAAM,OAAO,CAAC,OAAuB,UAAkB;AACrD,iBAAW,QAAQ,OAAO;AACxB,cAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,MAAM,CAAC;AACxC,YAAI,KAAK,SAAS,SAAS,CAAC,SAAS,IAAI,KAAK,IAAI,EAAG;AACrD,YAAI,eAAe,YAAY,WAAW,KAAK,MAAM;AACnD,gBAAM,KAAK;AAAA,YACT,MAAM;AAAA,YACN,QAAQ,KAAK;AAAA,YACb,MAAM,YAAY;AAAA,YAClB,OAAO,QAAQ;AAAA,UACjB,CAAC;AAAA,QACH;AACA,cAAM,YAAY,KAAK,aAAa,UAAa,KAAK,SAAS,WAAW;AAC1E,cAAM,YAAY,aAAa,IAAI,KAAK,IAAI,KAAK,OAAO,eAAe,IAAI,KAAK,IAAI;AAGpF,YAAI,KAAK,aAAa,aAAa,QAAQ,CAAC,WAAW;AACrD,gBAAM,KAAK,EAAE,MAAM,WAAW,MAAM,KAAK,MAAM,OAAO,QAAQ,EAAE,CAAC;AAAA,QACnE,WAAW,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AACpD,eAAK,KAAK,UAAU,QAAQ,CAAC;AAAA,QAC/B,WAAW,aAAa,WAAW;AACjC,gBAAM,KAAK,EAAE,MAAM,YAAY,MAAM,KAAK,MAAM,OAAO,QAAQ,EAAE,CAAC;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AACA,SAAK,aAAa,CAAC;AACnB,WAAO;AAAA,EACT,GAAG,CAAC,aAAa,UAAU,aAAa,cAAc,OAAO,gBAAgB,IAAI,CAAC;AAClF,QAAM,mBAAmBA;AAAA,IACvB,MAAM,YAAY,QAAQ,CAAC,SAAU,KAAK,SAAS,SAAS,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAE;AAAA,IAClF,CAAC,WAAW;AAAA,EACd;AACA,0BAAwB,gBAAgB;AAGxC,QAAM,WAAWA;AAAA,IACf,MACE,YAAY;AAAA,MAAQ,CAAC,SACnB,KAAK,SAAS,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC;AAAA,IACrE;AAAA,IACF,CAAC,WAAW;AAAA,EACd;AACA,QAAM,iBAAiBA;AAAA,IACrB,MAAM,IAAI,IAAI,SAAS,IAAI,CAAC,KAAK,UAAU,CAAC,IAAI,KAAK,MAAM,KAAK,CAAU,CAAC;AAAA,IAC3E,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,qBAAqBA,SAAQ,MAAM;AACvC,UAAM,YAAY,oBAAI,IAAmD;AACzE,UAAM,QAAQ,CAAC,UAA0B;AACvC,YAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,kBAAU,IAAI,KAAK,MAAM,EAAE,UAAU,QAAQ,GAAG,SAAS,MAAM,OAAO,CAAC;AACvE,YAAI,KAAK,SAAU,OAAM,KAAK,QAAQ;AAAA,MACxC,CAAC;AAAA,IACH;AACA,UAAM,WAAW;AACjB,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,CAAC;AAChB,QAAM,cAAc,SAAU,eAAe,IAAI,MAAM,KAAK,KAAM;AAClE,QAAM,qBAAqB,eAAe,IAAI,GAAG,MAAM,SAAS,WAAW,KAAK;AAKhF,QAAM,mBACJ,YAAY,OAAO,WAAW,UAAU,OAAO,UAAU,QAAQ,CAAC,OAAO;AAE3E,QAAM,gBAAgBD;AAAA,IACpB,OAAO,SAAuB;AAC5B,UAAI,CAAC,iBAAkB;AACvB,YAAM,YAAY,KAAK,SAAS;AAChC,cAAQ,IAAI;AACZ,UAAI;AACF,cAAM,OAAO,YAAY,KAAK,MAAM,SAAS;AAAA,MAC/C,QAAQ;AAAA,MAER,UAAE;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,MAAM;AAAA,EAC3B;AAEA,QAAM,YAAYA;AAAA,IAChB,OAAO,MAAoB,gBAA8B;AACvD,UAAI,CAAC,iBAAkB;AACvB,cAAQ,IAAI;AACZ,UAAI,CAAC,eAAe;AAClB,6BAAqB,UACnB,gBACC,OAAO,aAAa,eAAe,SAAS,yBAAyB,cAClE,SAAS,gBACT;AACN,yBAAiB,IAAI;AACrB;AAAA,MACF;AACA,UAAI,MAAM,cAAc,IAAI,EAAG,OAAM,cAAc,IAAI;AAAA,IACzD;AAAA,IACA,CAAC,kBAAkB,eAAe,aAAa;AAAA,EACjD;AAEA,QAAM,qBAAqBA;AAAA,IACzB,CAAC,mBAA4B;AAC3B,YAAM,eAAe,iBAAiB,qBAAqB,UAAU,eAAe;AACpF,2BAAqB,UAAU;AAC/B,uBAAiB,IAAI;AACrB,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO,sBAAsB,MAAM;AACjC,gBAAM,SAAS,cAAc,cAAc,eAAe,eAAe;AACzE,kBAAQ,MAAM;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,QAAM,eAAeA;AAAA,IACnB,OAAO,SAAiB;AACtB,YAAM,QAAQ;AACd,qBAAe,IAAI;AACnB,UAAI,CAAC,SAAS,CAAC,iBAAkB;AACjC,YAAM,UAAU,KAAK,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAC9C,UAAI,CAAC,QAAS;AACd,YAAM,OAAO,SAAS,MAAM,QAAQ,OAAO;AAC3C,cAAQ,IAAI;AACZ,UAAI;AACF,YAAI,MAAM,SAAS,OAAO;AACxB,gBAAM,OAAO,UAAU,IAAI;AAC3B,eAAK,IAAI;AAAA,QACX,OAAO;AACL,gBAAM,OAAO,WAAW,IAAI;AAE5B,oBAAU,IAAI;AACd,yBAAe,IAAI;AAAA,QACrB;AAAA,MACF,QAAQ;AAAA,MAER,UAAE;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,aAAa,kBAAkB,QAAQ,MAAM,YAAY;AAAA,EAC5D;AAEA,QAAM,eAAeA;AAAA,IACnB,OAAO,SAAiB;AACtB,YAAM,QAAQ;AACd,qBAAe,IAAI;AACnB,UAAI,CAAC,SAAS,CAAC,iBAAkB;AACjC,YAAM,OAAO,SAAS,aAAa,MAAM,IAAI;AAC7C,YAAM,UAAU,KAAK,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAC9C,UAAI,CAAC,QAAQ,CAAC,WAAW,YAAY,KAAK,KAAM;AAChD,YAAM,UAAU,SAASJ,UAAS,MAAM,IAAI,GAAG,OAAO;AACtD,cAAQ,IAAI;AACZ,UAAI;AACF,cAAM,OAAO,UAAU,MAAM,MAAM,OAAO;AAC1C,YAAI,KAAK,SAAS,WAAW,iBAAiB,MAAM,QAAQ,WAAW,MAAM,OAAO;AAClF,oBAAU,OAAO;AACjB,yBAAe,OAAO;AAAA,QACxB;AAAA,MACF,QAAQ;AAAA,MAER,UAAE;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,aAAa,kBAAkB,QAAQ,cAAc,QAAQ,cAAc,WAAW;AAAA,EACzF;AAGA,QAAM,cAAcI;AAAA,IAClB,CAAC,SAAyB;AACxB,UAAI,CAAC,iBAAkB;AACvB,YAAM,SAAS,SAAS,SAAS,aAAa,MAAM,IAAI;AACxD,YAAM,SAAS,SAAU,OAAO,SAAS,QAAQ,OAAO,OAAOJ,UAAS,OAAO,IAAI,IAAK;AACxF,UAAI,OAAQ,MAAK,MAAM;AACvB,qBAAe,IAAI;AACnB,cAAQ,IAAI;AACZ,qBAAe,EAAE,QAAQ,KAAK,CAAC;AAAA,IACjC;AAAA,IACA,CAAC,kBAAkB,QAAQ,MAAM,WAAW;AAAA,EAC9C;AAEA,QAAM,cAAcI;AAAA,IAClB,CAAC,SAAuB;AACtB,UAAI,CAAC,iBAAkB;AACvB,qBAAe,IAAI;AACnB,cAAQ,IAAI;AACZ,qBAAe,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,gBAAgB;AAAA,EACnB;AAGA,QAAM,aAAaA;AAAA,IACjB,OAAO,WAAmB,eAAuB;AAC/C,kBAAY,IAAI;AAChB,UAAI,CAAC,oBAAoB,CAAC,WAAY;AACtC,YAAM,MAAM,SAAS,aAAa,UAAU;AAC5C,UAAI,CAAC,IAAK;AAEV,UAAIJ,UAAS,UAAU,MAAM,UAAW;AACxC,UAAI,cAAc,cAAc,UAAU,WAAW,GAAG,UAAU,GAAG,EAAG;AACxE,YAAM,UAAU,SAAS,WAAW,IAAI,IAAI;AAC5C,UAAI,YAAY,WAAY;AAC5B,cAAQ,IAAI;AACZ,UAAI;AACF,cAAM,OAAO,UAAU,YAAY,OAAO;AAC1C,YAAI,IAAI,SAAS,WAAW,iBAAiB,cAAc,WAAW,aAAa;AACjF,oBAAU,OAAO;AACjB,yBAAe,OAAO;AAAA,QACxB;AAAA,MACF,QAAQ;AAAA,MAER,UAAE;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,kBAAkB,QAAQ,cAAc,QAAQ,cAAc,WAAW;AAAA,EAC5E;AAEA,QAAM,YAAYI;AAAA,IAChB,CAAC,MAA0C;AACzC,UAAI,eAAe,YAAa;AAChC,UAAI,SAAS,WAAW,EAAG;AAC3B,YAAM,MAAM,SAAS,UAAU,CAAC,MAAM,EAAE,KAAK,SAAS,MAAM;AAC5D,YAAM,OAAO,CAAC,SAAiB;AAC7B,cAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,SAAS,GAAG,IAAI,CAAC;AAC/D,cAAM,MAAM,SAAS,OAAO;AAC5B,YAAI,IAAK,WAAU,IAAI,KAAK,IAAI;AAChC,UAAE,eAAe;AAAA,MACnB;AACA,YAAM,MAAM,OAAO,IAAI,SAAS,GAAG,IAAI;AACvC,cAAQ,EAAE,KAAK;AAAA,QACb,KAAK;AACH,eAAK,MAAM,IAAI,IAAI,MAAM,CAAC;AAC1B;AAAA,QACF,KAAK;AACH,eAAK,MAAM,IAAI,IAAI,MAAM,CAAC;AAC1B;AAAA,QACF,KAAK;AACH,eAAK,CAAC;AACN;AAAA,QACF,KAAK;AACH,eAAK,SAAS,SAAS,CAAC;AACxB;AAAA,QACF,KAAK,YAAY;AACf,gBAAM,WAAW,KAAK;AAAA,YACpB;AAAA,YACA,KAAK,OAAO,aAAa,SAAS,gBAAgB,QAAQ,gBAAgB,KAAK,GAAG,IAAI;AAAA,UACxF;AACA,gBAAM,MAAM,IAAI,IAAI,OAAO,QAAQ;AACnC;AAAA,QACF;AAAA,QACA,KAAK,UAAU;AACb,gBAAM,WAAW,KAAK;AAAA,YACpB;AAAA,YACA,KAAK,OAAO,aAAa,SAAS,gBAAgB,QAAQ,gBAAgB,KAAK,GAAG,IAAI;AAAA,UACxF;AACA,gBAAM,MAAM,IAAI,IAAI,OAAO,QAAQ;AACnC;AAAA,QACF;AAAA,QACA,KAAK;AACH,cAAI,KAAK,KAAK,SAAS,OAAO;AAC5B,gBAAI,CAAC,SAAS,IAAI,IAAI,KAAK,IAAI,EAAG,MAAK,IAAI,KAAK,IAAI;AAAA,gBAC/C,MAAK,MAAM,CAAC;AACjB,cAAE,eAAe;AAAA,UACnB;AACA;AAAA,QACF,KAAK;AACH,cAAI,KAAK;AACP,gBAAI,IAAI,KAAK,SAAS,SAAS,SAAS,IAAI,IAAI,KAAK,IAAI,GAAG;AAC1D,0BAAY,CAAC,SAAS;AACpB,sBAAM,IAAI,IAAI,IAAI,IAAI;AACtB,kBAAE,OAAO,IAAI,KAAK,IAAI;AACtB,uBAAO;AAAA,cACT,CAAC;AAAA,YACH,OAAO;AACL,oBAAM,SAASJ,UAAS,IAAI,KAAK,IAAI;AACrC,kBAAI,OAAQ,WAAU,MAAM;AAAA,YAC9B;AACA,cAAE,eAAe;AAAA,UACnB;AACA;AAAA,QACF,KAAK;AACH,cAAI,KAAK;AACP,gBAAI,IAAI,KAAK,SAAS,MAAO,MAAK,OAAO,IAAI,IAAI;AAAA,gBAC5C,gBAAe,IAAI,KAAK,IAAI;AACjC,cAAE,eAAe;AAAA,UACnB;AACA;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,OAAO,qBAAqB,EAAE,QAAQ,iBAAiB,EAAE,WAAW;AACtE,kBAAM,WAAW,eAAe,IAAI,IAAI,KAAK,IAAI,KAAK;AACtD,kBAAM,MAAM,SAAS,eAAe,GAAG,MAAM,SAAS,QAAQ,EAAE;AAChE,kBAAM,OAAO,KAAK,sBAAsB;AACxC,oBAAQ;AAAA,cACN,MAAM,IAAI;AAAA,cACV,GAAG,OAAO,KAAK,OAAO,KAAK,IAAI,IAAI,KAAK,QAAQ,CAAC,IAAI;AAAA,cACrD,GAAG,OAAO,KAAK,SAAS;AAAA,YAC1B,CAAC;AACD,cAAE,eAAe;AAAA,UACnB,WAAW,EAAE,QAAQ,OAAO;AAC1B;AAAA,UACF;AACA;AAAA,QACF,KAAK;AACH,cAAI,KAAK;AACP,wBAAY,IAAI,IAAI;AACpB,cAAE,eAAe;AAAA,UACnB;AACA;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,cAAI,OAAO,kBAAkB;AAC3B,iBAAK,UAAU,IAAI,IAAI;AACvB,cAAE,eAAe;AAAA,UACnB;AACA;AAAA,MACJ;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,EAAAD,WAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,QAAQ,MAAM,QAAQ,IAAI;AAChC,WAAO,iBAAiB,SAAS,KAAK;AACtC,WAAO,iBAAiB,UAAU,OAAO,IAAI;AAC7C,WAAO,iBAAiB,UAAU,KAAK;AACvC,WAAO,MAAM;AACX,aAAO,oBAAoB,SAAS,KAAK;AACzC,aAAO,oBAAoB,UAAU,OAAO,IAAI;AAChD,aAAO,oBAAoB,UAAU,KAAK;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,iBAAiB,OAAO,SAAS,YAAY,WAAW,KAAK,CAAC;AACpE,QAAM,mBAAmB,OAAO,SAAS,YAAY,SAAS;AAC9D,QAAM,YAAY,CAAC,OAAO,WAAW,YAAY,WAAW,KAAK,CAAC;AAGlE,QAAM,cAAc,oBAAoB,OAAO;AAO/C,QAAM,kBAAkB,CAAC,kBAAkB,CAAC,aAAa,YAAY,SAAS;AAI9E,QAAM,gBAAgB,CAAC,MAAoB,UAA6B;AACtE,UAAM,SAAS,SAAS,IAAI,KAAK,IAAI;AACrC,QAAI,YAAY;AACd,aAAO,gBAAAF,KAAC,SAAK,qBAAW,MAAM,OAAO,MAAM,GAAE;AAAA,IAC/C;AACA,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,aAAa,KAAK,SAAS,gBAAgB,KAAK,SAAS;AAC/D,UAAM,WAAW,KAAK,SAAS;AAC/B,UAAM,YAAY,aAAa,IAAI,KAAK,IAAI,KAAK,OAAO,eAAe,IAAI,KAAK,IAAI;AACpF,UAAM,aAAa,aAAa,SAAS,KAAK;AAC9C,UAAM,eAAe,cAAc,QAAQ,KAAK,OAAOG,UAAS,KAAK,IAAI;AACzE,UAAM,UAAU,QAAQ,KAAK,OAAOA,UAAS,KAAK,IAAI;AACtD,UAAM,eAAe,mBAAmB,IAAI,KAAK,IAAI;AAErD,WACE,gBAAAH;AAAA,MAAC;AAAA;AAAA,QACC,IAAI,GAAG,MAAM,SAAS,eAAe,IAAI,KAAK,IAAI,KAAK,CAAC;AAAA,QACxD,MAAK;AAAA,QACL,cAAY,QAAQ;AAAA,QACpB,iBAAe,cAAc;AAAA,QAC7B,gBAAc,cAAc;AAAA,QAC5B,iBAAe,QAAQ,SAAS;AAAA,QAChC,iBAAe,YAAY;AAAA,QAC3B,aAAW,aAAa;AAAA,QACxB,YACE,mBACI,CAAC,MAAM;AACL,YAAE,eAAe;AACjB,YAAE,aAAa,aAAa;AAC5B,sBAAY,OAAO;AAAA,QACrB,IACA;AAAA,QAEN,aACE,mBACI,CAAC,MAAM;AACL,YAAE,gBAAgB;AAClB,sBAAY,CAAC,QAAS,QAAQ,UAAU,OAAO,GAAI;AAAA,QACrD,IACA;AAAA,QAEN,QACE,mBACI,CAAC,MAAM;AACL,YAAE,eAAe;AACjB,YAAE,gBAAgB;AAClB,gBAAM,MAAM,EAAE,aAAa,QAAQ,cAAc;AACjD,eAAK,WAAW,SAAS,GAAG;AAAA,QAC9B,IACA;AAAA,QAGL,uBACC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,MAAM,KAAK;AAAA,YACX,cAAc,KAAK;AAAA,YACnB,UAAU,CAAC,SAAS,KAAK,aAAa,IAAI;AAAA,YAC1C,UAAU,MAAM,eAAe,IAAI;AAAA;AAAA,QACrC,IAEA,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU;AAAA,YACV,WAAW,oBAAoB;AAAA,YAC/B,aACE,mBACI,CAAC,MAAM;AACL,gBAAE,aAAa,QAAQ,gBAAgB,KAAK,IAAI;AAChD,gBAAE,aAAa,gBAAgB;AAAA,YACjC,IACA;AAAA,YAEN,SAAS,MAAM;AACb,wBAAU,KAAK,IAAI;AACnB,kBAAI,MAAO,MAAK,OAAO,IAAI;AAAA,kBACtB,gBAAe,KAAK,IAAI;AAAA,YAC/B;AAAA,YACA,eAAe,MAAM,oBAAoB,YAAY,IAAI;AAAA,YACzD,eAAe,CAAC,MAAM;AACpB,kBAAI,CAAC,iBAAkB;AACvB,gBAAE,eAAe;AACjB,wBAAU,KAAK,IAAI;AACnB,sBAAQ,EAAE,MAAM,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,CAAC;AAAA,YAC9C;AAAA,YACA,WAAW;AAAA,cACT;AAAA,cACA;AAAA,cACA,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,gBAAgB;AAAA;AAAA,cAEhB,aACE;AAAA,cACF,KAAK,SAAS,YAAY,KAAK,MAAM,IAAI;AAAA,YAC3C;AAAA,YACA,OAAO,EAAE,aAAa,GAAG,QAAQ,KAAK,CAAC,KAAK;AAAA,YAE3C;AAAA,sBACC,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW;AAAA,oBACT;AAAA,oBACA,UAAU;AAAA,oBACV,aAAa;AAAA,kBACf;AAAA;AAAA,cACF,IAEA,gBAAAA,KAAC,UAAK,WAAU,6BAA4B;AAAA,cAE7C,QACC,gBAAAA,KAAC,cAAW,WAAU,qBAAoB,IAE1C,gBAAAA,KAAC,YAAS,WAAU,qBAAoB;AAAA,cAE1C,gBAAAA,KAAC,UAAK,WAAU,YAAY,eAAK,MAAK;AAAA,cACrC,oBACC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,UAAU;AAAA,kBACV,cAAW;AAAA,kBACX,SAAS,CAAC,MAAM;AACd,sBAAE,eAAe;AACjB,sBAAE,gBAAgB;AAClB,8BAAU,KAAK,IAAI;AACnB,0BAAM,OAAQ,EAAE,cAA8B,sBAAsB;AACpE,4BAAQ,EAAE,MAAM,GAAG,KAAK,OAAO,GAAG,KAAK,OAAO,CAAC;AAAA,kBACjD;AAAA,kBACA,WAAU;AAAA,kBACX;AAAA;AAAA,cAED;AAAA;AAAA;AAAA,QAEJ;AAAA;AAAA,IAEJ;AAAA,EAEJ;AAGA,QAAM,aAAa,CAAC,SAAgC;AAClD,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,eAAO,cAAc,KAAK,MAAM,KAAK,KAAK;AAAA,MAC5C,KAAK;AACH,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,KAAK;AAAA,YACZ,MAAM,KAAK;AAAA,YACX,cAAa;AAAA,YACb,UAAU,CAAC,SAAS,KAAK,aAAa,IAAI;AAAA,YAC1C,UAAU,MAAM,eAAe,IAAI;AAAA;AAAA,QACrC;AAAA,MAEJ,KAAK;AACH,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,eAAW;AAAA,YACX,OAAO,EAAE,aAAa,GAAG,KAAK,QAAQ,KAAK,CAAC,KAAK;AAAA,YACjD,WAAU;AAAA,YAET,WAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACd,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO,EAAE,OAAO,GAAG,KAAK,IAAI,EAAE,IAAI;AAAA;AAAA,cAF7B;AAAA,YAGP,CACD;AAAA;AAAA,QACH;AAAA,MAEJ,KAAK;AACH,eACE,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,EAAE,aAAa,GAAG,KAAK,QAAQ,KAAK,CAAC,KAAK;AAAA,YACjD,WAAU;AAAA,YAEV;AAAA,8BAAAD,KAAC,UAAK,WAAU,6BAA4B;AAAA,cAC5C,gBAAAA,KAAC,UAAK,WAAU,oBAAmB,uDAAoC;AAAA;AAAA;AAAA,QACzE;AAAA,IAEN;AAAA,EACF;AAGA,EAAAE,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AACb,UAAM,QAAQ,YAAY,UAAU,CAAC,OAAO,GAAG,SAAS,UAAU,GAAG,KAAK,SAAS,MAAM;AACzF,QAAI,SAAS,EAAG,UAAS,SAAS,cAAc,KAAK;AAAA,EACvD,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,cAAe;AACpB,UAAM,QAAQ,YAAY;AAAA,MACxB,CAAC,SAAS,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,cAAc;AAAA,IACrE;AACA,QAAI,QAAQ,EAAG;AACf,QAAI,iBAAiB;AACnB,eAAS,SAAS,cAAc,KAAK;AAAA,IACvC,OAAO;AACL,eAAS,eAAe,GAAG,MAAM,SAAS,KAAK,EAAE,GAAG,iBAAiB,EAAE,OAAO,UAAU,CAAC;AAAA,IAC3F;AACA;AAAA,MAAiB,CAAC,YAChB,SAAS,SAAS,cAAc,QAAQ,QAAQ,cAAc,cAAc,YACxE,OACA;AAAA,IACN;AAAA,EACF,GAAG,CAAC,aAAa,eAAe,QAAQ,eAAe,CAAC;AAExD,SACE,gBAAAD,MAAC,SAAI,WAAW,GAAG,iCAAiC,SAAS,GAC1D;AAAA,mBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,WAAU;AAAA,QAET;AAAA,6BACC,gBAAAA,MAAA,YACE;AAAA,4BAAAD,KAAC,iBAAc,OAAM,YAAW,SAAS,MAAM,YAAY,MAAM,GAAG,UAAU,MAC5E,0BAAAA,KAAC,gBAAa,WAAU,YAAW,GACrC;AAAA,YACA,gBAAAA,KAAC,iBAAc,OAAM,cAAa,SAAS,MAAM,YAAY,KAAK,GAAG,UAAU,MAC7E,0BAAAA,KAAC,kBAAe,WAAU,YAAW,GACvC;AAAA,YACA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAM;AAAA,gBACN,SAAS,MAAM;AACb,wBAAM,OAAO,SAAS,SAAS,aAAa,MAAM,IAAI;AACtD,sBAAI,KAAM,aAAY,IAAI;AAAA,gBAC5B;AAAA,gBACA,UAAU,QAAQ,CAAC;AAAA,gBAEnB,0BAAAA,KAAC,cAAW,WAAU,YAAW;AAAA;AAAA,YACnC;AAAA,YACA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAM;AAAA,gBACN,SAAS,CAAC,UAAU;AAClB,wBAAM,OAAO,SAAS,SAAS,aAAa,MAAM,IAAI;AACtD,sBAAI,KAAM,MAAK,UAAU,MAAM,MAAM,aAAa;AAAA,gBACpD;AAAA,gBACA,UAAU,QAAQ,CAAC;AAAA,gBAEnB,0BAAAA,KAAC,cAAW,WAAU,YAAW;AAAA;AAAA,YACnC;AAAA,aACF,IACE;AAAA,UACJ,gBAAAA,KAAC,UAAK,WAAU,WAAU;AAAA,UAC1B,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,SAAS,MAAM,KAAK,OAAO,QAAQ;AAAA,cACnC,UAAU,QAAQ,OAAO;AAAA,cAEzB,0BAAAA,KAAC,iBAAc,WAAW,GAAG,YAAY,OAAO,WAAW,cAAc,GAAG;AAAA;AAAA,UAC9E;AAAA;AAAA;AAAA,IACF;AAAA,IAGD,mBACC,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,aAAU;AAAA,QACV,gCAA4B;AAAA,QAC5B,WAAU;AAAA,QAEV;AAAA,0BAAAD,KAAC,qBAAkB,WAAU,4CAA2C,eAAW,MAAC;AAAA,UACpF,gBAAAA,KAAC,UAAK,WAAU,kBACb,iBAAO,WAAW,YACf,kFACA,uDACN;AAAA,UACA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,KAAK,OAAO,QAAQ;AAAA,cACnC,UAAU,OAAO;AAAA,cACjB,WAAU;AAAA,cAEV;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,GAAG,UAAU,OAAO,WAAW,yCAAyC;AAAA,oBACnF,eAAW;AAAA;AAAA,gBACb;AAAA,gBAAE;AAAA;AAAA;AAAA,UAEJ;AAAA;AAAA;AAAA,IACF,IACE;AAAA,IAIJ,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,UAAU;AAAA,QACf,SAAS,CAAC,UAAU;AAClB,cAAK,MAAM,OAAuB,OAAO,UAAU,cAAc,GAAG;AAClE,kBAAM,QAAQ,SAAS,CAAC;AACxB,gBAAI,MAAO,WAAU,MAAM,KAAK,IAAI;AAAA,UACtC;AAAA,QACF;AAAA,QACA;AAAA,QACA,YACE,mBACI,CAAC,MAAM;AACL,YAAE,eAAe;AACjB,YAAE,aAAa,aAAa;AAC5B,sBAAY,EAAE;AAAA,QAChB,IACA;AAAA,QAEN,QACE,mBACI,CAAC,MAAM;AACL,YAAE,eAAe;AACjB,gBAAM,MAAM,EAAE,aAAa,QAAQ,cAAc;AACjD,eAAK,WAAW,IAAI,GAAG;AAAA,QACzB,IACA;AAAA,QAEN,WAAW;AAAA,UACT;AAAA,UACA,aAAa,MAAM;AAAA,QACrB;AAAA,QACA,2BAAuB;AAAA,QAEtB,2BACC,gBAAAC,MAAC,SAAI,WAAU,oEACb;AAAA,0BAAAD,KAAC,SACE,sBACC,yBAAyB,OAAO,OAAO,WAAW,oCAAoC,IAC1F;AAAA,UACA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,KAAK,OAAO,QAAQ;AAAA,cACnC,UAAU,OAAO;AAAA,cACjB,WAAU;AAAA,cAEV;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,GAAG,YAAY,OAAO,WAAW,cAAc;AAAA,oBAC1D,eAAW;AAAA;AAAA,gBACb;AAAA,gBAAE;AAAA;AAAA;AAAA,UAEJ;AAAA,WACF,IACE,YACF,gBAAAA,KAAC,SAAI,WAAU,oCACZ,wBAAc,2BACjB,IACE,CAAC,kBACH,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,IAAI;AAAA,YACJ,MAAK;AAAA,YACL,cAAW;AAAA,YACX,yBAAuB;AAAA,YACvB,wBAAsB;AAAA,YACtB,UAAU;AAAA,YACV,WAAU;AAAA,YAET,sBAAY,IAAI,CAAC,SAChB,gBAAAA,KAAC,SAAwB,WAAU,WAChC,qBAAW,IAAI,KADR,QAAQ,IAAI,CAEtB,CACD;AAAA;AAAA,QACH;AAAA;AAAA;AAAA;AAAA,UAKA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,cAAW;AAAA,cACX,yBAAuB;AAAA,cACvB,wBAAsB;AAAA,cACtB,UAAU;AAAA,cACV,WAAU;AAAA,cACV,UAAU,gBAAgB,KAAK;AAAA,cAC/B,UAAU,KAAK,IAAI,IAAI,YAAY,MAAM;AAAA,cAExC,sBAAY,IAAI,CAAC,SAChB,gBAAAA,KAAC,SAAwB,WAAU,WAChC,qBAAW,IAAI,KADR,QAAQ,IAAI,CAEtB,CACD;AAAA;AAAA,UACH;AAAA;AAAA;AAAA,IAEJ;AAAA,IAEC,QAAQ,KAAK,QACZ,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,KAAK;AAAA,QACX,GAAG,KAAK;AAAA,QACR,GAAG,KAAK;AAAA,QACR,UAAU,MAAM,KAAK,QAAQ,YAAY,KAAK,IAAI;AAAA,QAClD,UAAU,MAAM,KAAK,QAAQ,KAAK,UAAU,KAAK,IAAI;AAAA,QACrD,WAAW,MAAM,YAAY,MAAM;AAAA,QACnC,aAAa,MAAM,YAAY,KAAK;AAAA,QACpC,SAAS,MAAM;AACb,kBAAQ,IAAI;AACZ,iBAAO,sBAAsB,MAAM,eAAe,GAAG,MAAM,CAAC;AAAA,QAC9D;AAAA;AAAA,IACF;AAAA,IAED,gBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,UAAU,MAAM,mBAAmB,IAAI;AAAA,QACvC,WAAW,MAAM;AACf,gBAAM,OAAO;AACb,6BAAmB,KAAK;AACxB,eAAK,cAAc,IAAI;AAAA,QACzB;AAAA;AAAA,IACF,IACE;AAAA,KACN;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,YAAYM,QAAiC,IAAI;AACvD,QAAM,CAAC,MAAM,OAAO,IAAID,UAAS,IAAI;AACrC,QAAM,iBAAiBC,QAA6B,QAAQ;AAC5D,QAAM,aAAaA,QAAO,KAAK;AAC/B,QAAM,iBAAiBA,QAA6C,IAAI;AAExE,QAAM,SAAS,MAAM;AACnB,QAAI,WAAW,QAAS;AACxB,eAAW,UAAU;AACrB,QAAI,eAAe,YAAY,WAAW;AACxC,gBAAU;AAAA,IACZ,OAAO;AACL,eAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM;AAC3B,QAAI,eAAe,YAAY,KAAM;AACrC,mBAAe,UAAU,WAAW,MAAM;AACxC,qBAAe,UAAU;AACzB,aAAO;AAAA,IACT,GAAG,CAAC;AAAA,EACN;AAEA,EAAAJ;AAAA,IACE,MAAM,MAAM;AACV,UAAI,eAAe,YAAY,KAAM,cAAa,eAAe,OAAO;AAAA,IAC1E;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SACE,gBAAAF;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC;AAAA,MACA,cAAc,CAAC,aAAa;AAC1B,YAAI,CAAC,YAAY,CAAC,MAAM;AACtB,kBAAQ,KAAK;AACb,yBAAe;AAAA,QACjB;AAAA,MACF;AAAA,MAEA,0BAAAC,MAAC,YAAY,QAAZ,EAAmB,WAAW,OAAO,aAAa,cAAc,OAAO,SAAS,MAC/E;AAAA,wBAAAD,KAAC,YAAY,SAAZ,EAAoB,WAAU,iEAAgE;AAAA,QAC/F,gBAAAC;AAAA,UAAC,YAAY;AAAA,UAAZ;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,YACP,iBAAiB,CAAC,UAAU;AAC1B,oBAAM,eAAe;AACrB,wBAAU,SAAS,MAAM;AAAA,YAC3B;AAAA,YACA,kBAAkB,CAAC,UAAU;AAC3B,oBAAM,eAAe;AACrB,6BAAe;AAAA,YACjB;AAAA,YACA,iBAAiB,CAAC,UAAU;AAC1B,oBAAM,gBAAgB;AACtB,kBAAI,MAAM;AACR,sBAAM,eAAe;AAAA,cACvB,OAAO;AACL,+BAAe,UAAU;AAAA,cAC3B;AAAA,YACF;AAAA,YAEA;AAAA,8BAAAA,MAAC,SAAI,WAAU,0BACb;AAAA,gCAAAD,KAAC,UAAK,WAAU,8GACd,0BAAAA,KAAC,cAAW,WAAU,UAAS,eAAW,MAAC,GAC7C;AAAA,gBACA,gBAAAC,MAAC,SAAI,WAAU,WACb;AAAA,kCAAAA,MAAC,YAAY,OAAZ,EAAkB,WAAU,4BAA2B;AAAA;AAAA,oBAC9C,KAAK,SAAS,QAAQ,WAAW;AAAA,oBAAO;AAAA,qBAClD;AAAA,kBACA,gBAAAA,MAAC,YAAY,aAAZ,EAAwB,WAAU,oDACjC;AAAA,oCAAAD,KAAC,UAAK,WAAU,qCAAqC,eAAK,MAAK;AAAA,oBAC9D,KAAK,SAAS,QACX,2DACA;AAAA,qBACN;AAAA,mBACF;AAAA,iBACF;AAAA,cACA,gBAAAC,MAAC,SAAI,WAAU,+BACb;AAAA,gCAAAD,KAAC,YAAY,QAAZ,EAAmB,SAAO,MACzB,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,KAAK;AAAA,oBACL,MAAK;AAAA,oBACL,SAAS,MAAM;AACb,qCAAe,UAAU;AAAA,oBAC3B;AAAA,oBACA,UAAU;AAAA,oBACV,WAAU;AAAA,oBACX;AAAA;AAAA,gBAED,GACF;AAAA,gBACA,gBAAAA,KAAC,YAAY,QAAZ,EAAmB,SAAO,MACzB,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAS,MAAM;AACb,qCAAe,UAAU;AAAA,oBAC3B;AAAA,oBACA,UAAU;AAAA,oBACV,WAAU;AAAA,oBACX;AAAA;AAAA,gBAED,GACF;AAAA,iBACF;AAAA;AAAA;AAAA,QACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAO;AAAA,MACP,cAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAGA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,CAAC,OAAO,QAAQ,IAAIK,UAAS,YAAY;AAC/C,QAAM,MAAMC,QAAgC,IAAI;AAEhD,QAAM,UAAUA,QAAO,KAAK;AAE5B,EAAAJ,WAAU,MAAM;AACd,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,GAAI;AACT,OAAG,MAAM;AAET,UAAM,MAAM,aAAa,YAAY,GAAG;AACxC,QAAI,gBAAgB,MAAM,EAAG,IAAG,kBAAkB,GAAG,GAAG;AAAA,QACnD,IAAG,OAAO;AAAA,EACjB,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,SAAS,CAAC,WAAoB;AAClC,QAAI,QAAQ,QAAS;AACrB,YAAQ,UAAU;AAClB,QAAI,OAAQ,UAAS,KAAK;AAAA,QACrB,UAAS;AAAA,EAChB;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,aAAa,GAAG,QAAQ,KAAK,CAAC,KAAK;AAAA,MAE5C;AAAA,wBAAAD,KAAC,UAAK,WAAU,6BAA4B;AAAA,QAC3C,SAAS,QACR,gBAAAA,KAAC,cAAW,WAAU,qBAAoB,IAE1C,gBAAAA,KAAC,YAAS,WAAU,qBAAoB;AAAA,QAE1C,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ,cAAa;AAAA,YACb,cAAY,SAAS,QAAQ,gBAAgB;AAAA,YAC7C,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,YACxC,QAAQ,MAAM,OAAO,IAAI;AAAA,YACzB,WAAW,CAAC,MAAM;AAChB,kBAAI,EAAE,QAAQ,SAAS;AACrB,kBAAE,eAAe;AACjB,uBAAO,IAAI;AAAA,cACb,WAAW,EAAE,QAAQ,UAAU;AAC7B,kBAAE,eAAe;AACjB,uBAAO,KAAK;AAAA,cACd;AACA,gBAAE,gBAAgB;AAAA,YACpB;AAAA,YACA,WAAW;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAGA,SAAS,YAAY;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASG;AACD,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,UAAUM,QAA8B,IAAI;AAElD,QAAM,KAAK,OAAO,WAAW,cAAc,OAAO,aAAa;AAC/D,QAAM,KAAK,OAAO,WAAW,cAAc,OAAO,cAAc;AAChE,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,CAAC;AAC9C,QAAM,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,GAAG,CAAC;AAE7C,EAAAJ,WAAU,MAAM;AACd,YAAQ,SAAS,cAAiC,mBAAmB,GAAG,MAAM;AAAA,EAChF,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,CAAC,UAA8C;AAC/D,UAAM,QAAQ,MAAM;AAAA,MAClB,QAAQ,SAAS,iBAAoC,mBAAmB,KAAK,CAAC;AAAA,IAChF;AACA,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,UAAU,MAAM,UAAU,CAACO,UAASA,UAAS,SAAS,aAAa;AACzE,QAAI,OAAsB;AAC1B,QAAI,MAAM,QAAQ,YAAa,SAAQ,UAAU,IAAI,MAAM,UAAU,MAAM;AAAA,aAClE,MAAM,QAAQ,UAAW,SAAQ,UAAU,IAAI,MAAM,UAAU,MAAM;AAAA,aACrE,MAAM,QAAQ,OAAQ,QAAO;AAAA,aAC7B,MAAM,QAAQ,MAAO,QAAO,MAAM,SAAS;AAAA,aAC3C,MAAM,QAAQ,UAAU;AAC/B,YAAM,eAAe;AACrB,YAAM,gBAAgB;AACtB,cAAQ;AACR;AAAA,IACF;AACA,QAAI,SAAS,KAAM;AACnB,UAAM,eAAe;AACrB,UAAM,gBAAgB;AACtB,UAAM,IAAI,GAAG,MAAM;AAAA,EACrB;AAEA,QAAM,OAAO,CAAC,OAAe,MAAiB,SAAqB,WACjE,gBAAAR;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAK;AAAA,MACL,SAAS,CAAC,MAAM;AACd,UAAE,gBAAgB;AAClB,gBAAQ;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,MAEC;AAAA;AAAA,QACA;AAAA;AAAA;AAAA,EACH;AAGF,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,MAAK;AAAA,MACL,cAAY,eAAe,KAAK,IAAI;AAAA,MACpC;AAAA,MACA,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,MAClC,OAAO,EAAE,MAAM,IAAI;AAAA,MACnB,WAAW,GAAG,oBAAoB,0CAA0C;AAAA,MAE3E;AAAA,iBACC,gBAAAA,MAAA,YACG;AAAA,eAAK,YAAY,gBAAAD,KAAC,gBAAa,GAAI,SAAS;AAAA,UAC5C,KAAK,cAAc,gBAAAA,KAAC,kBAAe,GAAI,WAAW;AAAA,UACnD,gBAAAA,KAAC,SAAI,MAAK,aAAY,WAAW,sBAAsB;AAAA,WACzD;AAAA,QAED,KAAK,UAAU,gBAAAA,KAAC,cAAW,GAAI,QAAQ;AAAA,QACvC,KAAK,UAAU,gBAAAA,KAAC,cAAW,GAAI,UAAU,IAAI;AAAA;AAAA;AAAA,EAChD;AAEJ;;;AEt7CA;AAAA,EAIE;AAAA,EACA;AAAA,EACA,aAAAU;AAAA,EACA,YAAAC;AAAA,EACA;AAAA,OACK;AA6FuC,gBAAAC,YAAA;AAnD9C,IAAM,WAAW,KAAK,YAAY;AAChC,QAAM,MAAO,MAAM,gBAAgB;AACnC,SAAO,EAAE,SAAS,IAAI,KAAK;AAC7B,CAAC;AAQM,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,KAAK;AAIxC,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,EAAAC,WAAU,MAAM;AACd,QAAI,YAAY;AAChB,cAAU,KAAK;AACf,oBAAgB,EAAE;AAAA,MAChB,MAAM;AACJ,YAAI,CAAC,UAAW,UAAS,IAAI;AAAA,MAC/B;AAAA,MACA,MAAM;AACJ,YAAI,CAAC,UAAW,WAAU,IAAI;AAAA,MAChC;AAAA,IACF;AACA,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,OAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK;AAEtD,MAAI,QAAQ;AACV,WACE,gBAAAF,KAAC,SAAI,WAAuB,sBAAY,gBAAAA,KAAC,aAAU,MAAY,UAAoB,GAAG;AAAA,EAE1F;AAEA,QAAM,UAAU;AAAA,IACd,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,GAAI,QACA,EAAE,MAAM,IACR;AAAA,MACE,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACJ,WAAW,aAAa;AAAA,EAC1B;AAIA,QAAM,aAAa;AAAA,IACjB,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,8BAA8B;AAAA,IAC9B,iCAAiC;AAAA;AAAA;AAAA,IAGjC,8BAA8B;AAAA,IAC9B,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,EACzB;AAEA,SACE,gBAAAA,KAAC,SAAI,WAAW,GAAG,WAAW,SAAS,GAAG,6BAAyB,MAAC,OAAO,YACzE,0BAAAA,KAAC,YAAS,UAAU,WAAW,gBAAAA,KAAC,gBAAa,GAG1C,kBACC,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB;AAAA,MACC,GAAI,sBAAsB,SAAY,EAAE,kBAAkB,IAAI,CAAC;AAAA;AAAA,EAClE,IAEC,WAAW,gBAAAA,KAAC,gBAAa,GAE9B,GACF;AAEJ;AAEA,SAAS,UAAU,EAAE,MAAM,SAAS,GAAuC;AACzE,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,aAAW;AAAA,MAEV;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,eAAe;AACtB,SAAO,gBAAAA,KAAC,SAAI,WAAU,oCAAmC,gCAAa;AACxE;;;APmGM,SAkOU,YAAAG,WAjOR,OAAAC,MADF,QAAAC,aAAA;AAhMC,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB,YAAY;AAAA,EACZ,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,CAAC,UAAU,WAAW,IAAIC,UAAwB,MAAM,uBAAuB,IAAI;AAGzF,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,KAAK;AAC9C,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAwB,IAAI;AAC9D,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAGxC,IAAI;AACd,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAAwB,IAAI;AAC9E,QAAM,CAAC,oBAAoB,qBAAqB,IAAIA,UAAS,CAAC;AAC9D,QAAM,kBAAkBC,QAA8B,IAAI;AAC1D,QAAM,oBAAoBA,QAA+B,IAAI;AAC7D,QAAM,oBAAoBA,QAA+B,IAAI;AAC7D,QAAM,aAAa,gBAAiB,0BAA0B,gBAAiB;AAE/E,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,iBAAiB,eAAe,MAAM;AACzC,wBAAkB,UAAU;AAC5B,wBAAkB,UAAU;AAC5B,2BAAqB,IAAI;AACzB;AAAA,IACF;AACA,QAAI,kBAAkB,YAAY,YAAY;AAC5C;AAAA,IACF;AACA,QAAI,CAAC,oBAAoB;AACvB,wBAAkB,UAAU;AAC5B,2BAAqB,IAAI;AACzB;AAAA,IACF;AACA,QAAI,iBAAiB,MAAM,WAAW,MAAM,KAAK,WAAW,EAAG;AAC/D,QAAI,iBAAiB,CAAC,MAAM,WAAW,MAAM,KAAK,WAAW,GAAG;AAC9D,wBAAkB,UAAU;AAC5B,wBAAkB,UAAU;AAC5B,2BAAqB,IAAI;AACzB;AAAA,IACF;AACA,QAAI,mBAAmB,MAAM,MAAM,eAAe,aAAa,MAAM,UAAU;AAC7E,wBAAkB,UAAU;AAC5B,wBAAkB,UAAU;AAC5B,2BAAqB,IAAI;AACzB;AAAA,IACF;AACA,sBAAkB,UAAU;AAC5B,sBAAkB,UAAU;AAC5B,gBAAY,aAAa;AACzB,2BAAuB,aAAa;AACpC,gBAAY,KAAK;AACjB,iBAAa,iBAAiB,QAAQ,gBAAgB,IAAI,gBAAgB,IAAI;AAC9E,yBAAqB,EAAE,MAAM,eAAe,WAAW,WAAW,CAAC;AACnE,0BAAsB,CAAC,aAAa,WAAW,CAAC;AAAA,EAClD,GAAG;AAAA,IACD,MAAM;AAAA,IACN,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAKD,QAAM,UAAUD,QAA8B,IAAI;AAClD,QAAM,CAAC,MAAM,OAAO,IAAID,UAAS,KAAK;AACtC,EAAAE,WAAU,MAAM;AACd,UAAM,KAAK,QAAQ;AACnB,QAAI,CAAC,GAAI;AACT,UAAM,SAAS,MAAM,QAAQ,GAAG,sBAAsB,EAAE,SAAS,GAAG;AACpE,WAAO;AACP,QAAI,OAAO,mBAAmB,YAAa;AAC3C,UAAM,WAAW,IAAI,eAAe,MAAM;AAC1C,aAAS,QAAQ,EAAE;AAMnB,UAAM,UAAU,GAAG,QAAQ,0BAA0B;AACrD,UAAM,kBACJ,WAAW,OAAO,qBAAqB,cAAc,IAAI,iBAAiB,MAAM,IAAI;AACtF,qBAAiB,QAAQ,SAAU;AAAA,MACjC,YAAY;AAAA,MACZ,iBAAiB,CAAC,SAAS,OAAO;AAAA,IACpC,CAAC;AACD,WAAO,MAAM;AACX,eAAS,WAAW;AACpB,uBAAiB,WAAW;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,QAAM,gBAAgB,aAAa,SAAS;AAK5C,QAAM,qBAAqB,WACvB,mBAAmB,MAAM,MAAM,UAAU,aAAa,IACtD;AACJ,QAAM,oBAAoB,QAAQ,iBAAiB,MAAM,WAAW,MAAM,KAAK,WAAW,CAAC;AAC3F,QAAM,WAAW,uBAAuB,YAAY,oBAAoB,OAAO;AAC/E,EAAAA,WAAU,MAAM;AACd,QAAI,aAAa,QAAQ,uBAAuB,SAAU;AAC1D,gBAAY,IAAI;AAChB,2BAAuB,IAAI;AAC3B,gBAAY,KAAK;AACjB,iBAAa,IAAI;AACjB,yBAAqB,IAAI;AACzB,yBAAqB,IAAI;AAAA,EAC3B,GAAG,CAAC,sBAAsB,UAAU,kBAAkB,CAAC;AACvD,QAAM,WAAW;AAAA,IACf;AAAA,IACA,MAAM;AAAA,IACN,GAAG,MAAM,mBAAmB,CAAC,IAAI,kBAAkB;AAAA,EACrD;AAEA,EAAAA,WAAU,MAAM;AACd,QAAI,cAAc,QAAQ,qBAAqB,KAAK,gBAAgB,SAAS;AAC3E,sBAAgB,QAAQ,YAAY;AAAA,IACtC;AAAA,EACF,GAAG,CAAC,WAAW,kBAAkB,CAAC;AAMlC,QAAM,aAAaC;AAAA,IACjB,CAAC,SAAiB;AAChB,UAAI,kBAAkB,YAAY,MAAM;AACtC,0BAAkB,UAAU,kBAAkB;AAC9C,0BAAkB,UAAU;AAAA,MAC9B;AACA,kBAAY,IAAI;AAChB,6BAAuB,IAAI;AAC3B,kBAAY,KAAK;AACjB,mBAAa,IAAI;AACjB,2BAAqB,IAAI;AACzB,2BAAqB,IAAI;AACzB,4BAAsB,CAAC;AAAA,IACzB;AAAA,IACA,CAAC,oBAAoB;AAAA,EACvB;AAMA,QAAM,UACJ,YACA,aAAa,QACb,CAAC,SAAS,WACV,SAAS,UAAU,QACnB,CAAC,SAAS,YACV,CAAC,SAAS,aACV,SAAS,YAAY;AACvB,QAAM,aAAa,WAAW;AAC9B,QAAM,yBACJ,SAAS,iBAAiB,+BAA+B,SAAS,QAAQ;AAC5E,QAAM,yBACJ,CAAC,kBACD,sBAAsB,aACrB,CAAC,sBAAsB,MAAM,YAC9B,2BAA2B;AAE7B,MAAI,kBAAkB,CAAC,sBAAsB,MAAM,WAAW,WAAW;AACvE,WACE,gBAAAJ,MAAC,UAAO,WAAsB,OAAM,iCAAgC,UAAS,SAC3E;AAAA,sBAAAD,KAAC,OAAG,yBAAe,SAAQ;AAAA,MAC1B,kBACC,gBAAAA,KAAC,cAAW,SAAS,iBAAiB,kCAAoB,IACxD;AAAA,OACN;AAAA,EAEJ;AAEA,MAAI,oBAAoB,iBAAiB;AACvC,WACE,gBAAAA,KAAC,SAAI,WAAW,GAAG,UAAU,SAAS,GAAG,mCAA+B,MACtE,0BAAAC;AAAA,MAAC;AAAA;AAAA,QACC,MACE,kBACE,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,eAAW;AAAA;AAAA,QACb,IAEA,gBAAAA,KAAC,iBAAc,WAAU,UAAS,eAAW,MAAC;AAAA,QAGlD,OAAO,kBAAkB,qBAAqB;AAAA,QAC9C,UAAS;AAAA,QAET;AAAA,0BAAAA,KAAC,OACE,4BACG,6CACA,wFACN;AAAA,UACC,CAAC,mBAAmB,kBACnB,gBAAAA,KAAC,cAAW,SAAS,iBAAiB,iCAAmB,IACvD;AAAA;AAAA;AAAA,IACN,GACF;AAAA,EAEJ;AAEA,MAAI,CAAC,qBAAqB;AACxB,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAM,gBAAAA,KAAC,mBAAgB,WAAU,UAAS,eAAW,MAAC;AAAA,QACtD,OAAM;AAAA,QACN,UAAS;AAAA,QACV;AAAA;AAAA,IAED;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,KAAK,SAAS,WAAW,GAAG,wCAAwC,SAAS,GAEhF;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,SACE,QAAQ,MAAM,WAAW,MAAM,cAAc,MAAM,WAAW,QAAQ,KAAK,OAAO,KAClF,MAAM,eAAe;AAAA,QAEvB,KACE,MAAM,cAAc;AAAA,UAClB,QAAQ,KAAK,UAAU;AAAA,UACvB,QAAQ,KAAK,UAAU;AAAA,UACvB,WAAW,KAAK,aAAa;AAAA,UAC7B,OAAO,KAAK,SAAS;AAAA,UACrB,QAAQ,KAAK,UAAU;AAAA,UACvB,YAAY,KAAK,KAAK,UAAU;AAAA,QAClC;AAAA;AAAA,IAEJ;AAAA,IAEA,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,aAAa,OAAO,eAAe;AAAA,QACnC,WAAW,GAAG,kBAAkB,OAAO,aAAa,UAAU;AAAA,QAI9D;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,aAAa,OAAO,UAAU;AAAA,cAC9B,SAAS,OAAO,UAAU;AAAA,cAC1B,SAAS,OAAO,QAAQ;AAAA,cACxB,WAAU;AAAA,cAEV,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAQ;AAAA,kBACR;AAAA,kBACA,cAAc,YAAY;AAAA,kBACzB,GAAI,oBACD;AAAA,oBACE,YAAY,kBAAkB;AAAA,oBAC9B,qBAAqB,kBAAkB;AAAA,kBACzC,IACA,CAAC;AAAA,kBACL,cAAc;AAAA,kBACd;AAAA,kBACA,YAAW;AAAA,kBACX,WAAU;AAAA;AAAA,cACZ;AAAA;AAAA,UACF;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,cAAW;AAAA,cACX,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,CAAC,QACC;AAAA,cACJ;AAAA;AAAA,UACF;AAAA,UAKA,gBAAAC;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,SAAS,OAAO,UAAU;AAAA,cAC1B,WAAW,GAAG,iCAAiC,CAAC,QAAQ,2BAA2B;AAAA,cAEnF;AAAA,gCAAAA,MAAC,SAAI,WAAU,wGACb;AAAA,kCAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,+BAA2B;AAAA,sBAC3B,WAAU;AAAA,sBAET,qBACG,cAAc,OACZ,GAAG,QAAQ,IAAI,SAAS,KACxB,WACF;AAAA;AAAA,kBACN;AAAA,kBAIC,WACC,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,SAAS;AAAA,wBACP,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,wBAC/B,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,sBACjC;AAAA,sBACA,OAAO,WAAW,SAAS;AAAA,sBAC3B,UAAU,CAAC,MAAM,YAAY,MAAM,MAAM;AAAA;AAAA,kBAC3C;AAAA,mBAEJ;AAAA,gBACA,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,KAAK;AAAA,oBACL,WAAU;AAAA,oBACV,oCAAgC;AAAA,oBAE/B,qBACC,cAAc,SAAS,YAAY,OACjC,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBAEC,MAAM;AAAA,wBACN,iBAAiB,SAAS;AAAA,wBAC1B,WAAW;AAAA,wBACX,QAAQ,CAAC,UAAU,qBACjB,MAAM,UAAU,UAAU,UAAU,EAAE,iBAAiB,iBAAiB,CAAC;AAAA,wBAE3E,aAAa,CAAC,aAAa,MAAM,UAAU,UAAU,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,wBAC9E,UAAU,MAAM,sBAAsB,CAAC,aAAa,WAAW,CAAC;AAAA,wBAC/D,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,wBACxC,WAAU;AAAA;AAAA,sBAVL;AAAA,oBAWP,IACE,mBACD,sBAAsB,YAAY,kBAAkB,aACrD,CAAC,qBACD,gBAAAC,MAAC,UAAO,OAAM,4BAA2B,UAAS,SAChD;AAAA,sCAAAD,KAAC,OAAG,yBAAe,SAAQ;AAAA,sBAC1B,kBACC,gBAAAA,KAAC,cAAW,SAAS,iBAAiB,6BAAe,IACnD;AAAA,uBACN,IACE,yBACF,gBAAAC;AAAA,sBAAC;AAAA;AAAA,wBACC,MACE,gBAAAD;AAAA,0BAAC;AAAA;AAAA,4BACC,WAAU;AAAA,4BACV,eAAW;AAAA;AAAA,wBACb;AAAA,wBAEF,OAAM;AAAA,wBACN,UAAS;AAAA,wBACV;AAAA;AAAA,0BACU;AAAA,0BAAS;AAAA;AAAA;AAAA,oBACpB,IACE,yBACF,gBAAAC,MAAC,UAAO,MAAM,gBAAAD,KAAC,iBAAc,WAAU,UAAS,eAAW,MAAC,GAAI,OAAM,cACpE;AAAA,sCAAAA,KAAC,OACE,iCAAuB,WAAW,cAC/B,yDACA,uBAAuB,WAAW,oBAChC,8CACA,uEACR;AAAA,sBACC,kBACC,gBAAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,SAAS,MAAM;AACb,iDAAqB,QAAQ;AAC7B,gCAAI,mBAAoB,MAAK,MAAM,QAAQ;AAAA,gCACtC,iBAAgB;AAAA,0BACvB;AAAA,0BAEC,+BAAqB,oBAAoB;AAAA;AAAA,sBAC5C,IACE;AAAA,uBACN,IACE,SAAS,QACX,gBAAAC,MAAC,UAAO,UAAS,SAAQ;AAAA;AAAA,sBACP;AAAA,sBAAS;AAAA,sBAAG,SAAS,MAAM;AAAA,uBAC7C,IACE,SAAS,UACX,gBAAAA,MAAC,UAAO,UAAS,UAAS;AAAA;AAAA,sBAAS;AAAA,sBAAS;AAAA,uBAAC,IAC3C,SAAS,WACX,gBAAAD;AAAA,sBAAC;AAAA;AAAA,wBAEC,KAAK,SAAS;AAAA,wBACd,MAAM;AAAA;AAAA,sBAFD,SAAS;AAAA,oBAGhB,IACE,SAAS,WACX,gBAAAC,MAAC,UACE;AAAA;AAAA,sBAAS;AAAA,sBAAoB,SAAS,aAAa;AAAA,sBAAE;AAAA,uBACxD,IACE,SAAS,YAAY,OACvB,gBAAAA,MAAAF,WAAA,EACG;AAAA,+BAAS,aACR,gBAAAE,MAAC,SAAI,WAAU,yFAAwF;AAAA;AAAA,wBAC1D,SAAS,aAAa;AAAA,wBAAE;AAAA,yBAErE;AAAA,sBAED,aAAa,cAAc,OAC1B,gBAAAD;AAAA,wBAAC;AAAA;AAAA,0BAEC,MAAM;AAAA,0BACN,UAAU,SAAS;AAAA,0BACnB,WAAW;AAAA,0BACX,UACE,gBAAAA,KAAC,SAAI,WAAU,uEACZ,mBAAS,SACZ;AAAA,0BAEF,WAAU;AAAA;AAAA,wBATL,GAAG,QAAQ,IAAI,kBAAkB;AAAA,sBAUxC,IACE,cAAc,OAChB,gBAAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAM;AAAA,0BACN,UAAU,SAAS;AAAA,0BACnB;AAAA;AAAA,sBACF,IAEA,gBAAAA,KAAC,SAAI,WAAU,uEACZ,mBAAS,SACZ;AAAA,uBAEJ,IAEA,gBAAAC,MAAC,UAAO,UAAS,UAAS;AAAA;AAAA,sBAAS;AAAA,sBAAS;AAAA,uBAAC;AAAA;AAAA,sBAGjD,iBAAiB,CAAC,qBAChB,iBACE,gBAAAA,MAAC,UAAO,OAAM,4BAA2B,UAAS,SAChD;AAAA,wCAAAD,KAAC,OAAG,yBAAe,SAAQ;AAAA,wBAC1B,kBACC,gBAAAA,KAAC,cAAW,SAAS,iBAAiB,6BAAe,IACnD;AAAA,yBACN,IAEA,gBAAAC;AAAA,wBAAC;AAAA;AAAA,0BACC,MACE,gBAAAD;AAAA,4BAAC;AAAA;AAAA,8BACC,WAAU;AAAA,8BACV,eAAW;AAAA;AAAA,0BACb;AAAA,0BAEF,OAAM;AAAA,0BACN,UAAS;AAAA,0BACV;AAAA;AAAA,4BACU;AAAA,4BAAc;AAAA;AAAA;AAAA,sBACzB,IAGF,gBAAAA,KAAC,UAAO,MAAM,gBAAAA,KAAC,iBAAc,WAAU,UAAS,eAAW,MAAC,GAAI,OAAM,iBAAgB,sDAEtF;AAAA;AAAA;AAAA,gBAEJ;AAAA;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AAEA,SAAS,WAAW,EAAE,UAAU,QAAQ,GAAiD;AACvF,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA,WAAU;AAAA,MAET;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,QAAQ,SAAS,MAAM,IAAI;AACjC,QAAM,UAAU,aAAa,KAAK,aAAa,MAAM;AACrD,QAAM,YAAYG,QAA8B,IAAI;AAEpD,EAAAC,WAAU,MAAM;AACd,cAAU,SAAS,eAAe;AAAA,MAChC,OAAO;AAAA,MACP,UAAU,qBAAqB,IAAI,SAAS;AAAA,IAC9C,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,WAAW,QAAQ,CAAC;AAE9B,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAK;AAAA,MACL,cAAY,UAAU,GAAG,IAAI,YAAY,SAAS,KAAK;AAAA,MAEtD;AAAA,SAAC,UACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACN;AAAA;AAAA,cACO;AAAA,cAAU;AAAA;AAAA;AAAA,QAClB,IACE;AAAA,QACJ,gBAAAD,KAAC,SACE,gBAAM,IAAI,CAAC,MAAM,UAAU;AAC1B,gBAAM,aAAa,QAAQ;AAC3B,gBAAM,UAAU,WAAW,eAAe;AAC1C,iBACE,gBAAAC;AAAA,YAAC;AAAA;AAAA,cAEC,KAAK,UAAU,YAAY;AAAA,cAC3B,2BAAyB;AAAA,cACxB,GAAI,UAAU,EAAE,4BAA4B,GAAG,IAAI,CAAC;AAAA,cACrD,gBAAc,UAAU,aAAa;AAAA,cACrC,WAAW,GAAG,oCAAoC,WAAW,mBAAmB;AAAA,cAEhF;AAAA,gCAAAD,KAAC,UAAK,WAAU,uEACb,sBACH;AAAA,gBACA,gBAAAA,KAAC,SAAI,WAAU,kDAAkD,kBAAQ,KAAI;AAAA;AAAA;AAAA,YAVxE;AAAA,UAWP;AAAA,QAEJ,CAAC,GACH;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,UAAU,EAAE,KAAK,QAAQ,GAAsD;AACtF,MAAI,SAAS;AACX,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAK;AAAA,QACL,aAAU;AAAA,QAEV;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAW;AAAA;AAAA,UACb;AAAA,UACA,gBAAAA,KAAC,UAAK,sCAAmB;AAAA;AAAA;AAAA,IAC3B;AAAA,EAEJ;AACA,QAAM,QAAQ,IAAI,aAAa;AAC/B,SACE,gBAAAC,MAAC,SAAI,WAAU,mGACb;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA,QAAQ,yBAAyB;AAAA,QACnC;AAAA;AAAA,IACF;AAAA,IACA,gBAAAA,KAAC,UAAK,WAAU,WACb,kBAAQ,0BAA0B,IAAI,UAAU,WAAW,0BAC9D;AAAA,IACA,gBAAAA,KAAC,UAAK,WAAU,oCACb,cAAI,YAAY,IACb,GAAG,IAAI,SAAS,kBACf,IAAI,WAAW,IAAI,SAAS,eAAe,YAClD;AAAA,KACE,IAAI,QAAQ,KAAK,IAAI,SAAS,MAC9B,gBAAAC,MAAC,UAAK,WAAU,mEAGb;AAAA,UAAI,QAAQ,KAAK,gBAAAA,MAAC,UAAK,yBAAqB,MAAC;AAAA;AAAA,QAAE,IAAI;AAAA,SAAM;AAAA,MACzD,IAAI,SAAS,KAAK,gBAAAA,MAAC,UAAK,yBAAqB,MAAC;AAAA;AAAA,QAAE,IAAI;AAAA,SAAO;AAAA,OAC9D;AAAA,IAED,SACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,eAAY;AAAA,QACZ,yBAAqB;AAAA,QACrB,WAAU;AAAA,QAET;AAAA,cAAI;AAAA,UAAW;AAAA;AAAA;AAAA,IAClB;AAAA,KAEJ;AAEJ;AAEA,SAAS,UAAU;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE,gBAAAD,KAAC,SAAI,WAAU,2EACZ,kBAAQ,IAAI,CAAC,QACZ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MAEC,MAAK;AAAA,MACL,SAAS,MAAM,SAAS,IAAI,KAAK;AAAA,MACjC,WAAW;AAAA,QACT;AAAA,QACA,IAAI,UAAU,QACV,iCACA;AAAA,MACN;AAAA,MAEC,cAAI;AAAA;AAAA,IAVA,IAAI;AAAA,EAWX,CACD,GACH;AAEJ;AAqBA,SAAS,YACP,MACA,UACA,iBAAkC,GACnB;AACf,QAAM,kBAAkBG,QAAsB,IAAI;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAID,UAAwB;AAAA,IAChD,SAAS;AAAA,IACT,UAAU;AAAA,IACV,WAAW;AAAA,IACX,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,EACT,CAAC;AACD,EAAAE,WAAU,MAAM;AACd,QAAI,CAAC,MAAM;AACT,sBAAgB,UAAU;AAC1B,eAAS;AAAA,QACP,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,QACX,SAAS;AAAA,QACT,OAAO;AAAA,MACT,CAAC;AACD;AAAA,IACF;AACA,UAAM,cAAc,gBAAgB,YAAY;AAChD,oBAAgB,UAAU;AAC1B,QAAI,YAAY;AAChB,UAAM,QAAQ,IAAI,gBAAgB;AAClC,QAAI,aAAa;AACf,eAAS;AAAA,QACP,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,QACX,SAAS;AAAA,QACT,OAAO;AAAA,MACT,CAAC;AAAA,IACH,OAAO;AAIL,eAAS,CAAC,cAAc,EAAE,GAAG,UAAU,OAAO,KAAK,EAAE;AAAA,IACvD;AACA,SAAK,SAAS,MAAM,EAAE,QAAQ,MAAM,OAAO,CAAC,EACzC,KAAK,CAAC,QAAQ;AACb,UAAI,UAAW;AACf,YAAM,UAAU,IAAI,WAChB,OACA,IAAI,aAAa,WACf,iBAAiB,IAAI,OAAO,IAC5B,IAAI;AACV,eAAS;AAAA,QACP;AAAA,QACA,UACE,CAAC,IAAI,aAAa,IAAI,aAAa,WAAW,eAAe,MAAM,IAAI,OAAO,IAAI;AAAA,QACpF,UAAU,IAAI;AAAA,QACd,WAAW,IAAI;AAAA,QACf,WAAW,IAAI;AAAA,QACf,SAAS;AAAA,QACT,OAAO;AAAA,MACT,CAAC;AAAA,IACH,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,UAAI,UAAW;AACf,YAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACtE;AAAA,QAAS,CAAC,aACR,cACI;AAAA,UACE,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAW;AAAA,UACX,WAAW;AAAA,UACX,SAAS;AAAA,UACT;AAAA,QACF,IACA,EAAE,GAAG,UAAU,SAAS,OAAO,MAAM;AAAA,MAC3C;AAAA,IACF,CAAC;AACH,WAAO,MAAM;AACX,kBAAY;AACZ,YAAM,MAAM;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,cAAc,CAAC;AACnC,SAAO;AACT;AAGA,SAAS,eAAe,MAAc,SAAgC;AACpE,QAAM,YAAY,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AACrD,QAAM,OACJ,cAAc,QACV,cACA,cAAc,SAAS,cAAc,SACnC,eACA,cAAc,QACZ,cACA,cAAc,SACZ,eACA;AACZ,SAAO,OAAO,QAAQ,IAAI,WAAW,OAAO,KAAK;AACnD;AAEA,SAAS,kBAAkB,EAAE,KAAK,KAAK,GAAkC;AACvE,QAAM,CAAC,QAAQ,SAAS,IAAIF,UAAS,KAAK;AAC1C,SAAO,SACL,gBAAAD,MAAC,UAAO,OAAM,6BAA4B,UAAS,SAAQ;AAAA;AAAA,IACvC;AAAA,IAAK;AAAA,KACzB,IAEA,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,KAAK;AAAA,MACL,SAAS,MAAM,UAAU,IAAI;AAAA,MAC7B,WAAU;AAAA;AAAA,EACZ;AAEJ;AAGA,SAAS,iBAAiB,KAAqB;AAC7C,MAAI;AACF,QAAI,OAAO,SAAS,YAAY;AAC9B,YAAM,SAAS,KAAK,GAAG;AACvB,YAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,OAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AACtE,aAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,IACvC;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEA,SAAS,OAAO;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,eAAa,WAAW,SAAS;AAAA,MACjC,aAAW,aAAa,UAAU,cAAc,aAAa,WAAW,WAAW;AAAA,MACnF,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEA,0BAAAC,MAAC,SAAI,WAAU,+CACZ;AAAA,eACC,gBAAAD,KAAC,UAAK,WAAU,oHACb,gBACH,IACE;AAAA,QACH,QAAQ,gBAAAA,KAAC,OAAE,WAAU,0BAA0B,iBAAM,IAAO;AAAA,QAC7D,gBAAAA,KAAC,SAAI,yBAAqB,MAAC,WAAU,aAClC,UACH;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;","names":["useCallback","useEffect","useRef","useState","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useEffect","useCallback","useMemo","useCallback","useEffect","useMemo","useRef","useState","useEffect","useMemo","useMemo","useEffect","jsx","jsxs","useEffect","parentOf","pathIsInsideDirectory","useState","useRef","useCallback","useMemo","item","useEffect","useState","jsx","useState","useEffect","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback"]}
|