@browsernode/elements 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider/sandbox-provider.tsx","../src/sandbox-chrome.tsx","../src/preview/sandbox-preview.tsx","../src/primitives/ui/button.tsx","../src/primitives/lib/utils.ts","../src/primitives/ui/collapsible.tsx","../src/primitives/ui/input.tsx","../src/primitives/ui/tooltip.tsx","../src/preview/primitives/web-preview.tsx","../src/primitives/stack-trace.tsx","../src/primitives/ui/dropdown-menu.tsx","../src/editor/sandbox-file-tree.tsx","../src/editor/primitives/file-tree.tsx","../src/primitives/ui/popover.tsx","../src/editor/internal/tree.tsx","../src/editor/sandbox-code-editor.tsx","../src/editor/primitives/code-editor.tsx","../src/primitives/ui/loading.tsx","../src/editor/internal/language.ts","../src/editor/sandbox-ide.tsx","../src/snapshots/sandbox-snapshots.tsx","../src/sandbox-attribution.tsx","../src/primitives/ui/tabs.tsx","../src/sandbox.tsx"],"sourcesContent":["// `<SandboxProvider>` — thin wrapper around @browsernode/react's\n// `<SandboxRuntime>` (the headless engine binding) that adds\n// elements-specific extras (theme, selectedPath, openTabs, activePanel)\n// and resolves the `framework` string (\"nextjs\" → nextjs()) plus the\n// default bundler.\n//\n// Lifecycle/sandbox management is delegated to @browsernode/react entirely.\n// Components inside elements should:\n// • read the sandbox via `useSandbox()` (re-exported from @browsernode/react)\n// • read elements extras via `useElementsContext()`\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n SandboxRuntime,\n type UseSandboxOptions,\n} from '@browsernode/react';\nimport { esbuild } from '@browsernode/esbuild-wasm';\nimport { nextjs } from '@browsernode/nextjs';\nimport type {\n BundlerAdapter,\n FrameworkAdapter,\n} from '@browsernode/sandbox';\n\nexport { useSandbox } from '@browsernode/react';\n\nexport type SandboxPanel = 'left' | 'top' | 'center' | 'bottom';\n\n/**\n * Resolved color scheme for elements that need light/dark variants\n * (e.g. `<CodeEditor>`'s syntax theme). Pass the resolved value from your\n * theme system — e.g. `next-themes`' `useTheme().resolvedTheme`. Defaults\n * to `'light'`.\n */\nexport type SandboxTheme = 'light' | 'dark';\n\nexport interface SandboxTab {\n path: string;\n label?: string;\n}\n\n/** Elements-specific extras: theme, file selection, open tabs. */\nexport interface ElementsContextValue {\n selectedPath: string | null;\n setSelectedPath(path: string | null): void;\n\n openTabs: SandboxTab[];\n openTab(tab: SandboxTab | string): void;\n closeTab(path: string): void;\n\n activePanel: SandboxPanel;\n setActivePanel(panel: SandboxPanel): void;\n\n theme: SandboxTheme;\n}\n\nconst ElementsContext = createContext<ElementsContextValue | null>(null);\n\nexport type SandboxProviderFramework = FrameworkAdapter | 'nextjs';\n\ninterface SandboxProviderBaseProps {\n children: ReactNode;\n initialActivePanel?: SandboxPanel;\n initialOpenTabs?: readonly (SandboxTab | string)[];\n initialSelectedPath?: string | null;\n theme?: SandboxTheme;\n}\n\nexport interface SandboxProviderProps\n extends SandboxProviderBaseProps,\n Omit<UseSandboxOptions, 'framework' | 'bundler'> {\n framework: SandboxProviderFramework;\n bundler?: BundlerAdapter;\n}\n\nfunction toTab(t: SandboxTab | string): SandboxTab {\n return typeof t === 'string' ? { path: t } : t;\n}\n\nfunction resolveFramework(framework: SandboxProviderFramework): FrameworkAdapter {\n if (framework === 'nextjs') return nextjs();\n if (typeof framework === 'string') {\n throw new Error(`Unsupported SandboxProvider framework \"${framework}\".`);\n }\n return framework;\n}\n\nexport function SandboxProvider({ children, ...props }: SandboxProviderProps) {\n const {\n initialActivePanel,\n initialOpenTabs,\n initialSelectedPath,\n theme,\n framework,\n bundler,\n ...sandboxOptions\n } = props;\n\n const options = useMemo<UseSandboxOptions>(\n () => ({\n ...sandboxOptions,\n framework: resolveFramework(framework),\n bundler: bundler ?? esbuild(),\n }),\n // The sandbox is created once on mount (managed by <SandboxRuntime>'s\n // useEffect deps); listing only framework/bundler here keeps the\n // ref-stable options object the way callers expect.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [framework, bundler],\n );\n\n return (\n <SandboxRuntime options={options}>\n <ElementsExtrasProvider\n initialActivePanel={initialActivePanel}\n initialOpenTabs={initialOpenTabs}\n initialSelectedPath={initialSelectedPath}\n theme={theme}\n >\n {children}\n </ElementsExtrasProvider>\n </SandboxRuntime>\n );\n}\n\ninterface ElementsExtrasProviderProps extends SandboxProviderBaseProps {}\n\nfunction ElementsExtrasProvider({\n children,\n initialActivePanel = 'center',\n initialOpenTabs = [],\n initialSelectedPath = null,\n theme = 'light',\n}: ElementsExtrasProviderProps) {\n const [selectedPath, setSelectedPath] = useState<string | null>(initialSelectedPath);\n const [openTabs, setOpenTabs] = useState<SandboxTab[]>(() =>\n initialOpenTabs.map(toTab),\n );\n const [activePanel, setActivePanel] = useState<SandboxPanel>(initialActivePanel);\n\n const openTab = useCallback((t: SandboxTab | string) => {\n const tab = toTab(t);\n setOpenTabs((prev) => {\n if (prev.some((x) => x.path === tab.path)) return prev;\n return [...prev, tab];\n });\n setSelectedPath(tab.path);\n }, []);\n\n const closeTab = useCallback((path: string) => {\n setOpenTabs((prev) => {\n const next = prev.filter((t) => t.path !== path);\n setSelectedPath((cur) => {\n if (cur !== path) return cur;\n const idx = prev.findIndex((t) => t.path === path);\n const fallback = next[idx - 1] ?? next[idx] ?? next[0] ?? null;\n return fallback?.path ?? null;\n });\n return next;\n });\n }, []);\n\n const extras = useMemo<ElementsContextValue>(\n () => ({\n selectedPath,\n setSelectedPath,\n openTabs,\n openTab,\n closeTab,\n activePanel,\n setActivePanel,\n theme,\n }),\n [selectedPath, openTabs, openTab, closeTab, activePanel, theme],\n );\n\n return <ElementsContext.Provider value={extras}>{children}</ElementsContext.Provider>;\n}\n\n/** Read elements-specific state (theme, selectedPath, openTabs). */\nexport function useElementsContext(): ElementsContextValue | null {\n return useContext(ElementsContext);\n}\n\nexport function useElementsContextOrThrow(): ElementsContextValue {\n const ctx = useContext(ElementsContext);\n if (!ctx) {\n throw new Error(\n 'useElementsContext() must be called inside <SandboxProvider> from @browsernode/elements.',\n );\n }\n return ctx;\n}\n","// `<SandboxChrome>` — UI shell only. Reads sandbox state from\n// `useSandbox()` (i.e. requires an `<SandboxProvider>` somewhere\n// above in the tree). Renders the navigation toolbar, web ↔ code body,\n// and console drawer; no provider lifecycle of its own.\n//\n// Use this when you want to compose siblings that share the sandbox:\n//\n// <SandboxProvider framework=\"nextjs\" source={...}>\n// <MyChat /> {/* useSandbox() — same instance */}\n// <SandboxChrome /> {/* useSandbox() — same instance */}\n// </SandboxProvider>\n//\n// For the zero-config drop-in (provider + chrome in one tag), use\n// `<Sandbox>`. It composes `<SandboxProvider>` + `<SandboxChrome>`.\n\nimport {\n useState,\n type CSSProperties,\n type ReactNode,\n} from 'react';\nimport { motion } from 'motion/react';\nimport {\n ArrowLeftIcon,\n ArrowRightIcon,\n ClockFadingIcon,\n CodeIcon,\n DownloadIcon,\n GlobeIcon,\n MaximizeIcon,\n MinimizeIcon,\n MonitorIcon,\n MoreVerticalIcon,\n RefreshCcwIcon,\n SmartphoneIcon,\n} from 'lucide-react';\nimport {\n SandboxPreviewProvider,\n SandboxPreviewConsole,\n SandboxPreviewWeb,\n useSandboxPreviewCtx,\n} from './preview/sandbox-preview';\nimport {\n WebPreview,\n WebPreviewNavigation,\n WebPreviewNavigationButton,\n} from './preview/primitives/web-preview';\nimport { SandboxIDE } from './editor/sandbox-ide';\nimport { SandboxSnapshots } from './snapshots/sandbox-snapshots';\nimport { SandboxAttribution } from './sandbox-attribution';\nimport { Input } from './primitives/ui/input';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from './primitives/ui/dropdown-menu';\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from './primitives/ui/popover';\nimport { Tabs, TabsList, TabsTrigger } from './primitives/ui/tabs';\nimport { cn } from './primitives/lib/utils';\n\n/** Per-control toggles for the Sandbox chrome. All default to `true`. */\nexport interface SandboxUi {\n /** Web ↔ Code editor toggle in the toolbar. */\n showCodeEditor?: boolean;\n /** Back / forward arrows + URL bar. */\n showNavigation?: boolean;\n /** Reload button. */\n showReload?: boolean;\n /** Desktop ↔ Mobile viewport toggle. */\n showDeviceToggle?: boolean;\n /** Fullscreen overlay toggle. */\n showFullScreenToggle?: boolean;\n /** Snapshots popover. */\n showSnapshots?: boolean;\n /** Export-as-zip menu item inside the More dropdown. */\n showExportFiles?: boolean;\n /** Settings dropdown (placeholder — opens an empty menu for now). */\n showSettings?: boolean;\n /** Console drawer at the bottom. */\n showConsole?: boolean;\n /** \"Made with BrowserNode\" badge in the bottom-right of the body. */\n showAttribution?: boolean;\n}\n\nconst DEFAULT_UI: Required<SandboxUi> = {\n showCodeEditor: true,\n showNavigation: true,\n showReload: true,\n showDeviceToggle: true,\n showFullScreenToggle: true,\n showSnapshots: true,\n showExportFiles: true,\n showSettings: false,\n showConsole: true,\n showAttribution: true,\n};\n\nexport interface SandboxChromeProps {\n ui?: SandboxUi;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SLIDE_TRANSITION = {\n type: 'spring' as const,\n stiffness: 320,\n damping: 32,\n mass: 0.7,\n};\n\n/**\n * `<SandboxChrome>` — the IDE shell (toolbar + web/code body + console).\n * Consumes the sandbox from a surrounding `<SandboxProvider>` via\n * `useSandbox()`; does not create its own provider. Throws if no\n * `<SandboxProvider>` is mounted above it — wrap with one or use\n * `<Sandbox>` for the bundled drop-in.\n */\nexport function SandboxChrome({ ui, className, style }: SandboxChromeProps) {\n const flags = { ...DEFAULT_UI, ...ui };\n const [view, setView] = useState<'web' | 'code'>('web');\n const isCode = view === 'code';\n\n return (\n <SandboxPreviewProvider>\n <SandboxOverlay className={className} style={style}>\n <SandboxToolbar\n flags={flags}\n view={view}\n onViewChange={setView}\n />\n\n {/* Sliding body — only this region animates, so toolbar stays put. */}\n <div className=\"relative flex-1 min-h-0 overflow-hidden\">\n <motion.div\n className=\"absolute inset-0\"\n animate={{ x: isCode ? '-100%' : '0%' }}\n transition={SLIDE_TRANSITION}\n >\n <SandboxPreviewWeb />\n </motion.div>\n {flags.showCodeEditor && (\n <motion.div\n className=\"absolute inset-0\"\n initial={{ x: '100%' }}\n animate={{ x: isCode ? '0%' : '100%' }}\n transition={SLIDE_TRANSITION}\n >\n <SandboxIDE hideBorder />\n </motion.div>\n )}\n {flags.showAttribution && !isCode && <SandboxAttribution />}\n </div>\n\n {flags.showConsole && <SandboxPreviewConsole />}\n </SandboxOverlay>\n </SandboxPreviewProvider>\n );\n}\n\n// CSS-fullscreen mount: when the inner ctx flips `overlay`, this div\n// goes `fixed inset-0 z-50` and takes over the viewport without invoking\n// the system fullscreen API (which is restricted inside iframes / on iOS).\nfunction SandboxOverlay({\n className,\n style,\n children,\n}: {\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}) {\n const { overlay } = useSandboxPreviewCtx();\n return (\n <WebPreview\n defaultUrl=\"\"\n className={cn(\n 'flex h-full w-full flex-col',\n overlay && 'fixed inset-0 z-50 bg-background',\n className,\n )}\n style={style}\n >\n {children}\n </WebPreview>\n );\n}\n\ninterface SandboxToolbarProps {\n flags: Required<SandboxUi>;\n view: 'web' | 'code';\n onViewChange: (view: 'web' | 'code') => void;\n}\n\nfunction SandboxToolbar({ flags, view, onViewChange }: SandboxToolbarProps) {\n const {\n inputValue,\n setInputValue,\n currentUrl,\n history,\n historyIndex,\n viewport,\n setViewport,\n spinCount,\n goBack,\n goForward,\n reload,\n overlay,\n toggleOverlay,\n submitUrl,\n download,\n } = useSandboxPreviewCtx();\n\n // Navigation strip — back / forward / URL / reload. Used twice:\n // (a) inside the mobile-only top row, and (b) inline within the chrome\n // row at md+. `display: contents` (via `md:contents`) lets the desktop\n // copy participate directly in the chrome row's flex layout without\n // adding a wrapper element.\n const navItems =\n flags.showNavigation || flags.showReload ? (\n <>\n {flags.showNavigation && (\n <>\n <WebPreviewNavigationButton\n tooltip=\"Back\"\n disabled={historyIndex <= 0}\n onClick={goBack}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton\n tooltip=\"Forward\"\n disabled={historyIndex >= history.length - 1}\n onClick={goForward}\n >\n <ArrowRightIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <Input\n className=\"h-8 flex-1 text-sm\"\n placeholder=\"Enter URL...\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n submitUrl();\n } else if (e.key === 'Escape') {\n setInputValue(currentUrl);\n (e.target as HTMLInputElement).blur();\n }\n }}\n />\n </>\n )}\n {flags.showReload && (\n <WebPreviewNavigationButton tooltip=\"Reload\" onClick={reload}>\n <RefreshCcwIcon\n key={spinCount}\n className=\"size-4 motion-safe:animate-[spin_0.6s_linear_reverse_1]\"\n />\n </WebPreviewNavigationButton>\n )}\n </>\n ) : null;\n\n return (\n <div className=\"flex flex-col\">\n {/* Mobile-only nav row above the chrome. Hidden at md+. */}\n {navItems && (\n <div className=\"md:hidden\">\n <WebPreviewNavigation>{navItems}</WebPreviewNavigation>\n </div>\n )}\n\n {/* Chrome row — always shown. Inline nav at md+. */}\n <WebPreviewNavigation>\n {flags.showCodeEditor && (\n <Tabs\n value={view}\n onValueChange={(v) => onViewChange(v as 'web' | 'code')}\n className=\"mr-1\"\n >\n <TabsList className=\"h-8\">\n <TabsTrigger value=\"web\" aria-label=\"Web\" className=\"size-7 p-0\">\n <GlobeIcon className=\"size-4\" />\n </TabsTrigger>\n <TabsTrigger value=\"code\" aria-label=\"Code\" className=\"size-7 p-0\">\n <CodeIcon className=\"size-4\" />\n </TabsTrigger>\n </TabsList>\n </Tabs>\n )}\n\n {/* Desktop-only inline nav strip. `display: contents` so the\n children (with `flex-1` Input) flow directly inside\n <WebPreviewNavigation>'s flex layout — the Input grows to\n fill all remaining space between the left tabs and the\n right chrome cluster. */}\n {navItems && <div className=\"hidden md:contents\">{navItems}</div>}\n\n {/* Mobile-only spacer (pushes chrome icons right when the URL\n bar isn't inline). On desktop the URL Input's flex-1 already\n does this. */}\n <div className=\"flex-1 md:hidden\" />\n\n {flags.showDeviceToggle && (\n <WebPreviewNavigationButton\n tooltip={viewport === 'desktop' ? 'Mobile view' : 'Desktop view'}\n onClick={() =>\n setViewport(viewport === 'desktop' ? 'mobile' : 'desktop')\n }\n className=\"hidden md:inline-flex\"\n >\n {viewport === 'desktop' ? (\n <SmartphoneIcon className=\"size-4\" />\n ) : (\n <MonitorIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n )}\n\n {flags.showFullScreenToggle && (\n <WebPreviewNavigationButton\n tooltip={overlay ? 'Exit fullscreen' : 'Fullscreen'}\n onClick={toggleOverlay}\n >\n {overlay ? (\n <MinimizeIcon className=\"size-4\" />\n ) : (\n <MaximizeIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n )}\n\n {flags.showSnapshots && (\n <Popover>\n <PopoverTrigger\n render={<WebPreviewNavigationButton tooltip=\"Snapshots\" />}\n >\n <ClockFadingIcon className=\"size-4\" />\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n className=\"w-80 p-0 max-h-[26rem] flex flex-col overflow-hidden\"\n >\n <SandboxSnapshots />\n </PopoverContent>\n </Popover>\n )}\n\n {(flags.showExportFiles || flags.showSettings) && (\n <DropdownMenu>\n <DropdownMenuTrigger\n render={<WebPreviewNavigationButton tooltip=\"More\" />}\n >\n <MoreVerticalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-40\">\n {flags.showExportFiles && (\n <DropdownMenuItem onClick={download}>\n <DownloadIcon className=\"size-4\" />\n Download .zip\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </WebPreviewNavigation>\n </div>\n );\n}\n","import {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { motion } from 'motion/react';\nimport {\n ArrowLeftIcon,\n ArrowRightIcon,\n DownloadIcon,\n MaximizeIcon,\n MinimizeIcon,\n MonitorIcon,\n MoreVerticalIcon,\n RefreshCcwIcon,\n SmartphoneIcon,\n} from 'lucide-react';\nimport type {\n BuildResult,\n ConsoleEvent,\n ConsoleLevel,\n Diagnostic,\n RuntimeErrorEvent,\n Sandbox,\n} from '@browsernode/sandbox';\nimport {\n SandboxIFrame,\n type SandboxIFrameHandle,\n type SandboxIFrameProps,\n} from '@browsernode/react';\nimport {\n WebPreview,\n WebPreviewConsole,\n WebPreviewNavigation,\n WebPreviewNavigationButton,\n} from './primitives/web-preview';\nimport {\n StackTrace,\n StackTraceActions,\n StackTraceContent,\n StackTraceCopyButton,\n StackTraceError,\n StackTraceErrorMessage,\n StackTraceErrorType,\n StackTraceExpandButton,\n StackTraceFrames,\n StackTraceHeader,\n} from '../primitives/stack-trace';\nimport { Input } from '../primitives/ui/input';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../primitives/ui/dropdown-menu';\nimport { useSandbox } from '../provider/sandbox-provider';\n\nexport type SandboxPreviewHandle = SandboxIFrameHandle;\n\n// WebPreviewConsole only knows three levels; collapse our 5 onto its 3.\ntype AiLogLevel = 'log' | 'warn' | 'error';\nconst LEVEL_MAP: Record<ConsoleLevel, AiLogLevel> = {\n log: 'log',\n info: 'log',\n debug: 'log',\n warn: 'warn',\n error: 'error',\n};\n\ninterface AiLog {\n level: AiLogLevel;\n message: string;\n timestamp: Date;\n}\n\n// ---------------------------------------------------------------------------\n// Context — lets <SandboxPreviewToolbar> live outside the motion wrapper\n// (so it stays stable while the body slides) while still sharing iframe\n// state with <SandboxPreviewWeb>.\n// ---------------------------------------------------------------------------\n\ninterface SandboxPreviewContextValue {\n sandbox: Sandbox | null;\n iframeProps?: SandboxIFrameProps['iframeProps'];\n rest: Omit<SandboxIFrameProps, 'sandbox' | 'iframeProps' | 'onNavigate'>;\n onNavigate?: SandboxIFrameProps['onNavigate'];\n\n innerRef: React.MutableRefObject<SandboxIFrameHandle | null>;\n containerRef: React.RefObject<HTMLDivElement | null>;\n attachHandle: (node: SandboxIFrameHandle | null) => void;\n\n inputValue: string;\n setInputValue: (v: string) => void;\n currentUrl: string;\n history: string[];\n historyIndex: number;\n viewport: 'desktop' | 'mobile';\n setViewport: (v: 'desktop' | 'mobile') => void;\n spinCount: number;\n logs: AiLog[];\n\n showOverlay: boolean;\n overlayTrace: string;\n setRuntimeError: (e: RuntimeErrorEvent | null) => void;\n\n goBack: () => void;\n goForward: () => void;\n reload: () => void;\n /** True when the preview frame is taking over the viewport (CSS overlay,\n * not native fullscreen). */\n overlay: boolean;\n toggleOverlay: () => void;\n submitUrl: () => void;\n download: () => void;\n}\n\nconst SandboxPreviewCtx = createContext<SandboxPreviewContextValue | null>(null);\n\nexport function useSandboxPreviewCtx(): SandboxPreviewContextValue {\n const ctx = useContext(SandboxPreviewCtx);\n if (!ctx) {\n throw new Error(\n '<SandboxPreviewToolbar>/<SandboxPreviewWeb> must be rendered inside <SandboxPreviewProvider>',\n );\n }\n return ctx;\n}\n\nexport interface SandboxPreviewProviderProps\n extends Omit<SandboxIFrameProps, 'sandbox'> {\n sandbox?: Sandbox | null;\n /** Initial URL to display in the bar. Defaults to '/'. */\n defaultUrl?: string;\n children: ReactNode;\n}\n\nexport const SandboxPreviewProvider = forwardRef<\n SandboxPreviewHandle,\n SandboxPreviewProviderProps\n>(function SandboxPreviewProvider(\n {\n sandbox: sandboxProp,\n defaultUrl = '/',\n onNavigate,\n iframeProps,\n children,\n ...rest\n },\n ref,\n) {\n const { sandbox: ctxSandbox } = useSandbox();\n const sandbox = sandboxProp ?? ctxSandbox ?? null;\n\n const innerRef = useRef<SandboxIFrameHandle | null>(null);\n const attachHandle = useCallback((node: SandboxIFrameHandle | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }, [ref]);\n\n const [currentUrl, setCurrentUrl] = useState(defaultUrl);\n const [inputValue, setInputValue] = useState(defaultUrl);\n const [history, setHistory] = useState<string[]>([defaultUrl]);\n const [historyIndex, setHistoryIndex] = useState(0);\n const [events, setEvents] = useState<ConsoleEvent[]>(() =>\n sandbox ? [...sandbox.console.history()] : [],\n );\n const [buildError, setBuildError] = useState<Diagnostic[] | null>(null);\n const [sandboxError, setSandboxError] = useState<Error | null>(null);\n const [runtimeError, setRuntimeError] = useState<RuntimeErrorEvent | null>(null);\n const [viewport, setViewport] = useState<'desktop' | 'mobile'>('desktop');\n const containerRef = useRef<HTMLDivElement>(null);\n // When the host programmatically navigates (back/forward), the iframe\n // echoes the URL back through the navigate channel. We expect that echo\n // and skip the history-push so the index doesn't drift.\n const skipNextEcho = useRef<string | null>(null);\n\n useEffect(() => {\n if (!sandbox) return;\n setEvents([...sandbox.console.history()]);\n const unsubNav = sandbox.on('navigate', (url) => {\n setCurrentUrl(url);\n setInputValue(url);\n // New navigation = stale runtime error, clear it.\n setRuntimeError(null);\n // If this is the echo from a host-driven back/forward, the index has\n // already moved — don't re-push and don't re-increment.\n if (skipNextEcho.current === url) {\n skipNextEcho.current = null;\n return;\n }\n setHistory((prev) => {\n const truncated = prev.slice(0, historyIndex + 1);\n if (truncated[truncated.length - 1] === url) return truncated;\n return [...truncated, url];\n });\n setHistoryIndex((i) => i + 1);\n });\n const unsubLog = sandbox.on('console', (level, args) => {\n setEvents((prev) => [...prev, { level, args, ts: Date.now() }]);\n });\n const unsubBuild = sandbox.on('build', (result: BuildResult) => {\n setBuildError(result.ok ? null : result.errors);\n // A clean build clears stale sandbox-orchestration errors too.\n if (result.ok) setSandboxError(null);\n });\n const unsubErr = sandbox.on('error', (err) => setSandboxError(err));\n return () => {\n unsubNav();\n unsubLog();\n unsubBuild();\n unsubErr();\n };\n }, [sandbox, historyIndex]);\n\n const goBack = useCallback(() => {\n if (historyIndex <= 0) return;\n const target = history[historyIndex - 1]!;\n skipNextEcho.current = target;\n setHistoryIndex(historyIndex - 1);\n innerRef.current?.navigate(target);\n }, [history, historyIndex]);\n\n const goForward = useCallback(() => {\n if (historyIndex >= history.length - 1) return;\n const target = history[historyIndex + 1]!;\n skipNextEcho.current = target;\n setHistoryIndex(historyIndex + 1);\n innerRef.current?.navigate(target);\n }, [history, historyIndex]);\n\n // Click count drives the icon's CSS spin animation (key remounts the\n // icon to retrigger). Reload calls sandbox.rebuild() so file edits get\n // picked up — autoRebuild's listener swaps the iframe to the fresh blob.\n const [spinCount, setSpinCount] = useState(0);\n const reload = useCallback(() => {\n setSpinCount((n) => n + 1);\n if (sandbox) {\n sandbox.rebuild().catch(() => {\n /* errors flow through sandbox.on('error') */\n });\n } else {\n innerRef.current?.reload();\n }\n }, [sandbox]);\n\n // CSS-only \"fullscreen\" — takes over the viewport via fixed positioning\n // without invoking the system fullscreen API. Works inside iframes, on\n // iOS, and across browsers that restrict requestFullscreen().\n const [overlay, setOverlay] = useState(false);\n const toggleOverlay = useCallback(() => setOverlay((v) => !v), []);\n useEffect(() => {\n if (!overlay) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOverlay(false);\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [overlay]);\n\n const submitUrl = useCallback(() => {\n const target = inputValue.trim() || '/';\n innerRef.current?.navigate(target);\n }, [inputValue]);\n\n const download = useCallback(async () => {\n if (!sandbox) return;\n const blob = await sandbox.download();\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `${sandbox.sandboxId ?? 'sandbox'}.zip`;\n document.body.appendChild(a);\n a.click();\n a.remove();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }, [sandbox]);\n\n const logs = useMemo<AiLog[]>(\n () =>\n events.map((e) => ({\n level: LEVEL_MAP[e.level],\n message: formatArgs(e.args),\n timestamp: new Date(e.ts),\n })),\n [events],\n );\n\n // Unified error overlay. Build errors take priority (most actionable),\n // then runtime errors (visible in the iframe app), then sandbox errors\n // (orchestration). All three normalize to a V8/Node-style trace string\n // that the ai-elements <StackTrace> can parse.\n const overlayTrace = useMemo(() => {\n if (buildError && buildError.length > 0) {\n const head = buildError[0]!;\n const frames = buildError.map((d) => {\n const file = d.file ?? '<unknown>';\n const line = d.line ?? 0;\n const col = d.column ?? 0;\n return ` at build (${file}:${line}:${col})`;\n });\n return [`BuildError: ${head.message}`, ...frames].join('\\n');\n }\n if (runtimeError) {\n if (runtimeError.stack) return runtimeError.stack;\n const errType =\n runtimeError.source === 'unhandledrejection'\n ? 'UnhandledRejection'\n : 'RuntimeError';\n const frame = ` at <iframe> (${runtimeError.filename ?? '<unknown>'}:${runtimeError.lineno ?? 0}:${runtimeError.colno ?? 0})`;\n return `${errType}: ${runtimeError.message}\\n${frame}`;\n }\n if (sandboxError) {\n return (\n sandboxError.stack ?? `SandboxError: ${sandboxError.message}`\n );\n }\n return '';\n }, [buildError, runtimeError, sandboxError]);\n\n const showOverlay =\n Boolean(buildError && buildError.length > 0) ||\n Boolean(runtimeError) ||\n Boolean(sandboxError);\n\n useImperativeHandle(ref, () => ({\n rebuild: () => innerRef.current?.rebuild(),\n reload: () => innerRef.current?.reload(),\n navigate: (u: string) => innerRef.current?.navigate(u),\n send: (message: unknown) => innerRef.current?.send(message),\n }) as SandboxIFrameHandle, []);\n\n const value = useMemo<SandboxPreviewContextValue>(() => ({\n sandbox,\n iframeProps,\n rest,\n onNavigate,\n innerRef,\n containerRef,\n attachHandle,\n inputValue,\n setInputValue,\n currentUrl,\n history,\n historyIndex,\n viewport,\n setViewport,\n spinCount,\n logs,\n showOverlay,\n overlayTrace,\n setRuntimeError,\n goBack,\n goForward,\n reload,\n overlay,\n toggleOverlay,\n submitUrl,\n download,\n }), [\n sandbox, iframeProps, rest, onNavigate, attachHandle,\n inputValue, currentUrl, history, historyIndex, viewport,\n spinCount, logs, showOverlay, overlayTrace,\n goBack, goForward, reload, overlay, toggleOverlay, submitUrl, download,\n ]);\n\n return (\n <SandboxPreviewCtx.Provider value={value}>\n {children}\n </SandboxPreviewCtx.Provider>\n );\n});\n\n// ---------------------------------------------------------------------------\n// Toolbar — can be rendered standalone (e.g. inside <SandboxPreview>'s stable\n// header) by wrapping in <SandboxPreviewProvider>. `startContent` lets a\n// parent prepend extra controls (e.g. Web/IDE view tabs) to the left\n// of the back/forward buttons.\n// ---------------------------------------------------------------------------\n\nexport interface SandboxPreviewToolbarProps {\n startContent?: ReactNode;\n /** Rendered after the standard nav controls (right-aligned end of the bar). */\n endContent?: ReactNode;\n}\n\nexport function SandboxPreviewToolbar({\n startContent,\n endContent,\n}: SandboxPreviewToolbarProps) {\n const {\n inputValue,\n setInputValue,\n currentUrl,\n history,\n historyIndex,\n viewport,\n setViewport,\n spinCount,\n goBack,\n goForward,\n reload,\n overlay,\n toggleOverlay,\n submitUrl,\n download,\n } = useSandboxPreviewCtx();\n\n return (\n <WebPreviewNavigation>\n {startContent}\n <WebPreviewNavigationButton\n tooltip=\"Back\"\n disabled={historyIndex <= 0}\n onClick={goBack}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton\n tooltip=\"Forward\"\n disabled={historyIndex >= history.length - 1}\n onClick={goForward}\n >\n <ArrowRightIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton tooltip=\"Reload\" onClick={reload}>\n <RefreshCcwIcon\n key={spinCount}\n className=\"size-4 motion-safe:animate-[spin_0.6s_linear_reverse_1]\"\n />\n </WebPreviewNavigationButton>\n <Input\n className=\"h-8 flex-1 text-sm\"\n placeholder=\"Enter URL...\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n submitUrl();\n } else if (e.key === 'Escape') {\n setInputValue(currentUrl);\n (e.target as HTMLInputElement).blur();\n }\n }}\n />\n <WebPreviewNavigationButton\n tooltip={viewport === 'desktop' ? 'Mobile view' : 'Desktop view'}\n onClick={() =>\n setViewport(viewport === 'desktop' ? 'mobile' : 'desktop')\n }\n >\n {viewport === 'desktop' ? (\n <SmartphoneIcon className=\"size-4\" />\n ) : (\n <MonitorIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton\n tooltip={overlay ? 'Exit fullscreen' : 'Fullscreen'}\n onClick={toggleOverlay}\n >\n {overlay ? (\n <MinimizeIcon className=\"size-4\" />\n ) : (\n <MaximizeIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n {endContent}\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <WebPreviewNavigationButton tooltip=\"More\" />\n }\n >\n <MoreVerticalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-40\">\n <DropdownMenuItem onClick={download}>\n <DownloadIcon className=\"size-4\" />\n Download .zip\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </WebPreviewNavigation>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Body — iframe + viewport animation + error overlay. Safe to wrap in motion.\n// ---------------------------------------------------------------------------\n\nexport function SandboxPreviewWeb() {\n const {\n sandbox,\n iframeProps,\n rest,\n onNavigate,\n containerRef,\n attachHandle,\n viewport,\n showOverlay,\n overlayTrace,\n setRuntimeError,\n } = useSandboxPreviewCtx();\n\n return (\n <div ref={containerRef} className=\"flex-1 min-h-0 flex justify-center bg-muted/30 relative h-full\">\n <motion.div\n initial={false}\n animate={{ width: viewport === 'mobile' ? 390 : '100%' }}\n transition={{ type: 'spring', stiffness: 320, damping: 32, mass: 0.7 }}\n className=\"h-full\"\n >\n <SandboxIFrame\n ref={attachHandle}\n sandbox={sandbox}\n iframeProps={{\n style: {\n width: '100%',\n height: '100%',\n border: 0,\n ...iframeProps?.style,\n },\n ...iframeProps,\n }}\n onNavigate={onNavigate}\n onRuntimeError={setRuntimeError}\n {...rest}\n />\n </motion.div>\n {showOverlay && (\n <div className=\"absolute inset-0 overflow-auto bg-background p-3\">\n <StackTrace defaultOpen trace={overlayTrace}>\n <StackTraceHeader>\n <StackTraceError>\n <StackTraceErrorType />\n <StackTraceErrorMessage />\n </StackTraceError>\n <StackTraceActions>\n <StackTraceCopyButton />\n <StackTraceExpandButton />\n </StackTraceActions>\n </StackTraceHeader>\n <StackTraceContent>\n <StackTraceFrames />\n </StackTraceContent>\n </StackTrace>\n </div>\n )}\n </div>\n );\n}\n\nexport function SandboxPreviewConsole() {\n const { logs } = useSandboxPreviewCtx();\n return <WebPreviewConsole logs={logs} />;\n}\n\nfunction formatArgs(args: unknown[]): string {\n return args.map(formatOne).join(' ');\n}\n\nfunction formatOne(v: unknown): string {\n if (typeof v === 'string') return v;\n if (v === null) return 'null';\n if (v === undefined) return 'undefined';\n if (typeof v === 'function') return '[Function]';\n if (typeof v === 'object') {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n }\n return String(v);\n}\n","import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n outline:\n \"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n icon: \"size-8\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\"\n\nfunction Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {\n return (\n <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />\n )\n}\n\nfunction CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {\n return (\n <CollapsiblePrimitive.Panel data-slot=\"collapsible-content\" {...props} />\n )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n","import * as React from \"react\"\nimport { Input as InputPrimitive } from \"@base-ui/react/input\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","import { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction TooltipProvider({\n delay = 0,\n ...props\n}: TooltipPrimitive.Provider.Props) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delay={delay}\n {...props}\n />\n )\n}\n\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n side = \"top\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n children,\n ...props\n}: TooltipPrimitive.Popup.Props &\n Pick<\n TooltipPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n \"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","\"use client\";\n\nimport { Button } from \"../../primitives/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../primitives/ui/collapsible\";\nimport { Input } from \"../../primitives/ui/input\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../../primitives/ui/tooltip\";\nimport { cn } from \"../../primitives/lib/utils\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\nexport interface WebPreviewContextValue {\n url: string;\n setUrl: (url: string) => void;\n consoleOpen: boolean;\n setConsoleOpen: (open: boolean) => void;\n}\n\nexport const WebPreviewContext = createContext<WebPreviewContextValue | null>(null);\n\nconst useWebPreview = () => {\n const context = useContext(WebPreviewContext);\n if (!context) {\n throw new Error(\"WebPreview components must be used within a WebPreview\");\n }\n return context;\n};\n\nexport type WebPreviewProps = ComponentProps<\"div\"> & {\n defaultUrl?: string;\n onUrlChange?: (url: string) => void;\n};\n\nexport const WebPreview = ({\n className,\n children,\n defaultUrl = \"\",\n onUrlChange,\n ...props\n}: WebPreviewProps) => {\n const [url, setUrl] = useState(defaultUrl);\n const [consoleOpen, setConsoleOpen] = useState(false);\n\n const handleUrlChange = useCallback(\n (newUrl: string) => {\n setUrl(newUrl);\n onUrlChange?.(newUrl);\n },\n [onUrlChange]\n );\n\n const contextValue = useMemo<WebPreviewContextValue>(\n () => ({\n consoleOpen,\n setConsoleOpen,\n setUrl: handleUrlChange,\n url,\n }),\n [consoleOpen, handleUrlChange, url]\n );\n\n return (\n <WebPreviewContext.Provider value={contextValue}>\n <div\n className={cn(\n \"flex size-full flex-col rounded-lg border bg-card\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </WebPreviewContext.Provider>\n );\n};\n\nexport type WebPreviewNavigationProps = ComponentProps<\"div\">;\n\nexport const WebPreviewNavigation = ({\n className,\n children,\n ...props\n}: WebPreviewNavigationProps) => (\n <div\n className={cn(\"flex items-center gap-1 border-b p-2\", className)}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type WebPreviewNavigationButtonProps = ComponentProps<typeof Button> & {\n tooltip?: string;\n};\n\nexport const WebPreviewNavigationButton = ({\n onClick,\n disabled,\n tooltip,\n children,\n className,\n ...props\n}: WebPreviewNavigationButtonProps) => (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n className={cn(\"h-8 w-8 p-0 hover:text-foreground\", className)}\n disabled={disabled}\n onClick={onClick}\n size=\"sm\"\n variant=\"ghost\"\n {...props}\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent>\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n);\n\nexport type WebPreviewUrlProps = ComponentProps<typeof Input>;\n\nexport const WebPreviewUrl = ({\n value,\n onChange,\n onKeyDown,\n ...props\n}: WebPreviewUrlProps) => {\n const { url, setUrl } = useWebPreview();\n const [prevUrl, setPrevUrl] = useState(url);\n const [inputValue, setInputValue] = useState(url);\n\n // Sync input value with context URL when it changes externally (derived state pattern)\n if (url !== prevUrl) {\n setPrevUrl(url);\n setInputValue(url);\n }\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(event.target.value);\n onChange?.(event);\n };\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Enter\") {\n const target = event.target as HTMLInputElement;\n setUrl(target.value);\n }\n onKeyDown?.(event);\n },\n [setUrl, onKeyDown]\n );\n\n return (\n <Input\n className=\"h-8 flex-1 text-sm\"\n onChange={onChange ?? handleChange}\n onKeyDown={handleKeyDown}\n placeholder=\"Enter URL...\"\n value={value ?? inputValue}\n {...props}\n />\n );\n};\n\nexport type WebPreviewBodyProps = ComponentProps<\"iframe\"> & {\n loading?: ReactNode;\n};\n\nexport const WebPreviewBody = ({\n className,\n loading,\n src,\n ...props\n}: WebPreviewBodyProps) => {\n const { url } = useWebPreview();\n\n return (\n <div className=\"flex-1\">\n <iframe\n className={cn(\"size-full\", className)}\n // oxlint-disable-next-line eslint-plugin-react(iframe-missing-sandbox)\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-presentation\"\n src={(src ?? url) || undefined}\n title=\"Preview\"\n {...props}\n />\n {loading}\n </div>\n );\n};\n\nexport type WebPreviewConsoleProps = ComponentProps<\"div\"> & {\n logs?: {\n level: \"log\" | \"warn\" | \"error\";\n message: string;\n timestamp: Date;\n }[];\n};\n\nexport const WebPreviewConsole = ({\n className,\n logs = [],\n children,\n ...props\n}: WebPreviewConsoleProps) => {\n const { consoleOpen, setConsoleOpen } = useWebPreview();\n\n return (\n <Collapsible\n className={cn(\"border-t bg-muted/50 font-mono text-sm\", className)}\n onOpenChange={setConsoleOpen}\n open={consoleOpen}\n {...props}\n >\n <CollapsibleTrigger render={<Button className=\"flex w-full items-center justify-between p-4 text-left font-medium hover:bg-muted/50\" variant=\"ghost\" />}>Console\n <ChevronDownIcon\n className={cn(\n \"h-4 w-4 transition-transform duration-200\",\n consoleOpen && \"rotate-180\"\n )}\n /></CollapsibleTrigger>\n <CollapsibleContent\n className={cn(\n \"px-4 pb-4\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\"\n )}\n >\n <div className=\"max-h-48 space-y-1 overflow-y-auto\">\n {logs.length === 0 ? (\n <p className=\"text-muted-foreground\">No console output</p>\n ) : (\n logs.map((log) => (\n <div\n className={cn(\n \"text-xs\",\n log.level === \"error\" && \"text-destructive\",\n log.level === \"warn\" && \"text-yellow-600\",\n log.level === \"log\" && \"text-foreground\"\n )}\n key={`${log.timestamp.getTime()}-${log.level}-${log.message}`}\n >\n <span className=\"text-muted-foreground\">\n {log.timestamp.toLocaleTimeString()}\n </span>{\" \"}\n {log.message}\n </div>\n ))\n )}\n {children}\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n};\n","// @ts-nocheck — vendored ai-elements, noUncheckedIndexedAccess complaints\n\"use client\";\n\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { Button } from \"./ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"./ui/collapsible\";\nimport { cn } from \"./lib/utils\";\nimport {\n AlertTriangleIcon,\n CheckIcon,\n ChevronDownIcon,\n CopyIcon,\n} from \"lucide-react\";\nimport type { ComponentProps } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\n// Regex patterns for parsing stack traces\nconst STACK_FRAME_WITH_PARENS_REGEX = /^at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/;\nconst STACK_FRAME_WITHOUT_FN_REGEX = /^at\\s+(.+):(\\d+):(\\d+)$/;\nconst ERROR_TYPE_REGEX = /^(\\w+Error|Error):\\s*(.*)$/;\nconst AT_PREFIX_REGEX = /^at\\s+/;\n\ninterface StackFrame {\n raw: string;\n functionName: string | null;\n filePath: string | null;\n lineNumber: number | null;\n columnNumber: number | null;\n isInternal: boolean;\n}\n\ninterface ParsedStackTrace {\n errorType: string | null;\n errorMessage: string;\n frames: StackFrame[];\n raw: string;\n}\n\ninterface StackTraceContextValue {\n trace: ParsedStackTrace;\n raw: string;\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n onFilePathClick?: (filePath: string, line?: number, column?: number) => void;\n}\n\nconst StackTraceContext = createContext<StackTraceContextValue | null>(null);\n\nconst useStackTrace = () => {\n const context = useContext(StackTraceContext);\n if (!context) {\n throw new Error(\"StackTrace components must be used within StackTrace\");\n }\n return context;\n};\n\nconst parseStackFrame = (line: string): StackFrame => {\n const trimmed = line.trim();\n\n // Pattern: at functionName (filePath:line:column)\n const withParensMatch = trimmed.match(STACK_FRAME_WITH_PARENS_REGEX);\n if (withParensMatch) {\n const [, functionName, filePath, lineNum, colNum] = withParensMatch;\n const isInternal =\n filePath.includes(\"node_modules\") ||\n filePath.startsWith(\"node:\") ||\n filePath.includes(\"internal/\");\n return {\n columnNumber: colNum ? Number.parseInt(colNum, 10) : null,\n filePath: filePath ?? null,\n functionName: functionName ?? null,\n isInternal,\n lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,\n raw: trimmed,\n };\n }\n\n // Pattern: at filePath:line:column (no function name)\n const withoutFnMatch = trimmed.match(STACK_FRAME_WITHOUT_FN_REGEX);\n if (withoutFnMatch) {\n const [, filePath, lineNum, colNum] = withoutFnMatch;\n const isInternal =\n (filePath?.includes(\"node_modules\") ?? false) ||\n (filePath?.startsWith(\"node:\") ?? false) ||\n (filePath?.includes(\"internal/\") ?? false);\n return {\n columnNumber: colNum ? Number.parseInt(colNum, 10) : null,\n filePath: filePath ?? null,\n functionName: null,\n isInternal,\n lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,\n raw: trimmed,\n };\n }\n\n // Fallback: unparseable line\n return {\n columnNumber: null,\n filePath: null,\n functionName: null,\n isInternal: trimmed.includes(\"node_modules\") || trimmed.includes(\"node:\"),\n lineNumber: null,\n raw: trimmed,\n };\n};\n\nconst parseStackTrace = (trace: string): ParsedStackTrace => {\n const lines = trace.split(\"\\n\").filter((line) => line.trim());\n\n if (lines.length === 0) {\n return {\n errorMessage: trace,\n errorType: null,\n frames: [],\n raw: trace,\n };\n }\n\n const firstLine = lines[0].trim();\n let errorType: string | null = null;\n let errorMessage = firstLine;\n\n // Try to extract error type from \"ErrorType: message\" format\n const errorMatch = firstLine.match(ERROR_TYPE_REGEX);\n if (errorMatch) {\n const [, type, msg] = errorMatch;\n errorType = type;\n errorMessage = msg || \"\";\n }\n\n // Parse stack frames (lines starting with \"at\")\n const frames = lines\n .slice(1)\n .filter((line) => line.trim().startsWith(\"at \"))\n .map(parseStackFrame);\n\n return {\n errorMessage,\n errorType,\n frames,\n raw: trace,\n };\n};\n\nexport type StackTraceProps = ComponentProps<\"div\"> & {\n trace: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n onFilePathClick?: (filePath: string, line?: number, column?: number) => void;\n};\n\nexport const StackTrace = memo(\n ({\n trace,\n className,\n open,\n defaultOpen = false,\n onOpenChange,\n onFilePathClick,\n children,\n ...props\n }: StackTraceProps) => {\n const [isOpen, setIsOpen] = useControllableState({\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n\n const parsedTrace = useMemo(() => parseStackTrace(trace), [trace]);\n\n const contextValue = useMemo(\n () => ({\n isOpen,\n onFilePathClick,\n raw: trace,\n setIsOpen,\n trace: parsedTrace,\n }),\n [parsedTrace, trace, isOpen, setIsOpen, onFilePathClick]\n );\n\n return (\n <StackTraceContext.Provider value={contextValue}>\n <div\n className={cn(\n \"not-prose w-full overflow-hidden rounded-lg border bg-background font-mono text-sm\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </StackTraceContext.Provider>\n );\n }\n);\n\nexport type StackTraceHeaderProps = ComponentProps<typeof CollapsibleTrigger>;\n\nexport const StackTraceHeader = memo(\n ({ className, children, ...props }: StackTraceHeaderProps) => {\n const { isOpen, setIsOpen } = useStackTrace();\n\n return (\n <Collapsible onOpenChange={setIsOpen} open={isOpen}>\n <CollapsibleTrigger {...props} render={<div className={cn(\n \"flex w-full cursor-pointer items-center gap-3 p-3 text-left transition-colors hover:bg-muted/50\",\n className\n )} />}>{children}</CollapsibleTrigger>\n </Collapsible>\n );\n }\n);\n\nexport type StackTraceErrorProps = ComponentProps<\"div\">;\n\nexport const StackTraceError = memo(\n ({ className, children, ...props }: StackTraceErrorProps) => (\n <div\n className={cn(\n \"flex flex-1 items-center gap-2 overflow-hidden\",\n className\n )}\n {...props}\n >\n <AlertTriangleIcon className=\"size-4 shrink-0 text-destructive\" />\n {children}\n </div>\n )\n);\n\nexport type StackTraceErrorTypeProps = ComponentProps<\"span\">;\n\nexport const StackTraceErrorType = memo(\n ({ className, children, ...props }: StackTraceErrorTypeProps) => {\n const { trace } = useStackTrace();\n\n return (\n <span\n className={cn(\"shrink-0 font-semibold text-destructive\", className)}\n {...props}\n >\n {children ?? trace.errorType}\n </span>\n );\n }\n);\n\nexport type StackTraceErrorMessageProps = ComponentProps<\"span\">;\n\nexport const StackTraceErrorMessage = memo(\n ({ className, children, ...props }: StackTraceErrorMessageProps) => {\n const { trace } = useStackTrace();\n\n return (\n <span className={cn(\"truncate text-foreground\", className)} {...props}>\n {children ?? trace.errorMessage}\n </span>\n );\n }\n);\n\nexport type StackTraceActionsProps = ComponentProps<\"div\">;\n\nconst handleActionsClick = (e: React.MouseEvent) => e.stopPropagation();\nconst handleActionsKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.stopPropagation();\n }\n};\n\nexport const StackTraceActions = memo(\n ({ className, children, ...props }: StackTraceActionsProps) => (\n <div\n className={cn(\"flex shrink-0 items-center gap-1\", className)}\n onClick={handleActionsClick}\n onKeyDown={handleActionsKeyDown}\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n )\n);\n\nexport type StackTraceCopyButtonProps = ComponentProps<typeof Button> & {\n onCopy?: () => void;\n onError?: (error: Error) => void;\n timeout?: number;\n};\n\nexport const StackTraceCopyButton = memo(\n ({\n onCopy,\n onError,\n timeout = 2000,\n className,\n children,\n ...props\n }: StackTraceCopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number>(0);\n const { raw } = useStackTrace();\n\n const copyToClipboard = useCallback(async () => {\n if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n onError?.(new Error(\"Clipboard API not available\"));\n return;\n }\n\n try {\n await navigator.clipboard.writeText(raw);\n setIsCopied(true);\n onCopy?.();\n timeoutRef.current = window.setTimeout(\n () => setIsCopied(false),\n timeout\n );\n } catch (error) {\n onError?.(error as Error);\n }\n }, [raw, onCopy, onError, timeout]);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current);\n },\n []\n );\n\n const Icon = isCopied ? CheckIcon : CopyIcon;\n\n return (\n <Button\n className={cn(\"size-7\", className)}\n onClick={copyToClipboard}\n size=\"icon\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <Icon size={14} />}\n </Button>\n );\n }\n);\n\nexport type StackTraceExpandButtonProps = ComponentProps<\"div\">;\n\nexport const StackTraceExpandButton = memo(\n ({ className, ...props }: StackTraceExpandButtonProps) => {\n const { isOpen } = useStackTrace();\n\n return (\n <div\n className={cn(\"flex size-7 items-center justify-center\", className)}\n {...props}\n >\n <ChevronDownIcon\n className={cn(\n \"size-4 text-muted-foreground transition-transform\",\n isOpen ? \"rotate-180\" : \"rotate-0\"\n )}\n />\n </div>\n );\n }\n);\n\nexport type StackTraceContentProps = ComponentProps<\n typeof CollapsibleContent\n> & {\n maxHeight?: number;\n};\n\nexport const StackTraceContent = memo(\n ({\n className,\n maxHeight = 400,\n children,\n ...props\n }: StackTraceContentProps) => {\n const { isOpen } = useStackTrace();\n\n return (\n <Collapsible open={isOpen}>\n <CollapsibleContent\n className={cn(\n \"overflow-auto border-t bg-muted/30\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n style={{ maxHeight }}\n {...props}\n >\n {children}\n </CollapsibleContent>\n </Collapsible>\n );\n }\n);\n\nexport type StackTraceFramesProps = ComponentProps<\"div\"> & {\n showInternalFrames?: boolean;\n};\n\ninterface FilePathButtonProps {\n frame: StackFrame;\n onFilePathClick?: (\n filePath: string,\n lineNumber?: number,\n columnNumber?: number\n ) => void;\n}\n\nconst FilePathButton = memo(\n ({ frame, onFilePathClick }: FilePathButtonProps) => {\n const handleClick = useCallback(() => {\n if (frame.filePath) {\n onFilePathClick?.(\n frame.filePath,\n frame.lineNumber ?? undefined,\n frame.columnNumber ?? undefined\n );\n }\n }, [frame, onFilePathClick]);\n\n return (\n <button\n className={cn(\n \"underline decoration-dotted hover:text-primary\",\n onFilePathClick && \"cursor-pointer\"\n )}\n disabled={!onFilePathClick}\n onClick={handleClick}\n type=\"button\"\n >\n {frame.filePath}\n {frame.lineNumber !== null && `:${frame.lineNumber}`}\n {frame.columnNumber !== null && `:${frame.columnNumber}`}\n </button>\n );\n }\n);\n\nFilePathButton.displayName = \"FilePathButton\";\n\nexport const StackTraceFrames = memo(\n ({\n className,\n showInternalFrames = true,\n ...props\n }: StackTraceFramesProps) => {\n const { trace, onFilePathClick } = useStackTrace();\n\n const framesToShow = showInternalFrames\n ? trace.frames\n : trace.frames.filter((f) => !f.isInternal);\n\n return (\n <div className={cn(\"space-y-1 p-3\", className)} {...props}>\n {framesToShow.map((frame) => (\n <div\n className={cn(\n \"text-xs\",\n frame.isInternal\n ? \"text-muted-foreground/50\"\n : \"text-foreground/90\"\n )}\n key={frame.raw}\n >\n <span className=\"text-muted-foreground\">at </span>\n {frame.functionName && (\n <span className={frame.isInternal ? \"\" : \"text-foreground\"}>\n {frame.functionName}{\" \"}\n </span>\n )}\n {frame.filePath && (\n <>\n <span className=\"text-muted-foreground\">(</span>\n <FilePathButton\n frame={frame}\n onFilePathClick={onFilePathClick}\n />\n <span className=\"text-muted-foreground\">)</span>\n </>\n )}\n {!(frame.filePath || frame.functionName) && (\n <span>{frame.raw.replace(AT_PREFIX_REGEX, \"\")}</span>\n )}\n </div>\n ))}\n {framesToShow.length === 0 && (\n <div className=\"text-muted-foreground text-xs\">No stack frames</div>\n )}\n </div>\n );\n }\n);\n\nStackTrace.displayName = \"StackTrace\";\nStackTraceHeader.displayName = \"StackTraceHeader\";\nStackTraceError.displayName = \"StackTraceError\";\nStackTraceErrorType.displayName = \"StackTraceErrorType\";\nStackTraceErrorMessage.displayName = \"StackTraceErrorMessage\";\nStackTraceActions.displayName = \"StackTraceActions\";\nStackTraceCopyButton.displayName = \"StackTraceCopyButton\";\nStackTraceExpandButton.displayName = \"StackTraceExpandButton\";\nStackTraceContent.displayName = \"StackTraceContent\";\nStackTraceFrames.displayName = \"StackTraceFrames\";\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\n\nimport { cn } from \"../lib/utils\"\nimport { ChevronRightIcon, CheckIcon } from \"lucide-react\"\n\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\n return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />\n}\n\nfunction DropdownMenuContent({\n align = \"start\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 4,\n className,\n ...props\n}: MenuPrimitive.Popup.Props &\n Pick<\n MenuPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <MenuPrimitive.Portal>\n <MenuPrimitive.Positioner\n className=\"isolate z-50 outline-none\"\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n >\n <MenuPrimitive.Popup\n data-slot=\"dropdown-menu-content\"\n className={cn(\"z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n {...props}\n />\n </MenuPrimitive.Positioner>\n </MenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\n return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: MenuPrimitive.GroupLabel.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.GroupLabel\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: MenuPrimitive.Item.Props & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <MenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.SubmenuTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </MenuPrimitive.SubmenuTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n align = \"start\",\n alignOffset = -3,\n side = \"right\",\n sideOffset = 0,\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) {\n return (\n <DropdownMenuContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\"w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-checkbox-item-indicator\"\n >\n <MenuPrimitive.CheckboxItemIndicator>\n <CheckIcon\n />\n </MenuPrimitive.CheckboxItemIndicator>\n </span>\n {children}\n </MenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n return (\n <MenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n inset,\n ...props\n}: MenuPrimitive.RadioItem.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-radio-item-indicator\"\n >\n <MenuPrimitive.RadioItemIndicator>\n <CheckIcon\n />\n </MenuPrimitive.RadioItemIndicator>\n </span>\n {children}\n </MenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: MenuPrimitive.Separator.Props) {\n return (\n <MenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","// `<SandboxFileTree>` — file tree only. Reads `selectedPath` /\n// `setSelectedPath` from `useElementsContext`. Subscribes to\n// `sandbox.fs` change events so the tree mirrors mutations.\n//\n// `display=\"dropdown\"` collapses the tree behind a folder-icon\n// `<Popover>` trigger — useful for mobile / narrow side panels.\n\nimport { useEffect, useMemo, useState, type ReactNode } from 'react';\nimport { MenuIcon } from 'lucide-react';\nimport type { Sandbox } from '@browsernode/sandbox';\nimport { FileTree } from './primitives/file-tree';\nimport { useElementsContext, useSandbox } from '../provider/sandbox-provider';\nimport { Button } from '../primitives/ui/button';\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../primitives/ui/popover';\nimport {\n buildTree,\n defaultExpansion,\n isFile,\n renderTree,\n} from './internal/tree';\n\nexport interface SandboxFileTreeProps {\n /** Override the sandbox from the surrounding `<SandboxProvider>`. */\n sandbox?: Sandbox | null;\n /** Initial folders to expand. Defaults to common roots when present. */\n defaultExpanded?: Set<string>;\n /**\n * Called when a file is selected. Fires *in addition* to updating the\n * elements context's `selectedPath`.\n */\n onSelect?: (path: string) => void;\n /**\n * Render mode:\n * • `\"tree\"` (default) — full inline tree, expects a parent that\n * gives it height to scroll within\n * • `\"dropdown\"` — folder-icon button that opens a popover with the\n * tree inside; selecting a file closes the popover\n */\n display?: 'tree' | 'dropdown';\n /**\n * Trigger contents (dropdown variant). Defaults to a hamburger icon\n * + \"Select file\" label.\n */\n triggerLabel?: ReactNode;\n className?: string;\n}\n\nexport function SandboxFileTree({\n sandbox: sandboxProp,\n defaultExpanded,\n onSelect,\n display = 'tree',\n triggerLabel,\n className,\n}: SandboxFileTreeProps) {\n const elementsCtx = useElementsContext();\n const sandboxState = useSandbox();\n const sandbox = sandboxProp ?? sandboxState.sandbox;\n\n const [files, setFiles] = useState<string[]>(() =>\n sandbox ? sandbox.fs.list() : [],\n );\n const [open, setOpen] = useState(false);\n\n const selectedPath = elementsCtx?.selectedPath ?? null;\n const setSelectedPath = elementsCtx?.setSelectedPath;\n\n useEffect(() => {\n if (!sandbox) return;\n setFiles(sandbox.fs.list());\n return sandbox.fs.on('change', () => setFiles(sandbox.fs.list()));\n }, [sandbox]);\n\n const tree = useMemo(() => buildTree(files), [files]);\n\n const handleSelect = (path: string) => {\n if (!isFile(path, files)) return;\n setSelectedPath?.(path);\n onSelect?.(path);\n if (display === 'dropdown') setOpen(false);\n };\n\n const treeNode = (\n <FileTree\n defaultExpanded={defaultExpanded ?? defaultExpansion(files)}\n onSelect={handleSelect}\n selectedPath={selectedPath ?? undefined}\n className={`h-full w-full overflow-auto rounded-none border-0 bg-transparent ${className ?? ''}`.trim()}\n >\n {renderTree(tree)}\n </FileTree>\n );\n\n if (display === 'dropdown') {\n // Default trigger contents adapt to selection state: with no file\n // selected, the button reads \"[☰] Select a file\" so the empty\n // state has a single self-explanatory affordance. Once a file is\n // selected, the button collapses to the icon only — the surrounding\n // header (or whatever the consumer composes) is responsible for\n // showing the filename next to it.\n const defaultLabel = selectedPath ? (\n <MenuIcon className=\"size-4\" />\n ) : (\n <>\n <MenuIcon className=\"size-4\" />\n <span>Select a file</span>\n </>\n );\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n render={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"Select file\"\n className={`h-8 gap-2 px-2 text-xs font-normal ${className ?? ''}`.trim()}\n />\n }\n >\n {triggerLabel ?? defaultLabel}\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"w-72 p-0 max-h-[26rem] flex flex-col overflow-hidden\"\n >\n {treeNode}\n </PopoverContent>\n </Popover>\n );\n }\n\n return treeNode;\n}\n","\"use client\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../primitives/ui/collapsible\";\nimport { cn } from \"../../primitives/lib/utils\";\nimport {\n ChevronRightIcon,\n FileIcon,\n FolderIcon,\n FolderOpenIcon,\n} from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\ninterface FileTreeContextType {\n expandedPaths: Set<string>;\n togglePath: (path: string) => void;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {};\n\nconst FileTreeContext = createContext<FileTreeContextType>({\n // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)\n expandedPaths: new Set(),\n togglePath: noop,\n});\n\nexport type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> & {\n expanded?: Set<string>;\n defaultExpanded?: Set<string>;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n onExpandedChange?: (expanded: Set<string>) => void;\n};\n\nexport const FileTree = ({\n expanded: controlledExpanded,\n defaultExpanded = new Set(),\n selectedPath,\n onSelect,\n onExpandedChange,\n className,\n children,\n ...props\n}: FileTreeProps) => {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const expandedPaths = controlledExpanded ?? internalExpanded;\n\n const togglePath = useCallback(\n (path: string) => {\n const newExpanded = new Set(expandedPaths);\n if (newExpanded.has(path)) {\n newExpanded.delete(path);\n } else {\n newExpanded.add(path);\n }\n setInternalExpanded(newExpanded);\n onExpandedChange?.(newExpanded);\n },\n [expandedPaths, onExpandedChange]\n );\n\n const contextValue = useMemo(\n () => ({ expandedPaths, onSelect, selectedPath, togglePath }),\n [expandedPaths, onSelect, selectedPath, togglePath]\n );\n\n return (\n <FileTreeContext.Provider value={contextValue}>\n <div\n className={cn(\n \"rounded-lg border bg-background font-mono text-sm\",\n className\n )}\n role=\"tree\"\n {...props}\n >\n <div className=\"p-2\">{children}</div>\n </div>\n </FileTreeContext.Provider>\n );\n};\n\nexport type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeIcon = ({\n className,\n children,\n ...props\n}: FileTreeIconProps) => (\n <span className={cn(\"shrink-0\", className)} {...props}>\n {children}\n </span>\n);\n\nexport type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeName = ({\n className,\n children,\n ...props\n}: FileTreeNameProps) => (\n <span className={cn(\"truncate\", className)} {...props}>\n {children}\n </span>\n);\n\ninterface FileTreeFolderContextType {\n path: string;\n name: string;\n isExpanded: boolean;\n}\n\nconst FileTreeFolderContext = createContext<FileTreeFolderContextType>({\n isExpanded: false,\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n};\n\nexport const FileTreeFolder = ({\n path,\n name,\n className,\n children,\n ...props\n}: FileTreeFolderProps) => {\n const { expandedPaths, togglePath, selectedPath, onSelect } =\n useContext(FileTreeContext);\n const isExpanded = expandedPaths.has(path);\n const isSelected = selectedPath === path;\n\n const handleOpenChange = useCallback(() => {\n togglePath(path);\n }, [togglePath, path]);\n\n const handleSelect = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const folderContextValue = useMemo(\n () => ({ isExpanded, name, path }),\n [isExpanded, name, path]\n );\n\n return (\n <FileTreeFolderContext.Provider value={folderContextValue}>\n <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>\n <div\n className={cn(\"\", className)}\n role=\"treeitem\"\n tabIndex={0}\n {...props}\n >\n <div\n className={cn(\n \"flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\"\n )}\n >\n <CollapsibleTrigger render={<button className=\"flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0\" type=\"button\" />}><ChevronRightIcon\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform\",\n isExpanded && \"rotate-90\"\n )}\n /></CollapsibleTrigger>\n <button\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n onClick={() => {\n handleSelect();\n togglePath(path);\n }}\n type=\"button\"\n >\n <FileTreeIcon>\n {isExpanded ? (\n <FolderOpenIcon className=\"size-4 text-blue-500\" />\n ) : (\n <FolderIcon className=\"size-4 text-blue-500\" />\n )}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ml-4 border-l pl-2\">{children}</div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n </FileTreeFolderContext.Provider>\n );\n};\n\ninterface FileTreeFileContextType {\n path: string;\n name: string;\n}\n\nconst FileTreeFileContext = createContext<FileTreeFileContextType>({\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFileProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n icon?: ReactNode;\n};\n\nexport const FileTreeFile = ({\n path,\n name,\n icon,\n className,\n children,\n ...props\n}: FileTreeFileProps) => {\n const { selectedPath, onSelect } = useContext(FileTreeContext);\n const isSelected = selectedPath === path;\n\n const handleClick = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n onSelect?.(path);\n }\n },\n [onSelect, path]\n );\n\n const fileContextValue = useMemo(() => ({ name, path }), [name, path]);\n\n return (\n <FileTreeFileContext.Provider value={fileContextValue}>\n <div\n className={cn(\n \"flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\",\n className\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role=\"treeitem\"\n tabIndex={0}\n {...props}\n >\n {children ?? (\n <>\n {/* Spacer for alignment */}\n <span className=\"size-4 shrink-0\" />\n <FileTreeIcon>\n {icon ?? <FileIcon className=\"size-4 text-muted-foreground\" />}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </>\n )}\n </div>\n </FileTreeFileContext.Provider>\n );\n};\n\nexport type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>;\n\nconst stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();\n\nexport const FileTreeActions = ({\n className,\n children,\n ...props\n}: FileTreeActionsProps) => (\n <div\n className={cn(\"ml-auto flex items-center gap-1\", className)}\n onClick={stopPropagation}\n onKeyDown={stopPropagation}\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n);\n","import * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 4,\n ...props\n}: PopoverPrimitive.Popup.Props &\n Pick<\n PopoverPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <PopoverPrimitive.Popup\n data-slot=\"popover-content\"\n className={cn(\n \"z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"popover-header\"\n className={cn(\"flex flex-col gap-0.5 text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\n return (\n <PopoverPrimitive.Title\n data-slot=\"popover-title\"\n className={cn(\"font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction PopoverDescription({\n className,\n ...props\n}: PopoverPrimitive.Description.Props) {\n return (\n <PopoverPrimitive.Description\n data-slot=\"popover-description\"\n className={cn(\"text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n}\n","// Shared tree builders for SandboxIDEFiles. Consumes a flat list of\n// absolute paths from `sandbox.fs.list()` and produces nodes the\n// FileTree primitive renders.\n\nimport type { ReactNode } from 'react';\nimport { FileTreeFile, FileTreeFolder } from '../primitives/file-tree';\n\ninterface TreeNode {\n name: string;\n path: string;\n /** null = file leaf. */\n children: Map<string, TreeNode> | null;\n}\n\nexport function buildTree(paths: string[]): TreeNode {\n const root: TreeNode = { name: '', path: '', children: new Map() };\n for (const path of paths) {\n const parts = path.split('/').filter(Boolean);\n let cur = root;\n for (let i = 0; i < parts.length; i++) {\n const name = parts[i]!;\n const isLeaf = i === parts.length - 1;\n // Tree paths are absolute (`/src/app/page.tsx`) so they match\n // `sandbox.fs.list()` output and `selectedPath` flows through\n // `fs.readFile` consistently.\n const childPath = '/' + parts.slice(0, i + 1).join('/');\n if (!cur.children) break;\n let child = cur.children.get(name);\n if (!child) {\n child = { name, path: childPath, children: isLeaf ? null : new Map() };\n cur.children.set(name, child);\n }\n if (!isLeaf && child.children) cur = child;\n else if (!isLeaf && !child.children) break; // path collision\n }\n }\n return root;\n}\n\nexport function renderTree(node: TreeNode): ReactNode {\n if (!node.children) return null;\n // Folders first, then files; alphabetical within each group.\n const entries = Array.from(node.children.values()).sort((a, b) => {\n const aFolder = a.children !== null;\n const bFolder = b.children !== null;\n if (aFolder !== bFolder) return aFolder ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n return entries.map((entry) =>\n entry.children ? (\n <FileTreeFolder key={entry.path} name={entry.name} path={entry.path}>\n {renderTree(entry)}\n </FileTreeFolder>\n ) : (\n <FileTreeFile key={entry.path} name={entry.name} path={entry.path} />\n ),\n );\n}\n\nexport function isFile(path: string, files: string[]): boolean {\n return files.includes(path);\n}\n\nexport function defaultExpansion(files: string[]): Set<string> {\n const roots = ['src', 'app', 'pages', 'components'];\n const expanded = new Set<string>();\n for (const root of roots) {\n const abs = '/' + root;\n if (files.some((f) => f === abs || f.startsWith(`${abs}/`))) {\n expanded.add(abs);\n }\n }\n return expanded;\n}\n","// `<SandboxCodeEditor>` — header chrome (filename + Save + More dropdown)\n// + a buffered CodeMirror editor. Reads `selectedPath` from elements\n// context; loads file contents on selection change; persists via\n// `sandbox.fs.writeFile` on Save (button or Cmd/Ctrl+S).\n//\n// CodeMirror knobs (theme, basicSetup, extensions, language) are passed\n// straight through to the underlying `<CodeEditor>` so callers can tune\n// the editor without dropping down a level.\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { MoreHorizontalIcon } from 'lucide-react';\nimport type { Extension } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport type { ReactCodeMirrorProps } from '@uiw/react-codemirror';\nimport type { Sandbox } from '@browsernode/sandbox';\nimport {\n CodeEditor,\n type CodeEditorLanguage,\n type CodeEditorTheme,\n} from './primitives/code-editor';\nimport { Button } from '../primitives/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../primitives/ui/dropdown-menu';\nimport { Loader } from '../primitives/ui/loading';\nimport { useElementsContext, useSandbox } from '../provider/sandbox-provider';\nimport { guessLanguage } from './internal/language';\n\nexport interface SandboxCodeEditorProps {\n /** Override the sandbox from the surrounding `<SandboxProvider>`. */\n sandbox?: Sandbox | null;\n /** Disable saves (Save button hidden, Cmd-S no-op). Default false. */\n readOnly?: boolean;\n /** CodeMirror theme override (forwarded to `<CodeEditor>`). */\n theme?: CodeEditorTheme;\n /** CodeMirror basic-setup overrides (line numbers, fold gutter, etc.). */\n basicSetup?: ReactCodeMirrorProps['basicSetup'];\n /** Extra CodeMirror extensions appended after the language ones. */\n extensions?: Extension[];\n /** Force a CodeMirror language regardless of file extension. */\n language?: CodeEditorLanguage;\n /** Hide the file header (filename + dirty dot + Save + More). */\n hideHeader?: boolean;\n /** Custom empty state when no file is selected. */\n emptyState?: ReactNode;\n /**\n * Slot rendered inside the header, immediately after the filename and\n * before the Save button. Used by `<SandboxIDELayout>` to inject the\n * mobile dropdown trigger; consumers can use it for any leading chrome.\n */\n headerStartSlot?: ReactNode;\n className?: string;\n}\n\ntype SaveStatus = 'idle' | 'saving' | 'saved' | 'error';\n\nexport function SandboxCodeEditor({\n sandbox: sandboxProp,\n readOnly = false,\n theme,\n basicSetup,\n extensions,\n language: languageProp,\n hideHeader = false,\n emptyState,\n headerStartSlot,\n className,\n}: SandboxCodeEditorProps) {\n const elementsCtx = useElementsContext();\n const sandboxState = useSandbox();\n const sandbox = sandboxProp ?? sandboxState.sandbox;\n\n const selectedPath = elementsCtx?.selectedPath ?? null;\n const setSelectedPath = elementsCtx?.setSelectedPath;\n\n const [savedText, setSavedText] = useState<string | null>(null);\n const [buffer, setBuffer] = useState<string>('');\n const [loadingPath, setLoadingPath] = useState<string | null>(null);\n const [saveStatus, setSaveStatus] = useState<SaveStatus>('idle');\n\n // Path the editor's current `buffer` was loaded from. Used to ignore\n // stale onChange callbacks during file-switch (CodeMirror's controlled\n // value briefly lags one frame).\n const loadedPathRef = useRef<string | null>(null);\n const savedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Refs for stable callbacks (Cmd-S keymap, delete handler).\n const sandboxRef = useRef(sandbox);\n const selectedPathRef = useRef(selectedPath);\n const bufferRef = useRef(buffer);\n const dirtyRef = useRef(false);\n sandboxRef.current = sandbox;\n selectedPathRef.current = selectedPath;\n bufferRef.current = buffer;\n\n useEffect(() => {\n if (!sandbox || !selectedPath) {\n setSavedText(null);\n setBuffer('');\n loadedPathRef.current = null;\n return;\n }\n setLoadingPath(selectedPath);\n setSaveStatus('idle');\n let cancelled = false;\n sandbox.fs\n .readFile(selectedPath)\n .then((c) => {\n if (cancelled) return;\n setSavedText(c);\n setBuffer(c);\n loadedPathRef.current = selectedPath;\n setLoadingPath(null);\n })\n .catch(() => {\n if (cancelled) return;\n const fallback = `// Could not read ${selectedPath}`;\n setSavedText(fallback);\n setBuffer(fallback);\n loadedPathRef.current = null;\n setLoadingPath(null);\n });\n return () => {\n cancelled = true;\n };\n }, [sandbox, selectedPath]);\n\n useEffect(() => {\n return () => {\n if (savedTimerRef.current) {\n clearTimeout(savedTimerRef.current);\n savedTimerRef.current = null;\n }\n };\n }, [selectedPath]);\n\n const handleEditorChange = useCallback(\n (next: string) => {\n setBuffer(next);\n if (readOnly) return;\n if (!selectedPath) return;\n // Drop changes fired before the load has settled on this path.\n if (loadedPathRef.current !== selectedPath) return;\n },\n [readOnly, selectedPath],\n );\n\n const dirty = !readOnly && savedText !== null && buffer !== savedText;\n dirtyRef.current = dirty;\n\n const deleteFile = useCallback(async () => {\n if (readOnly) return;\n const sb = sandboxRef.current;\n const path = selectedPathRef.current;\n if (!sb || !path) return;\n try {\n await sb.fs.rm(path);\n setSelectedPath?.(null);\n } catch {\n // Surfaces via sandbox.on('error') if anyone's listening.\n }\n }, [readOnly, setSelectedPath]);\n\n const save = useCallback(async () => {\n if (readOnly) return;\n const sb = sandboxRef.current;\n const path = selectedPathRef.current;\n const text = bufferRef.current;\n if (!sb || !path) return;\n if (!dirtyRef.current) return;\n // The in-memory write resolves the same microtask, so React would\n // batch this with the 'saved' set below and never paint the spinner.\n // The minimum-duration delay below holds the spinner visible long\n // enough to register visually.\n setSaveStatus('saving');\n try {\n await sb.fs.writeFile(path, text);\n await new Promise((r) => setTimeout(r, 500));\n setSavedText(text);\n setSaveStatus('idle');\n } catch {\n setSaveStatus('error');\n }\n }, [readOnly]);\n\n // Cmd/Ctrl+S keybinding. Stable extension array so we don't rebuild\n // CodeMirror on every keystroke.\n const editorExtensions = useMemo<Extension[]>(\n () => {\n const base = [\n keymap.of([\n {\n key: 'Mod-s',\n preventDefault: true,\n run: () => {\n void save();\n return true;\n },\n },\n ]),\n ];\n return extensions ? [...base, ...extensions] : base;\n },\n [save, extensions],\n );\n\n const lang: CodeEditorLanguage = languageProp\n ? languageProp\n : selectedPath\n ? guessLanguage(selectedPath)\n : 'plaintext';\n\n // Always render the outer column + header, even with no file selected,\n // so callers' `headerStartSlot` (typically the file-tree dropdown\n // trigger) stays reachable. Otherwise the user would be locked out of\n // the picker on mobile.\n //\n // When a slot is provided AND no file is selected, the slot owns the\n // empty-state messaging (e.g. the dropdown trigger reads \"Select a\n // file\"). We don't add a separate label so the text isn't duplicated.\n // Show just the basename in the header — full paths get long fast and\n // crowd out the Save/More buttons. Hover/title still exposes the full\n // path for orientation.\n const filename = selectedPath\n ? selectedPath.split('/').filter(Boolean).pop() ?? selectedPath\n : null;\n const headerLabel = selectedPath ? (\n <span className=\"font-mono\" title={selectedPath}>\n {filename}\n </span>\n ) : headerStartSlot ? null : (\n <span>Select a file</span>\n );\n\n return (\n <div className={`flex h-full w-full flex-col ${className ?? ''}`.trim()}>\n {!hideHeader && (\n <div className=\"flex flex-none items-center justify-between border-b px-3 py-2 text-xs\">\n <div className=\"flex items-center gap-1.5 text-muted-foreground\">\n {headerStartSlot}\n {headerLabel}\n </div>\n {selectedPath && !readOnly && (\n <div className=\"flex items-center gap-1\">\n <Button\n size=\"sm\"\n onClick={() => void save()}\n className=\"h-9 px-4 text-sm md:h-8 md:px-3 md:text-xs\"\n >\n {saveStatus === 'saving' ? (\n <>\n <Loader size={14} />\n Saving...\n </>\n ) : (\n 'Save'\n )}\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"File actions\"\n className=\"size-10 p-0 md:size-8\"\n />\n }\n >\n <MoreHorizontalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={() => void deleteFile()}\n className=\"text-destructive focus:text-destructive\"\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )}\n </div>\n )}\n <div className=\"flex-1 min-h-0 overflow-auto\">\n {selectedPath ? (\n <CodeEditor\n key={selectedPath}\n value={buffer}\n onChange={handleEditorChange}\n language={lang}\n theme={theme}\n basicSetup={basicSetup}\n readOnly={readOnly || loadingPath === selectedPath}\n extensions={editorExtensions}\n height=\"100%\"\n className=\"h-full text-sm\"\n />\n ) : (\n emptyState ?? (\n <div className=\"flex h-full w-full items-center justify-center text-muted-foreground text-sm\">\n Select a file from the menu\n </div>\n )\n )}\n </div>\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport CodeMirror, {\n EditorView,\n type Extension,\n type ReactCodeMirrorProps,\n} from '@uiw/react-codemirror';\nimport { javascript } from '@codemirror/lang-javascript';\nimport { css } from '@codemirror/lang-css';\nimport { html } from '@codemirror/lang-html';\nimport { json } from '@codemirror/lang-json';\nimport { markdown } from '@codemirror/lang-markdown';\nimport { useElementsContext } from '../../provider/sandbox-provider';\n\nexport type CodeEditorLanguage =\n | 'typescript'\n | 'tsx'\n | 'javascript'\n | 'jsx'\n | 'css'\n | 'html'\n | 'json'\n | 'markdown'\n | 'plaintext';\n\nexport type CodeEditorTheme = 'light' | 'dark' | Extension;\n\nexport interface CodeEditorProps\n extends Omit<\n ReactCodeMirrorProps,\n 'value' | 'onChange' | 'extensions' | 'theme'\n > {\n value: string;\n onChange?: (next: string) => void;\n language?: CodeEditorLanguage;\n /**\n * Editor color scheme. If omitted, falls back to `<SandboxProvider>`'s\n * `theme` (or `'light'` when no provider is mounted). Pass an\n * `Extension` to fully override CodeMirror's theme system.\n */\n theme?: CodeEditorTheme;\n /** Extra CodeMirror extensions appended to the language-derived ones. */\n extensions?: Extension[];\n className?: string;\n}\n\n/**\n * `<CodeEditor>` — thin CodeMirror 6 wrapper. Pass `value` + `onChange`\n * for controlled editing; `language` selects the syntax extension.\n *\n * The host is responsible for debouncing writes back to disk; this\n * component fires `onChange` for every keystroke.\n */\nexport function CodeEditor({\n value,\n onChange,\n language = 'plaintext',\n theme,\n extensions: extraExtensions,\n className,\n basicSetup,\n ...rest\n}: CodeEditorProps) {\n const ctx = useElementsContext();\n const resolvedTheme: CodeEditorTheme = theme ?? ctx?.theme ?? 'light';\n\n const extensions = useMemo<Extension[]>(() => {\n const langExt = languageExtension(language);\n const wrap = EditorView.lineWrapping;\n const base: Extension[] = [wrap];\n if (langExt) base.push(langExt);\n return extraExtensions ? [...base, ...extraExtensions] : base;\n }, [language, extraExtensions]);\n\n return (\n <CodeMirror\n value={value}\n onChange={onChange}\n extensions={extensions}\n theme={resolvedTheme}\n basicSetup={\n basicSetup ?? {\n lineNumbers: true,\n highlightActiveLine: true,\n highlightActiveLineGutter: true,\n foldGutter: true,\n autocompletion: true,\n bracketMatching: true,\n closeBrackets: true,\n indentOnInput: true,\n searchKeymap: true,\n }\n }\n className={className}\n {...rest}\n />\n );\n}\n\nfunction languageExtension(lang: CodeEditorLanguage): Extension | null {\n switch (lang) {\n case 'typescript':\n return javascript({ typescript: true });\n case 'tsx':\n return javascript({ typescript: true, jsx: true });\n case 'javascript':\n return javascript();\n case 'jsx':\n return javascript({ jsx: true });\n case 'css':\n return css();\n case 'html':\n return html();\n case 'json':\n return json();\n case 'markdown':\n return markdown();\n case 'plaintext':\n default:\n return null;\n }\n}\n","import type { HTMLAttributes } from 'react';\nimport { cn } from '../lib/utils';\n\ninterface LoaderIconProps {\n size?: number;\n}\n\nconst LoaderIcon = ({ size = 16 }: LoaderIconProps) => (\n <svg\n height={size}\n strokeLinejoin=\"round\"\n style={{ color: 'currentcolor' }}\n viewBox=\"0 0 16 16\"\n width={size}\n >\n <title>Loader</title>\n <g clipPath=\"url(#clip0_2393_1490)\">\n <path d=\"M8 0V4\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path\n d=\"M8 16V12\"\n opacity=\"0.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M3.29773 1.52783L5.64887 4.7639\"\n opacity=\"0.9\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M12.7023 1.52783L10.3511 4.7639\"\n opacity=\"0.1\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M12.7023 14.472L10.3511 11.236\"\n opacity=\"0.4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M3.29773 14.472L5.64887 11.236\"\n opacity=\"0.6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M15.6085 5.52783L11.8043 6.7639\"\n opacity=\"0.2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M0.391602 10.472L4.19583 9.23598\"\n opacity=\"0.7\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M15.6085 10.4722L11.8043 9.2361\"\n opacity=\"0.3\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M0.391602 5.52783L4.19583 6.7639\"\n opacity=\"0.8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_2393_1490\">\n <rect fill=\"white\" height=\"16\" width=\"16\" />\n </clipPath>\n </defs>\n </svg>\n);\n\nexport type LoaderProps = HTMLAttributes<HTMLDivElement> & {\n size?: number;\n};\n\nexport const Loader = ({ className, size = 16, ...props }: LoaderProps) => (\n <div\n className={cn(\n 'inline-flex animate-spin items-center justify-center',\n className,\n )}\n {...props}\n >\n <LoaderIcon size={size} />\n </div>\n);\n","// File-extension → CodeMirror language id. Kept as a tiny static map;\n// CodeEditor handles the language extension for each id.\n\nimport type { CodeEditorLanguage } from '../primitives/code-editor';\n\nconst EXT_TO_LANG: Record<string, CodeEditorLanguage> = {\n ts: 'typescript',\n tsx: 'tsx',\n js: 'javascript',\n jsx: 'jsx',\n mjs: 'javascript',\n cjs: 'javascript',\n json: 'json',\n md: 'markdown',\n mdx: 'markdown',\n css: 'css',\n scss: 'css',\n html: 'html',\n htm: 'html',\n};\n\nexport function guessLanguage(path: string): CodeEditorLanguage {\n const m = path.match(/\\.([^.]+)$/);\n if (!m) return 'plaintext';\n const ext = m[1]!.toLowerCase();\n return EXT_TO_LANG[ext] ?? 'plaintext';\n}\n","// `<SandboxIDE>` — responsive composition of `<SandboxFileTree>` and\n// `<SandboxCodeEditor>`.\n//\n// • md+ side-by-side: file tree as a 64-wide left column.\n// • below md stacked: a hamburger-icon trigger sits inside the\n// code-editor header next to the filename, opening a\n// popover with the tree (via\n// `<SandboxFileTree display=\"dropdown\" />`).\n//\n// CSS-driven (Tailwind's `md:` prefix); no JS resize listeners. Both\n// trees stay mounted across breakpoint changes — both are bound to the\n// same `selectedPath` in elements context, so selection is consistent.\n\nimport { type CSSProperties } from 'react';\nimport type { Sandbox } from '@browsernode/sandbox';\nimport { SandboxFileTree } from './sandbox-file-tree';\nimport {\n SandboxCodeEditor,\n type SandboxCodeEditorProps,\n} from './sandbox-code-editor';\n\nexport interface SandboxIDEProps\n extends Omit<SandboxCodeEditorProps, 'headerStartSlot' | 'className'> {\n /** Override the sandbox from the surrounding `<SandboxProvider>`. */\n sandbox?: Sandbox | null;\n /** Initial folders to expand (forwarded to `<SandboxFileTree>`). */\n defaultExpanded?: Set<string>;\n /** Hide the file tree entirely (editor-only layout). */\n hideTree?: boolean;\n /** Hide the code editor entirely (tree-only layout). */\n hideViewer?: boolean;\n /**\n * Drop the rounded-lg + border on the outer wrapper. Use when embedded\n * inside a host frame that already provides chrome (e.g. inside\n * `<Sandbox>`).\n */\n hideBorder?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function SandboxIDE({\n sandbox,\n defaultExpanded,\n hideTree = false,\n hideViewer = false,\n hideBorder = false,\n className,\n style,\n ...codeProps\n}: SandboxIDEProps) {\n // Tree-only layout — just render files directly.\n if (hideViewer) {\n return (\n <SandboxFileTree\n sandbox={sandbox}\n defaultExpanded={defaultExpanded}\n className={className}\n />\n );\n }\n\n // Editor-only layout — just render code, no tree (mobile or otherwise).\n if (hideTree) {\n return (\n <SandboxCodeEditor\n sandbox={sandbox}\n className={className}\n {...codeProps}\n />\n );\n }\n\n const frameClasses = hideBorder\n ? 'flex h-full w-full flex-col md:flex-row overflow-hidden bg-background'\n : 'flex h-full w-full flex-col md:flex-row overflow-hidden rounded-lg border bg-background';\n\n // Mobile-only file-picker trigger lives inside the code-editor header,\n // collapsing the would-be \"dropdown row\" into the same row as the\n // filename. Hidden at md+ where the sidebar tree is the picker. The\n // default trigger label adapts to selection state — \"[☰] Select a\n // file\" when empty, just \"[☰]\" when a file is loaded.\n const mobileTrigger = (\n <SandboxFileTree\n sandbox={sandbox}\n defaultExpanded={defaultExpanded}\n display=\"dropdown\"\n className=\"md:hidden -ml-1\"\n />\n );\n\n return (\n <div className={`${frameClasses} ${className ?? ''}`.trim()} style={style}>\n {/* Desktop-only: sidebar tree on the left. Hidden below md. Block\n (not flex) so the tree fills the column width to the divider. */}\n <div className=\"hidden md:block w-64 shrink-0 overflow-auto border-r\">\n <SandboxFileTree sandbox={sandbox} defaultExpanded={defaultExpanded} />\n </div>\n\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n <SandboxCodeEditor\n sandbox={sandbox}\n headerStartSlot={mobileTrigger}\n {...codeProps}\n />\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { MoreHorizontalIcon } from 'lucide-react';\nimport type { Sandbox, SnapshotMeta } from '@browsernode/sandbox';\nimport { Button } from '../primitives/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../primitives/ui/dropdown-menu';\nimport { Loader } from '../primitives/ui/loading';\nimport { useSandbox } from '../provider/sandbox-provider';\n\nexport interface SandboxSnapshotsProps {\n sandbox?: Sandbox | null;\n className?: string;\n /** Optional title shown above the list. Pass null to hide. */\n title?: React.ReactNode;\n}\n\n/**\n * `<SandboxSnapshots>` — list + create/restore/delete UI for\n * `sandbox.snapshots`. Capture the current vfs + env as a named checkpoint\n * and roll back later.\n */\nexport function SandboxSnapshots({\n sandbox: sandboxProp,\n className,\n title = 'Snapshots',\n}: SandboxSnapshotsProps) {\n const { sandbox: ctxSandbox } = useSandbox();\n const sandbox = sandboxProp ?? ctxSandbox ?? null;\n\n const [items, setItems] = useState<SnapshotMeta[]>([]);\n const [loading, setLoading] = useState(false);\n const [creating, setCreating] = useState(false);\n const [restoringId, setRestoringId] = useState<string | null>(null);\n\n const refresh = useCallback(async () => {\n if (!sandbox) return;\n setLoading(true);\n try {\n const list = await sandbox.snapshots.list();\n setItems(list);\n } finally {\n setLoading(false);\n }\n }, [sandbox]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const create = useCallback(async () => {\n if (!sandbox || creating) return;\n setCreating(true);\n try {\n await sandbox.snapshots.create();\n await refresh();\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to create snapshot', err);\n } finally {\n setCreating(false);\n }\n }, [sandbox, creating, refresh]);\n\n const restore = useCallback(\n async (id: string) => {\n if (!sandbox) return;\n setRestoringId(id);\n try {\n await sandbox.snapshots.restore(id);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to restore snapshot', err);\n } finally {\n setRestoringId(null);\n }\n },\n [sandbox],\n );\n\n const [confirmingDeleteId, setConfirmingDeleteId] = useState<string | null>(\n null,\n );\n const remove = useCallback(\n async (id: string) => {\n if (!sandbox) return;\n try {\n await sandbox.snapshots.delete(id);\n setConfirmingDeleteId(null);\n await refresh();\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to delete snapshot', err);\n }\n },\n [sandbox, refresh],\n );\n\n return (\n <div\n className={`flex min-h-0 flex-1 w-full flex-col ${className ?? ''}`.trim()}\n >\n <div className=\"flex flex-none items-center justify-between border-b px-3 py-2\">\n {title !== null ? (\n <span className=\"text-sm font-medium\">{title}</span>\n ) : <span />}\n <Button\n size=\"sm\"\n onClick={() => void create()}\n disabled={!sandbox || creating}\n >\n {creating ? (\n <>\n <Loader size={14} />\n Saving...\n </>\n ) : (\n 'New snapshot'\n )}\n </Button>\n </div>\n\n <div\n className=\"flex-1 min-h-0 overflow-y-auto [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden\"\n >\n {loading && items.length === 0 ? (\n <div className=\"flex h-full items-center justify-center text-xs text-muted-foreground\">\n Loading…\n </div>\n ) : items.length === 0 ? (\n <div className=\"flex items-center justify-center px-4 py-10 text-center text-xs text-muted-foreground\">\n No snapshots yet. Capture the current state to create one.\n </div>\n ) : (\n <ul className=\"divide-y\">\n {items.map((s) => (\n <li\n key={s.id}\n className=\"group flex cursor-pointer items-center justify-between gap-2 px-3 py-2 text-sm transition-colors hover:bg-muted/50\"\n >\n <button\n type=\"button\"\n onClick={() => void restore(s.id)}\n disabled={restoringId !== null}\n className=\"flex min-w-0 flex-1 cursor-pointer flex-col items-start text-left disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <span className=\"truncate font-medium\">\n {s.name ?? `v${s.version}`}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {formatTime(s.createdAt)}\n </span>\n </button>\n <div className=\"flex items-center gap-1\">\n {restoringId === s.id ? (\n <Loader size={14} />\n ) : null}\n <DropdownMenu\n onOpenChange={(open) => {\n // Reset the two-step confirm whenever the menu closes.\n if (!open) setConfirmingDeleteId(null);\n }}\n >\n <DropdownMenuTrigger\n render={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"Snapshot actions\"\n className=\"size-8 p-0\"\n />\n }\n >\n <MoreHorizontalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => void restore(s.id)}>\n Restore\n </DropdownMenuItem>\n <DropdownMenuItem\n // First click arms the destructive state; second\n // confirms. Selecting another menu item or closing\n // the menu resets it (handled in onOpenChange above).\n closeOnClick={confirmingDeleteId === s.id}\n onClick={(e) => {\n if (confirmingDeleteId !== s.id) {\n e.preventDefault();\n setConfirmingDeleteId(s.id);\n return;\n }\n void remove(s.id);\n }}\n className=\"text-destructive focus:text-destructive\"\n >\n {confirmingDeleteId === s.id ? 'Confirm delete' : 'Delete'}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts);\n return d.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n });\n}\n\n","// `<SandboxAttribution>` — small floating \"BrowserNode\" glass badge\n// pinned to the bottom-right of the sandbox body. Links back to\n// browsernode.dev. Visible by default in `<SandboxChrome>`; consumers\n// can hide it via `showAttribution={false}` on `<Sandbox>` /\n// `<SandboxChrome>`.\n\nimport type { CSSProperties } from 'react';\nimport { cn } from './primitives/lib/utils';\n\nexport interface SandboxAttributionProps {\n className?: string;\n style?: CSSProperties;\n /** Override the destination URL. Defaults to `https://browsernode.dev`. */\n href?: string;\n}\n\n// Positioning is inline so the badge is bulletproof even when the\n// consumer's Tailwind build hasn't picked up the elements package's\n// utility classes yet (e.g. fresh install before first CSS rebuild).\nconst POSITION: CSSProperties = {\n position: 'absolute',\n bottom: 14,\n right: 14,\n zIndex: 10,\n pointerEvents: 'auto',\n};\n\nexport function SandboxAttribution({\n className,\n style,\n href = 'https://browsernode.dev',\n}: SandboxAttributionProps) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"BrowserNode — visit browsernode.dev\"\n style={{ ...POSITION, ...style }}\n className={cn(\n // Solid pill — guaranteed legibility over any iframe content.\n // Matches the canonical BrowserNode wordmark (white \"Browser\" +\n // violet \"Node\") on a near-black surface.\n 'inline-flex items-center rounded-full',\n 'px-2.5 pt-1 pb-1.5 text-[11px] font-semibold tracking-tight leading-none',\n 'bg-zinc-950 ring-1 ring-white/10',\n 'shadow-lg shadow-black/30',\n 'transition-all duration-200 ease-out',\n 'hover:bg-zinc-900 hover:ring-white/20 hover:scale-[1.04]',\n 'select-none',\n className,\n )}\n >\n <span className=\"text-white\">Browser</span><span className=\"text-violet-400\">Node</span>\n </a>\n );\n}\n","\"use client\"\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Tabs({\n className,\n orientation = \"horizontal\",\n ...props\n}: TabsPrimitive.Root.Props) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n data-orientation={orientation}\n className={cn(\n \"group/tabs flex gap-2 data-horizontal:flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst tabsListVariants = cva(\n \"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none\",\n {\n variants: {\n variant: {\n default: \"bg-muted\",\n line: \"gap-1 bg-transparent\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction TabsList({\n className,\n variant = \"default\",\n ...props\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n data-variant={variant}\n className={cn(tabsListVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nfunction TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {\n return (\n <TabsPrimitive.Tab\n data-slot=\"tabs-trigger\"\n className={cn(\n \"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n \"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent\",\n \"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground\",\n \"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n return (\n <TabsPrimitive.Panel\n data-slot=\"tabs-content\"\n className={cn(\"flex-1 text-sm outline-none\", className)}\n {...props}\n />\n )\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }\n","// `<Sandbox>` — drop-in convenience: wraps `<SandboxProvider>` (which\n// creates and owns the sandbox) around `<SandboxChrome>` (the UI\n// shell). Use this when you want a self-contained preview surface in\n// one tag.\n//\n// For sibling composition (e.g. a chat panel beside the IDE that shares\n// the sandbox), don't use `<Sandbox>` — lift the provider yourself:\n//\n// <SandboxProvider framework=\"...\" source={...}>\n// <MyChat /> {/* useSandbox() — same instance */}\n// <SandboxChrome /> {/* same instance, just renders the IDE */}\n// </SandboxProvider>\n\nimport { type CSSProperties } from 'react';\nimport {\n SandboxProvider,\n type SandboxProviderProps,\n} from './provider/sandbox-provider';\nimport { SandboxChrome, type SandboxUi } from './sandbox-chrome';\n\nexport interface SandboxProps extends Omit<SandboxProviderProps, 'children'> {\n ui?: SandboxUi;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function Sandbox({ ui, className, style, ...providerProps }: SandboxProps) {\n return (\n <SandboxProvider {...providerProps}>\n <SandboxChrome ui={ui} className={className} style={style} />\n </SandboxProvider>\n );\n}\n"],"mappings":"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","names":["useState","motion","ArrowLeftIcon","ArrowRightIcon","DownloadIcon","MaximizeIcon","MinimizeIcon","MonitorIcon","MoreVerticalIcon","RefreshCcwIcon","SmartphoneIcon","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","jsx","jsx","jsx","jsx","createContext","useCallback","useContext","useMemo","useState","jsx","jsxs","jsxs","jsx","ChevronDownIcon","createContext","useCallback","useContext","useMemo","useState","jsx","jsxs","CheckIcon","jsx","jsxs","jsx","jsx","jsx","jsxs","createContext","useContext","SandboxPreviewProvider","useRef","useCallback","useState","useEffect","useMemo","jsxs","jsx","useEffect","useMemo","useState","ChevronRightIcon","createContext","useCallback","useContext","useMemo","useState","Fragment","jsx","jsxs","jsx","jsx","Fragment","jsx","jsxs","useState","useEffect","useMemo","useCallback","useEffect","useMemo","useRef","useState","useMemo","jsx","useMemo","jsx","jsxs","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useMemo","jsx","jsxs","useCallback","useEffect","useState","MoreHorizontalIcon","Fragment","jsx","jsxs","useState","useCallback","useEffect","MoreHorizontalIcon","jsx","jsxs","cva","jsx","cva","Fragment","jsx","jsxs","useState","motion","ArrowLeftIcon","ArrowRightIcon","RefreshCcwIcon","SmartphoneIcon","MonitorIcon","MinimizeIcon","MaximizeIcon","MoreVerticalIcon","DownloadIcon","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider/sandbox-provider.tsx","../src/sandbox-chrome.tsx","../src/preview/sandbox-preview.tsx","../src/primitives/ui/button.tsx","../src/primitives/lib/utils.ts","../src/primitives/ui/collapsible.tsx","../src/primitives/ui/input.tsx","../src/primitives/ui/tooltip.tsx","../src/preview/primitives/web-preview.tsx","../src/primitives/stack-trace.tsx","../src/primitives/ui/dropdown-menu.tsx","../src/editor/sandbox-file-tree.tsx","../src/editor/primitives/file-tree.tsx","../src/primitives/ui/popover.tsx","../src/editor/internal/tree.tsx","../src/editor/sandbox-code-editor.tsx","../src/editor/primitives/code-editor.tsx","../src/primitives/ui/loading.tsx","../src/editor/internal/language.ts","../src/editor/sandbox-ide.tsx","../src/snapshots/sandbox-snapshots.tsx","../src/sandbox-attribution.tsx","../src/primitives/ui/tabs.tsx","../src/sandbox.tsx"],"sourcesContent":["// `<SandboxProvider>` — thin wrapper around @browsernode/react's\n// `<SandboxRuntime>` (the headless engine binding) that adds\n// elements-specific extras (theme, selectedPath, openTabs, activePanel)\n// and resolves the `framework` string (\"nextjs\" → nextjs()) plus the\n// default bundler.\n//\n// Lifecycle/sandbox management is delegated to @browsernode/react entirely.\n// Components inside elements should:\n// • read the sandbox via `useSandbox()` (re-exported from @browsernode/react)\n// • read elements extras via `useElementsContext()`\n\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n SandboxRuntime,\n type UseSandboxOptions,\n} from '@browsernode/react';\nimport { esbuild } from '@browsernode/esbuild-wasm';\nimport { nextjs } from '@browsernode/nextjs';\nimport { vite } from '@browsernode/sandbox/vite';\nimport type {\n BundlerAdapter,\n FrameworkAdapter,\n} from '@browsernode/sandbox';\n\nexport { useSandbox } from '@browsernode/react';\n\nexport type SandboxPanel = 'left' | 'top' | 'center' | 'bottom';\n\n/**\n * Resolved color scheme for elements that need light/dark variants\n * (e.g. `<CodeEditor>`'s syntax theme). Pass the resolved value from your\n * theme system — e.g. `next-themes`' `useTheme().resolvedTheme`. Defaults\n * to `'light'`.\n */\nexport type SandboxTheme = 'light' | 'dark';\n\nexport interface SandboxTab {\n path: string;\n label?: string;\n}\n\n/** Elements-specific extras: theme, file selection, open tabs. */\nexport interface ElementsContextValue {\n selectedPath: string | null;\n setSelectedPath(path: string | null): void;\n\n openTabs: SandboxTab[];\n openTab(tab: SandboxTab | string): void;\n closeTab(path: string): void;\n\n activePanel: SandboxPanel;\n setActivePanel(panel: SandboxPanel): void;\n\n theme: SandboxTheme;\n}\n\nconst ElementsContext = createContext<ElementsContextValue | null>(null);\n\nexport type SandboxProviderFramework = FrameworkAdapter | 'nextjs' | 'vite';\n\ninterface SandboxProviderBaseProps {\n children: ReactNode;\n initialActivePanel?: SandboxPanel;\n initialOpenTabs?: readonly (SandboxTab | string)[];\n initialSelectedPath?: string | null;\n theme?: SandboxTheme;\n}\n\nexport interface SandboxProviderProps\n extends SandboxProviderBaseProps,\n Omit<UseSandboxOptions, 'framework' | 'bundler'> {\n framework: SandboxProviderFramework;\n bundler?: BundlerAdapter;\n}\n\nfunction toTab(t: SandboxTab | string): SandboxTab {\n return typeof t === 'string' ? { path: t } : t;\n}\n\nfunction resolveFramework(framework: SandboxProviderFramework): FrameworkAdapter {\n if (framework === 'nextjs') return nextjs();\n if (framework === 'vite') return vite();\n if (typeof framework === 'string') {\n throw new Error(`Unsupported SandboxProvider framework \"${framework}\".`);\n }\n return framework;\n}\n\nexport function SandboxProvider({ children, ...props }: SandboxProviderProps) {\n const {\n initialActivePanel,\n initialOpenTabs,\n initialSelectedPath,\n theme,\n framework,\n bundler,\n ...sandboxOptions\n } = props;\n\n const options = useMemo<UseSandboxOptions>(\n () => ({\n ...sandboxOptions,\n framework: resolveFramework(framework),\n bundler: bundler ?? esbuild(),\n }),\n // The sandbox is created once on mount (managed by <SandboxRuntime>'s\n // useEffect deps); listing only framework/bundler here keeps the\n // ref-stable options object the way callers expect.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [framework, bundler],\n );\n\n return (\n <SandboxRuntime options={options}>\n <ElementsExtrasProvider\n initialActivePanel={initialActivePanel}\n initialOpenTabs={initialOpenTabs}\n initialSelectedPath={initialSelectedPath}\n theme={theme}\n >\n {children}\n </ElementsExtrasProvider>\n </SandboxRuntime>\n );\n}\n\ninterface ElementsExtrasProviderProps extends SandboxProviderBaseProps {}\n\nfunction ElementsExtrasProvider({\n children,\n initialActivePanel = 'center',\n initialOpenTabs = [],\n initialSelectedPath = null,\n theme = 'light',\n}: ElementsExtrasProviderProps) {\n const [selectedPath, setSelectedPath] = useState<string | null>(initialSelectedPath);\n const [openTabs, setOpenTabs] = useState<SandboxTab[]>(() =>\n initialOpenTabs.map(toTab),\n );\n const [activePanel, setActivePanel] = useState<SandboxPanel>(initialActivePanel);\n\n const openTab = useCallback((t: SandboxTab | string) => {\n const tab = toTab(t);\n setOpenTabs((prev) => {\n if (prev.some((x) => x.path === tab.path)) return prev;\n return [...prev, tab];\n });\n setSelectedPath(tab.path);\n }, []);\n\n const closeTab = useCallback((path: string) => {\n setOpenTabs((prev) => {\n const next = prev.filter((t) => t.path !== path);\n setSelectedPath((cur) => {\n if (cur !== path) return cur;\n const idx = prev.findIndex((t) => t.path === path);\n const fallback = next[idx - 1] ?? next[idx] ?? next[0] ?? null;\n return fallback?.path ?? null;\n });\n return next;\n });\n }, []);\n\n const extras = useMemo<ElementsContextValue>(\n () => ({\n selectedPath,\n setSelectedPath,\n openTabs,\n openTab,\n closeTab,\n activePanel,\n setActivePanel,\n theme,\n }),\n [selectedPath, openTabs, openTab, closeTab, activePanel, theme],\n );\n\n return <ElementsContext.Provider value={extras}>{children}</ElementsContext.Provider>;\n}\n\n/** Read elements-specific state (theme, selectedPath, openTabs). */\nexport function useElementsContext(): ElementsContextValue | null {\n return useContext(ElementsContext);\n}\n\nexport function useElementsContextOrThrow(): ElementsContextValue {\n const ctx = useContext(ElementsContext);\n if (!ctx) {\n throw new Error(\n 'useElementsContext() must be called inside <SandboxProvider> from @browsernode/elements.',\n );\n }\n return ctx;\n}\n","// `<SandboxChrome>` — UI shell only. Reads sandbox state from\n// `useSandbox()` (i.e. requires an `<SandboxProvider>` somewhere\n// above in the tree). Renders the navigation toolbar, web ↔ code body,\n// and console drawer; no provider lifecycle of its own.\n//\n// Use this when you want to compose siblings that share the sandbox:\n//\n// <SandboxProvider framework=\"nextjs\" source={...}>\n// <MyChat /> {/* useSandbox() — same instance */}\n// <SandboxChrome /> {/* useSandbox() — same instance */}\n// </SandboxProvider>\n//\n// For the zero-config drop-in (provider + chrome in one tag), use\n// `<Sandbox>`. It composes `<SandboxProvider>` + `<SandboxChrome>`.\n\nimport {\n useState,\n type CSSProperties,\n type ReactNode,\n} from 'react';\nimport { motion } from 'motion/react';\nimport {\n ArrowLeftIcon,\n ArrowRightIcon,\n ClockFadingIcon,\n CodeIcon,\n DownloadIcon,\n GlobeIcon,\n MaximizeIcon,\n MinimizeIcon,\n MonitorIcon,\n MoreVerticalIcon,\n RefreshCcwIcon,\n SmartphoneIcon,\n} from 'lucide-react';\nimport {\n SandboxPreviewProvider,\n SandboxPreviewConsole,\n SandboxPreviewWeb,\n useSandboxPreviewCtx,\n} from './preview/sandbox-preview';\nimport {\n WebPreview,\n WebPreviewNavigation,\n WebPreviewNavigationButton,\n} from './preview/primitives/web-preview';\nimport { SandboxIDE } from './editor/sandbox-ide';\nimport { SandboxSnapshots } from './snapshots/sandbox-snapshots';\nimport { SandboxAttribution } from './sandbox-attribution';\nimport { Input } from './primitives/ui/input';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from './primitives/ui/dropdown-menu';\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from './primitives/ui/popover';\nimport { Tabs, TabsList, TabsTrigger } from './primitives/ui/tabs';\nimport { cn } from './primitives/lib/utils';\n\n/** Per-control toggles for the Sandbox chrome. All default to `true`. */\nexport interface SandboxUi {\n /** Web ↔ Code editor toggle in the toolbar. */\n showCodeEditor?: boolean;\n /** Back / forward arrows + URL bar. */\n showNavigation?: boolean;\n /** Reload button. */\n showReload?: boolean;\n /** Desktop ↔ Mobile viewport toggle. */\n showDeviceToggle?: boolean;\n /** Fullscreen overlay toggle. */\n showFullScreenToggle?: boolean;\n /** Snapshots popover. */\n showSnapshots?: boolean;\n /** Export-as-zip menu item inside the More dropdown. */\n showExportFiles?: boolean;\n /** Settings dropdown (placeholder — opens an empty menu for now). */\n showSettings?: boolean;\n /** Console drawer at the bottom. */\n showConsole?: boolean;\n /** \"Made with BrowserNode\" badge in the bottom-right of the body. */\n showAttribution?: boolean;\n}\n\nconst DEFAULT_UI: Required<SandboxUi> = {\n showCodeEditor: true,\n showNavigation: true,\n showReload: true,\n showDeviceToggle: true,\n showFullScreenToggle: true,\n showSnapshots: true,\n showExportFiles: true,\n showSettings: false,\n showConsole: true,\n showAttribution: true,\n};\n\nexport interface SandboxChromeProps {\n ui?: SandboxUi;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SLIDE_TRANSITION = {\n type: 'spring' as const,\n stiffness: 320,\n damping: 32,\n mass: 0.7,\n};\n\n/**\n * `<SandboxChrome>` — the IDE shell (toolbar + web/code body + console).\n * Consumes the sandbox from a surrounding `<SandboxProvider>` via\n * `useSandbox()`; does not create its own provider. Throws if no\n * `<SandboxProvider>` is mounted above it — wrap with one or use\n * `<Sandbox>` for the bundled drop-in.\n */\nexport function SandboxChrome({ ui, className, style }: SandboxChromeProps) {\n const flags = { ...DEFAULT_UI, ...ui };\n const [view, setView] = useState<'web' | 'code'>('web');\n const isCode = view === 'code';\n\n return (\n <SandboxPreviewProvider>\n <SandboxOverlay className={className} style={style}>\n <SandboxToolbar\n flags={flags}\n view={view}\n onViewChange={setView}\n />\n\n {/* Sliding body — only this region animates, so toolbar stays put. */}\n <div className=\"relative flex-1 min-h-0 overflow-hidden\">\n <motion.div\n className=\"absolute inset-0\"\n animate={{ x: isCode ? '-100%' : '0%' }}\n transition={SLIDE_TRANSITION}\n >\n <SandboxPreviewWeb />\n </motion.div>\n {flags.showCodeEditor && (\n <motion.div\n className=\"absolute inset-0\"\n initial={{ x: '100%' }}\n animate={{ x: isCode ? '0%' : '100%' }}\n transition={SLIDE_TRANSITION}\n >\n <SandboxIDE hideBorder />\n </motion.div>\n )}\n {flags.showAttribution && !isCode && <SandboxAttribution />}\n </div>\n\n {flags.showConsole && <SandboxPreviewConsole />}\n </SandboxOverlay>\n </SandboxPreviewProvider>\n );\n}\n\n// CSS-fullscreen mount: when the inner ctx flips `overlay`, this div\n// goes `fixed inset-0 z-50` and takes over the viewport without invoking\n// the system fullscreen API (which is restricted inside iframes / on iOS).\nfunction SandboxOverlay({\n className,\n style,\n children,\n}: {\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n}) {\n const { overlay } = useSandboxPreviewCtx();\n return (\n <WebPreview\n defaultUrl=\"\"\n className={cn(\n 'flex h-full w-full flex-col',\n overlay && 'fixed inset-0 z-50 bg-background',\n className,\n )}\n style={style}\n >\n {children}\n </WebPreview>\n );\n}\n\ninterface SandboxToolbarProps {\n flags: Required<SandboxUi>;\n view: 'web' | 'code';\n onViewChange: (view: 'web' | 'code') => void;\n}\n\nfunction SandboxToolbar({ flags, view, onViewChange }: SandboxToolbarProps) {\n const {\n inputValue,\n setInputValue,\n currentUrl,\n history,\n historyIndex,\n viewport,\n setViewport,\n spinCount,\n goBack,\n goForward,\n reload,\n overlay,\n toggleOverlay,\n submitUrl,\n download,\n } = useSandboxPreviewCtx();\n\n // Navigation strip — back / forward / URL / reload. Used twice:\n // (a) inside the mobile-only top row, and (b) inline within the chrome\n // row at md+. `display: contents` (via `md:contents`) lets the desktop\n // copy participate directly in the chrome row's flex layout without\n // adding a wrapper element.\n const navItems =\n flags.showNavigation || flags.showReload ? (\n <>\n {flags.showNavigation && (\n <>\n <WebPreviewNavigationButton\n tooltip=\"Back\"\n disabled={historyIndex <= 0}\n onClick={goBack}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton\n tooltip=\"Forward\"\n disabled={historyIndex >= history.length - 1}\n onClick={goForward}\n >\n <ArrowRightIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <Input\n className=\"h-8 flex-1 text-sm\"\n placeholder=\"Enter URL...\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n submitUrl();\n } else if (e.key === 'Escape') {\n setInputValue(currentUrl);\n (e.target as HTMLInputElement).blur();\n }\n }}\n />\n </>\n )}\n {flags.showReload && (\n <WebPreviewNavigationButton tooltip=\"Reload\" onClick={reload}>\n <RefreshCcwIcon\n key={spinCount}\n className=\"size-4 motion-safe:animate-[spin_0.6s_linear_reverse_1]\"\n />\n </WebPreviewNavigationButton>\n )}\n </>\n ) : null;\n\n return (\n <div className=\"flex flex-col\">\n {/* Mobile-only nav row above the chrome. Hidden at md+. */}\n {navItems && (\n <div className=\"md:hidden\">\n <WebPreviewNavigation>{navItems}</WebPreviewNavigation>\n </div>\n )}\n\n {/* Chrome row — always shown. Inline nav at md+. */}\n <WebPreviewNavigation>\n {flags.showCodeEditor && (\n <Tabs\n value={view}\n onValueChange={(v) => onViewChange(v as 'web' | 'code')}\n className=\"mr-1\"\n >\n <TabsList className=\"h-8\">\n <TabsTrigger value=\"web\" aria-label=\"Web\" className=\"size-7 p-0\">\n <GlobeIcon className=\"size-4\" />\n </TabsTrigger>\n <TabsTrigger value=\"code\" aria-label=\"Code\" className=\"size-7 p-0\">\n <CodeIcon className=\"size-4\" />\n </TabsTrigger>\n </TabsList>\n </Tabs>\n )}\n\n {/* Desktop-only inline nav strip. `display: contents` so the\n children (with `flex-1` Input) flow directly inside\n <WebPreviewNavigation>'s flex layout — the Input grows to\n fill all remaining space between the left tabs and the\n right chrome cluster. */}\n {navItems && <div className=\"hidden md:contents\">{navItems}</div>}\n\n {/* Mobile-only spacer (pushes chrome icons right when the URL\n bar isn't inline). On desktop the URL Input's flex-1 already\n does this. */}\n <div className=\"flex-1 md:hidden\" />\n\n {flags.showDeviceToggle && (\n <WebPreviewNavigationButton\n tooltip={viewport === 'desktop' ? 'Mobile view' : 'Desktop view'}\n onClick={() =>\n setViewport(viewport === 'desktop' ? 'mobile' : 'desktop')\n }\n className=\"hidden md:inline-flex\"\n >\n {viewport === 'desktop' ? (\n <SmartphoneIcon className=\"size-4\" />\n ) : (\n <MonitorIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n )}\n\n {flags.showFullScreenToggle && (\n <WebPreviewNavigationButton\n tooltip={overlay ? 'Exit fullscreen' : 'Fullscreen'}\n onClick={toggleOverlay}\n >\n {overlay ? (\n <MinimizeIcon className=\"size-4\" />\n ) : (\n <MaximizeIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n )}\n\n {flags.showSnapshots && (\n <Popover>\n <PopoverTrigger\n render={<WebPreviewNavigationButton tooltip=\"Snapshots\" />}\n >\n <ClockFadingIcon className=\"size-4\" />\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n className=\"w-80 p-0 max-h-[26rem] flex flex-col overflow-hidden\"\n >\n <SandboxSnapshots />\n </PopoverContent>\n </Popover>\n )}\n\n {(flags.showExportFiles || flags.showSettings) && (\n <DropdownMenu>\n <DropdownMenuTrigger\n render={<WebPreviewNavigationButton tooltip=\"More\" />}\n >\n <MoreVerticalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-40\">\n {flags.showExportFiles && (\n <DropdownMenuItem onClick={download}>\n <DownloadIcon className=\"size-4\" />\n Download .zip\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </WebPreviewNavigation>\n </div>\n );\n}\n","import {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { motion } from 'motion/react';\nimport {\n ArrowLeftIcon,\n ArrowRightIcon,\n DownloadIcon,\n MaximizeIcon,\n MinimizeIcon,\n MonitorIcon,\n MoreVerticalIcon,\n RefreshCcwIcon,\n SmartphoneIcon,\n} from 'lucide-react';\nimport type {\n BuildResult,\n ConsoleEvent,\n ConsoleLevel,\n Diagnostic,\n RuntimeErrorEvent,\n Sandbox,\n} from '@browsernode/sandbox';\nimport {\n SandboxIFrame,\n type SandboxIFrameHandle,\n type SandboxIFrameProps,\n} from '@browsernode/react';\nimport {\n WebPreview,\n WebPreviewConsole,\n WebPreviewNavigation,\n WebPreviewNavigationButton,\n} from './primitives/web-preview';\nimport {\n StackTrace,\n StackTraceActions,\n StackTraceContent,\n StackTraceCopyButton,\n StackTraceError,\n StackTraceErrorMessage,\n StackTraceErrorType,\n StackTraceExpandButton,\n StackTraceFrames,\n StackTraceHeader,\n} from '../primitives/stack-trace';\nimport { Input } from '../primitives/ui/input';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../primitives/ui/dropdown-menu';\nimport { useSandbox } from '../provider/sandbox-provider';\n\nexport type SandboxPreviewHandle = SandboxIFrameHandle;\n\n// WebPreviewConsole only knows three levels; collapse our 5 onto its 3.\ntype AiLogLevel = 'log' | 'warn' | 'error';\nconst LEVEL_MAP: Record<ConsoleLevel, AiLogLevel> = {\n log: 'log',\n info: 'log',\n debug: 'log',\n warn: 'warn',\n error: 'error',\n};\n\ninterface AiLog {\n level: AiLogLevel;\n message: string;\n timestamp: Date;\n}\n\n// ---------------------------------------------------------------------------\n// Context — lets <SandboxPreviewToolbar> live outside the motion wrapper\n// (so it stays stable while the body slides) while still sharing iframe\n// state with <SandboxPreviewWeb>.\n// ---------------------------------------------------------------------------\n\ninterface SandboxPreviewContextValue {\n sandbox: Sandbox | null;\n iframeProps?: SandboxIFrameProps['iframeProps'];\n rest: Omit<SandboxIFrameProps, 'sandbox' | 'iframeProps' | 'onNavigate'>;\n onNavigate?: SandboxIFrameProps['onNavigate'];\n\n innerRef: React.MutableRefObject<SandboxIFrameHandle | null>;\n containerRef: React.RefObject<HTMLDivElement | null>;\n attachHandle: (node: SandboxIFrameHandle | null) => void;\n\n inputValue: string;\n setInputValue: (v: string) => void;\n currentUrl: string;\n history: string[];\n historyIndex: number;\n viewport: 'desktop' | 'mobile';\n setViewport: (v: 'desktop' | 'mobile') => void;\n spinCount: number;\n logs: AiLog[];\n\n showOverlay: boolean;\n overlayTrace: string;\n setRuntimeError: (e: RuntimeErrorEvent | null) => void;\n\n goBack: () => void;\n goForward: () => void;\n reload: () => void;\n /** True when the preview frame is taking over the viewport (CSS overlay,\n * not native fullscreen). */\n overlay: boolean;\n toggleOverlay: () => void;\n submitUrl: () => void;\n download: () => void;\n}\n\nconst SandboxPreviewCtx = createContext<SandboxPreviewContextValue | null>(null);\n\nexport function useSandboxPreviewCtx(): SandboxPreviewContextValue {\n const ctx = useContext(SandboxPreviewCtx);\n if (!ctx) {\n throw new Error(\n '<SandboxPreviewToolbar>/<SandboxPreviewWeb> must be rendered inside <SandboxPreviewProvider>',\n );\n }\n return ctx;\n}\n\nexport interface SandboxPreviewProviderProps\n extends Omit<SandboxIFrameProps, 'sandbox'> {\n sandbox?: Sandbox | null;\n /** Initial URL to display in the bar. Defaults to '/'. */\n defaultUrl?: string;\n children: ReactNode;\n}\n\nexport const SandboxPreviewProvider = forwardRef<\n SandboxPreviewHandle,\n SandboxPreviewProviderProps\n>(function SandboxPreviewProvider(\n {\n sandbox: sandboxProp,\n defaultUrl = '/',\n onNavigate,\n iframeProps,\n children,\n ...rest\n },\n ref,\n) {\n const { sandbox: ctxSandbox } = useSandbox();\n const sandbox = sandboxProp ?? ctxSandbox ?? null;\n\n const innerRef = useRef<SandboxIFrameHandle | null>(null);\n const attachHandle = useCallback((node: SandboxIFrameHandle | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }, [ref]);\n\n const [currentUrl, setCurrentUrl] = useState(defaultUrl);\n const [inputValue, setInputValue] = useState(defaultUrl);\n const [history, setHistory] = useState<string[]>([defaultUrl]);\n const [historyIndex, setHistoryIndex] = useState(0);\n const [events, setEvents] = useState<ConsoleEvent[]>(() =>\n sandbox ? [...sandbox.console.history()] : [],\n );\n const [buildError, setBuildError] = useState<Diagnostic[] | null>(null);\n const [sandboxError, setSandboxError] = useState<Error | null>(null);\n const [runtimeError, setRuntimeError] = useState<RuntimeErrorEvent | null>(null);\n const [viewport, setViewport] = useState<'desktop' | 'mobile'>('desktop');\n const containerRef = useRef<HTMLDivElement>(null);\n // When the host programmatically navigates (back/forward), the iframe\n // echoes the URL back through the navigate channel. We expect that echo\n // and skip the history-push so the index doesn't drift.\n const skipNextEcho = useRef<string | null>(null);\n\n useEffect(() => {\n if (!sandbox) return;\n setEvents([...sandbox.console.history()]);\n const unsubNav = sandbox.on('navigate', (url) => {\n setCurrentUrl(url);\n setInputValue(url);\n // New navigation = stale runtime error, clear it.\n setRuntimeError(null);\n // If this is the echo from a host-driven back/forward, the index has\n // already moved — don't re-push and don't re-increment.\n if (skipNextEcho.current === url) {\n skipNextEcho.current = null;\n return;\n }\n setHistory((prev) => {\n const truncated = prev.slice(0, historyIndex + 1);\n if (truncated[truncated.length - 1] === url) return truncated;\n return [...truncated, url];\n });\n setHistoryIndex((i) => i + 1);\n });\n const unsubLog = sandbox.on('console', (level, args) => {\n setEvents((prev) => [...prev, { level, args, ts: Date.now() }]);\n });\n const unsubBuild = sandbox.on('build', (result: BuildResult) => {\n setBuildError(result.ok ? null : result.errors);\n // A clean build clears stale sandbox-orchestration errors too.\n if (result.ok) setSandboxError(null);\n });\n const unsubErr = sandbox.on('error', (err) => setSandboxError(err));\n return () => {\n unsubNav();\n unsubLog();\n unsubBuild();\n unsubErr();\n };\n }, [sandbox, historyIndex]);\n\n const goBack = useCallback(() => {\n if (historyIndex <= 0) return;\n const target = history[historyIndex - 1]!;\n skipNextEcho.current = target;\n setHistoryIndex(historyIndex - 1);\n innerRef.current?.navigate(target);\n }, [history, historyIndex]);\n\n const goForward = useCallback(() => {\n if (historyIndex >= history.length - 1) return;\n const target = history[historyIndex + 1]!;\n skipNextEcho.current = target;\n setHistoryIndex(historyIndex + 1);\n innerRef.current?.navigate(target);\n }, [history, historyIndex]);\n\n // Click count drives the icon's CSS spin animation (key remounts the\n // icon to retrigger). Reload calls sandbox.rebuild() so file edits get\n // picked up — autoRebuild's listener swaps the iframe to the fresh blob.\n const [spinCount, setSpinCount] = useState(0);\n const reload = useCallback(() => {\n setSpinCount((n) => n + 1);\n if (sandbox) {\n sandbox.rebuild().catch(() => {\n /* errors flow through sandbox.on('error') */\n });\n } else {\n innerRef.current?.reload();\n }\n }, [sandbox]);\n\n // CSS-only \"fullscreen\" — takes over the viewport via fixed positioning\n // without invoking the system fullscreen API. Works inside iframes, on\n // iOS, and across browsers that restrict requestFullscreen().\n const [overlay, setOverlay] = useState(false);\n const toggleOverlay = useCallback(() => setOverlay((v) => !v), []);\n useEffect(() => {\n if (!overlay) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOverlay(false);\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [overlay]);\n\n const submitUrl = useCallback(() => {\n const target = inputValue.trim() || '/';\n innerRef.current?.navigate(target);\n }, [inputValue]);\n\n const download = useCallback(async () => {\n if (!sandbox) return;\n const blob = await sandbox.download();\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `${sandbox.sandboxId ?? 'sandbox'}.zip`;\n document.body.appendChild(a);\n a.click();\n a.remove();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }, [sandbox]);\n\n const logs = useMemo<AiLog[]>(\n () =>\n events.map((e) => ({\n level: LEVEL_MAP[e.level],\n message: formatArgs(e.args),\n timestamp: new Date(e.ts),\n })),\n [events],\n );\n\n // Unified error overlay. Build errors take priority (most actionable),\n // then runtime errors (visible in the iframe app), then sandbox errors\n // (orchestration). All three normalize to a V8/Node-style trace string\n // that the ai-elements <StackTrace> can parse.\n const overlayTrace = useMemo(() => {\n if (buildError && buildError.length > 0) {\n const head = buildError[0]!;\n const frames = buildError.map((d) => {\n const file = d.file ?? '<unknown>';\n const line = d.line ?? 0;\n const col = d.column ?? 0;\n return ` at build (${file}:${line}:${col})`;\n });\n return [`BuildError: ${head.message}`, ...frames].join('\\n');\n }\n if (runtimeError) {\n if (runtimeError.stack) return runtimeError.stack;\n const errType =\n runtimeError.source === 'unhandledrejection'\n ? 'UnhandledRejection'\n : 'RuntimeError';\n const frame = ` at <iframe> (${runtimeError.filename ?? '<unknown>'}:${runtimeError.lineno ?? 0}:${runtimeError.colno ?? 0})`;\n return `${errType}: ${runtimeError.message}\\n${frame}`;\n }\n if (sandboxError) {\n return (\n sandboxError.stack ?? `SandboxError: ${sandboxError.message}`\n );\n }\n return '';\n }, [buildError, runtimeError, sandboxError]);\n\n const showOverlay =\n Boolean(buildError && buildError.length > 0) ||\n Boolean(runtimeError) ||\n Boolean(sandboxError);\n\n useImperativeHandle(ref, () => ({\n rebuild: () => innerRef.current?.rebuild(),\n reload: () => innerRef.current?.reload(),\n navigate: (u: string) => innerRef.current?.navigate(u),\n send: (message: unknown) => innerRef.current?.send(message),\n }) as SandboxIFrameHandle, []);\n\n const value = useMemo<SandboxPreviewContextValue>(() => ({\n sandbox,\n iframeProps,\n rest,\n onNavigate,\n innerRef,\n containerRef,\n attachHandle,\n inputValue,\n setInputValue,\n currentUrl,\n history,\n historyIndex,\n viewport,\n setViewport,\n spinCount,\n logs,\n showOverlay,\n overlayTrace,\n setRuntimeError,\n goBack,\n goForward,\n reload,\n overlay,\n toggleOverlay,\n submitUrl,\n download,\n }), [\n sandbox, iframeProps, rest, onNavigate, attachHandle,\n inputValue, currentUrl, history, historyIndex, viewport,\n spinCount, logs, showOverlay, overlayTrace,\n goBack, goForward, reload, overlay, toggleOverlay, submitUrl, download,\n ]);\n\n return (\n <SandboxPreviewCtx.Provider value={value}>\n {children}\n </SandboxPreviewCtx.Provider>\n );\n});\n\n// ---------------------------------------------------------------------------\n// Toolbar — can be rendered standalone (e.g. inside <SandboxPreview>'s stable\n// header) by wrapping in <SandboxPreviewProvider>. `startContent` lets a\n// parent prepend extra controls (e.g. Web/IDE view tabs) to the left\n// of the back/forward buttons.\n// ---------------------------------------------------------------------------\n\nexport interface SandboxPreviewToolbarProps {\n startContent?: ReactNode;\n /** Rendered after the standard nav controls (right-aligned end of the bar). */\n endContent?: ReactNode;\n}\n\nexport function SandboxPreviewToolbar({\n startContent,\n endContent,\n}: SandboxPreviewToolbarProps) {\n const {\n inputValue,\n setInputValue,\n currentUrl,\n history,\n historyIndex,\n viewport,\n setViewport,\n spinCount,\n goBack,\n goForward,\n reload,\n overlay,\n toggleOverlay,\n submitUrl,\n download,\n } = useSandboxPreviewCtx();\n\n return (\n <WebPreviewNavigation>\n {startContent}\n <WebPreviewNavigationButton\n tooltip=\"Back\"\n disabled={historyIndex <= 0}\n onClick={goBack}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton\n tooltip=\"Forward\"\n disabled={historyIndex >= history.length - 1}\n onClick={goForward}\n >\n <ArrowRightIcon className=\"size-4\" />\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton tooltip=\"Reload\" onClick={reload}>\n <RefreshCcwIcon\n key={spinCount}\n className=\"size-4 motion-safe:animate-[spin_0.6s_linear_reverse_1]\"\n />\n </WebPreviewNavigationButton>\n <Input\n className=\"h-8 flex-1 text-sm\"\n placeholder=\"Enter URL...\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n submitUrl();\n } else if (e.key === 'Escape') {\n setInputValue(currentUrl);\n (e.target as HTMLInputElement).blur();\n }\n }}\n />\n <WebPreviewNavigationButton\n tooltip={viewport === 'desktop' ? 'Mobile view' : 'Desktop view'}\n onClick={() =>\n setViewport(viewport === 'desktop' ? 'mobile' : 'desktop')\n }\n >\n {viewport === 'desktop' ? (\n <SmartphoneIcon className=\"size-4\" />\n ) : (\n <MonitorIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n <WebPreviewNavigationButton\n tooltip={overlay ? 'Exit fullscreen' : 'Fullscreen'}\n onClick={toggleOverlay}\n >\n {overlay ? (\n <MinimizeIcon className=\"size-4\" />\n ) : (\n <MaximizeIcon className=\"size-4\" />\n )}\n </WebPreviewNavigationButton>\n {endContent}\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <WebPreviewNavigationButton tooltip=\"More\" />\n }\n >\n <MoreVerticalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-40\">\n <DropdownMenuItem onClick={download}>\n <DownloadIcon className=\"size-4\" />\n Download .zip\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </WebPreviewNavigation>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Body — iframe + viewport animation + error overlay. Safe to wrap in motion.\n// ---------------------------------------------------------------------------\n\nexport function SandboxPreviewWeb() {\n const {\n sandbox,\n iframeProps,\n rest,\n onNavigate,\n containerRef,\n attachHandle,\n viewport,\n showOverlay,\n overlayTrace,\n setRuntimeError,\n } = useSandboxPreviewCtx();\n\n return (\n <div ref={containerRef} className=\"flex-1 min-h-0 flex justify-center bg-muted/30 relative h-full\">\n <motion.div\n initial={false}\n animate={{ width: viewport === 'mobile' ? 390 : '100%' }}\n transition={{ type: 'spring', stiffness: 320, damping: 32, mass: 0.7 }}\n className=\"h-full\"\n >\n <SandboxIFrame\n ref={attachHandle}\n sandbox={sandbox}\n iframeProps={{\n style: {\n width: '100%',\n height: '100%',\n border: 0,\n ...iframeProps?.style,\n },\n ...iframeProps,\n }}\n onNavigate={onNavigate}\n onRuntimeError={setRuntimeError}\n {...rest}\n />\n </motion.div>\n {showOverlay && (\n <div className=\"absolute inset-0 overflow-auto bg-background p-3\">\n <StackTrace defaultOpen trace={overlayTrace}>\n <StackTraceHeader>\n <StackTraceError>\n <StackTraceErrorType />\n <StackTraceErrorMessage />\n </StackTraceError>\n <StackTraceActions>\n <StackTraceCopyButton />\n <StackTraceExpandButton />\n </StackTraceActions>\n </StackTraceHeader>\n <StackTraceContent>\n <StackTraceFrames />\n </StackTraceContent>\n </StackTrace>\n </div>\n )}\n </div>\n );\n}\n\nexport function SandboxPreviewConsole() {\n const { logs } = useSandboxPreviewCtx();\n return <WebPreviewConsole logs={logs} />;\n}\n\nfunction formatArgs(args: unknown[]): string {\n return args.map(formatOne).join(' ');\n}\n\nfunction formatOne(v: unknown): string {\n if (typeof v === 'string') return v;\n if (v === null) return 'null';\n if (v === undefined) return 'undefined';\n if (typeof v === 'function') return '[Function]';\n if (typeof v === 'object') {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n }\n return String(v);\n}\n","import { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n outline:\n \"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n icon: \"size-8\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\"\n\nfunction Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {\n return (\n <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />\n )\n}\n\nfunction CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {\n return (\n <CollapsiblePrimitive.Panel data-slot=\"collapsible-content\" {...props} />\n )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n","import * as React from \"react\"\nimport { Input as InputPrimitive } from \"@base-ui/react/input\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n","import { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction TooltipProvider({\n delay = 0,\n ...props\n}: TooltipPrimitive.Provider.Props) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delay={delay}\n {...props}\n />\n )\n}\n\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n side = \"top\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n children,\n ...props\n}: TooltipPrimitive.Popup.Props &\n Pick<\n TooltipPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n \"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","\"use client\";\n\nimport { Button } from \"../../primitives/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../primitives/ui/collapsible\";\nimport { Input } from \"../../primitives/ui/input\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../../primitives/ui/tooltip\";\nimport { cn } from \"../../primitives/lib/utils\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\nexport interface WebPreviewContextValue {\n url: string;\n setUrl: (url: string) => void;\n consoleOpen: boolean;\n setConsoleOpen: (open: boolean) => void;\n}\n\nexport const WebPreviewContext = createContext<WebPreviewContextValue | null>(null);\n\nconst useWebPreview = () => {\n const context = useContext(WebPreviewContext);\n if (!context) {\n throw new Error(\"WebPreview components must be used within a WebPreview\");\n }\n return context;\n};\n\nexport type WebPreviewProps = ComponentProps<\"div\"> & {\n defaultUrl?: string;\n onUrlChange?: (url: string) => void;\n};\n\nexport const WebPreview = ({\n className,\n children,\n defaultUrl = \"\",\n onUrlChange,\n ...props\n}: WebPreviewProps) => {\n const [url, setUrl] = useState(defaultUrl);\n const [consoleOpen, setConsoleOpen] = useState(false);\n\n const handleUrlChange = useCallback(\n (newUrl: string) => {\n setUrl(newUrl);\n onUrlChange?.(newUrl);\n },\n [onUrlChange]\n );\n\n const contextValue = useMemo<WebPreviewContextValue>(\n () => ({\n consoleOpen,\n setConsoleOpen,\n setUrl: handleUrlChange,\n url,\n }),\n [consoleOpen, handleUrlChange, url]\n );\n\n return (\n <WebPreviewContext.Provider value={contextValue}>\n <div\n className={cn(\n \"flex size-full flex-col rounded-lg border bg-card\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </WebPreviewContext.Provider>\n );\n};\n\nexport type WebPreviewNavigationProps = ComponentProps<\"div\">;\n\nexport const WebPreviewNavigation = ({\n className,\n children,\n ...props\n}: WebPreviewNavigationProps) => (\n <div\n className={cn(\"flex items-center gap-1 border-b p-2\", className)}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type WebPreviewNavigationButtonProps = ComponentProps<typeof Button> & {\n tooltip?: string;\n};\n\nexport const WebPreviewNavigationButton = ({\n onClick,\n disabled,\n tooltip,\n children,\n className,\n ...props\n}: WebPreviewNavigationButtonProps) => (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger\n render={\n <Button\n className={cn(\"h-8 w-8 p-0 hover:text-foreground\", className)}\n disabled={disabled}\n onClick={onClick}\n size=\"sm\"\n variant=\"ghost\"\n {...props}\n />\n }\n >\n {children}\n </TooltipTrigger>\n <TooltipContent>\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n);\n\nexport type WebPreviewUrlProps = ComponentProps<typeof Input>;\n\nexport const WebPreviewUrl = ({\n value,\n onChange,\n onKeyDown,\n ...props\n}: WebPreviewUrlProps) => {\n const { url, setUrl } = useWebPreview();\n const [prevUrl, setPrevUrl] = useState(url);\n const [inputValue, setInputValue] = useState(url);\n\n // Sync input value with context URL when it changes externally (derived state pattern)\n if (url !== prevUrl) {\n setPrevUrl(url);\n setInputValue(url);\n }\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setInputValue(event.target.value);\n onChange?.(event);\n };\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === \"Enter\") {\n const target = event.target as HTMLInputElement;\n setUrl(target.value);\n }\n onKeyDown?.(event);\n },\n [setUrl, onKeyDown]\n );\n\n return (\n <Input\n className=\"h-8 flex-1 text-sm\"\n onChange={onChange ?? handleChange}\n onKeyDown={handleKeyDown}\n placeholder=\"Enter URL...\"\n value={value ?? inputValue}\n {...props}\n />\n );\n};\n\nexport type WebPreviewBodyProps = ComponentProps<\"iframe\"> & {\n loading?: ReactNode;\n};\n\nexport const WebPreviewBody = ({\n className,\n loading,\n src,\n ...props\n}: WebPreviewBodyProps) => {\n const { url } = useWebPreview();\n\n return (\n <div className=\"flex-1\">\n <iframe\n className={cn(\"size-full\", className)}\n // oxlint-disable-next-line eslint-plugin-react(iframe-missing-sandbox)\n sandbox=\"allow-scripts allow-same-origin allow-forms allow-popups allow-presentation\"\n src={(src ?? url) || undefined}\n title=\"Preview\"\n {...props}\n />\n {loading}\n </div>\n );\n};\n\nexport type WebPreviewConsoleProps = ComponentProps<\"div\"> & {\n logs?: {\n level: \"log\" | \"warn\" | \"error\";\n message: string;\n timestamp: Date;\n }[];\n};\n\nexport const WebPreviewConsole = ({\n className,\n logs = [],\n children,\n ...props\n}: WebPreviewConsoleProps) => {\n const { consoleOpen, setConsoleOpen } = useWebPreview();\n\n return (\n <Collapsible\n className={cn(\"border-t bg-muted/50 font-mono text-sm\", className)}\n onOpenChange={setConsoleOpen}\n open={consoleOpen}\n {...props}\n >\n <CollapsibleTrigger render={<Button className=\"flex w-full items-center justify-between p-4 text-left font-medium hover:bg-muted/50\" variant=\"ghost\" />}>Console\n <ChevronDownIcon\n className={cn(\n \"h-4 w-4 transition-transform duration-200\",\n consoleOpen && \"rotate-180\"\n )}\n /></CollapsibleTrigger>\n <CollapsibleContent\n className={cn(\n \"px-4 pb-4\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\"\n )}\n >\n <div className=\"max-h-48 space-y-1 overflow-y-auto\">\n {logs.length === 0 ? (\n <p className=\"text-muted-foreground\">No console output</p>\n ) : (\n logs.map((log) => (\n <div\n className={cn(\n \"text-xs\",\n log.level === \"error\" && \"text-destructive\",\n log.level === \"warn\" && \"text-yellow-600\",\n log.level === \"log\" && \"text-foreground\"\n )}\n key={`${log.timestamp.getTime()}-${log.level}-${log.message}`}\n >\n <span className=\"text-muted-foreground\">\n {log.timestamp.toLocaleTimeString()}\n </span>{\" \"}\n {log.message}\n </div>\n ))\n )}\n {children}\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n};\n","// @ts-nocheck — vendored ai-elements, noUncheckedIndexedAccess complaints\n\"use client\";\n\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { Button } from \"./ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"./ui/collapsible\";\nimport { cn } from \"./lib/utils\";\nimport {\n AlertTriangleIcon,\n CheckIcon,\n ChevronDownIcon,\n CopyIcon,\n} from \"lucide-react\";\nimport type { ComponentProps } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\n// Regex patterns for parsing stack traces\nconst STACK_FRAME_WITH_PARENS_REGEX = /^at\\s+(.+?)\\s+\\((.+):(\\d+):(\\d+)\\)$/;\nconst STACK_FRAME_WITHOUT_FN_REGEX = /^at\\s+(.+):(\\d+):(\\d+)$/;\nconst ERROR_TYPE_REGEX = /^(\\w+Error|Error):\\s*(.*)$/;\nconst AT_PREFIX_REGEX = /^at\\s+/;\n\ninterface StackFrame {\n raw: string;\n functionName: string | null;\n filePath: string | null;\n lineNumber: number | null;\n columnNumber: number | null;\n isInternal: boolean;\n}\n\ninterface ParsedStackTrace {\n errorType: string | null;\n errorMessage: string;\n frames: StackFrame[];\n raw: string;\n}\n\ninterface StackTraceContextValue {\n trace: ParsedStackTrace;\n raw: string;\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n onFilePathClick?: (filePath: string, line?: number, column?: number) => void;\n}\n\nconst StackTraceContext = createContext<StackTraceContextValue | null>(null);\n\nconst useStackTrace = () => {\n const context = useContext(StackTraceContext);\n if (!context) {\n throw new Error(\"StackTrace components must be used within StackTrace\");\n }\n return context;\n};\n\nconst parseStackFrame = (line: string): StackFrame => {\n const trimmed = line.trim();\n\n // Pattern: at functionName (filePath:line:column)\n const withParensMatch = trimmed.match(STACK_FRAME_WITH_PARENS_REGEX);\n if (withParensMatch) {\n const [, functionName, filePath, lineNum, colNum] = withParensMatch;\n const isInternal =\n filePath.includes(\"node_modules\") ||\n filePath.startsWith(\"node:\") ||\n filePath.includes(\"internal/\");\n return {\n columnNumber: colNum ? Number.parseInt(colNum, 10) : null,\n filePath: filePath ?? null,\n functionName: functionName ?? null,\n isInternal,\n lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,\n raw: trimmed,\n };\n }\n\n // Pattern: at filePath:line:column (no function name)\n const withoutFnMatch = trimmed.match(STACK_FRAME_WITHOUT_FN_REGEX);\n if (withoutFnMatch) {\n const [, filePath, lineNum, colNum] = withoutFnMatch;\n const isInternal =\n (filePath?.includes(\"node_modules\") ?? false) ||\n (filePath?.startsWith(\"node:\") ?? false) ||\n (filePath?.includes(\"internal/\") ?? false);\n return {\n columnNumber: colNum ? Number.parseInt(colNum, 10) : null,\n filePath: filePath ?? null,\n functionName: null,\n isInternal,\n lineNumber: lineNum ? Number.parseInt(lineNum, 10) : null,\n raw: trimmed,\n };\n }\n\n // Fallback: unparseable line\n return {\n columnNumber: null,\n filePath: null,\n functionName: null,\n isInternal: trimmed.includes(\"node_modules\") || trimmed.includes(\"node:\"),\n lineNumber: null,\n raw: trimmed,\n };\n};\n\nconst parseStackTrace = (trace: string): ParsedStackTrace => {\n const lines = trace.split(\"\\n\").filter((line) => line.trim());\n\n if (lines.length === 0) {\n return {\n errorMessage: trace,\n errorType: null,\n frames: [],\n raw: trace,\n };\n }\n\n const firstLine = lines[0].trim();\n let errorType: string | null = null;\n let errorMessage = firstLine;\n\n // Try to extract error type from \"ErrorType: message\" format\n const errorMatch = firstLine.match(ERROR_TYPE_REGEX);\n if (errorMatch) {\n const [, type, msg] = errorMatch;\n errorType = type;\n errorMessage = msg || \"\";\n }\n\n // Parse stack frames (lines starting with \"at\")\n const frames = lines\n .slice(1)\n .filter((line) => line.trim().startsWith(\"at \"))\n .map(parseStackFrame);\n\n return {\n errorMessage,\n errorType,\n frames,\n raw: trace,\n };\n};\n\nexport type StackTraceProps = ComponentProps<\"div\"> & {\n trace: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n onFilePathClick?: (filePath: string, line?: number, column?: number) => void;\n};\n\nexport const StackTrace = memo(\n ({\n trace,\n className,\n open,\n defaultOpen = false,\n onOpenChange,\n onFilePathClick,\n children,\n ...props\n }: StackTraceProps) => {\n const [isOpen, setIsOpen] = useControllableState({\n defaultProp: defaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n\n const parsedTrace = useMemo(() => parseStackTrace(trace), [trace]);\n\n const contextValue = useMemo(\n () => ({\n isOpen,\n onFilePathClick,\n raw: trace,\n setIsOpen,\n trace: parsedTrace,\n }),\n [parsedTrace, trace, isOpen, setIsOpen, onFilePathClick]\n );\n\n return (\n <StackTraceContext.Provider value={contextValue}>\n <div\n className={cn(\n \"not-prose w-full overflow-hidden rounded-lg border bg-background font-mono text-sm\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </StackTraceContext.Provider>\n );\n }\n);\n\nexport type StackTraceHeaderProps = ComponentProps<typeof CollapsibleTrigger>;\n\nexport const StackTraceHeader = memo(\n ({ className, children, ...props }: StackTraceHeaderProps) => {\n const { isOpen, setIsOpen } = useStackTrace();\n\n return (\n <Collapsible onOpenChange={setIsOpen} open={isOpen}>\n <CollapsibleTrigger {...props} render={<div className={cn(\n \"flex w-full cursor-pointer items-center gap-3 p-3 text-left transition-colors hover:bg-muted/50\",\n className\n )} />}>{children}</CollapsibleTrigger>\n </Collapsible>\n );\n }\n);\n\nexport type StackTraceErrorProps = ComponentProps<\"div\">;\n\nexport const StackTraceError = memo(\n ({ className, children, ...props }: StackTraceErrorProps) => (\n <div\n className={cn(\n \"flex flex-1 items-center gap-2 overflow-hidden\",\n className\n )}\n {...props}\n >\n <AlertTriangleIcon className=\"size-4 shrink-0 text-destructive\" />\n {children}\n </div>\n )\n);\n\nexport type StackTraceErrorTypeProps = ComponentProps<\"span\">;\n\nexport const StackTraceErrorType = memo(\n ({ className, children, ...props }: StackTraceErrorTypeProps) => {\n const { trace } = useStackTrace();\n\n return (\n <span\n className={cn(\"shrink-0 font-semibold text-destructive\", className)}\n {...props}\n >\n {children ?? trace.errorType}\n </span>\n );\n }\n);\n\nexport type StackTraceErrorMessageProps = ComponentProps<\"span\">;\n\nexport const StackTraceErrorMessage = memo(\n ({ className, children, ...props }: StackTraceErrorMessageProps) => {\n const { trace } = useStackTrace();\n\n return (\n <span className={cn(\"truncate text-foreground\", className)} {...props}>\n {children ?? trace.errorMessage}\n </span>\n );\n }\n);\n\nexport type StackTraceActionsProps = ComponentProps<\"div\">;\n\nconst handleActionsClick = (e: React.MouseEvent) => e.stopPropagation();\nconst handleActionsKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.stopPropagation();\n }\n};\n\nexport const StackTraceActions = memo(\n ({ className, children, ...props }: StackTraceActionsProps) => (\n <div\n className={cn(\"flex shrink-0 items-center gap-1\", className)}\n onClick={handleActionsClick}\n onKeyDown={handleActionsKeyDown}\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n )\n);\n\nexport type StackTraceCopyButtonProps = ComponentProps<typeof Button> & {\n onCopy?: () => void;\n onError?: (error: Error) => void;\n timeout?: number;\n};\n\nexport const StackTraceCopyButton = memo(\n ({\n onCopy,\n onError,\n timeout = 2000,\n className,\n children,\n ...props\n }: StackTraceCopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number>(0);\n const { raw } = useStackTrace();\n\n const copyToClipboard = useCallback(async () => {\n if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n onError?.(new Error(\"Clipboard API not available\"));\n return;\n }\n\n try {\n await navigator.clipboard.writeText(raw);\n setIsCopied(true);\n onCopy?.();\n timeoutRef.current = window.setTimeout(\n () => setIsCopied(false),\n timeout\n );\n } catch (error) {\n onError?.(error as Error);\n }\n }, [raw, onCopy, onError, timeout]);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current);\n },\n []\n );\n\n const Icon = isCopied ? CheckIcon : CopyIcon;\n\n return (\n <Button\n className={cn(\"size-7\", className)}\n onClick={copyToClipboard}\n size=\"icon\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <Icon size={14} />}\n </Button>\n );\n }\n);\n\nexport type StackTraceExpandButtonProps = ComponentProps<\"div\">;\n\nexport const StackTraceExpandButton = memo(\n ({ className, ...props }: StackTraceExpandButtonProps) => {\n const { isOpen } = useStackTrace();\n\n return (\n <div\n className={cn(\"flex size-7 items-center justify-center\", className)}\n {...props}\n >\n <ChevronDownIcon\n className={cn(\n \"size-4 text-muted-foreground transition-transform\",\n isOpen ? \"rotate-180\" : \"rotate-0\"\n )}\n />\n </div>\n );\n }\n);\n\nexport type StackTraceContentProps = ComponentProps<\n typeof CollapsibleContent\n> & {\n maxHeight?: number;\n};\n\nexport const StackTraceContent = memo(\n ({\n className,\n maxHeight = 400,\n children,\n ...props\n }: StackTraceContentProps) => {\n const { isOpen } = useStackTrace();\n\n return (\n <Collapsible open={isOpen}>\n <CollapsibleContent\n className={cn(\n \"overflow-auto border-t bg-muted/30\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n style={{ maxHeight }}\n {...props}\n >\n {children}\n </CollapsibleContent>\n </Collapsible>\n );\n }\n);\n\nexport type StackTraceFramesProps = ComponentProps<\"div\"> & {\n showInternalFrames?: boolean;\n};\n\ninterface FilePathButtonProps {\n frame: StackFrame;\n onFilePathClick?: (\n filePath: string,\n lineNumber?: number,\n columnNumber?: number\n ) => void;\n}\n\nconst FilePathButton = memo(\n ({ frame, onFilePathClick }: FilePathButtonProps) => {\n const handleClick = useCallback(() => {\n if (frame.filePath) {\n onFilePathClick?.(\n frame.filePath,\n frame.lineNumber ?? undefined,\n frame.columnNumber ?? undefined\n );\n }\n }, [frame, onFilePathClick]);\n\n return (\n <button\n className={cn(\n \"underline decoration-dotted hover:text-primary\",\n onFilePathClick && \"cursor-pointer\"\n )}\n disabled={!onFilePathClick}\n onClick={handleClick}\n type=\"button\"\n >\n {frame.filePath}\n {frame.lineNumber !== null && `:${frame.lineNumber}`}\n {frame.columnNumber !== null && `:${frame.columnNumber}`}\n </button>\n );\n }\n);\n\nFilePathButton.displayName = \"FilePathButton\";\n\nexport const StackTraceFrames = memo(\n ({\n className,\n showInternalFrames = true,\n ...props\n }: StackTraceFramesProps) => {\n const { trace, onFilePathClick } = useStackTrace();\n\n const framesToShow = showInternalFrames\n ? trace.frames\n : trace.frames.filter((f) => !f.isInternal);\n\n return (\n <div className={cn(\"space-y-1 p-3\", className)} {...props}>\n {framesToShow.map((frame) => (\n <div\n className={cn(\n \"text-xs\",\n frame.isInternal\n ? \"text-muted-foreground/50\"\n : \"text-foreground/90\"\n )}\n key={frame.raw}\n >\n <span className=\"text-muted-foreground\">at </span>\n {frame.functionName && (\n <span className={frame.isInternal ? \"\" : \"text-foreground\"}>\n {frame.functionName}{\" \"}\n </span>\n )}\n {frame.filePath && (\n <>\n <span className=\"text-muted-foreground\">(</span>\n <FilePathButton\n frame={frame}\n onFilePathClick={onFilePathClick}\n />\n <span className=\"text-muted-foreground\">)</span>\n </>\n )}\n {!(frame.filePath || frame.functionName) && (\n <span>{frame.raw.replace(AT_PREFIX_REGEX, \"\")}</span>\n )}\n </div>\n ))}\n {framesToShow.length === 0 && (\n <div className=\"text-muted-foreground text-xs\">No stack frames</div>\n )}\n </div>\n );\n }\n);\n\nStackTrace.displayName = \"StackTrace\";\nStackTraceHeader.displayName = \"StackTraceHeader\";\nStackTraceError.displayName = \"StackTraceError\";\nStackTraceErrorType.displayName = \"StackTraceErrorType\";\nStackTraceErrorMessage.displayName = \"StackTraceErrorMessage\";\nStackTraceActions.displayName = \"StackTraceActions\";\nStackTraceCopyButton.displayName = \"StackTraceCopyButton\";\nStackTraceExpandButton.displayName = \"StackTraceExpandButton\";\nStackTraceContent.displayName = \"StackTraceContent\";\nStackTraceFrames.displayName = \"StackTraceFrames\";\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\n\nimport { cn } from \"../lib/utils\"\nimport { ChevronRightIcon, CheckIcon } from \"lucide-react\"\n\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\n return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />\n}\n\nfunction DropdownMenuContent({\n align = \"start\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 4,\n className,\n ...props\n}: MenuPrimitive.Popup.Props &\n Pick<\n MenuPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <MenuPrimitive.Portal>\n <MenuPrimitive.Positioner\n className=\"isolate z-50 outline-none\"\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n >\n <MenuPrimitive.Popup\n data-slot=\"dropdown-menu-content\"\n className={cn(\"z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n {...props}\n />\n </MenuPrimitive.Positioner>\n </MenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\n return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: MenuPrimitive.GroupLabel.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.GroupLabel\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: MenuPrimitive.Item.Props & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <MenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.SubmenuTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </MenuPrimitive.SubmenuTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n align = \"start\",\n alignOffset = -3,\n side = \"right\",\n sideOffset = 0,\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) {\n return (\n <DropdownMenuContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\"w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-checkbox-item-indicator\"\n >\n <MenuPrimitive.CheckboxItemIndicator>\n <CheckIcon\n />\n </MenuPrimitive.CheckboxItemIndicator>\n </span>\n {children}\n </MenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n return (\n <MenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n inset,\n ...props\n}: MenuPrimitive.RadioItem.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-radio-item-indicator\"\n >\n <MenuPrimitive.RadioItemIndicator>\n <CheckIcon\n />\n </MenuPrimitive.RadioItemIndicator>\n </span>\n {children}\n </MenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: MenuPrimitive.Separator.Props) {\n return (\n <MenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","// `<SandboxFileTree>` — file tree only. Reads `selectedPath` /\n// `setSelectedPath` from `useElementsContext`. Subscribes to\n// `sandbox.fs` change events so the tree mirrors mutations.\n//\n// `display=\"dropdown\"` collapses the tree behind a folder-icon\n// `<Popover>` trigger — useful for mobile / narrow side panels.\n\nimport { useEffect, useMemo, useState, type ReactNode } from 'react';\nimport { MenuIcon } from 'lucide-react';\nimport type { Sandbox } from '@browsernode/sandbox';\nimport { FileTree } from './primitives/file-tree';\nimport { useElementsContext, useSandbox } from '../provider/sandbox-provider';\nimport { Button } from '../primitives/ui/button';\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../primitives/ui/popover';\nimport {\n buildTree,\n defaultExpansion,\n isFile,\n renderTree,\n} from './internal/tree';\n\nexport interface SandboxFileTreeProps {\n /** Override the sandbox from the surrounding `<SandboxProvider>`. */\n sandbox?: Sandbox | null;\n /** Initial folders to expand. Defaults to common roots when present. */\n defaultExpanded?: Set<string>;\n /**\n * Called when a file is selected. Fires *in addition* to updating the\n * elements context's `selectedPath`.\n */\n onSelect?: (path: string) => void;\n /**\n * Render mode:\n * • `\"tree\"` (default) — full inline tree, expects a parent that\n * gives it height to scroll within\n * • `\"dropdown\"` — folder-icon button that opens a popover with the\n * tree inside; selecting a file closes the popover\n */\n display?: 'tree' | 'dropdown';\n /**\n * Trigger contents (dropdown variant). Defaults to a hamburger icon\n * + \"Select file\" label.\n */\n triggerLabel?: ReactNode;\n className?: string;\n}\n\nexport function SandboxFileTree({\n sandbox: sandboxProp,\n defaultExpanded,\n onSelect,\n display = 'tree',\n triggerLabel,\n className,\n}: SandboxFileTreeProps) {\n const elementsCtx = useElementsContext();\n const sandboxState = useSandbox();\n const sandbox = sandboxProp ?? sandboxState.sandbox;\n\n const [files, setFiles] = useState<string[]>(() =>\n sandbox ? sandbox.fs.list() : [],\n );\n const [open, setOpen] = useState(false);\n\n const selectedPath = elementsCtx?.selectedPath ?? null;\n const setSelectedPath = elementsCtx?.setSelectedPath;\n\n useEffect(() => {\n if (!sandbox) return;\n setFiles(sandbox.fs.list());\n return sandbox.fs.on('change', () => setFiles(sandbox.fs.list()));\n }, [sandbox]);\n\n const tree = useMemo(() => buildTree(files), [files]);\n\n const handleSelect = (path: string) => {\n if (!isFile(path, files)) return;\n setSelectedPath?.(path);\n onSelect?.(path);\n if (display === 'dropdown') setOpen(false);\n };\n\n const treeNode = (\n <FileTree\n defaultExpanded={defaultExpanded ?? defaultExpansion(files)}\n onSelect={handleSelect}\n selectedPath={selectedPath ?? undefined}\n className={`h-full w-full overflow-auto rounded-none border-0 bg-transparent ${className ?? ''}`.trim()}\n >\n {renderTree(tree)}\n </FileTree>\n );\n\n if (display === 'dropdown') {\n // Default trigger contents adapt to selection state: with no file\n // selected, the button reads \"[☰] Select a file\" so the empty\n // state has a single self-explanatory affordance. Once a file is\n // selected, the button collapses to the icon only — the surrounding\n // header (or whatever the consumer composes) is responsible for\n // showing the filename next to it.\n const defaultLabel = selectedPath ? (\n <MenuIcon className=\"size-4\" />\n ) : (\n <>\n <MenuIcon className=\"size-4\" />\n <span>Select a file</span>\n </>\n );\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger\n render={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"Select file\"\n className={`h-8 gap-2 px-2 text-xs font-normal ${className ?? ''}`.trim()}\n />\n }\n >\n {triggerLabel ?? defaultLabel}\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"w-72 p-0 max-h-[26rem] flex flex-col overflow-hidden\"\n >\n {treeNode}\n </PopoverContent>\n </Popover>\n );\n }\n\n return treeNode;\n}\n","\"use client\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../../primitives/ui/collapsible\";\nimport { cn } from \"../../primitives/lib/utils\";\nimport {\n ChevronRightIcon,\n FileIcon,\n FolderIcon,\n FolderOpenIcon,\n} from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\ninterface FileTreeContextType {\n expandedPaths: Set<string>;\n togglePath: (path: string) => void;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {};\n\nconst FileTreeContext = createContext<FileTreeContextType>({\n // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)\n expandedPaths: new Set(),\n togglePath: noop,\n});\n\nexport type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> & {\n expanded?: Set<string>;\n defaultExpanded?: Set<string>;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n onExpandedChange?: (expanded: Set<string>) => void;\n};\n\nexport const FileTree = ({\n expanded: controlledExpanded,\n defaultExpanded = new Set(),\n selectedPath,\n onSelect,\n onExpandedChange,\n className,\n children,\n ...props\n}: FileTreeProps) => {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const expandedPaths = controlledExpanded ?? internalExpanded;\n\n const togglePath = useCallback(\n (path: string) => {\n const newExpanded = new Set(expandedPaths);\n if (newExpanded.has(path)) {\n newExpanded.delete(path);\n } else {\n newExpanded.add(path);\n }\n setInternalExpanded(newExpanded);\n onExpandedChange?.(newExpanded);\n },\n [expandedPaths, onExpandedChange]\n );\n\n const contextValue = useMemo(\n () => ({ expandedPaths, onSelect, selectedPath, togglePath }),\n [expandedPaths, onSelect, selectedPath, togglePath]\n );\n\n return (\n <FileTreeContext.Provider value={contextValue}>\n <div\n className={cn(\n \"rounded-lg border bg-background font-mono text-sm\",\n className\n )}\n role=\"tree\"\n {...props}\n >\n <div className=\"p-2\">{children}</div>\n </div>\n </FileTreeContext.Provider>\n );\n};\n\nexport type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeIcon = ({\n className,\n children,\n ...props\n}: FileTreeIconProps) => (\n <span className={cn(\"shrink-0\", className)} {...props}>\n {children}\n </span>\n);\n\nexport type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeName = ({\n className,\n children,\n ...props\n}: FileTreeNameProps) => (\n <span className={cn(\"truncate\", className)} {...props}>\n {children}\n </span>\n);\n\ninterface FileTreeFolderContextType {\n path: string;\n name: string;\n isExpanded: boolean;\n}\n\nconst FileTreeFolderContext = createContext<FileTreeFolderContextType>({\n isExpanded: false,\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n};\n\nexport const FileTreeFolder = ({\n path,\n name,\n className,\n children,\n ...props\n}: FileTreeFolderProps) => {\n const { expandedPaths, togglePath, selectedPath, onSelect } =\n useContext(FileTreeContext);\n const isExpanded = expandedPaths.has(path);\n const isSelected = selectedPath === path;\n\n const handleOpenChange = useCallback(() => {\n togglePath(path);\n }, [togglePath, path]);\n\n const handleSelect = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const folderContextValue = useMemo(\n () => ({ isExpanded, name, path }),\n [isExpanded, name, path]\n );\n\n return (\n <FileTreeFolderContext.Provider value={folderContextValue}>\n <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>\n <div\n className={cn(\"\", className)}\n role=\"treeitem\"\n tabIndex={0}\n {...props}\n >\n <div\n className={cn(\n \"flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\"\n )}\n >\n <CollapsibleTrigger render={<button className=\"flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0\" type=\"button\" />}><ChevronRightIcon\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform\",\n isExpanded && \"rotate-90\"\n )}\n /></CollapsibleTrigger>\n <button\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n onClick={() => {\n handleSelect();\n togglePath(path);\n }}\n type=\"button\"\n >\n <FileTreeIcon>\n {isExpanded ? (\n <FolderOpenIcon className=\"size-4 text-blue-500\" />\n ) : (\n <FolderIcon className=\"size-4 text-blue-500\" />\n )}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ml-4 border-l pl-2\">{children}</div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n </FileTreeFolderContext.Provider>\n );\n};\n\ninterface FileTreeFileContextType {\n path: string;\n name: string;\n}\n\nconst FileTreeFileContext = createContext<FileTreeFileContextType>({\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFileProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n icon?: ReactNode;\n};\n\nexport const FileTreeFile = ({\n path,\n name,\n icon,\n className,\n children,\n ...props\n}: FileTreeFileProps) => {\n const { selectedPath, onSelect } = useContext(FileTreeContext);\n const isSelected = selectedPath === path;\n\n const handleClick = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n onSelect?.(path);\n }\n },\n [onSelect, path]\n );\n\n const fileContextValue = useMemo(() => ({ name, path }), [name, path]);\n\n return (\n <FileTreeFileContext.Provider value={fileContextValue}>\n <div\n className={cn(\n \"flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\",\n className\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n role=\"treeitem\"\n tabIndex={0}\n {...props}\n >\n {children ?? (\n <>\n {/* Spacer for alignment */}\n <span className=\"size-4 shrink-0\" />\n <FileTreeIcon>\n {icon ?? <FileIcon className=\"size-4 text-muted-foreground\" />}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </>\n )}\n </div>\n </FileTreeFileContext.Provider>\n );\n};\n\nexport type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>;\n\nconst stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();\n\nexport const FileTreeActions = ({\n className,\n children,\n ...props\n}: FileTreeActionsProps) => (\n <div\n className={cn(\"ml-auto flex items-center gap-1\", className)}\n onClick={stopPropagation}\n onKeyDown={stopPropagation}\n role=\"group\"\n {...props}\n >\n {children}\n </div>\n);\n","import * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 4,\n ...props\n}: PopoverPrimitive.Popup.Props &\n Pick<\n PopoverPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <PopoverPrimitive.Popup\n data-slot=\"popover-content\"\n className={cn(\n \"z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )\n}\n\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"popover-header\"\n className={cn(\"flex flex-col gap-0.5 text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\n return (\n <PopoverPrimitive.Title\n data-slot=\"popover-title\"\n className={cn(\"font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction PopoverDescription({\n className,\n ...props\n}: PopoverPrimitive.Description.Props) {\n return (\n <PopoverPrimitive.Description\n data-slot=\"popover-description\"\n className={cn(\"text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Popover,\n PopoverContent,\n PopoverDescription,\n PopoverHeader,\n PopoverTitle,\n PopoverTrigger,\n}\n","// Shared tree builders for SandboxIDEFiles. Consumes a flat list of\n// absolute paths from `sandbox.fs.list()` and produces nodes the\n// FileTree primitive renders.\n\nimport type { ReactNode } from 'react';\nimport { FileTreeFile, FileTreeFolder } from '../primitives/file-tree';\n\ninterface TreeNode {\n name: string;\n path: string;\n /** null = file leaf. */\n children: Map<string, TreeNode> | null;\n}\n\nexport function buildTree(paths: string[]): TreeNode {\n const root: TreeNode = { name: '', path: '', children: new Map() };\n for (const path of paths) {\n const parts = path.split('/').filter(Boolean);\n let cur = root;\n for (let i = 0; i < parts.length; i++) {\n const name = parts[i]!;\n const isLeaf = i === parts.length - 1;\n // Tree paths are absolute (`/src/app/page.tsx`) so they match\n // `sandbox.fs.list()` output and `selectedPath` flows through\n // `fs.readFile` consistently.\n const childPath = '/' + parts.slice(0, i + 1).join('/');\n if (!cur.children) break;\n let child = cur.children.get(name);\n if (!child) {\n child = { name, path: childPath, children: isLeaf ? null : new Map() };\n cur.children.set(name, child);\n }\n if (!isLeaf && child.children) cur = child;\n else if (!isLeaf && !child.children) break; // path collision\n }\n }\n return root;\n}\n\nexport function renderTree(node: TreeNode): ReactNode {\n if (!node.children) return null;\n // Folders first, then files; alphabetical within each group.\n const entries = Array.from(node.children.values()).sort((a, b) => {\n const aFolder = a.children !== null;\n const bFolder = b.children !== null;\n if (aFolder !== bFolder) return aFolder ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n return entries.map((entry) =>\n entry.children ? (\n <FileTreeFolder key={entry.path} name={entry.name} path={entry.path}>\n {renderTree(entry)}\n </FileTreeFolder>\n ) : (\n <FileTreeFile key={entry.path} name={entry.name} path={entry.path} />\n ),\n );\n}\n\nexport function isFile(path: string, files: string[]): boolean {\n return files.includes(path);\n}\n\nexport function defaultExpansion(files: string[]): Set<string> {\n const roots = ['src', 'app', 'pages', 'components'];\n const expanded = new Set<string>();\n for (const root of roots) {\n const abs = '/' + root;\n if (files.some((f) => f === abs || f.startsWith(`${abs}/`))) {\n expanded.add(abs);\n }\n }\n return expanded;\n}\n","// `<SandboxCodeEditor>` — header chrome (filename + Save + More dropdown)\n// + a buffered CodeMirror editor. Reads `selectedPath` from elements\n// context; loads file contents on selection change; persists via\n// `sandbox.fs.writeFile` on Save (button or Cmd/Ctrl+S).\n//\n// CodeMirror knobs (theme, basicSetup, extensions, language) are passed\n// straight through to the underlying `<CodeEditor>` so callers can tune\n// the editor without dropping down a level.\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { MoreHorizontalIcon } from 'lucide-react';\nimport type { Extension } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport type { ReactCodeMirrorProps } from '@uiw/react-codemirror';\nimport type { Sandbox } from '@browsernode/sandbox';\nimport {\n CodeEditor,\n type CodeEditorLanguage,\n type CodeEditorTheme,\n} from './primitives/code-editor';\nimport { Button } from '../primitives/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../primitives/ui/dropdown-menu';\nimport { Loader } from '../primitives/ui/loading';\nimport { useElementsContext, useSandbox } from '../provider/sandbox-provider';\nimport { guessLanguage } from './internal/language';\n\nexport interface SandboxCodeEditorProps {\n /** Override the sandbox from the surrounding `<SandboxProvider>`. */\n sandbox?: Sandbox | null;\n /** Disable saves (Save button hidden, Cmd-S no-op). Default false. */\n readOnly?: boolean;\n /** CodeMirror theme override (forwarded to `<CodeEditor>`). */\n theme?: CodeEditorTheme;\n /** CodeMirror basic-setup overrides (line numbers, fold gutter, etc.). */\n basicSetup?: ReactCodeMirrorProps['basicSetup'];\n /** Extra CodeMirror extensions appended after the language ones. */\n extensions?: Extension[];\n /** Force a CodeMirror language regardless of file extension. */\n language?: CodeEditorLanguage;\n /** Hide the file header (filename + dirty dot + Save + More). */\n hideHeader?: boolean;\n /** Custom empty state when no file is selected. */\n emptyState?: ReactNode;\n /**\n * Slot rendered inside the header, immediately after the filename and\n * before the Save button. Used by `<SandboxIDELayout>` to inject the\n * mobile dropdown trigger; consumers can use it for any leading chrome.\n */\n headerStartSlot?: ReactNode;\n className?: string;\n}\n\ntype SaveStatus = 'idle' | 'saving' | 'saved' | 'error';\n\nexport function SandboxCodeEditor({\n sandbox: sandboxProp,\n readOnly = false,\n theme,\n basicSetup,\n extensions,\n language: languageProp,\n hideHeader = false,\n emptyState,\n headerStartSlot,\n className,\n}: SandboxCodeEditorProps) {\n const elementsCtx = useElementsContext();\n const sandboxState = useSandbox();\n const sandbox = sandboxProp ?? sandboxState.sandbox;\n\n const selectedPath = elementsCtx?.selectedPath ?? null;\n const setSelectedPath = elementsCtx?.setSelectedPath;\n\n const [savedText, setSavedText] = useState<string | null>(null);\n const [buffer, setBuffer] = useState<string>('');\n const [loadingPath, setLoadingPath] = useState<string | null>(null);\n const [saveStatus, setSaveStatus] = useState<SaveStatus>('idle');\n\n // Path the editor's current `buffer` was loaded from. Used to ignore\n // stale onChange callbacks during file-switch (CodeMirror's controlled\n // value briefly lags one frame).\n const loadedPathRef = useRef<string | null>(null);\n const savedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Refs for stable callbacks (Cmd-S keymap, delete handler).\n const sandboxRef = useRef(sandbox);\n const selectedPathRef = useRef(selectedPath);\n const bufferRef = useRef(buffer);\n const dirtyRef = useRef(false);\n sandboxRef.current = sandbox;\n selectedPathRef.current = selectedPath;\n bufferRef.current = buffer;\n\n useEffect(() => {\n if (!sandbox || !selectedPath) {\n setSavedText(null);\n setBuffer('');\n loadedPathRef.current = null;\n return;\n }\n setLoadingPath(selectedPath);\n setSaveStatus('idle');\n let cancelled = false;\n sandbox.fs\n .readFile(selectedPath)\n .then((c) => {\n if (cancelled) return;\n setSavedText(c);\n setBuffer(c);\n loadedPathRef.current = selectedPath;\n setLoadingPath(null);\n })\n .catch(() => {\n if (cancelled) return;\n const fallback = `// Could not read ${selectedPath}`;\n setSavedText(fallback);\n setBuffer(fallback);\n loadedPathRef.current = null;\n setLoadingPath(null);\n });\n return () => {\n cancelled = true;\n };\n }, [sandbox, selectedPath]);\n\n useEffect(() => {\n return () => {\n if (savedTimerRef.current) {\n clearTimeout(savedTimerRef.current);\n savedTimerRef.current = null;\n }\n };\n }, [selectedPath]);\n\n const handleEditorChange = useCallback(\n (next: string) => {\n setBuffer(next);\n if (readOnly) return;\n if (!selectedPath) return;\n // Drop changes fired before the load has settled on this path.\n if (loadedPathRef.current !== selectedPath) return;\n },\n [readOnly, selectedPath],\n );\n\n const dirty = !readOnly && savedText !== null && buffer !== savedText;\n dirtyRef.current = dirty;\n\n const deleteFile = useCallback(async () => {\n if (readOnly) return;\n const sb = sandboxRef.current;\n const path = selectedPathRef.current;\n if (!sb || !path) return;\n try {\n await sb.fs.rm(path);\n setSelectedPath?.(null);\n } catch {\n // Surfaces via sandbox.on('error') if anyone's listening.\n }\n }, [readOnly, setSelectedPath]);\n\n const save = useCallback(async () => {\n if (readOnly) return;\n const sb = sandboxRef.current;\n const path = selectedPathRef.current;\n const text = bufferRef.current;\n if (!sb || !path) return;\n if (!dirtyRef.current) return;\n // The in-memory write resolves the same microtask, so React would\n // batch this with the 'saved' set below and never paint the spinner.\n // The minimum-duration delay below holds the spinner visible long\n // enough to register visually.\n setSaveStatus('saving');\n try {\n await sb.fs.writeFile(path, text);\n await new Promise((r) => setTimeout(r, 500));\n setSavedText(text);\n setSaveStatus('idle');\n } catch {\n setSaveStatus('error');\n }\n }, [readOnly]);\n\n // Cmd/Ctrl+S keybinding. Stable extension array so we don't rebuild\n // CodeMirror on every keystroke.\n const editorExtensions = useMemo<Extension[]>(\n () => {\n const base = [\n keymap.of([\n {\n key: 'Mod-s',\n preventDefault: true,\n run: () => {\n void save();\n return true;\n },\n },\n ]),\n ];\n return extensions ? [...base, ...extensions] : base;\n },\n [save, extensions],\n );\n\n const lang: CodeEditorLanguage = languageProp\n ? languageProp\n : selectedPath\n ? guessLanguage(selectedPath)\n : 'plaintext';\n\n // Always render the outer column + header, even with no file selected,\n // so callers' `headerStartSlot` (typically the file-tree dropdown\n // trigger) stays reachable. Otherwise the user would be locked out of\n // the picker on mobile.\n //\n // When a slot is provided AND no file is selected, the slot owns the\n // empty-state messaging (e.g. the dropdown trigger reads \"Select a\n // file\"). We don't add a separate label so the text isn't duplicated.\n // Show just the basename in the header — full paths get long fast and\n // crowd out the Save/More buttons. Hover/title still exposes the full\n // path for orientation.\n const filename = selectedPath\n ? selectedPath.split('/').filter(Boolean).pop() ?? selectedPath\n : null;\n const headerLabel = selectedPath ? (\n <span className=\"font-mono\" title={selectedPath}>\n {filename}\n </span>\n ) : headerStartSlot ? null : (\n <span>Select a file</span>\n );\n\n return (\n <div className={`flex h-full w-full flex-col ${className ?? ''}`.trim()}>\n {!hideHeader && (\n <div className=\"flex flex-none items-center justify-between border-b px-3 py-2 text-xs\">\n <div className=\"flex items-center gap-1.5 text-muted-foreground\">\n {headerStartSlot}\n {headerLabel}\n </div>\n {selectedPath && !readOnly && (\n <div className=\"flex items-center gap-1\">\n <Button\n size=\"sm\"\n onClick={() => void save()}\n className=\"h-9 px-4 text-sm md:h-8 md:px-3 md:text-xs\"\n >\n {saveStatus === 'saving' ? (\n <>\n <Loader size={14} />\n Saving...\n </>\n ) : (\n 'Save'\n )}\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"File actions\"\n className=\"size-10 p-0 md:size-8\"\n />\n }\n >\n <MoreHorizontalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem\n onClick={() => void deleteFile()}\n className=\"text-destructive focus:text-destructive\"\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )}\n </div>\n )}\n <div className=\"flex-1 min-h-0 overflow-auto\">\n {selectedPath ? (\n <CodeEditor\n key={selectedPath}\n value={buffer}\n onChange={handleEditorChange}\n language={lang}\n theme={theme}\n basicSetup={basicSetup}\n readOnly={readOnly || loadingPath === selectedPath}\n extensions={editorExtensions}\n height=\"100%\"\n className=\"h-full text-sm\"\n />\n ) : (\n emptyState ?? (\n <div className=\"flex h-full w-full items-center justify-center text-muted-foreground text-sm\">\n Select a file from the menu\n </div>\n )\n )}\n </div>\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport CodeMirror, {\n EditorView,\n type Extension,\n type ReactCodeMirrorProps,\n} from '@uiw/react-codemirror';\nimport { javascript } from '@codemirror/lang-javascript';\nimport { css } from '@codemirror/lang-css';\nimport { html } from '@codemirror/lang-html';\nimport { json } from '@codemirror/lang-json';\nimport { markdown } from '@codemirror/lang-markdown';\nimport { useElementsContext } from '../../provider/sandbox-provider';\n\nexport type CodeEditorLanguage =\n | 'typescript'\n | 'tsx'\n | 'javascript'\n | 'jsx'\n | 'css'\n | 'html'\n | 'json'\n | 'markdown'\n | 'plaintext';\n\nexport type CodeEditorTheme = 'light' | 'dark' | Extension;\n\nexport interface CodeEditorProps\n extends Omit<\n ReactCodeMirrorProps,\n 'value' | 'onChange' | 'extensions' | 'theme'\n > {\n value: string;\n onChange?: (next: string) => void;\n language?: CodeEditorLanguage;\n /**\n * Editor color scheme. If omitted, falls back to `<SandboxProvider>`'s\n * `theme` (or `'light'` when no provider is mounted). Pass an\n * `Extension` to fully override CodeMirror's theme system.\n */\n theme?: CodeEditorTheme;\n /** Extra CodeMirror extensions appended to the language-derived ones. */\n extensions?: Extension[];\n className?: string;\n}\n\n/**\n * `<CodeEditor>` — thin CodeMirror 6 wrapper. Pass `value` + `onChange`\n * for controlled editing; `language` selects the syntax extension.\n *\n * The host is responsible for debouncing writes back to disk; this\n * component fires `onChange` for every keystroke.\n */\nexport function CodeEditor({\n value,\n onChange,\n language = 'plaintext',\n theme,\n extensions: extraExtensions,\n className,\n basicSetup,\n ...rest\n}: CodeEditorProps) {\n const ctx = useElementsContext();\n const resolvedTheme: CodeEditorTheme = theme ?? ctx?.theme ?? 'light';\n\n const extensions = useMemo<Extension[]>(() => {\n const langExt = languageExtension(language);\n const wrap = EditorView.lineWrapping;\n const base: Extension[] = [wrap];\n if (langExt) base.push(langExt);\n return extraExtensions ? [...base, ...extraExtensions] : base;\n }, [language, extraExtensions]);\n\n return (\n <CodeMirror\n value={value}\n onChange={onChange}\n extensions={extensions}\n theme={resolvedTheme}\n basicSetup={\n basicSetup ?? {\n lineNumbers: true,\n highlightActiveLine: true,\n highlightActiveLineGutter: true,\n foldGutter: true,\n autocompletion: true,\n bracketMatching: true,\n closeBrackets: true,\n indentOnInput: true,\n searchKeymap: true,\n }\n }\n className={className}\n {...rest}\n />\n );\n}\n\nfunction languageExtension(lang: CodeEditorLanguage): Extension | null {\n switch (lang) {\n case 'typescript':\n return javascript({ typescript: true });\n case 'tsx':\n return javascript({ typescript: true, jsx: true });\n case 'javascript':\n return javascript();\n case 'jsx':\n return javascript({ jsx: true });\n case 'css':\n return css();\n case 'html':\n return html();\n case 'json':\n return json();\n case 'markdown':\n return markdown();\n case 'plaintext':\n default:\n return null;\n }\n}\n","import type { HTMLAttributes } from 'react';\nimport { cn } from '../lib/utils';\n\ninterface LoaderIconProps {\n size?: number;\n}\n\nconst LoaderIcon = ({ size = 16 }: LoaderIconProps) => (\n <svg\n height={size}\n strokeLinejoin=\"round\"\n style={{ color: 'currentcolor' }}\n viewBox=\"0 0 16 16\"\n width={size}\n >\n <title>Loader</title>\n <g clipPath=\"url(#clip0_2393_1490)\">\n <path d=\"M8 0V4\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path\n d=\"M8 16V12\"\n opacity=\"0.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M3.29773 1.52783L5.64887 4.7639\"\n opacity=\"0.9\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M12.7023 1.52783L10.3511 4.7639\"\n opacity=\"0.1\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M12.7023 14.472L10.3511 11.236\"\n opacity=\"0.4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M3.29773 14.472L5.64887 11.236\"\n opacity=\"0.6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M15.6085 5.52783L11.8043 6.7639\"\n opacity=\"0.2\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M0.391602 10.472L4.19583 9.23598\"\n opacity=\"0.7\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M15.6085 10.4722L11.8043 9.2361\"\n opacity=\"0.3\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M0.391602 5.52783L4.19583 6.7639\"\n opacity=\"0.8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_2393_1490\">\n <rect fill=\"white\" height=\"16\" width=\"16\" />\n </clipPath>\n </defs>\n </svg>\n);\n\nexport type LoaderProps = HTMLAttributes<HTMLDivElement> & {\n size?: number;\n};\n\nexport const Loader = ({ className, size = 16, ...props }: LoaderProps) => (\n <div\n className={cn(\n 'inline-flex animate-spin items-center justify-center',\n className,\n )}\n {...props}\n >\n <LoaderIcon size={size} />\n </div>\n);\n","// File-extension → CodeMirror language id. Kept as a tiny static map;\n// CodeEditor handles the language extension for each id.\n\nimport type { CodeEditorLanguage } from '../primitives/code-editor';\n\nconst EXT_TO_LANG: Record<string, CodeEditorLanguage> = {\n ts: 'typescript',\n tsx: 'tsx',\n js: 'javascript',\n jsx: 'jsx',\n mjs: 'javascript',\n cjs: 'javascript',\n json: 'json',\n md: 'markdown',\n mdx: 'markdown',\n css: 'css',\n scss: 'css',\n html: 'html',\n htm: 'html',\n};\n\nexport function guessLanguage(path: string): CodeEditorLanguage {\n const m = path.match(/\\.([^.]+)$/);\n if (!m) return 'plaintext';\n const ext = m[1]!.toLowerCase();\n return EXT_TO_LANG[ext] ?? 'plaintext';\n}\n","// `<SandboxIDE>` — responsive composition of `<SandboxFileTree>` and\n// `<SandboxCodeEditor>`.\n//\n// • md+ side-by-side: file tree as a 64-wide left column.\n// • below md stacked: a hamburger-icon trigger sits inside the\n// code-editor header next to the filename, opening a\n// popover with the tree (via\n// `<SandboxFileTree display=\"dropdown\" />`).\n//\n// CSS-driven (Tailwind's `md:` prefix); no JS resize listeners. Both\n// trees stay mounted across breakpoint changes — both are bound to the\n// same `selectedPath` in elements context, so selection is consistent.\n\nimport { type CSSProperties } from 'react';\nimport type { Sandbox } from '@browsernode/sandbox';\nimport { SandboxFileTree } from './sandbox-file-tree';\nimport {\n SandboxCodeEditor,\n type SandboxCodeEditorProps,\n} from './sandbox-code-editor';\n\nexport interface SandboxIDEProps\n extends Omit<SandboxCodeEditorProps, 'headerStartSlot' | 'className'> {\n /** Override the sandbox from the surrounding `<SandboxProvider>`. */\n sandbox?: Sandbox | null;\n /** Initial folders to expand (forwarded to `<SandboxFileTree>`). */\n defaultExpanded?: Set<string>;\n /** Hide the file tree entirely (editor-only layout). */\n hideTree?: boolean;\n /** Hide the code editor entirely (tree-only layout). */\n hideViewer?: boolean;\n /**\n * Drop the rounded-lg + border on the outer wrapper. Use when embedded\n * inside a host frame that already provides chrome (e.g. inside\n * `<Sandbox>`).\n */\n hideBorder?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function SandboxIDE({\n sandbox,\n defaultExpanded,\n hideTree = false,\n hideViewer = false,\n hideBorder = false,\n className,\n style,\n ...codeProps\n}: SandboxIDEProps) {\n // Tree-only layout — just render files directly.\n if (hideViewer) {\n return (\n <SandboxFileTree\n sandbox={sandbox}\n defaultExpanded={defaultExpanded}\n className={className}\n />\n );\n }\n\n // Editor-only layout — just render code, no tree (mobile or otherwise).\n if (hideTree) {\n return (\n <SandboxCodeEditor\n sandbox={sandbox}\n className={className}\n {...codeProps}\n />\n );\n }\n\n const frameClasses = hideBorder\n ? 'flex h-full w-full flex-col md:flex-row overflow-hidden bg-background'\n : 'flex h-full w-full flex-col md:flex-row overflow-hidden rounded-lg border bg-background';\n\n // Mobile-only file-picker trigger lives inside the code-editor header,\n // collapsing the would-be \"dropdown row\" into the same row as the\n // filename. Hidden at md+ where the sidebar tree is the picker. The\n // default trigger label adapts to selection state — \"[☰] Select a\n // file\" when empty, just \"[☰]\" when a file is loaded.\n const mobileTrigger = (\n <SandboxFileTree\n sandbox={sandbox}\n defaultExpanded={defaultExpanded}\n display=\"dropdown\"\n className=\"md:hidden -ml-1\"\n />\n );\n\n return (\n <div className={`${frameClasses} ${className ?? ''}`.trim()} style={style}>\n {/* Desktop-only: sidebar tree on the left. Hidden below md. Block\n (not flex) so the tree fills the column width to the divider. */}\n <div className=\"hidden md:block w-64 shrink-0 overflow-auto border-r\">\n <SandboxFileTree sandbox={sandbox} defaultExpanded={defaultExpanded} />\n </div>\n\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n <SandboxCodeEditor\n sandbox={sandbox}\n headerStartSlot={mobileTrigger}\n {...codeProps}\n />\n </div>\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { MoreHorizontalIcon } from 'lucide-react';\nimport type { Sandbox, SnapshotMeta } from '@browsernode/sandbox';\nimport { Button } from '../primitives/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../primitives/ui/dropdown-menu';\nimport { Loader } from '../primitives/ui/loading';\nimport { useSandbox } from '../provider/sandbox-provider';\n\nexport interface SandboxSnapshotsProps {\n sandbox?: Sandbox | null;\n className?: string;\n /** Optional title shown above the list. Pass null to hide. */\n title?: React.ReactNode;\n}\n\n/**\n * `<SandboxSnapshots>` — list + create/restore/delete UI for\n * `sandbox.snapshots`. Capture the current vfs + env as a named checkpoint\n * and roll back later.\n */\nexport function SandboxSnapshots({\n sandbox: sandboxProp,\n className,\n title = 'Snapshots',\n}: SandboxSnapshotsProps) {\n const { sandbox: ctxSandbox } = useSandbox();\n const sandbox = sandboxProp ?? ctxSandbox ?? null;\n\n const [items, setItems] = useState<SnapshotMeta[]>([]);\n const [loading, setLoading] = useState(false);\n const [creating, setCreating] = useState(false);\n const [restoringId, setRestoringId] = useState<string | null>(null);\n\n const refresh = useCallback(async () => {\n if (!sandbox) return;\n setLoading(true);\n try {\n const list = await sandbox.snapshots.list();\n setItems(list);\n } finally {\n setLoading(false);\n }\n }, [sandbox]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const create = useCallback(async () => {\n if (!sandbox || creating) return;\n setCreating(true);\n try {\n await sandbox.snapshots.create();\n await refresh();\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to create snapshot', err);\n } finally {\n setCreating(false);\n }\n }, [sandbox, creating, refresh]);\n\n const restore = useCallback(\n async (id: string) => {\n if (!sandbox) return;\n setRestoringId(id);\n try {\n await sandbox.snapshots.restore(id);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to restore snapshot', err);\n } finally {\n setRestoringId(null);\n }\n },\n [sandbox],\n );\n\n const [confirmingDeleteId, setConfirmingDeleteId] = useState<string | null>(\n null,\n );\n const remove = useCallback(\n async (id: string) => {\n if (!sandbox) return;\n try {\n await sandbox.snapshots.delete(id);\n setConfirmingDeleteId(null);\n await refresh();\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to delete snapshot', err);\n }\n },\n [sandbox, refresh],\n );\n\n return (\n <div\n className={`flex min-h-0 flex-1 w-full flex-col ${className ?? ''}`.trim()}\n >\n <div className=\"flex flex-none items-center justify-between border-b px-3 py-2\">\n {title !== null ? (\n <span className=\"text-sm font-medium\">{title}</span>\n ) : <span />}\n <Button\n size=\"sm\"\n onClick={() => void create()}\n disabled={!sandbox || creating}\n >\n {creating ? (\n <>\n <Loader size={14} />\n Saving...\n </>\n ) : (\n 'New snapshot'\n )}\n </Button>\n </div>\n\n <div\n className=\"flex-1 min-h-0 overflow-y-auto [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden\"\n >\n {loading && items.length === 0 ? (\n <div className=\"flex h-full items-center justify-center text-xs text-muted-foreground\">\n Loading…\n </div>\n ) : items.length === 0 ? (\n <div className=\"flex items-center justify-center px-4 py-10 text-center text-xs text-muted-foreground\">\n No snapshots yet. Capture the current state to create one.\n </div>\n ) : (\n <ul className=\"divide-y\">\n {items.map((s) => (\n <li\n key={s.id}\n className=\"group flex cursor-pointer items-center justify-between gap-2 px-3 py-2 text-sm transition-colors hover:bg-muted/50\"\n >\n <button\n type=\"button\"\n onClick={() => void restore(s.id)}\n disabled={restoringId !== null}\n className=\"flex min-w-0 flex-1 cursor-pointer flex-col items-start text-left disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <span className=\"truncate font-medium\">\n {s.name ?? `v${s.version}`}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {formatTime(s.createdAt)}\n </span>\n </button>\n <div className=\"flex items-center gap-1\">\n {restoringId === s.id ? (\n <Loader size={14} />\n ) : null}\n <DropdownMenu\n onOpenChange={(open) => {\n // Reset the two-step confirm whenever the menu closes.\n if (!open) setConfirmingDeleteId(null);\n }}\n >\n <DropdownMenuTrigger\n render={\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label=\"Snapshot actions\"\n className=\"size-8 p-0\"\n />\n }\n >\n <MoreHorizontalIcon className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => void restore(s.id)}>\n Restore\n </DropdownMenuItem>\n <DropdownMenuItem\n // First click arms the destructive state; second\n // confirms. Selecting another menu item or closing\n // the menu resets it (handled in onOpenChange above).\n closeOnClick={confirmingDeleteId === s.id}\n onClick={(e) => {\n if (confirmingDeleteId !== s.id) {\n e.preventDefault();\n setConfirmingDeleteId(s.id);\n return;\n }\n void remove(s.id);\n }}\n className=\"text-destructive focus:text-destructive\"\n >\n {confirmingDeleteId === s.id ? 'Confirm delete' : 'Delete'}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n\n\nfunction formatTime(ts: number): string {\n const d = new Date(ts);\n return d.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n });\n}\n\n","// `<SandboxAttribution>` — small floating \"BrowserNode\" glass badge\n// pinned to the bottom-right of the sandbox body. Links back to\n// browsernode.dev. Visible by default in `<SandboxChrome>`; consumers\n// can hide it via `showAttribution={false}` on `<Sandbox>` /\n// `<SandboxChrome>`.\n\nimport type { CSSProperties } from 'react';\nimport { cn } from './primitives/lib/utils';\n\nexport interface SandboxAttributionProps {\n className?: string;\n style?: CSSProperties;\n /** Override the destination URL. Defaults to `https://browsernode.dev`. */\n href?: string;\n}\n\n// Positioning is inline so the badge is bulletproof even when the\n// consumer's Tailwind build hasn't picked up the elements package's\n// utility classes yet (e.g. fresh install before first CSS rebuild).\nconst POSITION: CSSProperties = {\n position: 'absolute',\n bottom: 14,\n right: 14,\n zIndex: 10,\n pointerEvents: 'auto',\n};\n\nexport function SandboxAttribution({\n className,\n style,\n href = 'https://browsernode.dev',\n}: SandboxAttributionProps) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"BrowserNode — visit browsernode.dev\"\n style={{ ...POSITION, ...style }}\n className={cn(\n // Solid pill — guaranteed legibility over any iframe content.\n // Matches the canonical BrowserNode wordmark (white \"Browser\" +\n // violet \"Node\") on a near-black surface.\n 'inline-flex items-center rounded-full',\n 'px-2.5 pt-1 pb-1.5 text-[11px] font-semibold tracking-tight leading-none',\n 'bg-zinc-950 ring-1 ring-white/10',\n 'shadow-lg shadow-black/30',\n 'transition-all duration-200 ease-out',\n 'hover:bg-zinc-900 hover:ring-white/20 hover:scale-[1.04]',\n 'select-none',\n className,\n )}\n >\n <span className=\"text-white\">Browser</span><span className=\"text-violet-400\">Node</span>\n </a>\n );\n}\n","\"use client\"\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Tabs({\n className,\n orientation = \"horizontal\",\n ...props\n}: TabsPrimitive.Root.Props) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n data-orientation={orientation}\n className={cn(\n \"group/tabs flex gap-2 data-horizontal:flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst tabsListVariants = cva(\n \"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none\",\n {\n variants: {\n variant: {\n default: \"bg-muted\",\n line: \"gap-1 bg-transparent\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction TabsList({\n className,\n variant = \"default\",\n ...props\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n data-variant={variant}\n className={cn(tabsListVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nfunction TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {\n return (\n <TabsPrimitive.Tab\n data-slot=\"tabs-trigger\"\n className={cn(\n \"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n \"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent\",\n \"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground\",\n \"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n return (\n <TabsPrimitive.Panel\n data-slot=\"tabs-content\"\n className={cn(\"flex-1 text-sm outline-none\", className)}\n {...props}\n />\n )\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }\n","// `<Sandbox>` — drop-in convenience: wraps `<SandboxProvider>` (which\n// creates and owns the sandbox) around `<SandboxChrome>` (the UI\n// shell). Use this when you want a self-contained preview surface in\n// one tag.\n//\n// For sibling composition (e.g. a chat panel beside the IDE that shares\n// the sandbox), don't use `<Sandbox>` — lift the provider yourself:\n//\n// <SandboxProvider framework=\"...\" source={...}>\n// <MyChat /> {/* useSandbox() — same instance */}\n// <SandboxChrome /> {/* same instance, just renders the IDE */}\n// </SandboxProvider>\n\nimport { type CSSProperties } from 'react';\nimport {\n SandboxProvider,\n type SandboxProviderProps,\n} from './provider/sandbox-provider';\nimport { SandboxChrome, type SandboxUi } from './sandbox-chrome';\n\nexport interface SandboxProps extends Omit<SandboxProviderProps, 'children'> {\n ui?: SandboxUi;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function Sandbox({ ui, className, style, ...providerProps }: SandboxProps) {\n return (\n <SandboxProvider {...providerProps}>\n <SandboxChrome ui={ui} className={className} style={style} />\n </SandboxProvider>\n );\n}\n"],"mappings":";AAWA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAEK;AACP,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,YAAY;AAMrB,SAAS,kBAAkB;AA0FrB;AA1DN,IAAM,kBAAkB,cAA2C,IAAI;AAmBvE,SAAS,MAAM,GAAoC;AACjD,SAAO,OAAO,MAAM,WAAW,EAAE,MAAM,EAAE,IAAI;AAC/C;AAEA,SAAS,iBAAiB,WAAuD;AAC/E,MAAI,cAAc,SAAU,QAAO,OAAO;AAC1C,MAAI,cAAc,OAAQ,QAAO,KAAK;AACtC,MAAI,OAAO,cAAc,UAAU;AACjC,UAAM,IAAI,MAAM,0CAA0C,SAAS,IAAI;AAAA,EACzE;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,EAAE,UAAU,GAAG,MAAM,GAAyB;AAC5E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,MACL,GAAG;AAAA,MACH,WAAW,iBAAiB,SAAS;AAAA,MACrC,SAAS,WAAW,QAAQ;AAAA,IAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,CAAC,WAAW,OAAO;AAAA,EACrB;AAEA,SACE,oBAAC,kBAAe,SACd;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,EACH,GACF;AAEJ;AAIA,SAAS,uBAAuB;AAAA,EAC9B;AAAA,EACA,qBAAqB;AAAA,EACrB,kBAAkB,CAAC;AAAA,EACnB,sBAAsB;AAAA,EACtB,QAAQ;AACV,GAAgC;AAC9B,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,mBAAmB;AACnF,QAAM,CAAC,UAAU,WAAW,IAAI;AAAA,IAAuB,MACrD,gBAAgB,IAAI,KAAK;AAAA,EAC3B;AACA,QAAM,CAAC,aAAa,cAAc,IAAI,SAAuB,kBAAkB;AAE/E,QAAM,UAAU,YAAY,CAAC,MAA2B;AACtD,UAAM,MAAM,MAAM,CAAC;AACnB,gBAAY,CAAC,SAAS;AACpB,UAAI,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,IAAI,EAAG,QAAO;AAClD,aAAO,CAAC,GAAG,MAAM,GAAG;AAAA,IACtB,CAAC;AACD,oBAAgB,IAAI,IAAI;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,WAAW,YAAY,CAAC,SAAiB;AAC7C,gBAAY,CAAC,SAAS;AACpB,YAAM,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,sBAAgB,CAAC,QAAQ;AACvB,YAAI,QAAQ,KAAM,QAAO;AACzB,cAAM,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,SAAS,IAAI;AACjD,cAAM,WAAW,KAAK,MAAM,CAAC,KAAK,KAAK,GAAG,KAAK,KAAK,CAAC,KAAK;AAC1D,eAAO,UAAU,QAAQ;AAAA,MAC3B,CAAC;AACD,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,SAAS;AAAA,IACb,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,cAAc,UAAU,SAAS,UAAU,aAAa,KAAK;AAAA,EAChE;AAEA,SAAO,oBAAC,gBAAgB,UAAhB,EAAyB,OAAO,QAAS,UAAS;AAC5D;AAGO,SAAS,qBAAkD;AAChE,SAAO,WAAW,eAAe;AACnC;AAEO,SAAS,4BAAkD;AAChE,QAAM,MAAM,WAAW,eAAe;AACtC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACzLA;AAAA,EACE,YAAAA;AAAA,OAGK;AACP,SAAS,UAAAC,eAAc;AACvB;AAAA,EACE,iBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,kBAAAC;AAAA,OACK;;;AClCP;AAAA,EACE,iBAAAC;AAAA,EACA;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAEK;AACP,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP;AAAA,EACE;AAAA,OAGK;;;ACpCP,SAAS,UAAU,uBAAuB;AAC1C,SAAS,WAA8B;;;ACDvC,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;AD4CI,gBAAAC,YAAA;AA5CJ,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,SACE;AAAA,QACF,WACE;AAAA,QACF,OACE;AAAA,QACF,aACE;AAAA,QACF,MAAM;AAAA,MACR;AAAA,MACA,MAAM;AAAA,QACJ,SACE;AAAA,QACF,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,WACE;AAAA,QACF,WACE;AAAA,QACF,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,OAAO;AAAA,EACd;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,GAAG;AACL,GAAgE;AAC9D,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,EAAE,SAAS,MAAM,UAAU,CAAC,CAAC;AAAA,MACzD,GAAG;AAAA;AAAA,EACN;AAEJ;;;AErDA,SAAS,eAAe,4BAA4B;AAG3C,gBAAAC,YAAA;AADT,SAAS,YAAY,EAAE,GAAG,MAAM,GAAoC;AAClE,SAAO,gBAAAA,KAAC,qBAAqB,MAArB,EAA0B,aAAU,eAAe,GAAG,OAAO;AACvE;AAEA,SAAS,mBAAmB,EAAE,GAAG,MAAM,GAAuC;AAC5E,SACE,gBAAAA,KAAC,qBAAqB,SAArB,EAA6B,aAAU,uBAAuB,GAAG,OAAO;AAE7E;AAEA,SAAS,mBAAmB,EAAE,GAAG,MAAM,GAAqC;AAC1E,SACE,gBAAAA,KAAC,qBAAqB,OAArB,EAA2B,aAAU,uBAAuB,GAAG,OAAO;AAE3E;;;ACjBA,SAAS,SAAS,sBAAsB;AAMpC,gBAAAC,YAAA;AAFJ,SAAS,MAAM,EAAE,WAAW,MAAM,GAAG,MAAM,GAAkC;AAC3E,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACjBA,SAAS,WAAW,wBAAwB;AASxC,gBAAAC,MAsCI,YAtCJ;AALJ,SAAS,gBAAgB;AAAA,EACvB,QAAQ;AAAA,EACR,GAAG;AACL,GAAoC;AAClC,SACE,gBAAAA;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,QAAQ,EAAE,GAAG,MAAM,GAAgC;AAC1D,SAAO,gBAAAA,KAAC,iBAAiB,MAAjB,EAAsB,aAAU,WAAW,GAAG,OAAO;AAC/D;AAEA,SAAS,eAAe,EAAE,GAAG,MAAM,GAAmC;AACpE,SAAO,gBAAAA,KAAC,iBAAiB,SAAjB,EAAyB,aAAU,mBAAmB,GAAG,OAAO;AAC1E;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA,GAAG;AACL,GAIK;AACH,SACE,gBAAAA,KAAC,iBAAiB,QAAjB,EACC,0BAAAA;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MAEV;AAAA,QAAC,iBAAiB;AAAA,QAAjB;AAAA,UACC,aAAU;AAAA,UACV,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UACC,GAAG;AAAA,UAEH;AAAA;AAAA,YACD,gBAAAA,KAAC,iBAAiB,OAAjB,EAAuB,WAAU,4hBAA2hB;AAAA;AAAA;AAAA,MAC/jB;AAAA;AAAA,EACF,GACF;AAEJ;;;AC7CA,SAAS,uBAAuB;AAEhC;AAAA,EACE,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AAsDD,gBAAAC,MAyCF,QAAAC,aAzCE;AA7CC,IAAM,oBAAoBN,eAA6C,IAAI;AAElF,IAAM,gBAAgB,MAAM;AAC1B,QAAM,UAAUE,YAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO;AACT;AAOO,IAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA,GAAG;AACL,MAAuB;AACrB,QAAM,CAAC,KAAK,MAAM,IAAIE,UAAS,UAAU;AACzC,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,KAAK;AAEpD,QAAM,kBAAkBH;AAAA,IACtB,CAAC,WAAmB;AAClB,aAAO,MAAM;AACb,oBAAc,MAAM;AAAA,IACtB;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,eAAeE;AAAA,IACnB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,aAAa,iBAAiB,GAAG;AAAA,EACpC;AAEA,SACE,gBAAAE,KAAC,kBAAkB,UAAlB,EAA2B,OAAO,cACjC,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH,GACF;AAEJ;AAIO,IAAM,uBAAuB,CAAC;AAAA,EACnC;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,WAAW,GAAG,wCAAwC,SAAS;AAAA,IAC9D,GAAG;AAAA,IAEH;AAAA;AACH;AAOK,IAAM,6BAA6B,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,gBAAAA,KAAC,mBACC,0BAAAC,MAAC,WACC;AAAA,kBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,QACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,GAAG,qCAAqC,SAAS;AAAA,UAC5D;AAAA,UACA;AAAA,UACA,MAAK;AAAA,UACL,SAAQ;AAAA,UACP,GAAG;AAAA;AAAA,MACN;AAAA,MAGD;AAAA;AAAA,EACH;AAAA,EACA,gBAAAA,KAAC,kBACC,0BAAAA,KAAC,OAAG,mBAAQ,GACd;AAAA,GACF,GACF;AAoFK,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA,OAAO,CAAC;AAAA,EACR;AAAA,EACA,GAAG;AACL,MAA8B;AAC5B,QAAM,EAAE,aAAa,eAAe,IAAI,cAAc;AAEtD,SACE,gBAAAE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,0CAA0C,SAAS;AAAA,MACjE,cAAc;AAAA,MACd,MAAM;AAAA,MACL,GAAG;AAAA,MAEJ;AAAA,wBAAAA,MAAC,sBAAmB,QAAQ,gBAAAC,KAAC,UAAO,WAAU,wFAAuF,SAAQ,SAAQ,GAAI;AAAA;AAAA,UAC3I,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,eAAe;AAAA,cACjB;AAAA;AAAA,UACF;AAAA,WAAE;AAAA,QAChB,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA;AAAA,YACF;AAAA,YAEA,0BAAAD,MAAC,SAAI,WAAU,sCACZ;AAAA,mBAAK,WAAW,IACf,gBAAAC,KAAC,OAAE,WAAU,yBAAwB,+BAAiB,IAEtD,KAAK,IAAI,CAAC,QACR,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW;AAAA,oBACT;AAAA,oBACA,IAAI,UAAU,WAAW;AAAA,oBACzB,IAAI,UAAU,UAAU;AAAA,oBACxB,IAAI,UAAU,SAAS;AAAA,kBACzB;AAAA,kBAGA;AAAA,oCAAAC,KAAC,UAAK,WAAU,yBACb,cAAI,UAAU,mBAAmB,GACpC;AAAA,oBAAQ;AAAA,oBACP,IAAI;AAAA;AAAA;AAAA,gBALA,GAAG,IAAI,UAAU,QAAQ,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO;AAAA,cAM7D,CACD;AAAA,cAEF;AAAA,eACH;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACjRA,SAAS,4BAA4B;AAQrC;AAAA,EACE;AAAA,EACA;AAAA,EACA,mBAAAC;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE,iBAAAC;AAAA,EACA;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,WAAAC;AAAA,EACA;AAAA,EACA,YAAAC;AAAA,OACK;AA0KC,SAsSM,UAtSN,OAAAC,MAmCJ,QAAAC,aAnCI;AAvKR,IAAM,gCAAgC;AACtC,IAAM,+BAA+B;AACrC,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AA0BxB,IAAM,oBAAoBN,eAA6C,IAAI;AAE3E,IAAM,gBAAgB,MAAM;AAC1B,QAAM,UAAUE,YAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,SAAO;AACT;AAEA,IAAM,kBAAkB,CAAC,SAA6B;AACpD,QAAM,UAAU,KAAK,KAAK;AAG1B,QAAM,kBAAkB,QAAQ,MAAM,6BAA6B;AACnE,MAAI,iBAAiB;AACnB,UAAM,CAAC,EAAE,cAAc,UAAU,SAAS,MAAM,IAAI;AACpD,UAAM,aACJ,SAAS,SAAS,cAAc,KAChC,SAAS,WAAW,OAAO,KAC3B,SAAS,SAAS,WAAW;AAC/B,WAAO;AAAA,MACL,cAAc,SAAS,OAAO,SAAS,QAAQ,EAAE,IAAI;AAAA,MACrD,UAAU,YAAY;AAAA,MACtB,cAAc,gBAAgB;AAAA,MAC9B;AAAA,MACA,YAAY,UAAU,OAAO,SAAS,SAAS,EAAE,IAAI;AAAA,MACrD,KAAK;AAAA,IACP;AAAA,EACF;AAGA,QAAM,iBAAiB,QAAQ,MAAM,4BAA4B;AACjE,MAAI,gBAAgB;AAClB,UAAM,CAAC,EAAE,UAAU,SAAS,MAAM,IAAI;AACtC,UAAM,cACH,UAAU,SAAS,cAAc,KAAK,WACtC,UAAU,WAAW,OAAO,KAAK,WACjC,UAAU,SAAS,WAAW,KAAK;AACtC,WAAO;AAAA,MACL,cAAc,SAAS,OAAO,SAAS,QAAQ,EAAE,IAAI;AAAA,MACrD,UAAU,YAAY;AAAA,MACtB,cAAc;AAAA,MACd;AAAA,MACA,YAAY,UAAU,OAAO,SAAS,SAAS,EAAE,IAAI;AAAA,MACrD,KAAK;AAAA,IACP;AAAA,EACF;AAGA,SAAO;AAAA,IACL,cAAc;AAAA,IACd,UAAU;AAAA,IACV,cAAc;AAAA,IACd,YAAY,QAAQ,SAAS,cAAc,KAAK,QAAQ,SAAS,OAAO;AAAA,IACxE,YAAY;AAAA,IACZ,KAAK;AAAA,EACP;AACF;AAEA,IAAM,kBAAkB,CAAC,UAAoC;AAC3D,QAAM,QAAQ,MAAM,MAAM,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,CAAC;AAE5D,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL,cAAc;AAAA,MACd,WAAW;AAAA,MACX,QAAQ,CAAC;AAAA,MACT,KAAK;AAAA,IACP;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,CAAC,EAAE,KAAK;AAChC,MAAI,YAA2B;AAC/B,MAAI,eAAe;AAGnB,QAAM,aAAa,UAAU,MAAM,gBAAgB;AACnD,MAAI,YAAY;AACd,UAAM,CAAC,EAAE,MAAM,GAAG,IAAI;AACtB,gBAAY;AACZ,mBAAe,OAAO;AAAA,EACxB;AAGA,QAAM,SAAS,MACZ,MAAM,CAAC,EACP,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,WAAW,KAAK,CAAC,EAC9C,IAAI,eAAe;AAEtB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,EACP;AACF;AAUO,IAAM,aAAa;AAAA,EACxB,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,MAAuB;AACrB,UAAM,CAAC,QAAQ,SAAS,IAAI,qBAAqB;AAAA,MAC/C,aAAa;AAAA,MACb,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAED,UAAM,cAAcC,SAAQ,MAAM,gBAAgB,KAAK,GAAG,CAAC,KAAK,CAAC;AAEjE,UAAM,eAAeA;AAAA,MACnB,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACA,OAAO;AAAA,MACT;AAAA,MACA,CAAC,aAAa,OAAO,QAAQ,WAAW,eAAe;AAAA,IACzD;AAEA,WACE,gBAAAE,KAAC,kBAAkB,UAAlB,EAA2B,OAAO,cACjC,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH,GACF;AAAA,EAEJ;AACF;AAIO,IAAM,mBAAmB;AAAA,EAC9B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,MAA6B;AAC5D,UAAM,EAAE,QAAQ,UAAU,IAAI,cAAc;AAE5C,WACE,gBAAAA,KAAC,eAAY,cAAc,WAAW,MAAM,QAC1C,0BAAAA,KAAC,sBAAoB,GAAG,OAAO,QAAQ,gBAAAA,KAAC,SAAI,WAAW;AAAA,MACrC;AAAA,MACA;AAAA,IACF,GAAG,GAAK,UAAS,GACnC;AAAA,EAEJ;AACF;AAIO,IAAM,kBAAkB;AAAA,EAC7B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,MAC/B,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,wBAAAD,KAAC,qBAAkB,WAAU,oCAAmC;AAAA,QAC/D;AAAA;AAAA;AAAA,EACH;AAEJ;AAIO,IAAM,sBAAsB;AAAA,EACjC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,MAAgC;AAC/D,UAAM,EAAE,MAAM,IAAI,cAAc;AAEhC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,2CAA2C,SAAS;AAAA,QACjE,GAAG;AAAA,QAEH,sBAAY,MAAM;AAAA;AAAA,IACrB;AAAA,EAEJ;AACF;AAIO,IAAM,yBAAyB;AAAA,EACpC,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,MAAmC;AAClE,UAAM,EAAE,MAAM,IAAI,cAAc;AAEhC,WACE,gBAAAA,KAAC,UAAK,WAAW,GAAG,4BAA4B,SAAS,GAAI,GAAG,OAC7D,sBAAY,MAAM,cACrB;AAAA,EAEJ;AACF;AAIA,IAAM,qBAAqB,CAAC,MAAwB,EAAE,gBAAgB;AACtE,IAAM,uBAAuB,CAAC,MAA2B;AACvD,MAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,MAAE,gBAAgB;AAAA,EACpB;AACF;AAEO,IAAM,oBAAoB;AAAA,EAC/B,CAAC,EAAE,WAAW,UAAU,GAAG,MAAM,MAC/B,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,oCAAoC,SAAS;AAAA,MAC3D,SAAS;AAAA,MACT,WAAW;AAAA,MACX,MAAK;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;AAQO,IAAM,uBAAuB;AAAA,EAClC,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,MAAiC;AAC/B,UAAM,CAAC,UAAU,WAAW,IAAID,UAAS,KAAK;AAC9C,UAAM,aAAa,OAAe,CAAC;AACnC,UAAM,EAAE,IAAI,IAAI,cAAc;AAE9B,UAAM,kBAAkBH,aAAY,YAAY;AAC9C,UAAI,OAAO,WAAW,eAAe,CAAC,WAAW,WAAW,WAAW;AACrE,kBAAU,IAAI,MAAM,6BAA6B,CAAC;AAClD;AAAA,MACF;AAEA,UAAI;AACF,cAAM,UAAU,UAAU,UAAU,GAAG;AACvC,oBAAY,IAAI;AAChB,iBAAS;AACT,mBAAW,UAAU,OAAO;AAAA,UAC1B,MAAM,YAAY,KAAK;AAAA,UACvB;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,kBAAU,KAAc;AAAA,MAC1B;AAAA,IACF,GAAG,CAAC,KAAK,QAAQ,SAAS,OAAO,CAAC;AAElC;AAAA,MACE,MAAM,MAAM;AACV,eAAO,aAAa,WAAW,OAAO;AAAA,MACxC;AAAA,MACA,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,WAAW,YAAY;AAEpC,WACE,gBAAAI;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,UAAU,SAAS;AAAA,QACjC,SAAS;AAAA,QACT,MAAK;AAAA,QACL,SAAQ;AAAA,QACP,GAAG;AAAA,QAEH,sBAAY,gBAAAA,KAAC,QAAK,MAAM,IAAI;AAAA;AAAA,IAC/B;AAAA,EAEJ;AACF;AAIO,IAAM,yBAAyB;AAAA,EACpC,CAAC,EAAE,WAAW,GAAG,MAAM,MAAmC;AACxD,UAAM,EAAE,OAAO,IAAI,cAAc;AAEjC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,2CAA2C,SAAS;AAAA,QACjE,GAAG;AAAA,QAEJ,0BAAAA;AAAA,UAACN;AAAA,UAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,SAAS,eAAe;AAAA,YAC1B;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAQO,IAAM,oBAAoB;AAAA,EAC/B,CAAC;AAAA,IACC;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,MAA8B;AAC5B,UAAM,EAAE,OAAO,IAAI,cAAc;AAEjC,WACE,gBAAAM,KAAC,eAAY,MAAM,QACjB,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,OAAO,EAAE,UAAU;AAAA,QAClB,GAAG;AAAA,QAEH;AAAA;AAAA,IACH,GACF;AAAA,EAEJ;AACF;AAeA,IAAM,iBAAiB;AAAA,EACrB,CAAC,EAAE,OAAO,gBAAgB,MAA2B;AACnD,UAAM,cAAcJ,aAAY,MAAM;AACpC,UAAI,MAAM,UAAU;AAClB;AAAA,UACE,MAAM;AAAA,UACN,MAAM,cAAc;AAAA,UACpB,MAAM,gBAAgB;AAAA,QACxB;AAAA,MACF;AAAA,IACF,GAAG,CAAC,OAAO,eAAe,CAAC;AAE3B,WACE,gBAAAK;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,mBAAmB;AAAA,QACrB;AAAA,QACA,UAAU,CAAC;AAAA,QACX,SAAS;AAAA,QACT,MAAK;AAAA,QAEJ;AAAA,gBAAM;AAAA,UACN,MAAM,eAAe,QAAQ,IAAI,MAAM,UAAU;AAAA,UACjD,MAAM,iBAAiB,QAAQ,IAAI,MAAM,YAAY;AAAA;AAAA;AAAA,IACxD;AAAA,EAEJ;AACF;AAEA,eAAe,cAAc;AAEtB,IAAM,mBAAmB;AAAA,EAC9B,CAAC;AAAA,IACC;AAAA,IACA,qBAAqB;AAAA,IACrB,GAAG;AAAA,EACL,MAA6B;AAC3B,UAAM,EAAE,OAAO,gBAAgB,IAAI,cAAc;AAEjD,UAAM,eAAe,qBACjB,MAAM,SACN,MAAM,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU;AAE5C,WACE,gBAAAA,MAAC,SAAI,WAAW,GAAG,iBAAiB,SAAS,GAAI,GAAG,OACjD;AAAA,mBAAa,IAAI,CAAC,UACjB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,MAAM,aACF,6BACA;AAAA,UACN;AAAA,UAGA;AAAA,4BAAAD,KAAC,UAAK,WAAU,yBAAwB,iBAAG;AAAA,YAC1C,MAAM,gBACL,gBAAAC,MAAC,UAAK,WAAW,MAAM,aAAa,KAAK,mBACtC;AAAA,oBAAM;AAAA,cAAc;AAAA,eACvB;AAAA,YAED,MAAM,YACL,gBAAAA,MAAA,YACE;AAAA,8BAAAD,KAAC,UAAK,WAAU,yBAAwB,eAAC;AAAA,cACzC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA;AAAA;AAAA,cACF;AAAA,cACA,gBAAAA,KAAC,UAAK,WAAU,yBAAwB,eAAC;AAAA,eAC3C;AAAA,YAED,EAAE,MAAM,YAAY,MAAM,iBACzB,gBAAAA,KAAC,UAAM,gBAAM,IAAI,QAAQ,iBAAiB,EAAE,GAAE;AAAA;AAAA;AAAA,QAnB3C,MAAM;AAAA,MAqBb,CACD;AAAA,MACA,aAAa,WAAW,KACvB,gBAAAA,KAAC,SAAI,WAAU,iCAAgC,6BAAe;AAAA,OAElE;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;AACzB,iBAAiB,cAAc;AAC/B,gBAAgB,cAAc;AAC9B,oBAAoB,cAAc;AAClC,uBAAuB,cAAc;AACrC,kBAAkB,cAAc;AAChC,qBAAqB,cAAc;AACnC,uBAAuB,cAAc;AACrC,kBAAkB,cAAc;AAChC,iBAAiB,cAAc;;;ACvgB/B,SAAS,QAAQ,qBAAqB;AAGtC,SAAS,kBAAkB,aAAAE,kBAAiB;AAGnC,gBAAAC,MAsGL,QAAAC,aAtGK;AADT,SAAS,aAAa,EAAE,GAAG,MAAM,GAA6B;AAC5D,SAAO,gBAAAD,KAAC,cAAc,MAAd,EAAmB,aAAU,iBAAiB,GAAG,OAAO;AAClE;AAMA,SAAS,oBAAoB,EAAE,GAAG,MAAM,GAAgC;AACtE,SAAO,gBAAAE,KAAC,cAAc,SAAd,EAAsB,aAAU,yBAAyB,GAAG,OAAO;AAC7E;AAEA,SAAS,oBAAoB;AAAA,EAC3B,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,OAAO;AAAA,EACP,aAAa;AAAA,EACb;AAAA,EACA,GAAG;AACL,GAIK;AACH,SACE,gBAAAA,KAAC,cAAc,QAAd,EACC,0BAAAA;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,WAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA,0BAAAA;AAAA,QAAC,cAAc;AAAA,QAAd;AAAA,UACC,aAAU;AAAA,UACV,WAAW,GAAG,qoBAAqoB,SAAU;AAAA,UAC5pB,GAAG;AAAA;AAAA,MACN;AAAA;AAAA,EACF,GACF;AAEJ;AA0BA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAGG;AACD,SACE,gBAAAC;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,gBAAc;AAAA,MACd,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ARsRI,gBAAAC,MA+GM,QAAAC,aA/GN;AAlTJ,IAAM,YAA8C;AAAA,EAClD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AACT;AAiDA,IAAM,oBAAoBC,eAAiD,IAAI;AAExE,SAAS,uBAAmD;AACjE,QAAM,MAAMC,YAAW,iBAAiB;AACxC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAUO,IAAM,yBAAyB,WAGpC,SAASC,wBACT;AAAA,EACE,SAAS;AAAA,EACT,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GACA,KACA;AACA,QAAM,EAAE,SAAS,WAAW,IAAI,WAAW;AAC3C,QAAM,UAAU,eAAe,cAAc;AAE7C,QAAM,WAAWC,QAAmC,IAAI;AACxD,QAAM,eAAeC,aAAY,CAAC,SAAqC;AACrE,aAAS,UAAU;AACnB,QAAI,OAAO,QAAQ,WAAY,KAAI,IAAI;AAAA,aAC9B,IAAK,KAAI,UAAU;AAAA,EAC9B,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,CAAC,YAAY,aAAa,IAAIC,UAAS,UAAU;AACvD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,UAAU;AACvD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAmB,CAAC,UAAU,CAAC;AAC7D,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,CAAC;AAClD,QAAM,CAAC,QAAQ,SAAS,IAAIA;AAAA,IAAyB,MACnD,UAAU,CAAC,GAAG,QAAQ,QAAQ,QAAQ,CAAC,IAAI,CAAC;AAAA,EAC9C;AACA,QAAM,CAAC,YAAY,aAAa,IAAIA,UAA8B,IAAI;AACtE,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAuB,IAAI;AACnE,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAmC,IAAI;AAC/E,QAAM,CAAC,UAAU,WAAW,IAAIA,UAA+B,SAAS;AACxE,QAAM,eAAeF,QAAuB,IAAI;AAIhD,QAAM,eAAeA,QAAsB,IAAI;AAE/C,EAAAG,WAAU,MAAM;AACd,QAAI,CAAC,QAAS;AACd,cAAU,CAAC,GAAG,QAAQ,QAAQ,QAAQ,CAAC,CAAC;AACxC,UAAM,WAAW,QAAQ,GAAG,YAAY,CAAC,QAAQ;AAC/C,oBAAc,GAAG;AACjB,oBAAc,GAAG;AAEjB,sBAAgB,IAAI;AAGpB,UAAI,aAAa,YAAY,KAAK;AAChC,qBAAa,UAAU;AACvB;AAAA,MACF;AACA,iBAAW,CAAC,SAAS;AACnB,cAAM,YAAY,KAAK,MAAM,GAAG,eAAe,CAAC;AAChD,YAAI,UAAU,UAAU,SAAS,CAAC,MAAM,IAAK,QAAO;AACpD,eAAO,CAAC,GAAG,WAAW,GAAG;AAAA,MAC3B,CAAC;AACD,sBAAgB,CAAC,MAAM,IAAI,CAAC;AAAA,IAC9B,CAAC;AACD,UAAM,WAAW,QAAQ,GAAG,WAAW,CAAC,OAAO,SAAS;AACtD,gBAAU,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,OAAO,MAAM,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;AAAA,IAChE,CAAC;AACD,UAAM,aAAa,QAAQ,GAAG,SAAS,CAAC,WAAwB;AAC9D,oBAAc,OAAO,KAAK,OAAO,OAAO,MAAM;AAE9C,UAAI,OAAO,GAAI,iBAAgB,IAAI;AAAA,IACrC,CAAC;AACD,UAAM,WAAW,QAAQ,GAAG,SAAS,CAAC,QAAQ,gBAAgB,GAAG,CAAC;AAClE,WAAO,MAAM;AACX,eAAS;AACT,eAAS;AACT,iBAAW;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,QAAM,SAASF,aAAY,MAAM;AAC/B,QAAI,gBAAgB,EAAG;AACvB,UAAM,SAAS,QAAQ,eAAe,CAAC;AACvC,iBAAa,UAAU;AACvB,oBAAgB,eAAe,CAAC;AAChC,aAAS,SAAS,SAAS,MAAM;AAAA,EACnC,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,QAAM,YAAYA,aAAY,MAAM;AAClC,QAAI,gBAAgB,QAAQ,SAAS,EAAG;AACxC,UAAM,SAAS,QAAQ,eAAe,CAAC;AACvC,iBAAa,UAAU;AACvB,oBAAgB,eAAe,CAAC;AAChC,aAAS,SAAS,SAAS,MAAM;AAAA,EACnC,GAAG,CAAC,SAAS,YAAY,CAAC;AAK1B,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,CAAC;AAC5C,QAAM,SAASD,aAAY,MAAM;AAC/B,iBAAa,CAAC,MAAM,IAAI,CAAC;AACzB,QAAI,SAAS;AACX,cAAQ,QAAQ,EAAE,MAAM,MAAM;AAAA,MAE9B,CAAC;AAAA,IACH,OAAO;AACL,eAAS,SAAS,OAAO;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAKZ,QAAM,CAAC,SAAS,UAAU,IAAIC,UAAS,KAAK;AAC5C,QAAM,gBAAgBD,aAAY,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;AACjE,EAAAE,WAAU,MAAM;AACd,QAAI,CAAC,QAAS;AACd,UAAM,QAAQ,CAAC,MAAqB;AAClC,UAAI,EAAE,QAAQ,SAAU,YAAW,KAAK;AAAA,IAC1C;AACA,WAAO,iBAAiB,WAAW,KAAK;AACxC,WAAO,MAAM,OAAO,oBAAoB,WAAW,KAAK;AAAA,EAC1D,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,YAAYF,aAAY,MAAM;AAClC,UAAM,SAAS,WAAW,KAAK,KAAK;AACpC,aAAS,SAAS,SAAS,MAAM;AAAA,EACnC,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,WAAWA,aAAY,YAAY;AACvC,QAAI,CAAC,QAAS;AACd,UAAM,OAAO,MAAM,QAAQ,SAAS;AACpC,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,IAAI,SAAS,cAAc,GAAG;AACpC,MAAE,OAAO;AACT,MAAE,WAAW,GAAG,QAAQ,aAAa,SAAS;AAC9C,aAAS,KAAK,YAAY,CAAC;AAC3B,MAAE,MAAM;AACR,MAAE,OAAO;AACT,eAAW,MAAM,IAAI,gBAAgB,GAAG,GAAG,GAAI;AAAA,EACjD,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,OAAOG;AAAA,IACX,MACE,OAAO,IAAI,CAAC,OAAO;AAAA,MACjB,OAAO,UAAU,EAAE,KAAK;AAAA,MACxB,SAAS,WAAW,EAAE,IAAI;AAAA,MAC1B,WAAW,IAAI,KAAK,EAAE,EAAE;AAAA,IAC1B,EAAE;AAAA,IACJ,CAAC,MAAM;AAAA,EACT;AAMA,QAAM,eAAeA,SAAQ,MAAM;AACjC,QAAI,cAAc,WAAW,SAAS,GAAG;AACvC,YAAM,OAAO,WAAW,CAAC;AACzB,YAAM,SAAS,WAAW,IAAI,CAAC,MAAM;AACnC,cAAM,OAAO,EAAE,QAAQ;AACvB,cAAM,OAAO,EAAE,QAAQ;AACvB,cAAM,MAAM,EAAE,UAAU;AACxB,eAAO,iBAAiB,IAAI,IAAI,IAAI,IAAI,GAAG;AAAA,MAC7C,CAAC;AACD,aAAO,CAAC,eAAe,KAAK,OAAO,IAAI,GAAG,MAAM,EAAE,KAAK,IAAI;AAAA,IAC7D;AACA,QAAI,cAAc;AAChB,UAAI,aAAa,MAAO,QAAO,aAAa;AAC5C,YAAM,UACJ,aAAa,WAAW,uBACpB,uBACA;AACN,YAAM,QAAQ,oBAAoB,aAAa,YAAY,WAAW,IAAI,aAAa,UAAU,CAAC,IAAI,aAAa,SAAS,CAAC;AAC7H,aAAO,GAAG,OAAO,KAAK,aAAa,OAAO;AAAA,EAAK,KAAK;AAAA,IACtD;AACA,QAAI,cAAc;AAChB,aACE,aAAa,SAAS,iBAAiB,aAAa,OAAO;AAAA,IAE/D;AACA,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,cAAc,YAAY,CAAC;AAE3C,QAAM,cACJ,QAAQ,cAAc,WAAW,SAAS,CAAC,KAC3C,QAAQ,YAAY,KACpB,QAAQ,YAAY;AAEtB,sBAAoB,KAAK,OAAO;AAAA,IAC9B,SAAS,MAAM,SAAS,SAAS,QAAQ;AAAA,IACzC,QAAQ,MAAM,SAAS,SAAS,OAAO;AAAA,IACvC,UAAU,CAAC,MAAc,SAAS,SAAS,SAAS,CAAC;AAAA,IACrD,MAAM,CAAC,YAAqB,SAAS,SAAS,KAAK,OAAO;AAAA,EAC5D,IAA2B,CAAC,CAAC;AAE7B,QAAM,QAAQA,SAAoC,OAAO;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAAA,IACF;AAAA,IAAS;AAAA,IAAa;AAAA,IAAM;AAAA,IAAY;AAAA,IACxC;AAAA,IAAY;AAAA,IAAY;AAAA,IAAS;AAAA,IAAc;AAAA,IAC/C;AAAA,IAAW;AAAA,IAAM;AAAA,IAAa;AAAA,IAC9B;AAAA,IAAQ;AAAA,IAAW;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAe;AAAA,IAAW;AAAA,EAChE,CAAC;AAED,SACE,gBAAAT,KAAC,kBAAkB,UAAlB,EAA2B,OACzB,UACH;AAEJ,CAAC;AAyHM,SAAS,oBAAoB;AAClC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,qBAAqB;AAEzB,SACE,gBAAAU,MAAC,SAAI,KAAK,cAAc,WAAU,kEAChC;AAAA,oBAAAC;AAAA,MAAC,OAAO;AAAA,MAAP;AAAA,QACC,SAAS;AAAA,QACT,SAAS,EAAE,OAAO,aAAa,WAAW,MAAM,OAAO;AAAA,QACvD,YAAY,EAAE,MAAM,UAAU,WAAW,KAAK,SAAS,IAAI,MAAM,IAAI;AAAA,QACrE,WAAU;AAAA,QAEV,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL;AAAA,YACA,aAAa;AAAA,cACX,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,GAAG,aAAa;AAAA,cAClB;AAAA,cACA,GAAG;AAAA,YACL;AAAA,YACA;AAAA,YACA,gBAAgB;AAAA,YACf,GAAG;AAAA;AAAA,QACN;AAAA;AAAA,IACF;AAAA,IACC,eACC,gBAAAA,KAAC,SAAI,WAAU,oDACb,0BAAAD,MAAC,cAAW,aAAW,MAAC,OAAO,cAC7B;AAAA,sBAAAA,MAAC,oBACC;AAAA,wBAAAA,MAAC,mBACC;AAAA,0BAAAC,KAAC,uBAAoB;AAAA,UACrB,gBAAAA,KAAC,0BAAuB;AAAA,WAC1B;AAAA,QACA,gBAAAD,MAAC,qBACC;AAAA,0BAAAC,KAAC,wBAAqB;AAAA,UACtB,gBAAAA,KAAC,0BAAuB;AAAA,WAC1B;AAAA,SACF;AAAA,MACA,gBAAAA,KAAC,qBACC,0BAAAA,KAAC,oBAAiB,GACpB;AAAA,OACF,GACF;AAAA,KAEJ;AAEJ;AAEO,SAAS,wBAAwB;AACtC,QAAM,EAAE,KAAK,IAAI,qBAAqB;AACtC,SAAO,gBAAAA,KAAC,qBAAkB,MAAY;AACxC;AAEA,SAAS,WAAW,MAAyB;AAC3C,SAAO,KAAK,IAAI,SAAS,EAAE,KAAK,GAAG;AACrC;AAEA,SAAS,UAAU,GAAoB;AACrC,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,MAAM,OAAW,QAAO;AAC5B,MAAI,OAAO,MAAM,WAAY,QAAO;AACpC,MAAI,OAAO,MAAM,UAAU;AACzB,QAAI;AACF,aAAO,KAAK,UAAU,CAAC;AAAA,IACzB,QAAQ;AACN,aAAO,OAAO,CAAC;AAAA,IACjB;AAAA,EACF;AACA,SAAO,OAAO,CAAC;AACjB;;;AShkBA,SAAS,aAAAC,YAAW,WAAAC,UAAS,YAAAC,iBAAgC;AAC7D,SAAS,gBAAgB;;;ACAzB;AAAA,EACE,oBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AAqEC,SAiLE,YAAAC,WAjLF,OAAAC,OA6FI,QAAAC,aA7FJ;AA1DR,IAAM,OAAO,MAAM;AAAC;AAEpB,IAAM,kBAAkBP,eAAmC;AAAA;AAAA,EAEzD,eAAe,oBAAI,IAAI;AAAA,EACvB,YAAY;AACd,CAAC;AAUM,IAAM,WAAW,CAAC;AAAA,EACvB,UAAU;AAAA,EACV,kBAAkB,oBAAI,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAqB;AACnB,QAAM,CAAC,kBAAkB,mBAAmB,IAAII,UAAS,eAAe;AACxE,QAAM,gBAAgB,sBAAsB;AAE5C,QAAM,aAAaH;AAAA,IACjB,CAAC,SAAiB;AAChB,YAAM,cAAc,IAAI,IAAI,aAAa;AACzC,UAAI,YAAY,IAAI,IAAI,GAAG;AACzB,oBAAY,OAAO,IAAI;AAAA,MACzB,OAAO;AACL,oBAAY,IAAI,IAAI;AAAA,MACtB;AACA,0BAAoB,WAAW;AAC/B,yBAAmB,WAAW;AAAA,IAChC;AAAA,IACA,CAAC,eAAe,gBAAgB;AAAA,EAClC;AAEA,QAAM,eAAeE;AAAA,IACnB,OAAO,EAAE,eAAe,UAAU,cAAc,WAAW;AAAA,IAC3D,CAAC,eAAe,UAAU,cAAc,UAAU;AAAA,EACpD;AAEA,SACE,gBAAAG,MAAC,gBAAgB,UAAhB,EAAyB,OAAO,cAC/B,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACJ,GAAG;AAAA,MAEJ,0BAAAA,MAAC,SAAI,WAAU,OAAO,UAAS;AAAA;AAAA,EACjC,GACF;AAEJ;AAIO,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,gBAAAA,MAAC,UAAK,WAAW,GAAG,YAAY,SAAS,GAAI,GAAG,OAC7C,UACH;AAKK,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,gBAAAA,MAAC,UAAK,WAAW,GAAG,YAAY,SAAS,GAAI,GAAG,OAC7C,UACH;AASF,IAAM,wBAAwBN,eAAyC;AAAA,EACrE,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,MAAM;AACR,CAAC;AAOM,IAAM,iBAAiB,CAAC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAA2B;AACzB,QAAM,EAAE,eAAe,YAAY,cAAc,SAAS,IACxDE,YAAW,eAAe;AAC5B,QAAM,aAAa,cAAc,IAAI,IAAI;AACzC,QAAM,aAAa,iBAAiB;AAEpC,QAAM,mBAAmBD,aAAY,MAAM;AACzC,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,YAAY,IAAI,CAAC;AAErB,QAAM,eAAeA,aAAY,MAAM;AACrC,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,UAAU,IAAI,CAAC;AAEnB,QAAM,qBAAqBE;AAAA,IACzB,OAAO,EAAE,YAAY,MAAM,KAAK;AAAA,IAChC,CAAC,YAAY,MAAM,IAAI;AAAA,EACzB;AAEA,SACE,gBAAAG,MAAC,sBAAsB,UAAtB,EAA+B,OAAO,oBACrC,0BAAAA,MAAC,eAAY,cAAc,kBAAkB,MAAM,YACjD,0BAAAC;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,IAAI,SAAS;AAAA,MAC3B,MAAK;AAAA,MACL,UAAU;AAAA,MACT,GAAG;AAAA,MAEJ;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,cAAc;AAAA,YAChB;AAAA,YAEA;AAAA,8BAAAD,MAAC,sBAAmB,QAAQ,gBAAAA,MAAC,YAAO,WAAU,4EAA2E,MAAK,UAAS,GAAI,0BAAAA;AAAA,gBAACP;AAAA,gBAAA;AAAA,kBAChH,WAAW;AAAA,oBACT;AAAA,oBACA,cAAc;AAAA,kBAChB;AAAA;AAAA,cACF,GAAE;AAAA,cAC5B,gBAAAQ;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,SAAS,MAAM;AACb,iCAAa;AACb,+BAAW,IAAI;AAAA,kBACjB;AAAA,kBACA,MAAK;AAAA,kBAEL;AAAA,oCAAAD,MAAC,gBACE,uBACC,gBAAAA,MAAC,kBAAe,WAAU,wBAAuB,IAEjD,gBAAAA,MAAC,cAAW,WAAU,wBAAuB,GAEjD;AAAA,oBACA,gBAAAA,MAAC,gBAAc,gBAAK;AAAA;AAAA;AAAA,cACtB;AAAA;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA,MAAC,sBACC,0BAAAA,MAAC,SAAI,WAAU,sBAAsB,UAAS,GAChD;AAAA;AAAA;AAAA,EACF,GACF,GACF;AAEJ;AAOA,IAAM,sBAAsBN,eAAuC;AAAA,EACjE,MAAM;AAAA,EACN,MAAM;AACR,CAAC;AAQM,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAyB;AACvB,QAAM,EAAE,cAAc,SAAS,IAAIE,YAAW,eAAe;AAC7D,QAAM,aAAa,iBAAiB;AAEpC,QAAM,cAAcD,aAAY,MAAM;AACpC,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,UAAU,IAAI,CAAC;AAEnB,QAAM,gBAAgBA;AAAA,IACpB,CAAC,MAA2B;AAC1B,UAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,mBAAW,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,IACA,CAAC,UAAU,IAAI;AAAA,EACjB;AAEA,QAAM,mBAAmBE,SAAQ,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC;AAErE,SACE,gBAAAG,MAAC,oBAAoB,UAApB,EAA6B,OAAO,kBACnC,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,cAAc;AAAA,QACd;AAAA,MACF;AAAA,MACA,SAAS;AAAA,MACT,WAAW;AAAA,MACX,MAAK;AAAA,MACL,UAAU;AAAA,MACT,GAAG;AAAA,MAEH,sBACC,gBAAAC,MAAAF,WAAA,EAEE;AAAA,wBAAAC,MAAC,UAAK,WAAU,mBAAkB;AAAA,QAClC,gBAAAA,MAAC,gBACE,kBAAQ,gBAAAA,MAAC,YAAS,WAAU,gCAA+B,GAC9D;AAAA,QACA,gBAAAA,MAAC,gBAAc,gBAAK;AAAA,SACtB;AAAA;AAAA,EAEJ,GACF;AAEJ;;;ACtRA,SAAS,WAAW,wBAAwB;AAKnC,gBAAAE,aAAA;AADT,SAAS,QAAQ,EAAE,GAAG,MAAM,GAAgC;AAC1D,SAAO,gBAAAA,MAAC,iBAAiB,MAAjB,EAAsB,aAAU,WAAW,GAAG,OAAO;AAC/D;AAEA,SAAS,eAAe,EAAE,GAAG,MAAM,GAAmC;AACpE,SAAO,gBAAAA,MAAC,iBAAiB,SAAjB,EAAyB,aAAU,mBAAmB,GAAG,OAAO;AAC1E;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,OAAO;AAAA,EACP,aAAa;AAAA,EACb,GAAG;AACL,GAIK;AACH,SACE,gBAAAA,MAAC,iBAAiB,QAAjB,EACC,0BAAAA;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MAEV,0BAAAA;AAAA,QAAC,iBAAiB;AAAA,QAAjB;AAAA,UACC,aAAU;AAAA,UACV,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UACC,GAAG;AAAA;AAAA,MACN;AAAA;AAAA,EACF,GACF;AAEJ;;;ACKM,gBAAAC,aAAA;AApCC,SAAS,UAAU,OAA2B;AACnD,QAAM,OAAiB,EAAE,MAAM,IAAI,MAAM,IAAI,UAAU,oBAAI,IAAI,EAAE;AACjE,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC5C,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,SAAS,MAAM,MAAM,SAAS;AAIpC,YAAM,YAAY,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,GAAG;AACtD,UAAI,CAAC,IAAI,SAAU;AACnB,UAAI,QAAQ,IAAI,SAAS,IAAI,IAAI;AACjC,UAAI,CAAC,OAAO;AACV,gBAAQ,EAAE,MAAM,MAAM,WAAW,UAAU,SAAS,OAAO,oBAAI,IAAI,EAAE;AACrE,YAAI,SAAS,IAAI,MAAM,KAAK;AAAA,MAC9B;AACA,UAAI,CAAC,UAAU,MAAM,SAAU,OAAM;AAAA,eAC5B,CAAC,UAAU,CAAC,MAAM,SAAU;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,WAAW,MAA2B;AACpD,MAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,QAAM,UAAU,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AAChE,UAAM,UAAU,EAAE,aAAa;AAC/B,UAAM,UAAU,EAAE,aAAa;AAC/B,QAAI,YAAY,QAAS,QAAO,UAAU,KAAK;AAC/C,WAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,EACpC,CAAC;AACD,SAAO,QAAQ;AAAA,IAAI,CAAC,UAClB,MAAM,WACJ,gBAAAA,MAAC,kBAAgC,MAAM,MAAM,MAAM,MAAM,MAAM,MAC5D,qBAAW,KAAK,KADE,MAAM,IAE3B,IAEA,gBAAAA,MAAC,gBAA8B,MAAM,MAAM,MAAM,MAAM,MAAM,QAA1C,MAAM,IAA0C;AAAA,EAEvE;AACF;AAEO,SAAS,OAAO,MAAc,OAA0B;AAC7D,SAAO,MAAM,SAAS,IAAI;AAC5B;AAEO,SAAS,iBAAiB,OAA8B;AAC7D,QAAM,QAAQ,CAAC,OAAO,OAAO,SAAS,YAAY;AAClD,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,QAAQ,OAAO;AACxB,UAAM,MAAM,MAAM;AAClB,QAAI,MAAM,KAAK,CAAC,MAAM,MAAM,OAAO,EAAE,WAAW,GAAG,GAAG,GAAG,CAAC,GAAG;AAC3D,eAAS,IAAI,GAAG;AAAA,IAClB;AAAA,EACF;AACA,SAAO;AACT;;;AHcI,SAoBE,YAAAC,WApBF,OAAAC,OAoBE,QAAAC,aApBF;AApCG,SAAS,gBAAgB;AAAA,EAC9B,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,cAAc,mBAAmB;AACvC,QAAM,eAAe,WAAW;AAChC,QAAM,UAAU,eAAe,aAAa;AAE5C,QAAM,CAAC,OAAO,QAAQ,IAAIC;AAAA,IAAmB,MAC3C,UAAU,QAAQ,GAAG,KAAK,IAAI,CAAC;AAAA,EACjC;AACA,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAS,KAAK;AAEtC,QAAM,eAAe,aAAa,gBAAgB;AAClD,QAAM,kBAAkB,aAAa;AAErC,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,QAAS;AACd,aAAS,QAAQ,GAAG,KAAK,CAAC;AAC1B,WAAO,QAAQ,GAAG,GAAG,UAAU,MAAM,SAAS,QAAQ,GAAG,KAAK,CAAC,CAAC;AAAA,EAClE,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,OAAOC,SAAQ,MAAM,UAAU,KAAK,GAAG,CAAC,KAAK,CAAC;AAEpD,QAAM,eAAe,CAAC,SAAiB;AACrC,QAAI,CAAC,OAAO,MAAM,KAAK,EAAG;AAC1B,sBAAkB,IAAI;AACtB,eAAW,IAAI;AACf,QAAI,YAAY,WAAY,SAAQ,KAAK;AAAA,EAC3C;AAEA,QAAM,WACJ,gBAAAJ;AAAA,IAAC;AAAA;AAAA,MACC,iBAAiB,mBAAmB,iBAAiB,KAAK;AAAA,MAC1D,UAAU;AAAA,MACV,cAAc,gBAAgB;AAAA,MAC9B,WAAW,oEAAoE,aAAa,EAAE,GAAG,KAAK;AAAA,MAErG,qBAAW,IAAI;AAAA;AAAA,EAClB;AAGF,MAAI,YAAY,YAAY;AAO1B,UAAM,eAAe,eACnB,gBAAAA,MAAC,YAAS,WAAU,UAAS,IAE7B,gBAAAC,MAAAF,WAAA,EACE;AAAA,sBAAAC,MAAC,YAAS,WAAU,UAAS;AAAA,MAC7B,gBAAAA,MAAC,UAAK,2BAAa;AAAA,OACrB;AAEF,WACE,gBAAAC,MAAC,WAAQ,MAAY,cAAc,SACjC;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,QACE,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,cAAW;AAAA,cACX,WAAW,sCAAsC,aAAa,EAAE,GAAG,KAAK;AAAA;AAAA,UAC1E;AAAA,UAGD,0BAAgB;AAAA;AAAA,MACnB;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAM;AAAA,UACN,WAAU;AAAA,UAET;AAAA;AAAA,MACH;AAAA,OACF;AAAA,EAEJ;AAEA,SAAO;AACT;;;AIhIA;AAAA,EACE,eAAAK;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAEK;AACP,SAAS,0BAA0B;AAEnC,SAAS,cAAc;;;ACnBvB,SAAS,WAAAC,gBAAe;AACxB,OAAO;AAAA,EACL;AAAA,OAGK;AACP,SAAS,kBAAkB;AAC3B,SAAS,WAAW;AACpB,SAAS,YAAY;AACrB,SAAS,YAAY;AACrB,SAAS,gBAAgB;AAgErB,gBAAAC,aAAA;AAtBG,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,QAAM,MAAM,mBAAmB;AAC/B,QAAM,gBAAiC,SAAS,KAAK,SAAS;AAE9D,QAAM,aAAaC,SAAqB,MAAM;AAC5C,UAAM,UAAU,kBAAkB,QAAQ;AAC1C,UAAM,OAAO,WAAW;AACxB,UAAM,OAAoB,CAAC,IAAI;AAC/B,QAAI,QAAS,MAAK,KAAK,OAAO;AAC9B,WAAO,kBAAkB,CAAC,GAAG,MAAM,GAAG,eAAe,IAAI;AAAA,EAC3D,GAAG,CAAC,UAAU,eAAe,CAAC;AAE9B,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,YACE,cAAc;AAAA,QACZ,aAAa;AAAA,QACb,qBAAqB;AAAA,QACrB,2BAA2B;AAAA,QAC3B,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,eAAe;AAAA,QACf,eAAe;AAAA,QACf,cAAc;AAAA,MAChB;AAAA,MAEF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,kBAAkB,MAA4C;AACrE,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,WAAW,EAAE,YAAY,KAAK,CAAC;AAAA,IACxC,KAAK;AACH,aAAO,WAAW,EAAE,YAAY,MAAM,KAAK,KAAK,CAAC;AAAA,IACnD,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,WAAW,EAAE,KAAK,KAAK,CAAC;AAAA,IACjC,KAAK;AACH,aAAO,IAAI;AAAA,IACb,KAAK;AACH,aAAO,KAAK;AAAA,IACd,KAAK;AACH,aAAO,KAAK;AAAA,IACd,KAAK;AACH,aAAO,SAAS;AAAA,IAClB,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;;;ACzGI,gBAAAE,OACA,QAAAC,aADA;AARJ,IAAM,aAAa,CAAC,EAAE,OAAO,GAAG,MAC9B,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,QAAQ;AAAA,IACR,gBAAe;AAAA,IACf,OAAO,EAAE,OAAO,eAAe;AAAA,IAC/B,SAAQ;AAAA,IACR,OAAO;AAAA,IAEP;AAAA,sBAAAD,MAAC,WAAM,oBAAM;AAAA,MACb,gBAAAC,MAAC,OAAE,UAAS,yBACV;AAAA,wBAAAD,MAAC,UAAK,GAAE,UAAS,QAAO,gBAAe,aAAY,OAAM;AAAA,QACzD,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,SACF;AAAA,MACA,gBAAAA,MAAC,UACC,0BAAAA,MAAC,cAAS,IAAG,mBACX,0BAAAA,MAAC,UAAK,MAAK,SAAQ,QAAO,MAAK,OAAM,MAAK,GAC5C,GACF;AAAA;AAAA;AACF;AAOK,IAAM,SAAS,CAAC,EAAE,WAAW,OAAO,IAAI,GAAG,MAAM,MACtD,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA,IAEJ,0BAAAA,MAAC,cAAW,MAAY;AAAA;AAC1B;;;ACzFF,IAAM,cAAkD;AAAA,EACtD,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AACP;AAEO,SAAS,cAAc,MAAkC;AAC9D,QAAM,IAAI,KAAK,MAAM,YAAY;AACjC,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,MAAM,EAAE,CAAC,EAAG,YAAY;AAC9B,SAAO,YAAY,GAAG,KAAK;AAC7B;;;AHmNI,SAuBc,YAAAE,WAvBd,OAAAC,OAWM,QAAAC,aAXN;AA3KG,SAAS,kBAAkB;AAAA,EAChC,SAAS;AAAA,EACT,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,cAAc,mBAAmB;AACvC,QAAM,eAAe,WAAW;AAChC,QAAM,UAAU,eAAe,aAAa;AAE5C,QAAM,eAAe,aAAa,gBAAgB;AAClD,QAAM,kBAAkB,aAAa;AAErC,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAwB,IAAI;AAC9D,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAiB,EAAE;AAC/C,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAwB,IAAI;AAClE,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAqB,MAAM;AAK/D,QAAM,gBAAgBC,QAAsB,IAAI;AAChD,QAAM,gBAAgBA,QAA6C,IAAI;AAGvE,QAAM,aAAaA,QAAO,OAAO;AACjC,QAAM,kBAAkBA,QAAO,YAAY;AAC3C,QAAM,YAAYA,QAAO,MAAM;AAC/B,QAAM,WAAWA,QAAO,KAAK;AAC7B,aAAW,UAAU;AACrB,kBAAgB,UAAU;AAC1B,YAAU,UAAU;AAEpB,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,cAAc;AAC7B,mBAAa,IAAI;AACjB,gBAAU,EAAE;AACZ,oBAAc,UAAU;AACxB;AAAA,IACF;AACA,mBAAe,YAAY;AAC3B,kBAAc,MAAM;AACpB,QAAI,YAAY;AAChB,YAAQ,GACL,SAAS,YAAY,EACrB,KAAK,CAAC,MAAM;AACX,UAAI,UAAW;AACf,mBAAa,CAAC;AACd,gBAAU,CAAC;AACX,oBAAc,UAAU;AACxB,qBAAe,IAAI;AAAA,IACrB,CAAC,EACA,MAAM,MAAM;AACX,UAAI,UAAW;AACf,YAAM,WAAW,qBAAqB,YAAY;AAClD,mBAAa,QAAQ;AACrB,gBAAU,QAAQ;AAClB,oBAAc,UAAU;AACxB,qBAAe,IAAI;AAAA,IACrB,CAAC;AACH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,SAAS,YAAY,CAAC;AAE1B,EAAAA,WAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,cAAc,SAAS;AACzB,qBAAa,cAAc,OAAO;AAClC,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,qBAAqBC;AAAA,IACzB,CAAC,SAAiB;AAChB,gBAAU,IAAI;AACd,UAAI,SAAU;AACd,UAAI,CAAC,aAAc;AAEnB,UAAI,cAAc,YAAY,aAAc;AAAA,IAC9C;AAAA,IACA,CAAC,UAAU,YAAY;AAAA,EACzB;AAEA,QAAM,QAAQ,CAAC,YAAY,cAAc,QAAQ,WAAW;AAC5D,WAAS,UAAU;AAEnB,QAAM,aAAaA,aAAY,YAAY;AACzC,QAAI,SAAU;AACd,UAAM,KAAK,WAAW;AACtB,UAAM,OAAO,gBAAgB;AAC7B,QAAI,CAAC,MAAM,CAAC,KAAM;AAClB,QAAI;AACF,YAAM,GAAG,GAAG,GAAG,IAAI;AACnB,wBAAkB,IAAI;AAAA,IACxB,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,UAAU,eAAe,CAAC;AAE9B,QAAM,OAAOA,aAAY,YAAY;AACnC,QAAI,SAAU;AACd,UAAM,KAAK,WAAW;AACtB,UAAM,OAAO,gBAAgB;AAC7B,UAAM,OAAO,UAAU;AACvB,QAAI,CAAC,MAAM,CAAC,KAAM;AAClB,QAAI,CAAC,SAAS,QAAS;AAKvB,kBAAc,QAAQ;AACtB,QAAI;AACF,YAAM,GAAG,GAAG,UAAU,MAAM,IAAI;AAChC,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC3C,mBAAa,IAAI;AACjB,oBAAc,MAAM;AAAA,IACtB,QAAQ;AACN,oBAAc,OAAO;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAIb,QAAM,mBAAmBC;AAAA,IACvB,MAAM;AACJ,YAAM,OAAO;AAAA,QACX,OAAO,GAAG;AAAA,UACR;AAAA,YACE,KAAK;AAAA,YACL,gBAAgB;AAAA,YAChB,KAAK,MAAM;AACT,mBAAK,KAAK;AACV,qBAAO;AAAA,YACT;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AACA,aAAO,aAAa,CAAC,GAAG,MAAM,GAAG,UAAU,IAAI;AAAA,IACjD;AAAA,IACA,CAAC,MAAM,UAAU;AAAA,EACnB;AAEA,QAAM,OAA2B,eAC7B,eACA,eACE,cAAc,YAAY,IAC1B;AAaN,QAAM,WAAW,eACb,aAAa,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,eACjD;AACJ,QAAM,cAAc,eAClB,gBAAAN,MAAC,UAAK,WAAU,aAAY,OAAO,cAChC,oBACH,IACE,kBAAkB,OACpB,gBAAAA,MAAC,UAAK,2BAAa;AAGrB,SACE,gBAAAC,MAAC,SAAI,WAAW,+BAA+B,aAAa,EAAE,GAAG,KAAK,GACnE;AAAA,KAAC,cACA,gBAAAA,MAAC,SAAI,WAAU,0EACb;AAAA,sBAAAA,MAAC,SAAI,WAAU,mDACZ;AAAA;AAAA,QACA;AAAA,SACH;AAAA,MACC,gBAAgB,CAAC,YAChB,gBAAAA,MAAC,SAAI,WAAU,2BACb;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,KAAK,KAAK;AAAA,YACzB,WAAU;AAAA,YAET,yBAAe,WACd,gBAAAC,MAAAF,WAAA,EACE;AAAA,8BAAAC,MAAC,UAAO,MAAM,IAAI;AAAA,cAAE;AAAA,eAEtB,IAEA;AAAA;AAAA,QAEJ;AAAA,QACA,gBAAAC,MAAC,gBACC;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,QACE,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,cAAW;AAAA,kBACX,WAAU;AAAA;AAAA,cACZ;AAAA,cAGF,0BAAAA,MAAC,sBAAmB,WAAU,UAAS;AAAA;AAAA,UACzC;AAAA,UACA,gBAAAA,MAAC,uBAAoB,OAAM,OACzB,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS,MAAM,KAAK,WAAW;AAAA,cAC/B,WAAU;AAAA,cACX;AAAA;AAAA,UAED,GACF;AAAA,WACF;AAAA,SACF;AAAA,OAEJ;AAAA,IAEF,gBAAAA,MAAC,SAAI,WAAU,gCACZ,yBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,UAAU,YAAY,gBAAgB;AAAA,QACtC,YAAY;AAAA,QACZ,QAAO;AAAA,QACP,WAAU;AAAA;AAAA,MATL;AAAA,IAUP,IAEA,cACE,gBAAAA,MAAC,SAAI,WAAU,gFAA+E,yCAE9F,GAGN;AAAA,KACF;AAEJ;;;AIxQM,gBAAAO,OAsCF,QAAAC,cAtCE;AAbC,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAoB;AAElB,MAAI,YAAY;AACd,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AAGA,MAAI,UAAU;AACZ,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AAEA,QAAM,eAAe,aACjB,0EACA;AAOJ,QAAM,gBACJ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,SAAQ;AAAA,MACR,WAAU;AAAA;AAAA,EACZ;AAGF,SACE,gBAAAC,OAAC,SAAI,WAAW,GAAG,YAAY,IAAI,aAAa,EAAE,GAAG,KAAK,GAAG,OAG3D;AAAA,oBAAAD,MAAC,SAAI,WAAU,wDACb,0BAAAA,MAAC,mBAAgB,SAAkB,iBAAkC,GACvE;AAAA,IAEA,gBAAAA,MAAC,SAAI,WAAU,kCACb,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,iBAAiB;AAAA,QAChB,GAAG;AAAA;AAAA,IACN,GACF;AAAA,KACF;AAEJ;;;AC5GA,SAAS,eAAAE,cAAa,aAAAC,YAAW,YAAAC,iBAAgB;AACjD,SAAS,sBAAAC,2BAA0B;AA0GzB,SAQE,YAAAC,WARF,OAAAC,OAQE,QAAAC,cARF;AAlFH,SAAS,iBAAiB;AAAA,EAC/B,SAAS;AAAA,EACT;AAAA,EACA,QAAQ;AACV,GAA0B;AACxB,QAAM,EAAE,SAAS,WAAW,IAAI,WAAW;AAC3C,QAAM,UAAU,eAAe,cAAc;AAE7C,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAyB,CAAC,CAAC;AACrD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,KAAK;AAC9C,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAwB,IAAI;AAElE,QAAM,UAAUC,aAAY,YAAY;AACtC,QAAI,CAAC,QAAS;AACd,eAAW,IAAI;AACf,QAAI;AACF,YAAM,OAAO,MAAM,QAAQ,UAAU,KAAK;AAC1C,eAAS,IAAI;AAAA,IACf,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,EAAAC,WAAU,MAAM;AACd,SAAK,QAAQ;AAAA,EACf,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,SAASD,aAAY,YAAY;AACrC,QAAI,CAAC,WAAW,SAAU;AAC1B,gBAAY,IAAI;AAChB,QAAI;AACF,YAAM,QAAQ,UAAU,OAAO;AAC/B,YAAM,QAAQ;AAAA,IAChB,SAAS,KAAK;AAEZ,cAAQ,MAAM,6BAA6B,GAAG;AAAA,IAChD,UAAE;AACA,kBAAY,KAAK;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,SAAS,UAAU,OAAO,CAAC;AAE/B,QAAM,UAAUA;AAAA,IACd,OAAO,OAAe;AACpB,UAAI,CAAC,QAAS;AACd,qBAAe,EAAE;AACjB,UAAI;AACF,cAAM,QAAQ,UAAU,QAAQ,EAAE;AAAA,MACpC,SAAS,KAAK;AAEZ,gBAAQ,MAAM,8BAA8B,GAAG;AAAA,MACjD,UAAE;AACA,uBAAe,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,QAAM,CAAC,oBAAoB,qBAAqB,IAAID;AAAA,IAClD;AAAA,EACF;AACA,QAAM,SAASC;AAAA,IACb,OAAO,OAAe;AACpB,UAAI,CAAC,QAAS;AACd,UAAI;AACF,cAAM,QAAQ,UAAU,OAAO,EAAE;AACjC,8BAAsB,IAAI;AAC1B,cAAM,QAAQ;AAAA,MAChB,SAAS,KAAK;AAEZ,gBAAQ,MAAM,6BAA6B,GAAG;AAAA,MAChD;AAAA,IACF;AAAA,IACA,CAAC,SAAS,OAAO;AAAA,EACnB;AAEA,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,uCAAuC,aAAa,EAAE,GAAG,KAAK;AAAA,MAEzE;AAAA,wBAAAA,OAAC,SAAI,WAAU,kEACZ;AAAA,oBAAU,OACT,gBAAAD,MAAC,UAAK,WAAU,uBAAuB,iBAAM,IAC3C,gBAAAA,MAAC,UAAK;AAAA,UACV,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,KAAK,OAAO;AAAA,cAC3B,UAAU,CAAC,WAAW;AAAA,cAErB,qBACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,gCAAAC,MAAC,UAAO,MAAM,IAAI;AAAA,gBAAE;AAAA,iBAEtB,IAEA;AAAA;AAAA,UAEJ;AAAA,WACF;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YAET,qBAAW,MAAM,WAAW,IAC3B,gBAAAA,MAAC,SAAI,WAAU,yEAAwE,2BAEvF,IACE,MAAM,WAAW,IACnB,gBAAAA,MAAC,SAAI,WAAU,yFAAwF,wEAEvG,IAEA,gBAAAA,MAAC,QAAG,WAAU,YACX,gBAAM,IAAI,CAAC,MACV,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBAEC,WAAU;AAAA,gBAEV;AAAA,kCAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAS,MAAM,KAAK,QAAQ,EAAE,EAAE;AAAA,sBAChC,UAAU,gBAAgB;AAAA,sBAC1B,WAAU;AAAA,sBAEV;AAAA,wCAAAD,MAAC,UAAK,WAAU,wBACb,YAAE,QAAQ,IAAI,EAAE,OAAO,IAC1B;AAAA,wBACA,gBAAAA,MAAC,UAAK,WAAU,iCACb,qBAAW,EAAE,SAAS,GACzB;AAAA;AAAA;AAAA,kBACF;AAAA,kBACA,gBAAAC,OAAC,SAAI,WAAU,2BACZ;AAAA,oCAAgB,EAAE,KACjB,gBAAAD,MAAC,UAAO,MAAM,IAAI,IAChB;AAAA,oBACJ,gBAAAC;AAAA,sBAAC;AAAA;AAAA,wBACC,cAAc,CAAC,SAAS;AAEtB,8BAAI,CAAC,KAAM,uBAAsB,IAAI;AAAA,wBACvC;AAAA,wBAEA;AAAA,0CAAAD;AAAA,4BAAC;AAAA;AAAA,8BACC,QACE,gBAAAA;AAAA,gCAAC;AAAA;AAAA,kCACC,MAAK;AAAA,kCACL,SAAQ;AAAA,kCACR,cAAW;AAAA,kCACX,WAAU;AAAA;AAAA,8BACZ;AAAA,8BAGF,0BAAAA,MAACK,qBAAA,EAAmB,WAAU,UAAS;AAAA;AAAA,0BACzC;AAAA,0BACA,gBAAAJ,OAAC,uBAAoB,OAAM,OACzB;AAAA,4CAAAD,MAAC,oBAAiB,SAAS,MAAM,KAAK,QAAQ,EAAE,EAAE,GAAG,qBAErD;AAAA,4BACA,gBAAAA;AAAA,8BAAC;AAAA;AAAA,gCAIC,cAAc,uBAAuB,EAAE;AAAA,gCACvC,SAAS,CAAC,MAAM;AACd,sCAAI,uBAAuB,EAAE,IAAI;AAC/B,sCAAE,eAAe;AACjB,0DAAsB,EAAE,EAAE;AAC1B;AAAA,kCACF;AACA,uCAAK,OAAO,EAAE,EAAE;AAAA,gCAClB;AAAA,gCACA,WAAU;AAAA,gCAET,iCAAuB,EAAE,KAAK,mBAAmB;AAAA;AAAA,4BACpD;AAAA,6BACF;AAAA;AAAA;AAAA,oBACF;AAAA,qBACF;AAAA;AAAA;AAAA,cA7DK,EAAE;AAAA,YA8DT,CACD,GACH;AAAA;AAAA,QAEJ;AAAA;AAAA;AAAA,EACF;AAEJ;AAGA,SAAS,WAAW,IAAoB;AACtC,QAAM,IAAI,IAAI,KAAK,EAAE;AACrB,SAAO,EAAE,eAAe,QAAW;AAAA,IACjC,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACH;;;AC3LI,SAoBE,OAAAM,OApBF,QAAAC,cAAA;AAdJ,IAAM,WAA0B;AAAA,EAC9B,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,eAAe;AACjB;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,OAAO;AACT,GAA4B;AAC1B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,cAAW;AAAA,MACX,OAAO,EAAE,GAAG,UAAU,GAAG,MAAM;AAAA,MAC/B,WAAW;AAAA;AAAA;AAAA;AAAA,QAIT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,wBAAAD,MAAC,UAAK,WAAU,cAAa,qBAAO;AAAA,QAAO,gBAAAA,MAAC,UAAK,WAAU,mBAAkB,kBAAI;AAAA;AAAA;AAAA,EACnF;AAEJ;;;ACtDA,SAAS,QAAQ,qBAAqB;AACtC,SAAS,OAAAE,YAA8B;AAUnC,gBAAAC,aAAA;AANJ,SAAS,KAAK;AAAA,EACZ;AAAA,EACA,cAAc;AAAA,EACd,GAAG;AACL,GAA6B;AAC3B,SACE,gBAAAA;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,aAAU;AAAA,MACV,oBAAkB;AAAA,MAClB,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,IAAM,mBAAmBC;AAAA,EACvB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,SAAS;AAAA,EAChB;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAqE;AACnE,SACE,gBAAAD;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,WAAW,GAAG,iBAAiB,EAAE,QAAQ,CAAC,GAAG,SAAS;AAAA,MACrD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,MAAM,GAA4B;AACrE,SACE,gBAAAA;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ArB4DQ,SAgGE,YAAAE,WAhGF,OAAAC,OAOA,QAAAC,cAPA;AAzCR,IAAM,aAAkC;AAAA,EACtC,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,iBAAiB;AACnB;AAQA,IAAM,mBAAmB;AAAA,EACvB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM;AACR;AASO,SAAS,cAAc,EAAE,IAAI,WAAW,MAAM,GAAuB;AAC1E,QAAM,QAAQ,EAAE,GAAG,YAAY,GAAG,GAAG;AACrC,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAyB,KAAK;AACtD,QAAM,SAAS,SAAS;AAExB,SACE,gBAAAF,MAAC,0BACC,0BAAAC,OAAC,kBAAe,WAAsB,OACpC;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,cAAc;AAAA;AAAA,IAChB;AAAA,IAGA,gBAAAC,OAAC,SAAI,WAAU,2CACb;AAAA,sBAAAD;AAAA,QAACG,QAAO;AAAA,QAAP;AAAA,UACC,WAAU;AAAA,UACV,SAAS,EAAE,GAAG,SAAS,UAAU,KAAK;AAAA,UACtC,YAAY;AAAA,UAEZ,0BAAAH,MAAC,qBAAkB;AAAA;AAAA,MACrB;AAAA,MACC,MAAM,kBACL,gBAAAA;AAAA,QAACG,QAAO;AAAA,QAAP;AAAA,UACC,WAAU;AAAA,UACV,SAAS,EAAE,GAAG,OAAO;AAAA,UACrB,SAAS,EAAE,GAAG,SAAS,OAAO,OAAO;AAAA,UACrC,YAAY;AAAA,UAEZ,0BAAAH,MAAC,cAAW,YAAU,MAAC;AAAA;AAAA,MACzB;AAAA,MAED,MAAM,mBAAmB,CAAC,UAAU,gBAAAA,MAAC,sBAAmB;AAAA,OAC3D;AAAA,IAEC,MAAM,eAAe,gBAAAA,MAAC,yBAAsB;AAAA,KAC/C,GACF;AAEJ;AAKA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,EAAE,QAAQ,IAAI,qBAAqB;AACzC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,YAAW;AAAA,MACX,WAAW;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAQA,SAAS,eAAe,EAAE,OAAO,MAAM,aAAa,GAAwB;AAC1E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,qBAAqB;AAOzB,QAAM,WACJ,MAAM,kBAAkB,MAAM,aAC5B,gBAAAC,OAAAF,WAAA,EACG;AAAA,UAAM,kBACL,gBAAAE,OAAAF,WAAA,EACE;AAAA,sBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,UAAU,gBAAgB;AAAA,UAC1B,SAAS;AAAA,UAET,0BAAAA,MAACI,gBAAA,EAAc,WAAU,UAAS;AAAA;AAAA,MACpC;AAAA,MACA,gBAAAJ;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,UAAU,gBAAgB,QAAQ,SAAS;AAAA,UAC3C,SAAS;AAAA,UAET,0BAAAA,MAACK,iBAAA,EAAe,WAAU,UAAS;AAAA;AAAA,MACrC;AAAA,MACA,gBAAAL;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,aAAY;AAAA,UACZ,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,KAAK;AAAA,UAC7C,WAAW,CAAC,MAAM;AAChB,gBAAI,EAAE,QAAQ,SAAS;AACrB,gBAAE,eAAe;AACjB,wBAAU;AAAA,YACZ,WAAW,EAAE,QAAQ,UAAU;AAC7B,4BAAc,UAAU;AACxB,cAAC,EAAE,OAA4B,KAAK;AAAA,YACtC;AAAA,UACF;AAAA;AAAA,MACF;AAAA,OACF;AAAA,IAED,MAAM,cACL,gBAAAA,MAAC,8BAA2B,SAAQ,UAAS,SAAS,QACpD,0BAAAA;AAAA,MAACM;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA;AAAA,MADL;AAAA,IAEP,GACF;AAAA,KAEJ,IACE;AAEN,SACE,gBAAAL,OAAC,SAAI,WAAU,iBAEZ;AAAA,gBACC,gBAAAD,MAAC,SAAI,WAAU,aACb,0BAAAA,MAAC,wBAAsB,oBAAS,GAClC;AAAA,IAIF,gBAAAC,OAAC,wBACE;AAAA,YAAM,kBACL,gBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,eAAe,CAAC,MAAM,aAAa,CAAmB;AAAA,UACtD,WAAU;AAAA,UAEV,0BAAAC,OAAC,YAAS,WAAU,OAClB;AAAA,4BAAAD,MAAC,eAAY,OAAM,OAAM,cAAW,OAAM,WAAU,cAClD,0BAAAA,MAAC,aAAU,WAAU,UAAS,GAChC;AAAA,YACA,gBAAAA,MAAC,eAAY,OAAM,QAAO,cAAW,QAAO,WAAU,cACpD,0BAAAA,MAAC,YAAS,WAAU,UAAS,GAC/B;AAAA,aACF;AAAA;AAAA,MACF;AAAA,MAQD,YAAY,gBAAAA,MAAC,SAAI,WAAU,sBAAsB,oBAAS;AAAA,MAK3D,gBAAAA,MAAC,SAAI,WAAU,oBAAmB;AAAA,MAEjC,MAAM,oBACL,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,aAAa,YAAY,gBAAgB;AAAA,UAClD,SAAS,MACP,YAAY,aAAa,YAAY,WAAW,SAAS;AAAA,UAE3D,WAAU;AAAA,UAET,uBAAa,YACZ,gBAAAA,MAACO,iBAAA,EAAe,WAAU,UAAS,IAEnC,gBAAAP,MAACQ,cAAA,EAAY,WAAU,UAAS;AAAA;AAAA,MAEpC;AAAA,MAGD,MAAM,wBACL,gBAAAR;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,UAAU,oBAAoB;AAAA,UACvC,SAAS;AAAA,UAER,oBACC,gBAAAA,MAACS,eAAA,EAAa,WAAU,UAAS,IAEjC,gBAAAT,MAACU,eAAA,EAAa,WAAU,UAAS;AAAA;AAAA,MAErC;AAAA,MAGD,MAAM,iBACL,gBAAAT,OAAC,WACC;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ,gBAAAA,MAAC,8BAA2B,SAAQ,aAAY;AAAA,YAExD,0BAAAA,MAAC,mBAAgB,WAAU,UAAS;AAAA;AAAA,QACtC;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,WAAU;AAAA,YAEV,0BAAAA,MAAC,oBAAiB;AAAA;AAAA,QACpB;AAAA,SACF;AAAA,OAGA,MAAM,mBAAmB,MAAM,iBAC/B,gBAAAC,OAAC,gBACC;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ,gBAAAA,MAAC,8BAA2B,SAAQ,QAAO;AAAA,YAEnD,0BAAAA,MAACW,mBAAA,EAAiB,WAAU,UAAS;AAAA;AAAA,QACvC;AAAA,QACA,gBAAAX,MAAC,uBAAoB,OAAM,OAAM,WAAU,YACxC,gBAAM,mBACL,gBAAAC,OAAC,oBAAiB,SAAS,UACzB;AAAA,0BAAAD,MAACY,eAAA,EAAa,WAAU,UAAS;AAAA,UAAE;AAAA,WAErC,GAEJ;AAAA,SACF;AAAA,OAEJ;AAAA,KACF;AAEJ;;;AsBxVM,gBAAAC,aAAA;AAHC,SAAS,QAAQ,EAAE,IAAI,WAAW,OAAO,GAAG,cAAc,GAAiB;AAChF,SACE,gBAAAA,MAAC,mBAAiB,GAAG,eACnB,0BAAAA,MAAC,iBAAc,IAAQ,WAAsB,OAAc,GAC7D;AAEJ;","names":["useState","motion","ArrowLeftIcon","ArrowRightIcon","DownloadIcon","MaximizeIcon","MinimizeIcon","MonitorIcon","MoreVerticalIcon","RefreshCcwIcon","SmartphoneIcon","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","jsx","jsx","jsx","jsx","createContext","useCallback","useContext","useMemo","useState","jsx","jsxs","jsxs","jsx","ChevronDownIcon","createContext","useCallback","useContext","useMemo","useState","jsx","jsxs","CheckIcon","jsx","jsxs","jsx","jsx","jsx","jsxs","createContext","useContext","SandboxPreviewProvider","useRef","useCallback","useState","useEffect","useMemo","jsxs","jsx","useEffect","useMemo","useState","ChevronRightIcon","createContext","useCallback","useContext","useMemo","useState","Fragment","jsx","jsxs","jsx","jsx","Fragment","jsx","jsxs","useState","useEffect","useMemo","useCallback","useEffect","useMemo","useRef","useState","useMemo","jsx","useMemo","jsx","jsxs","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useMemo","jsx","jsxs","useCallback","useEffect","useState","MoreHorizontalIcon","Fragment","jsx","jsxs","useState","useCallback","useEffect","MoreHorizontalIcon","jsx","jsxs","cva","jsx","cva","Fragment","jsx","jsxs","useState","motion","ArrowLeftIcon","ArrowRightIcon","RefreshCcwIcon","SmartphoneIcon","MonitorIcon","MinimizeIcon","MaximizeIcon","MoreVerticalIcon","DownloadIcon","jsx"]}
|