@tutti-os/browser-node 0.0.1 → 0.0.3

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.
@@ -862,8 +862,8 @@ function BrowserNode({
862
862
  children: [
863
863
  /* @__PURE__ */ jsx("div", { className: "flex size-11 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--state-danger)_22%,transparent)] bg-[color-mix(in_srgb,var(--state-danger)_8%,transparent)] text-[var(--state-danger)]", children: /* @__PURE__ */ jsx(WarningLinedIcon, { className: "size-5" }) }),
864
864
  /* @__PURE__ */ jsx("div", { className: "mt-4 text-lg font-semibold text-[var(--text-primary)]", children: feature.i18n.t("loadFailed") }),
865
- /* @__PURE__ */ jsx("div", { className: "mt-1 max-w-[360px] text-sm leading-5 text-[var(--text-secondary)]", children: errorMessage }),
866
- errorStatus ? /* @__PURE__ */ jsx("div", { className: "mt-4 rounded-full border border-border bg-[var(--transparency-block)] px-2.5 py-1 text-xs font-medium text-[var(--text-secondary)]", children: errorStatus }) : null,
865
+ /* @__PURE__ */ jsx("div", { className: "mt-1 max-w-[360px] text-[13px] leading-5 text-[var(--text-secondary)]", children: errorMessage }),
866
+ errorStatus ? /* @__PURE__ */ jsx("div", { className: "mt-4 rounded-full border border-border bg-[var(--transparency-block)] px-2.5 py-1 text-[11px] font-medium text-[var(--text-secondary)]", children: errorStatus }) : null,
867
867
  openExternalUrl ? /* @__PURE__ */ jsx("div", { className: "mt-5 flex flex-wrap items-center justify-center gap-2", children: /* @__PURE__ */ jsxs(
868
868
  Button,
869
869
  {
@@ -1176,4 +1176,4 @@ export {
1176
1176
  BrowserNodeWorkbenchHeader,
1177
1177
  BrowserNodeHeader
1178
1178
  };
1179
- //# sourceMappingURL=chunk-2GEY55PS.js.map
1179
+ //# sourceMappingURL=chunk-BZRJYTPK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/BrowserNode.tsx","../src/react/useBrowserNodeController.ts","../src/core/nodeController.ts","../src/react/useBrowserNodeWebview.ts","../src/core/webviewController.ts"],"sourcesContent":["import {\n ArrowLeftIcon,\n ArrowRightIcon,\n Badge,\n Button,\n Input,\n LaunchIcon,\n LoadingIcon,\n RefreshIcon,\n WarningLinedIcon,\n ViewportMenuSurface,\n cn,\n menuItemClassName\n} from \"@tutti-os/ui-system\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { HTMLAttributes, JSX, ReactNode } from \"react\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeNavigationPolicy,\n BrowserNodeRuntimeError,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport { useBrowserNodeController } from \"./useBrowserNodeController.ts\";\nimport { useBrowserNodeWebview } from \"./useBrowserNodeWebview.ts\";\n\n// Electron needs the serialized string attribute for dynamically created webviews.\nconst browserNodeAllowPopupsAttribute = \"true\" as unknown as boolean;\n\nexport interface BrowserNodeProps {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onFocusRequest?: () => void;\n onNavigated?: (url: string) => void;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n showHeader?: boolean;\n syncDefaultUrl?: boolean;\n}\n\nexport function BrowserNode({\n defaultUrl,\n feature,\n navigationPolicy = null,\n nodeId,\n onFocusRequest,\n onNavigated,\n profileId = null,\n sessionMode = \"shared\",\n sessionPartition = null,\n showHeader = true,\n syncDefaultUrl = false\n}: BrowserNodeProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n navigationPolicy,\n nodeId,\n profileId,\n sessionMode,\n sessionPartition,\n syncDefaultUrl\n });\n const runtime = state.runtime;\n const lastNavigatedUrlRef = useRef<string | null>(\n state.runtime.url?.trim() || null\n );\n const errorMessage = runtime.error\n ? formatBrowserNodeErrorMessage(feature, runtime.error)\n : null;\n const errorStatus = runtime.error\n ? formatBrowserNodeErrorStatus(feature, runtime.error)\n : null;\n const isShowingLoadError = errorMessage !== null;\n const openExternalUrl = feature.hostApi.openExternal\n ? feature.resolveAddressInput(state.displayUrl).url\n : null;\n const {\n devToolsContextMenu,\n dismissDevToolsContextMenu,\n openDevToolsFromContextMenu,\n shouldRenderWebview,\n setWebviewRef,\n webviewKey,\n webviewPartition,\n webviewSrc\n } = useBrowserNodeWebview({\n feature,\n initialUrl: state.displayUrl,\n lifecycle: runtime.lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction: onFocusRequest,\n profileId,\n sessionMode,\n sessionPartition\n });\n\n useEffect(() => {\n const navigatedUrl = state.runtime.url?.trim() ?? \"\";\n if (\n !onNavigated ||\n state.runtime.isLoading ||\n state.runtime.error ||\n navigatedUrl.length === 0 ||\n navigatedUrl === \"about:blank\" ||\n lastNavigatedUrlRef.current === navigatedUrl\n ) {\n return;\n }\n\n lastNavigatedUrlRef.current = navigatedUrl;\n onNavigated(navigatedUrl);\n }, [\n onNavigated,\n state.runtime.error,\n state.runtime.isLoading,\n state.runtime.url\n ]);\n\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden bg-[var(--background-panel)]\">\n {showHeader ? (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n draftUrl={state.draftUrl}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onOpenExternal={\n openExternalUrl\n ? () => {\n void feature.hostApi\n .openExternal?.({ url: openExternalUrl })\n .catch(() => undefined);\n }\n : undefined\n }\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n />\n ) : null}\n <div className=\"relative min-h-0 flex-1 overflow-hidden bg-[var(--background-panel)]\">\n {shouldRenderWebview ? (\n <webview\n allowpopups={browserNodeAllowPopupsAttribute}\n key={webviewKey}\n ref={setWebviewRef}\n className={cn(\n \"absolute inset-0 h-full w-full border-0 bg-[var(--background-panel)]\",\n isShowingLoadError ? \"hidden pointer-events-none\" : \"visible\"\n )}\n data-browser-node-webview=\"true\"\n partition={webviewPartition}\n src={webviewSrc}\n />\n ) : null}\n {errorMessage ? (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-[var(--background-panel)] px-8 py-10 text-center\">\n <div\n className=\"flex w-full max-w-[440px] flex-col items-center\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div className=\"flex size-11 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--state-danger)_22%,transparent)] bg-[color-mix(in_srgb,var(--state-danger)_8%,transparent)] text-[var(--state-danger)]\">\n <WarningLinedIcon className=\"size-5\" />\n </div>\n <div className=\"mt-4 text-lg font-semibold text-[var(--text-primary)]\">\n {feature.i18n.t(\"loadFailed\")}\n </div>\n <div className=\"mt-1 max-w-[360px] text-[13px] leading-5 text-[var(--text-secondary)]\">\n {errorMessage}\n </div>\n {errorStatus ? (\n <div className=\"mt-4 rounded-full border border-border bg-[var(--transparency-block)] px-2.5 py-1 text-[11px] font-medium text-[var(--text-secondary)]\">\n {errorStatus}\n </div>\n ) : null}\n {openExternalUrl ? (\n <div className=\"mt-5 flex flex-wrap items-center justify-center gap-2\">\n <Button\n size=\"sm\"\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n void feature.hostApi\n .openExternal?.({ url: openExternalUrl })\n .catch(() => undefined);\n }}\n >\n <LaunchIcon className=\"size-3.5\" />\n {feature.i18n.t(\"actions.openExternal\")}\n </Button>\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n {devToolsContextMenu ? (\n <ViewportMenuSurface\n open\n className=\"w-44\"\n dismissOnEscape\n dismissOnPointerDownOutside\n onDismiss={dismissDevToolsContextMenu}\n placement={{\n type: \"point\",\n point: devToolsContextMenu,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 176,\n height: 40\n }\n }}\n >\n <button\n className={cn(menuItemClassName, \"w-full\")}\n type=\"button\"\n onClick={() => {\n void openDevToolsFromContextMenu().catch(() => undefined);\n }}\n >\n {feature.i18n.t(\"actions.openDevTools\")}\n </button>\n </ViewportMenuSurface>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport interface BrowserNodeWorkbenchHeaderProps {\n className?: string;\n defaultActions?: ReactNode;\n defaultUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n nodeId: string;\n onCloseRequest?: () => void;\n onFocusRequest?: () => void;\n}\n\nexport function BrowserNodeWorkbenchHeader({\n className,\n defaultActions,\n defaultUrl,\n dragHandleProps,\n feature,\n nodeId,\n onCloseRequest,\n onFocusRequest\n}: BrowserNodeWorkbenchHeaderProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n nodeId\n });\n const runtime = state.runtime;\n const openExternalUrl = feature.hostApi.openExternal\n ? feature.resolveAddressInput(state.displayUrl).url\n : null;\n\n return (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n className={className}\n defaultActions={defaultActions}\n draftUrl={state.draftUrl}\n dragHandleProps={dragHandleProps}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onCloseRequest={onCloseRequest}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onOpenExternal={\n openExternalUrl\n ? () => {\n void feature.hostApi\n .openExternal?.({ url: openExternalUrl })\n .catch(() => undefined);\n }\n : undefined\n }\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n withBorder={false}\n />\n );\n}\n\nexport function BrowserNodeHeader({\n canGoBack,\n canGoForward,\n className,\n defaultActions,\n draftUrl,\n dragHandleProps,\n feature,\n isCold = false,\n isLoading,\n onCloseRequest,\n onDraftUrlChange,\n onFocusRequest,\n onGoBack,\n onGoForward,\n onOpenExternal,\n onReload,\n onSubmitUrl,\n withBorder = true\n}: {\n canGoBack: boolean;\n canGoForward: boolean;\n className?: string;\n defaultActions?: ReactNode;\n draftUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n isCold?: boolean;\n isLoading: boolean;\n onCloseRequest?: () => void;\n onDraftUrlChange: (nextUrl: string) => void;\n onFocusRequest?: () => void;\n onGoBack: () => void;\n onGoForward: () => void;\n onOpenExternal?: () => void;\n onReload: () => void;\n onSubmitUrl: () => void;\n withBorder?: boolean;\n}): JSX.Element {\n const [reloadAnimationKey, setReloadAnimationKey] = useState(0);\n\n const handleReload = (): void => {\n setReloadAnimationKey((currentKey) => currentKey + 1);\n onReload();\n };\n\n return (\n <div\n className={cn(\n \"flex h-[var(--workbench-header-height,38px)] min-h-[var(--workbench-header-height,38px)] items-center gap-2 bg-[var(--background-panel)] px-2 pl-3\",\n withBorder ? \"border-b border-border\" : null,\n className\n )}\n data-browser-node-header=\"true\"\n onDoubleClick={(event) => {\n if (\n event.target instanceof Element &&\n event.target.closest(\".nodrag\")\n ) {\n return;\n }\n event.stopPropagation();\n dragHandleProps?.onDoubleClick?.(event);\n }}\n >\n <div className=\"inline-flex items-center gap-1\">\n <BrowserNodeHeaderButton\n disabled={!canGoBack}\n label={feature.i18n.t(\"actions.back\")}\n onClick={onGoBack}\n >\n <ArrowLeftIcon className=\"size-[15px]\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n disabled={!canGoForward}\n label={feature.i18n.t(\"actions.forward\")}\n onClick={onGoForward}\n >\n <ArrowRightIcon className=\"size-[15px]\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n label={feature.i18n.t(\"actions.reload\")}\n onClick={handleReload}\n >\n <RefreshIcon\n key={reloadAnimationKey}\n className={cn(\n \"size-[15px]\",\n reloadAnimationKey > 0 &&\n \"motion-safe:animate-[spin_520ms_cubic-bezier(0.4,0,0.2,1)_1_reverse]\"\n )}\n />\n </BrowserNodeHeaderButton>\n </div>\n <div\n {...dragHandleProps}\n className=\"h-full w-8 shrink-0 cursor-grab active:cursor-grabbing\"\n data-browser-node-drag-gutter=\"true\"\n data-node-drag-handle=\"true\"\n aria-hidden=\"true\"\n />\n <form\n className=\"nodrag relative min-w-0 flex-1\"\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onSubmitUrl();\n }}\n >\n <Input\n aria-label={feature.i18n.t(\"addressLabel\")}\n className=\"pr-8 focus-visible:border-input focus-visible:ring-0 focus-visible:ring-offset-0\"\n placeholder={feature.i18n.t(\"addressPlaceholder\")}\n size=\"sm\"\n value={draftUrl}\n onChange={(event) => onDraftUrlChange(event.target.value)}\n onFocus={onFocusRequest}\n />\n {isLoading ? (\n <LoadingIcon className=\"pointer-events-none absolute right-2 top-1/2 z-[1] size-4 -translate-y-1/2 animate-spin text-[var(--text-tertiary)]\" />\n ) : null}\n </form>\n {onOpenExternal ? (\n <BrowserNodeHeaderButton\n label={feature.i18n.t(\"actions.openExternal\")}\n onClick={onOpenExternal}\n >\n <LaunchIcon className=\"size-[15px]\" />\n </BrowserNodeHeaderButton>\n ) : null}\n {defaultActions ? (\n <div className=\"nodrag flex shrink-0 items-center gap-1.5\">\n {isCold ? (\n <Badge\n className=\"h-[26px] min-w-7 rounded-md text-[10px] font-semibold lowercase tracking-[0.08em]\"\n aria-label={feature.i18n.t(\"coldStatus\")}\n >\n {feature.i18n.t(\"coldStatus\")}\n </Badge>\n ) : null}\n <span\n className=\"contents\"\n onClickCapture={(event) => {\n if (\n !onCloseRequest ||\n !(event.target instanceof Element) ||\n !event.target.closest('[data-workbench-action=\"close\"]')\n ) {\n return;\n }\n onCloseRequest();\n }}\n >\n {defaultActions}\n </span>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction formatBrowserNodeErrorMessage(\n feature: BrowserNodeFeature,\n error: BrowserNodeRuntimeError\n): string {\n switch (error.code) {\n case \"invalid-url\":\n return feature.i18n.t(\"errors.invalidUrl\", error.params);\n case \"navigation-failed\":\n if (error.params && error.params.statusCode !== undefined) {\n return feature.i18n.t(\n \"errors.navigationFailedWithStatus\",\n error.params\n );\n }\n return feature.i18n.t(\"errors.navigationFailed\", error.params);\n case \"unsupported-protocol\":\n return feature.i18n.t(\"errors.unsupportedProtocol\", error.params);\n case \"unsupported-url\":\n return feature.i18n.t(\"errors.unsupportedUrl\", error.params);\n }\n}\n\nfunction formatBrowserNodeErrorStatus(\n feature: BrowserNodeFeature,\n error: BrowserNodeRuntimeError\n): string | null {\n if (error.code !== \"navigation-failed\" || !error.params) {\n return null;\n }\n\n const statusCode = error.params.statusCode;\n if (typeof statusCode === \"number\") {\n return feature.i18n.t(\"errors.statusCode\", { statusCode });\n }\n\n const errorCode = error.params.errorCode;\n if (typeof errorCode === \"number\") {\n return feature.i18n.t(\"errors.errorCode\", { errorCode });\n }\n\n return null;\n}\n\nfunction BrowserNodeHeaderButton({\n children,\n disabled,\n label,\n onClick\n}: {\n children: ReactNode;\n disabled?: boolean;\n label: string;\n onClick: () => void;\n}) {\n return (\n <Button\n aria-label={label}\n className=\"rounded-md\"\n disabled={disabled}\n size=\"icon-sm\"\n title={label}\n type=\"button\"\n variant=\"chrome\"\n onClick={onClick}\n >\n {children}\n </Button>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@tutti-os/ui-react-hooks\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport {\n acquireBrowserNodeController,\n type BrowserNodeControllerState\n} from \"../core/nodeController.ts\";\nimport type {\n BrowserNodeNavigationPolicy,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\n\nexport function useBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n syncDefaultUrl?: boolean;\n}) {\n const controller = useMemo(\n () =>\n acquireBrowserNodeController({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\",\n sessionPartition: input.sessionPartition,\n syncDefaultUrl: input.syncDefaultUrl ?? false\n }),\n [\n input.defaultUrl,\n input.feature,\n input.navigationPolicy,\n input.nodeId,\n input.profileId,\n input.sessionMode,\n input.sessionPartition,\n input.syncDefaultUrl\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n\n useEffect(() => {\n controller.sync();\n }, [\n controller,\n input.defaultUrl,\n input.feature,\n input.navigationPolicy,\n input.nodeId,\n input.profileId,\n input.sessionMode,\n input.sessionPartition,\n input.syncDefaultUrl\n ]);\n const state = useExternalStoreSnapshot<BrowserNodeControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n return {\n controller,\n state\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport {\n normalizeBrowserComparableUrl,\n normalizeHostBrowserComparableUrl\n} from \"./url.ts\";\nimport type {\n BrowserNodeNavigationPolicy,\n BrowserNodeRuntimeState,\n BrowserNodeSessionMode\n} from \"./types.ts\";\n\nexport interface BrowserNodeControllerState {\n displayUrl: string;\n draftUrl: string;\n runtime: BrowserNodeRuntimeState;\n}\n\nexport interface BrowserNodeController {\n getState(): BrowserNodeControllerState;\n goBack(): Promise<void>;\n goForward(): Promise<void>;\n reload(): Promise<void>;\n release(): void;\n retain(): void;\n setDraftUrl(nextUrl: string): void;\n sync(): void;\n subscribe(listener: () => void): () => void;\n submitDraftUrl(): Promise<void>;\n}\n\ninterface BrowserNodeControllerContext {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n syncDefaultUrl: boolean;\n}\n\ninterface BrowserNodeControllerEntry {\n connectedRelease: (() => void) | null;\n controller: BrowserNodeController;\n context: BrowserNodeControllerContext;\n lastColdActivationUrl: string | null;\n listeners: Set<() => void>;\n pendingColdActivationUrl: string | null;\n refCount: number;\n runtimeUnsubscribe: (() => void) | null;\n state: BrowserNodeControllerState;\n}\n\nconst controllerRegistry = new Map<string, BrowserNodeControllerEntry>();\n\nexport function acquireBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n syncDefaultUrl?: boolean;\n}): BrowserNodeController {\n const existing = controllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeControllerEntry({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\",\n sessionPartition: input.sessionPartition,\n syncDefaultUrl: input.syncDefaultUrl ?? false\n });\n\n entry.context = {\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\",\n sessionPartition: input.sessionPartition,\n syncDefaultUrl: input.syncDefaultUrl ?? false\n };\n\n if (!existing) {\n controllerRegistry.set(input.nodeId, entry);\n }\n\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: false,\n notifyListeners: false\n });\n\n return entry.controller;\n}\n\nfunction createBrowserNodeControllerEntry(\n context: BrowserNodeControllerContext\n): BrowserNodeControllerEntry {\n const runtime = context.feature.runtimeStore.getNodeState(context.nodeId);\n const displayUrl = resolveBrowserNodeDisplayUrl(runtime, context.defaultUrl);\n const entry = {\n connectedRelease: null,\n controller: null as unknown as BrowserNodeController,\n context,\n lastColdActivationUrl: resolveInitialLastColdActivationUrl(\n runtime,\n context.defaultUrl\n ),\n listeners: new Set(),\n pendingColdActivationUrl: null,\n refCount: 0,\n runtimeUnsubscribe: null,\n state: {\n displayUrl,\n draftUrl: displayUrl,\n runtime\n }\n } as BrowserNodeControllerEntry;\n\n entry.controller = {\n getState() {\n return entry.state;\n },\n goBack() {\n return entry.context.feature.hostApi.goBack({\n nodeId: entry.context.nodeId\n });\n },\n goForward() {\n return entry.context.feature.hostApi.goForward({\n nodeId: entry.context.nodeId\n });\n },\n reload() {\n return entry.context.feature.hostApi.reload({\n nodeId: entry.context.nodeId\n });\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n\n entry.connectedRelease?.();\n entry.connectedRelease = null;\n entry.runtimeUnsubscribe?.();\n entry.runtimeUnsubscribe = null;\n controllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n\n if (!controllerRegistry.has(entry.context.nodeId)) {\n controllerRegistry.set(entry.context.nodeId, entry);\n }\n entry.connectedRelease = entry.context.feature.connect();\n entry.runtimeUnsubscribe = entry.context.feature.runtimeStore.subscribe(\n () => {\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n }\n );\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n },\n setDraftUrl(nextUrl) {\n if (entry.state.draftUrl === nextUrl) {\n return;\n }\n\n entry.state = {\n ...entry.state,\n draftUrl: nextUrl\n };\n notifyBrowserNodeControllerListeners(entry);\n },\n sync() {\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n },\n async submitDraftUrl() {\n const resolved = entry.context.feature.resolveAddressInput(\n entry.state.draftUrl\n );\n if (!resolved.url) {\n return;\n }\n\n if (entry.state.draftUrl !== resolved.url) {\n entry.state = {\n ...entry.state,\n draftUrl: resolved.url\n };\n notifyBrowserNodeControllerListeners(entry);\n }\n\n await entry.context.feature.hostApi.navigate({\n navigationPolicy: entry.context.navigationPolicy,\n nodeId: entry.context.nodeId,\n url: resolved.url\n });\n }\n };\n\n return entry;\n}\n\nfunction resolveInitialLastColdActivationUrl(\n runtime: BrowserNodeRuntimeState,\n defaultUrl: string\n): string | null {\n const trimmedUrl = defaultUrl.trim();\n if (\n runtime.lifecycle === \"cold\" ||\n runtime.error !== null ||\n trimmedUrl.length === 0 ||\n trimmedUrl === \"about:blank\"\n ) {\n return null;\n }\n\n const comparableDefaultUrl = normalizeBrowserComparableUrl(trimmedUrl);\n const comparableRuntimeUrl = runtime.url\n ? normalizeBrowserComparableUrl(runtime.url)\n : null;\n return comparableDefaultUrl !== null &&\n comparableDefaultUrl === comparableRuntimeUrl\n ? trimmedUrl\n : null;\n}\n\nfunction notifyBrowserNodeControllerListeners(\n entry: BrowserNodeControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction resolveBrowserNodeDisplayUrl(\n runtime: BrowserNodeRuntimeState,\n defaultUrl: string\n): string {\n const resolvedRuntimeUrl = runtime.url?.trim() ?? \"\";\n return resolvedRuntimeUrl.length > 0 ? resolvedRuntimeUrl : defaultUrl;\n}\n\nfunction reconcileBrowserNodeControllerState(\n entry: BrowserNodeControllerEntry,\n options: {\n allowAutoActivate: boolean;\n notifyListeners: boolean;\n }\n): void {\n const runtime = entry.context.feature.runtimeStore.getNodeState(\n entry.context.nodeId\n );\n const displayUrl = resolveBrowserNodeDisplayUrl(\n runtime,\n entry.context.defaultUrl\n );\n const nextDraftUrl =\n displayUrl !== entry.state.displayUrl ? displayUrl : entry.state.draftUrl;\n\n const changed =\n entry.state.runtime !== runtime ||\n entry.state.displayUrl !== displayUrl ||\n entry.state.draftUrl !== nextDraftUrl;\n\n if (changed) {\n entry.state = {\n displayUrl,\n draftUrl: nextDraftUrl,\n runtime\n };\n if (options.notifyListeners) {\n notifyBrowserNodeControllerListeners(entry);\n }\n }\n\n if (options.allowAutoActivate) {\n void maybeActivateBrowserNodeDefaultUrl(entry).catch(() => undefined);\n }\n}\n\nasync function maybeActivateBrowserNodeDefaultUrl(\n entry: BrowserNodeControllerEntry\n): Promise<void> {\n const {\n defaultUrl,\n feature,\n navigationPolicy,\n nodeId,\n profileId,\n sessionMode,\n sessionPartition,\n syncDefaultUrl\n } = entry.context;\n const trimmedUrl = defaultUrl.trim();\n const comparableDefaultUrl = normalizeHostBrowserComparableUrl(trimmedUrl);\n const comparableRuntimeUrl = entry.state.runtime.url\n ? normalizeHostBrowserComparableUrl(entry.state.runtime.url)\n : null;\n const shouldActivateColdNode = entry.state.runtime.lifecycle === \"cold\";\n const shouldSyncDefaultUrl =\n syncDefaultUrl &&\n entry.state.runtime.lifecycle !== \"cold\" &&\n comparableDefaultUrl !== null &&\n (comparableRuntimeUrl !== comparableDefaultUrl ||\n entry.state.runtime.error !== null) &&\n entry.lastColdActivationUrl !== trimmedUrl;\n if (\n trimmedUrl.length === 0 ||\n trimmedUrl === \"about:blank\" ||\n entry.state.runtime.isLoading ||\n entry.pendingColdActivationUrl === trimmedUrl ||\n (!shouldActivateColdNode && !shouldSyncDefaultUrl) ||\n (shouldActivateColdNode &&\n entry.state.runtime.error !== null &&\n entry.lastColdActivationUrl === trimmedUrl)\n ) {\n return;\n }\n\n entry.pendingColdActivationUrl = trimmedUrl;\n try {\n await feature.hostApi.activate({\n navigationPolicy,\n nodeId,\n profileId,\n sessionMode,\n sessionPartition,\n url: trimmedUrl\n });\n entry.lastColdActivationUrl = trimmedUrl;\n } finally {\n if (entry.pendingColdActivationUrl === trimmedUrl) {\n entry.pendingColdActivationUrl = null;\n }\n }\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@tutti-os/ui-react-hooks\";\nimport {\n acquireBrowserNodeWebviewController,\n type BrowserNodeWebviewContextMenuPoint,\n type BrowserNodeWebviewControllerState\n} from \"../core/webviewController.ts\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeLifecycle,\n BrowserNodeNavigationPolicy,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport type { BrowserNodeWebviewTag } from \"./webviewTag.ts\";\n\nexport function useBrowserNodeWebview({\n feature,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n}: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n}): {\n devToolsContextMenu: BrowserNodeWebviewContextMenuPoint | null;\n dismissDevToolsContextMenu: () => void;\n openDevToolsFromContextMenu: () => Promise<void>;\n shouldRenderWebview: boolean;\n setWebviewRef: (element: BrowserNodeWebviewTag | null) => void;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n} {\n const controller = useMemo(\n () =>\n acquireBrowserNodeWebviewController({\n feature,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n }),\n [\n feature,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n\n useEffect(() => {\n controller.sync();\n }, [\n controller,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n ]);\n const state = useExternalStoreSnapshot<BrowserNodeWebviewControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n const setWebviewRef = useCallback(\n (element: BrowserNodeWebviewTag | null) => {\n controller.setWebview(element);\n },\n [controller]\n );\n const dismissDevToolsContextMenu = useCallback(() => {\n controller.dismissDevToolsContextMenu();\n }, [controller]);\n const openDevToolsFromContextMenu = useCallback(() => {\n return controller.openDevToolsFromContextMenu();\n }, [controller]);\n\n return {\n devToolsContextMenu: state.devToolsContextMenu,\n dismissDevToolsContextMenu,\n openDevToolsFromContextMenu,\n shouldRenderWebview: state.shouldRenderWebview,\n setWebviewRef,\n webviewKey: state.webviewKey,\n webviewPartition: state.webviewPartition,\n webviewSrc: state.webviewSrc\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport { resolveBrowserSessionPartition } from \"./session.ts\";\nimport type {\n BrowserNodeLifecycle,\n BrowserNodeNavigationPolicy,\n BrowserNodeSessionMode\n} from \"./types.ts\";\nimport type { BrowserNodeWebviewTag } from \"../react/webviewTag.ts\";\n\nconst browserGuestUnregisterGraceMs = 250;\nconst browserNodeInitialWebviewSrc = \"about:blank\";\n\nexport interface BrowserNodeWebviewControllerState {\n devToolsContextMenu: BrowserNodeWebviewContextMenuPoint | null;\n shouldRenderWebview: boolean;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n}\n\nexport interface BrowserNodeWebviewContextMenuPoint {\n x: number;\n y: number;\n}\n\nexport interface BrowserNodeWebviewController {\n dismissDevToolsContextMenu(): void;\n getState(): BrowserNodeWebviewControllerState;\n openDevToolsFromContextMenu(): Promise<void>;\n release(): void;\n retain(): void;\n setWebview(element: BrowserNodeWebviewTag | null): void;\n sync(): void;\n subscribe(listener: () => void): () => void;\n}\n\ninterface BrowserNodeWebviewControllerContext {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n}\n\ninterface BrowserNodeWebviewControllerEntry {\n attachedListeners: Array<{\n event: string;\n listener: EventListener;\n }>;\n context: BrowserNodeWebviewControllerContext;\n controller: BrowserNodeWebviewController;\n listeners: Set<() => void>;\n refCount: number;\n registeredGuestId: number | null;\n registeringGuestId: number | null;\n state: BrowserNodeWebviewControllerState;\n webview: BrowserNodeWebviewTag | null;\n}\n\nconst webviewControllerRegistry = new Map<\n string,\n BrowserNodeWebviewControllerEntry\n>();\nconst pendingGuestIdsByNodeId = new Map<string, number>();\nconst pendingUnregisterTimersByNodeId = new Map<\n string,\n ReturnType<typeof globalThis.setTimeout>\n>();\n\nexport function acquireBrowserNodeWebviewController(input: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n}): BrowserNodeWebviewController {\n const existing = webviewControllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeWebviewControllerEntry({\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode,\n sessionPartition: input.sessionPartition\n });\n\n entry.context = {\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode,\n sessionPartition: input.sessionPartition\n };\n if (!existing) {\n webviewControllerRegistry.set(input.nodeId, entry);\n }\n return entry.controller;\n}\n\nfunction createBrowserNodeWebviewControllerEntry(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerEntry {\n const state = resolveBrowserNodeWebviewControllerState(context);\n const entry = {\n attachedListeners: [],\n context,\n controller: null as unknown as BrowserNodeWebviewController,\n listeners: new Set(),\n refCount: 0,\n registeredGuestId: null,\n registeringGuestId: null,\n state,\n webview: null\n } as BrowserNodeWebviewControllerEntry;\n\n entry.controller = {\n dismissDevToolsContextMenu() {\n setBrowserNodeDevToolsContextMenu(entry, null);\n },\n getState() {\n return entry.state;\n },\n async openDevToolsFromContextMenu() {\n setBrowserNodeDevToolsContextMenu(entry, null);\n try {\n await entry.context.feature.hostApi.openDevTools?.({\n nodeId: entry.context.nodeId\n });\n } catch (error) {\n reportBrowserNodeWebviewDiagnostic(\n entry,\n \"devtools.open.failed\",\n {\n error: error instanceof Error ? error.message : String(error),\n webContentsId: readBrowserNodeWebContentsId(entry.webview),\n webviewPartition: entry.state.webviewPartition\n },\n \"warn\"\n );\n throw error;\n }\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n scheduleBrowserNodeGuestUnregister(entry);\n detachBrowserNodeWebview(entry);\n webviewControllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n setWebview(element) {\n if (entry.webview === element) {\n return;\n }\n detachBrowserNodeWebview(entry);\n entry.webview = element;\n attachBrowserNodeWebview(entry);\n },\n sync() {\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n }\n };\n\n return entry;\n}\n\nfunction resolveBrowserNodeWebviewControllerState(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerState {\n const webviewPartition = resolveBrowserSessionPartition({\n profileId: context.profileId,\n sessionMode: context.sessionMode,\n sessionPartition: context.sessionPartition\n });\n return {\n devToolsContextMenu: null,\n shouldRenderWebview: context.lifecycle !== \"cold\",\n webviewKey: `${context.nodeId}:${webviewPartition}`,\n webviewPartition,\n webviewSrc: browserNodeInitialWebviewSrc\n };\n}\n\nfunction reconcileBrowserNodeWebviewControllerState(\n entry: BrowserNodeWebviewControllerEntry,\n options: {\n allowHostEffects: boolean;\n notifyListeners: boolean;\n rebindWebview: boolean;\n }\n): void {\n const nextState = resolveBrowserNodeWebviewControllerState(entry.context);\n const changed =\n entry.state.devToolsContextMenu !== nextState.devToolsContextMenu ||\n entry.state.shouldRenderWebview !== nextState.shouldRenderWebview ||\n entry.state.webviewKey !== nextState.webviewKey ||\n entry.state.webviewPartition !== nextState.webviewPartition ||\n entry.state.webviewSrc !== nextState.webviewSrc;\n\n if (options.allowHostEffects) {\n if (entry.context.lifecycle === \"cold\") {\n scheduleBrowserNodeGuestUnregister(entry);\n } else {\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n void entry.context.feature.hostApi\n .prepareSession({\n navigationPolicy: entry.context.navigationPolicy,\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode,\n sessionPartition: entry.context.sessionPartition\n })\n .catch(() => undefined);\n }\n }\n\n if (!changed) {\n if (\n options.rebindWebview &&\n entry.webview &&\n entry.attachedListeners.length === 0\n ) {\n attachBrowserNodeWebview(entry);\n }\n return;\n }\n\n entry.state = nextState;\n detachBrowserNodeWebview(entry);\n attachBrowserNodeWebview(entry);\n if (options.notifyListeners) {\n notifyBrowserNodeWebviewControllerListeners(entry);\n }\n}\n\nfunction setBrowserNodeDevToolsContextMenu(\n entry: BrowserNodeWebviewControllerEntry,\n devToolsContextMenu: BrowserNodeWebviewContextMenuPoint | null\n): void {\n if (\n entry.state.devToolsContextMenu?.x === devToolsContextMenu?.x &&\n entry.state.devToolsContextMenu?.y === devToolsContextMenu?.y\n ) {\n return;\n }\n entry.state = {\n ...entry.state,\n devToolsContextMenu\n };\n notifyBrowserNodeWebviewControllerListeners(entry);\n}\n\nfunction notifyBrowserNodeWebviewControllerListeners(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction clearPendingBrowserNodeGuestUnregister(nodeId: string): void {\n const timerId = pendingUnregisterTimersByNodeId.get(nodeId);\n if (timerId !== undefined) {\n globalThis.clearTimeout(timerId);\n pendingUnregisterTimersByNodeId.delete(nodeId);\n }\n pendingGuestIdsByNodeId.delete(nodeId);\n}\n\nfunction scheduleBrowserNodeGuestUnregister(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const guestId = entry.registeredGuestId;\n const nodeId = entry.context.nodeId;\n entry.registeringGuestId = null;\n if (guestId === null) {\n clearPendingBrowserNodeGuestUnregister(nodeId);\n return;\n }\n\n entry.registeredGuestId = null;\n clearPendingBrowserNodeGuestUnregister(nodeId);\n pendingGuestIdsByNodeId.set(nodeId, guestId);\n const timerId = globalThis.setTimeout(() => {\n pendingUnregisterTimersByNodeId.delete(nodeId);\n const pendingGuestId = pendingGuestIdsByNodeId.get(nodeId);\n pendingGuestIdsByNodeId.delete(nodeId);\n if (\n typeof pendingGuestId !== \"number\" ||\n !Number.isFinite(pendingGuestId)\n ) {\n return;\n }\n\n void entry.context.feature.hostApi\n .unregisterGuest({\n nodeId: entry.context.nodeId,\n webContentsId: pendingGuestId\n })\n .catch(() => undefined);\n }, browserGuestUnregisterGraceMs);\n pendingUnregisterTimersByNodeId.set(nodeId, timerId);\n}\n\nfunction detachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n if (!entry.webview) {\n entry.attachedListeners = [];\n return;\n }\n for (const record of entry.attachedListeners) {\n entry.webview.removeEventListener(record.event, record.listener);\n }\n entry.attachedListeners = [];\n}\n\nfunction attachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const webview = entry.webview;\n if (!webview || !entry.state.shouldRenderWebview) {\n return;\n }\n\n const registerGuest = async (): Promise<void> => {\n const guestId = webview.getWebContentsId?.();\n if (\n typeof guestId !== \"number\" ||\n !Number.isFinite(guestId) ||\n guestId <= 0 ||\n entry.registeredGuestId === guestId ||\n entry.registeringGuestId === guestId\n ) {\n return;\n }\n\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n entry.registeringGuestId = guestId;\n try {\n await entry.context.feature.hostApi.registerGuest({\n navigationPolicy: entry.context.navigationPolicy,\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode,\n sessionPartition: entry.context.sessionPartition,\n webContentsId: guestId\n });\n entry.registeredGuestId = guestId;\n } finally {\n if (entry.registeringGuestId === guestId) {\n entry.registeringGuestId = null;\n }\n }\n };\n\n const handleDidAttach: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleDomReady: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleGuestInteraction: EventListener = () => {\n entry.context.onGuestInteraction?.();\n };\n const handleDevToolsContextMenu: EventListener = (event) => {\n const hasNativeContextMenu =\n entry.context.feature.hostApi.showDevToolsContextMenu !== undefined;\n const hasInlineContextMenu =\n entry.context.feature.hostApi.openDevTools !== undefined;\n if (!hasNativeContextMenu && !hasInlineContextMenu) {\n return;\n }\n event.preventDefault();\n const point = resolveBrowserNodeContextMenuPoint(event, webview);\n if (hasNativeContextMenu) {\n void entry.context.feature.hostApi\n .showDevToolsContextMenu?.({\n label: entry.context.feature.i18n.t(\"actions.openDevTools\"),\n nodeId: entry.context.nodeId,\n point\n })\n .catch((error: unknown) => {\n reportBrowserNodeWebviewDiagnostic(\n entry,\n \"devtools.native-context-menu.failed\",\n {\n error: error instanceof Error ? error.message : String(error),\n webContentsId: readBrowserNodeWebContentsId(webview),\n webviewPartition: entry.state.webviewPartition\n },\n \"warn\"\n );\n });\n return;\n }\n setBrowserNodeDevToolsContextMenu(entry, point);\n };\n\n const records = [\n { event: \"did-attach\", listener: handleDidAttach },\n { event: \"dom-ready\", listener: handleDomReady },\n { event: \"context-menu\", listener: handleDevToolsContextMenu },\n { event: \"contextmenu\", listener: handleDevToolsContextMenu },\n { event: \"focus\", listener: handleGuestInteraction },\n { event: \"ipc-message\", listener: handleGuestInteraction }\n ];\n for (const record of records) {\n webview.addEventListener(record.event, record.listener);\n }\n entry.attachedListeners = records;\n}\n\nfunction resolveBrowserNodeContextMenuPoint(\n event: Event,\n webview: BrowserNodeWebviewTag\n): BrowserNodeWebviewContextMenuPoint {\n const eventWithPoint = event as Event & {\n clientX?: unknown;\n clientY?: unknown;\n params?: { x?: unknown; y?: unknown };\n };\n const clientX = readFiniteNumber(eventWithPoint.clientX);\n const clientY = readFiniteNumber(eventWithPoint.clientY);\n if (clientX !== null && clientY !== null) {\n return { x: clientX, y: clientY };\n }\n\n const paramX = readFiniteNumber(eventWithPoint.params?.x);\n const paramY = readFiniteNumber(eventWithPoint.params?.y);\n if (paramX !== null && paramY !== null) {\n return { x: paramX, y: paramY };\n }\n\n const rect = webview.getBoundingClientRect();\n return {\n x: rect.left,\n y: rect.top\n };\n}\n\nfunction readFiniteNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction readBrowserNodeWebContentsId(\n webview: BrowserNodeWebviewTag | null\n): number | null {\n const webContentsId = webview?.getWebContentsId?.();\n return typeof webContentsId === \"number\" && Number.isFinite(webContentsId)\n ? webContentsId\n : null;\n}\n\nfunction reportBrowserNodeWebviewDiagnostic(\n entry: BrowserNodeWebviewControllerEntry,\n event: string,\n details: Record<string, unknown>,\n level: \"debug\" | \"info\" | \"warn\" | \"error\" = \"info\"\n): void {\n entry.context.feature.reportDiagnostic?.({\n details: {\n ...details,\n nodeId: entry.context.nodeId\n },\n event,\n level\n });\n}\n"],"mappings":"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","names":["useEffect","useEffect","useMemo","useExternalStoreSnapshot","useMemo","useEffect","useExternalStoreSnapshot","useEffect"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BrowserNode,
3
3
  BrowserNodeHeader
4
- } from "../chunk-2GEY55PS.js";
4
+ } from "../chunk-BZRJYTPK.js";
5
5
  import "../chunk-UTXZLRPE.js";
6
6
  import "../chunk-LVVPDNEF.js";
7
7
  export {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BrowserNode,
3
3
  BrowserNodeWorkbenchHeader
4
- } from "../chunk-2GEY55PS.js";
4
+ } from "../chunk-BZRJYTPK.js";
5
5
  import "../chunk-UTXZLRPE.js";
6
6
  import "../chunk-LVVPDNEF.js";
7
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tutti-os/browser-node",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -48,10 +48,10 @@
48
48
  "directory": "packages/browser/workbench-node"
49
49
  },
50
50
  "dependencies": {
51
- "@tutti-os/ui-i18n-runtime": "0.0.1",
52
- "@tutti-os/ui-react-hooks": "0.0.1",
53
- "@tutti-os/ui-system": "0.0.1",
54
- "@tutti-os/workbench-surface": "0.0.1",
51
+ "@tutti-os/ui-i18n-runtime": "0.0.3",
52
+ "@tutti-os/ui-react-hooks": "0.0.3",
53
+ "@tutti-os/ui-system": "0.0.3",
54
+ "@tutti-os/workbench-surface": "0.0.3",
55
55
  "ws": "^8.21.0"
56
56
  },
57
57
  "devDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/BrowserNode.tsx","../src/react/useBrowserNodeController.ts","../src/core/nodeController.ts","../src/react/useBrowserNodeWebview.ts","../src/core/webviewController.ts"],"sourcesContent":["import {\n ArrowLeftIcon,\n ArrowRightIcon,\n Badge,\n Button,\n Input,\n LaunchIcon,\n LoadingIcon,\n RefreshIcon,\n WarningLinedIcon,\n ViewportMenuSurface,\n cn,\n menuItemClassName\n} from \"@tutti-os/ui-system\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { HTMLAttributes, JSX, ReactNode } from \"react\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeNavigationPolicy,\n BrowserNodeRuntimeError,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport { useBrowserNodeController } from \"./useBrowserNodeController.ts\";\nimport { useBrowserNodeWebview } from \"./useBrowserNodeWebview.ts\";\n\n// Electron needs the serialized string attribute for dynamically created webviews.\nconst browserNodeAllowPopupsAttribute = \"true\" as unknown as boolean;\n\nexport interface BrowserNodeProps {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onFocusRequest?: () => void;\n onNavigated?: (url: string) => void;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n showHeader?: boolean;\n syncDefaultUrl?: boolean;\n}\n\nexport function BrowserNode({\n defaultUrl,\n feature,\n navigationPolicy = null,\n nodeId,\n onFocusRequest,\n onNavigated,\n profileId = null,\n sessionMode = \"shared\",\n sessionPartition = null,\n showHeader = true,\n syncDefaultUrl = false\n}: BrowserNodeProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n navigationPolicy,\n nodeId,\n profileId,\n sessionMode,\n sessionPartition,\n syncDefaultUrl\n });\n const runtime = state.runtime;\n const lastNavigatedUrlRef = useRef<string | null>(\n state.runtime.url?.trim() || null\n );\n const errorMessage = runtime.error\n ? formatBrowserNodeErrorMessage(feature, runtime.error)\n : null;\n const errorStatus = runtime.error\n ? formatBrowserNodeErrorStatus(feature, runtime.error)\n : null;\n const isShowingLoadError = errorMessage !== null;\n const openExternalUrl = feature.hostApi.openExternal\n ? feature.resolveAddressInput(state.displayUrl).url\n : null;\n const {\n devToolsContextMenu,\n dismissDevToolsContextMenu,\n openDevToolsFromContextMenu,\n shouldRenderWebview,\n setWebviewRef,\n webviewKey,\n webviewPartition,\n webviewSrc\n } = useBrowserNodeWebview({\n feature,\n initialUrl: state.displayUrl,\n lifecycle: runtime.lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction: onFocusRequest,\n profileId,\n sessionMode,\n sessionPartition\n });\n\n useEffect(() => {\n const navigatedUrl = state.runtime.url?.trim() ?? \"\";\n if (\n !onNavigated ||\n state.runtime.isLoading ||\n state.runtime.error ||\n navigatedUrl.length === 0 ||\n navigatedUrl === \"about:blank\" ||\n lastNavigatedUrlRef.current === navigatedUrl\n ) {\n return;\n }\n\n lastNavigatedUrlRef.current = navigatedUrl;\n onNavigated(navigatedUrl);\n }, [\n onNavigated,\n state.runtime.error,\n state.runtime.isLoading,\n state.runtime.url\n ]);\n\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden bg-[var(--background-panel)]\">\n {showHeader ? (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n draftUrl={state.draftUrl}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onOpenExternal={\n openExternalUrl\n ? () => {\n void feature.hostApi\n .openExternal?.({ url: openExternalUrl })\n .catch(() => undefined);\n }\n : undefined\n }\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n />\n ) : null}\n <div className=\"relative min-h-0 flex-1 overflow-hidden bg-[var(--background-panel)]\">\n {shouldRenderWebview ? (\n <webview\n allowpopups={browserNodeAllowPopupsAttribute}\n key={webviewKey}\n ref={setWebviewRef}\n className={cn(\n \"absolute inset-0 h-full w-full border-0 bg-[var(--background-panel)]\",\n isShowingLoadError ? \"hidden pointer-events-none\" : \"visible\"\n )}\n data-browser-node-webview=\"true\"\n partition={webviewPartition}\n src={webviewSrc}\n />\n ) : null}\n {errorMessage ? (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-[var(--background-panel)] px-8 py-10 text-center\">\n <div\n className=\"flex w-full max-w-[440px] flex-col items-center\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div className=\"flex size-11 items-center justify-center rounded-full border border-[color-mix(in_srgb,var(--state-danger)_22%,transparent)] bg-[color-mix(in_srgb,var(--state-danger)_8%,transparent)] text-[var(--state-danger)]\">\n <WarningLinedIcon className=\"size-5\" />\n </div>\n <div className=\"mt-4 text-lg font-semibold text-[var(--text-primary)]\">\n {feature.i18n.t(\"loadFailed\")}\n </div>\n <div className=\"mt-1 max-w-[360px] text-sm leading-5 text-[var(--text-secondary)]\">\n {errorMessage}\n </div>\n {errorStatus ? (\n <div className=\"mt-4 rounded-full border border-border bg-[var(--transparency-block)] px-2.5 py-1 text-xs font-medium text-[var(--text-secondary)]\">\n {errorStatus}\n </div>\n ) : null}\n {openExternalUrl ? (\n <div className=\"mt-5 flex flex-wrap items-center justify-center gap-2\">\n <Button\n size=\"sm\"\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n void feature.hostApi\n .openExternal?.({ url: openExternalUrl })\n .catch(() => undefined);\n }}\n >\n <LaunchIcon className=\"size-3.5\" />\n {feature.i18n.t(\"actions.openExternal\")}\n </Button>\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n {devToolsContextMenu ? (\n <ViewportMenuSurface\n open\n className=\"w-44\"\n dismissOnEscape\n dismissOnPointerDownOutside\n onDismiss={dismissDevToolsContextMenu}\n placement={{\n type: \"point\",\n point: devToolsContextMenu,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 176,\n height: 40\n }\n }}\n >\n <button\n className={cn(menuItemClassName, \"w-full\")}\n type=\"button\"\n onClick={() => {\n void openDevToolsFromContextMenu().catch(() => undefined);\n }}\n >\n {feature.i18n.t(\"actions.openDevTools\")}\n </button>\n </ViewportMenuSurface>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport interface BrowserNodeWorkbenchHeaderProps {\n className?: string;\n defaultActions?: ReactNode;\n defaultUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n nodeId: string;\n onCloseRequest?: () => void;\n onFocusRequest?: () => void;\n}\n\nexport function BrowserNodeWorkbenchHeader({\n className,\n defaultActions,\n defaultUrl,\n dragHandleProps,\n feature,\n nodeId,\n onCloseRequest,\n onFocusRequest\n}: BrowserNodeWorkbenchHeaderProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n nodeId\n });\n const runtime = state.runtime;\n const openExternalUrl = feature.hostApi.openExternal\n ? feature.resolveAddressInput(state.displayUrl).url\n : null;\n\n return (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n className={className}\n defaultActions={defaultActions}\n draftUrl={state.draftUrl}\n dragHandleProps={dragHandleProps}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onCloseRequest={onCloseRequest}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onOpenExternal={\n openExternalUrl\n ? () => {\n void feature.hostApi\n .openExternal?.({ url: openExternalUrl })\n .catch(() => undefined);\n }\n : undefined\n }\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n withBorder={false}\n />\n );\n}\n\nexport function BrowserNodeHeader({\n canGoBack,\n canGoForward,\n className,\n defaultActions,\n draftUrl,\n dragHandleProps,\n feature,\n isCold = false,\n isLoading,\n onCloseRequest,\n onDraftUrlChange,\n onFocusRequest,\n onGoBack,\n onGoForward,\n onOpenExternal,\n onReload,\n onSubmitUrl,\n withBorder = true\n}: {\n canGoBack: boolean;\n canGoForward: boolean;\n className?: string;\n defaultActions?: ReactNode;\n draftUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n isCold?: boolean;\n isLoading: boolean;\n onCloseRequest?: () => void;\n onDraftUrlChange: (nextUrl: string) => void;\n onFocusRequest?: () => void;\n onGoBack: () => void;\n onGoForward: () => void;\n onOpenExternal?: () => void;\n onReload: () => void;\n onSubmitUrl: () => void;\n withBorder?: boolean;\n}): JSX.Element {\n const [reloadAnimationKey, setReloadAnimationKey] = useState(0);\n\n const handleReload = (): void => {\n setReloadAnimationKey((currentKey) => currentKey + 1);\n onReload();\n };\n\n return (\n <div\n className={cn(\n \"flex h-[var(--workbench-header-height,38px)] min-h-[var(--workbench-header-height,38px)] items-center gap-2 bg-[var(--background-panel)] px-2 pl-3\",\n withBorder ? \"border-b border-border\" : null,\n className\n )}\n data-browser-node-header=\"true\"\n onDoubleClick={(event) => {\n if (\n event.target instanceof Element &&\n event.target.closest(\".nodrag\")\n ) {\n return;\n }\n event.stopPropagation();\n dragHandleProps?.onDoubleClick?.(event);\n }}\n >\n <div className=\"inline-flex items-center gap-1\">\n <BrowserNodeHeaderButton\n disabled={!canGoBack}\n label={feature.i18n.t(\"actions.back\")}\n onClick={onGoBack}\n >\n <ArrowLeftIcon className=\"size-[15px]\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n disabled={!canGoForward}\n label={feature.i18n.t(\"actions.forward\")}\n onClick={onGoForward}\n >\n <ArrowRightIcon className=\"size-[15px]\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n label={feature.i18n.t(\"actions.reload\")}\n onClick={handleReload}\n >\n <RefreshIcon\n key={reloadAnimationKey}\n className={cn(\n \"size-[15px]\",\n reloadAnimationKey > 0 &&\n \"motion-safe:animate-[spin_520ms_cubic-bezier(0.4,0,0.2,1)_1_reverse]\"\n )}\n />\n </BrowserNodeHeaderButton>\n </div>\n <div\n {...dragHandleProps}\n className=\"h-full w-8 shrink-0 cursor-grab active:cursor-grabbing\"\n data-browser-node-drag-gutter=\"true\"\n data-node-drag-handle=\"true\"\n aria-hidden=\"true\"\n />\n <form\n className=\"nodrag relative min-w-0 flex-1\"\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onSubmitUrl();\n }}\n >\n <Input\n aria-label={feature.i18n.t(\"addressLabel\")}\n className=\"pr-8 focus-visible:border-input focus-visible:ring-0 focus-visible:ring-offset-0\"\n placeholder={feature.i18n.t(\"addressPlaceholder\")}\n size=\"sm\"\n value={draftUrl}\n onChange={(event) => onDraftUrlChange(event.target.value)}\n onFocus={onFocusRequest}\n />\n {isLoading ? (\n <LoadingIcon className=\"pointer-events-none absolute right-2 top-1/2 z-[1] size-4 -translate-y-1/2 animate-spin text-[var(--text-tertiary)]\" />\n ) : null}\n </form>\n {onOpenExternal ? (\n <BrowserNodeHeaderButton\n label={feature.i18n.t(\"actions.openExternal\")}\n onClick={onOpenExternal}\n >\n <LaunchIcon className=\"size-[15px]\" />\n </BrowserNodeHeaderButton>\n ) : null}\n {defaultActions ? (\n <div className=\"nodrag flex shrink-0 items-center gap-1.5\">\n {isCold ? (\n <Badge\n className=\"h-[26px] min-w-7 rounded-md text-[10px] font-semibold lowercase tracking-[0.08em]\"\n aria-label={feature.i18n.t(\"coldStatus\")}\n >\n {feature.i18n.t(\"coldStatus\")}\n </Badge>\n ) : null}\n <span\n className=\"contents\"\n onClickCapture={(event) => {\n if (\n !onCloseRequest ||\n !(event.target instanceof Element) ||\n !event.target.closest('[data-workbench-action=\"close\"]')\n ) {\n return;\n }\n onCloseRequest();\n }}\n >\n {defaultActions}\n </span>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction formatBrowserNodeErrorMessage(\n feature: BrowserNodeFeature,\n error: BrowserNodeRuntimeError\n): string {\n switch (error.code) {\n case \"invalid-url\":\n return feature.i18n.t(\"errors.invalidUrl\", error.params);\n case \"navigation-failed\":\n if (error.params && error.params.statusCode !== undefined) {\n return feature.i18n.t(\n \"errors.navigationFailedWithStatus\",\n error.params\n );\n }\n return feature.i18n.t(\"errors.navigationFailed\", error.params);\n case \"unsupported-protocol\":\n return feature.i18n.t(\"errors.unsupportedProtocol\", error.params);\n case \"unsupported-url\":\n return feature.i18n.t(\"errors.unsupportedUrl\", error.params);\n }\n}\n\nfunction formatBrowserNodeErrorStatus(\n feature: BrowserNodeFeature,\n error: BrowserNodeRuntimeError\n): string | null {\n if (error.code !== \"navigation-failed\" || !error.params) {\n return null;\n }\n\n const statusCode = error.params.statusCode;\n if (typeof statusCode === \"number\") {\n return feature.i18n.t(\"errors.statusCode\", { statusCode });\n }\n\n const errorCode = error.params.errorCode;\n if (typeof errorCode === \"number\") {\n return feature.i18n.t(\"errors.errorCode\", { errorCode });\n }\n\n return null;\n}\n\nfunction BrowserNodeHeaderButton({\n children,\n disabled,\n label,\n onClick\n}: {\n children: ReactNode;\n disabled?: boolean;\n label: string;\n onClick: () => void;\n}) {\n return (\n <Button\n aria-label={label}\n className=\"rounded-md\"\n disabled={disabled}\n size=\"icon-sm\"\n title={label}\n type=\"button\"\n variant=\"chrome\"\n onClick={onClick}\n >\n {children}\n </Button>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@tutti-os/ui-react-hooks\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport {\n acquireBrowserNodeController,\n type BrowserNodeControllerState\n} from \"../core/nodeController.ts\";\nimport type {\n BrowserNodeNavigationPolicy,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\n\nexport function useBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n syncDefaultUrl?: boolean;\n}) {\n const controller = useMemo(\n () =>\n acquireBrowserNodeController({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\",\n sessionPartition: input.sessionPartition,\n syncDefaultUrl: input.syncDefaultUrl ?? false\n }),\n [\n input.defaultUrl,\n input.feature,\n input.navigationPolicy,\n input.nodeId,\n input.profileId,\n input.sessionMode,\n input.sessionPartition,\n input.syncDefaultUrl\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n\n useEffect(() => {\n controller.sync();\n }, [\n controller,\n input.defaultUrl,\n input.feature,\n input.navigationPolicy,\n input.nodeId,\n input.profileId,\n input.sessionMode,\n input.sessionPartition,\n input.syncDefaultUrl\n ]);\n const state = useExternalStoreSnapshot<BrowserNodeControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n return {\n controller,\n state\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport {\n normalizeBrowserComparableUrl,\n normalizeHostBrowserComparableUrl\n} from \"./url.ts\";\nimport type {\n BrowserNodeNavigationPolicy,\n BrowserNodeRuntimeState,\n BrowserNodeSessionMode\n} from \"./types.ts\";\n\nexport interface BrowserNodeControllerState {\n displayUrl: string;\n draftUrl: string;\n runtime: BrowserNodeRuntimeState;\n}\n\nexport interface BrowserNodeController {\n getState(): BrowserNodeControllerState;\n goBack(): Promise<void>;\n goForward(): Promise<void>;\n reload(): Promise<void>;\n release(): void;\n retain(): void;\n setDraftUrl(nextUrl: string): void;\n sync(): void;\n subscribe(listener: () => void): () => void;\n submitDraftUrl(): Promise<void>;\n}\n\ninterface BrowserNodeControllerContext {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n syncDefaultUrl: boolean;\n}\n\ninterface BrowserNodeControllerEntry {\n connectedRelease: (() => void) | null;\n controller: BrowserNodeController;\n context: BrowserNodeControllerContext;\n lastColdActivationUrl: string | null;\n listeners: Set<() => void>;\n pendingColdActivationUrl: string | null;\n refCount: number;\n runtimeUnsubscribe: (() => void) | null;\n state: BrowserNodeControllerState;\n}\n\nconst controllerRegistry = new Map<string, BrowserNodeControllerEntry>();\n\nexport function acquireBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n syncDefaultUrl?: boolean;\n}): BrowserNodeController {\n const existing = controllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeControllerEntry({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\",\n sessionPartition: input.sessionPartition,\n syncDefaultUrl: input.syncDefaultUrl ?? false\n });\n\n entry.context = {\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\",\n sessionPartition: input.sessionPartition,\n syncDefaultUrl: input.syncDefaultUrl ?? false\n };\n\n if (!existing) {\n controllerRegistry.set(input.nodeId, entry);\n }\n\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: false,\n notifyListeners: false\n });\n\n return entry.controller;\n}\n\nfunction createBrowserNodeControllerEntry(\n context: BrowserNodeControllerContext\n): BrowserNodeControllerEntry {\n const runtime = context.feature.runtimeStore.getNodeState(context.nodeId);\n const displayUrl = resolveBrowserNodeDisplayUrl(runtime, context.defaultUrl);\n const entry = {\n connectedRelease: null,\n controller: null as unknown as BrowserNodeController,\n context,\n lastColdActivationUrl: resolveInitialLastColdActivationUrl(\n runtime,\n context.defaultUrl\n ),\n listeners: new Set(),\n pendingColdActivationUrl: null,\n refCount: 0,\n runtimeUnsubscribe: null,\n state: {\n displayUrl,\n draftUrl: displayUrl,\n runtime\n }\n } as BrowserNodeControllerEntry;\n\n entry.controller = {\n getState() {\n return entry.state;\n },\n goBack() {\n return entry.context.feature.hostApi.goBack({\n nodeId: entry.context.nodeId\n });\n },\n goForward() {\n return entry.context.feature.hostApi.goForward({\n nodeId: entry.context.nodeId\n });\n },\n reload() {\n return entry.context.feature.hostApi.reload({\n nodeId: entry.context.nodeId\n });\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n\n entry.connectedRelease?.();\n entry.connectedRelease = null;\n entry.runtimeUnsubscribe?.();\n entry.runtimeUnsubscribe = null;\n controllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n\n if (!controllerRegistry.has(entry.context.nodeId)) {\n controllerRegistry.set(entry.context.nodeId, entry);\n }\n entry.connectedRelease = entry.context.feature.connect();\n entry.runtimeUnsubscribe = entry.context.feature.runtimeStore.subscribe(\n () => {\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n }\n );\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n },\n setDraftUrl(nextUrl) {\n if (entry.state.draftUrl === nextUrl) {\n return;\n }\n\n entry.state = {\n ...entry.state,\n draftUrl: nextUrl\n };\n notifyBrowserNodeControllerListeners(entry);\n },\n sync() {\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n },\n async submitDraftUrl() {\n const resolved = entry.context.feature.resolveAddressInput(\n entry.state.draftUrl\n );\n if (!resolved.url) {\n return;\n }\n\n if (entry.state.draftUrl !== resolved.url) {\n entry.state = {\n ...entry.state,\n draftUrl: resolved.url\n };\n notifyBrowserNodeControllerListeners(entry);\n }\n\n await entry.context.feature.hostApi.navigate({\n navigationPolicy: entry.context.navigationPolicy,\n nodeId: entry.context.nodeId,\n url: resolved.url\n });\n }\n };\n\n return entry;\n}\n\nfunction resolveInitialLastColdActivationUrl(\n runtime: BrowserNodeRuntimeState,\n defaultUrl: string\n): string | null {\n const trimmedUrl = defaultUrl.trim();\n if (\n runtime.lifecycle === \"cold\" ||\n runtime.error !== null ||\n trimmedUrl.length === 0 ||\n trimmedUrl === \"about:blank\"\n ) {\n return null;\n }\n\n const comparableDefaultUrl = normalizeBrowserComparableUrl(trimmedUrl);\n const comparableRuntimeUrl = runtime.url\n ? normalizeBrowserComparableUrl(runtime.url)\n : null;\n return comparableDefaultUrl !== null &&\n comparableDefaultUrl === comparableRuntimeUrl\n ? trimmedUrl\n : null;\n}\n\nfunction notifyBrowserNodeControllerListeners(\n entry: BrowserNodeControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction resolveBrowserNodeDisplayUrl(\n runtime: BrowserNodeRuntimeState,\n defaultUrl: string\n): string {\n const resolvedRuntimeUrl = runtime.url?.trim() ?? \"\";\n return resolvedRuntimeUrl.length > 0 ? resolvedRuntimeUrl : defaultUrl;\n}\n\nfunction reconcileBrowserNodeControllerState(\n entry: BrowserNodeControllerEntry,\n options: {\n allowAutoActivate: boolean;\n notifyListeners: boolean;\n }\n): void {\n const runtime = entry.context.feature.runtimeStore.getNodeState(\n entry.context.nodeId\n );\n const displayUrl = resolveBrowserNodeDisplayUrl(\n runtime,\n entry.context.defaultUrl\n );\n const nextDraftUrl =\n displayUrl !== entry.state.displayUrl ? displayUrl : entry.state.draftUrl;\n\n const changed =\n entry.state.runtime !== runtime ||\n entry.state.displayUrl !== displayUrl ||\n entry.state.draftUrl !== nextDraftUrl;\n\n if (changed) {\n entry.state = {\n displayUrl,\n draftUrl: nextDraftUrl,\n runtime\n };\n if (options.notifyListeners) {\n notifyBrowserNodeControllerListeners(entry);\n }\n }\n\n if (options.allowAutoActivate) {\n void maybeActivateBrowserNodeDefaultUrl(entry).catch(() => undefined);\n }\n}\n\nasync function maybeActivateBrowserNodeDefaultUrl(\n entry: BrowserNodeControllerEntry\n): Promise<void> {\n const {\n defaultUrl,\n feature,\n navigationPolicy,\n nodeId,\n profileId,\n sessionMode,\n sessionPartition,\n syncDefaultUrl\n } = entry.context;\n const trimmedUrl = defaultUrl.trim();\n const comparableDefaultUrl = normalizeHostBrowserComparableUrl(trimmedUrl);\n const comparableRuntimeUrl = entry.state.runtime.url\n ? normalizeHostBrowserComparableUrl(entry.state.runtime.url)\n : null;\n const shouldActivateColdNode = entry.state.runtime.lifecycle === \"cold\";\n const shouldSyncDefaultUrl =\n syncDefaultUrl &&\n entry.state.runtime.lifecycle !== \"cold\" &&\n comparableDefaultUrl !== null &&\n (comparableRuntimeUrl !== comparableDefaultUrl ||\n entry.state.runtime.error !== null) &&\n entry.lastColdActivationUrl !== trimmedUrl;\n if (\n trimmedUrl.length === 0 ||\n trimmedUrl === \"about:blank\" ||\n entry.state.runtime.isLoading ||\n entry.pendingColdActivationUrl === trimmedUrl ||\n (!shouldActivateColdNode && !shouldSyncDefaultUrl) ||\n (shouldActivateColdNode &&\n entry.state.runtime.error !== null &&\n entry.lastColdActivationUrl === trimmedUrl)\n ) {\n return;\n }\n\n entry.pendingColdActivationUrl = trimmedUrl;\n try {\n await feature.hostApi.activate({\n navigationPolicy,\n nodeId,\n profileId,\n sessionMode,\n sessionPartition,\n url: trimmedUrl\n });\n entry.lastColdActivationUrl = trimmedUrl;\n } finally {\n if (entry.pendingColdActivationUrl === trimmedUrl) {\n entry.pendingColdActivationUrl = null;\n }\n }\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@tutti-os/ui-react-hooks\";\nimport {\n acquireBrowserNodeWebviewController,\n type BrowserNodeWebviewContextMenuPoint,\n type BrowserNodeWebviewControllerState\n} from \"../core/webviewController.ts\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeLifecycle,\n BrowserNodeNavigationPolicy,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport type { BrowserNodeWebviewTag } from \"./webviewTag.ts\";\n\nexport function useBrowserNodeWebview({\n feature,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n}: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n}): {\n devToolsContextMenu: BrowserNodeWebviewContextMenuPoint | null;\n dismissDevToolsContextMenu: () => void;\n openDevToolsFromContextMenu: () => Promise<void>;\n shouldRenderWebview: boolean;\n setWebviewRef: (element: BrowserNodeWebviewTag | null) => void;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n} {\n const controller = useMemo(\n () =>\n acquireBrowserNodeWebviewController({\n feature,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n }),\n [\n feature,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n\n useEffect(() => {\n controller.sync();\n }, [\n controller,\n initialUrl,\n lifecycle,\n navigationPolicy,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode,\n sessionPartition\n ]);\n const state = useExternalStoreSnapshot<BrowserNodeWebviewControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n const setWebviewRef = useCallback(\n (element: BrowserNodeWebviewTag | null) => {\n controller.setWebview(element);\n },\n [controller]\n );\n const dismissDevToolsContextMenu = useCallback(() => {\n controller.dismissDevToolsContextMenu();\n }, [controller]);\n const openDevToolsFromContextMenu = useCallback(() => {\n return controller.openDevToolsFromContextMenu();\n }, [controller]);\n\n return {\n devToolsContextMenu: state.devToolsContextMenu,\n dismissDevToolsContextMenu,\n openDevToolsFromContextMenu,\n shouldRenderWebview: state.shouldRenderWebview,\n setWebviewRef,\n webviewKey: state.webviewKey,\n webviewPartition: state.webviewPartition,\n webviewSrc: state.webviewSrc\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport { resolveBrowserSessionPartition } from \"./session.ts\";\nimport type {\n BrowserNodeLifecycle,\n BrowserNodeNavigationPolicy,\n BrowserNodeSessionMode\n} from \"./types.ts\";\nimport type { BrowserNodeWebviewTag } from \"../react/webviewTag.ts\";\n\nconst browserGuestUnregisterGraceMs = 250;\nconst browserNodeInitialWebviewSrc = \"about:blank\";\n\nexport interface BrowserNodeWebviewControllerState {\n devToolsContextMenu: BrowserNodeWebviewContextMenuPoint | null;\n shouldRenderWebview: boolean;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n}\n\nexport interface BrowserNodeWebviewContextMenuPoint {\n x: number;\n y: number;\n}\n\nexport interface BrowserNodeWebviewController {\n dismissDevToolsContextMenu(): void;\n getState(): BrowserNodeWebviewControllerState;\n openDevToolsFromContextMenu(): Promise<void>;\n release(): void;\n retain(): void;\n setWebview(element: BrowserNodeWebviewTag | null): void;\n sync(): void;\n subscribe(listener: () => void): () => void;\n}\n\ninterface BrowserNodeWebviewControllerContext {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n}\n\ninterface BrowserNodeWebviewControllerEntry {\n attachedListeners: Array<{\n event: string;\n listener: EventListener;\n }>;\n context: BrowserNodeWebviewControllerContext;\n controller: BrowserNodeWebviewController;\n listeners: Set<() => void>;\n refCount: number;\n registeredGuestId: number | null;\n registeringGuestId: number | null;\n state: BrowserNodeWebviewControllerState;\n webview: BrowserNodeWebviewTag | null;\n}\n\nconst webviewControllerRegistry = new Map<\n string,\n BrowserNodeWebviewControllerEntry\n>();\nconst pendingGuestIdsByNodeId = new Map<string, number>();\nconst pendingUnregisterTimersByNodeId = new Map<\n string,\n ReturnType<typeof globalThis.setTimeout>\n>();\n\nexport function acquireBrowserNodeWebviewController(input: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n navigationPolicy?: BrowserNodeNavigationPolicy | null;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n sessionPartition?: string | null;\n}): BrowserNodeWebviewController {\n const existing = webviewControllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeWebviewControllerEntry({\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode,\n sessionPartition: input.sessionPartition\n });\n\n entry.context = {\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n navigationPolicy: input.navigationPolicy,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode,\n sessionPartition: input.sessionPartition\n };\n if (!existing) {\n webviewControllerRegistry.set(input.nodeId, entry);\n }\n return entry.controller;\n}\n\nfunction createBrowserNodeWebviewControllerEntry(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerEntry {\n const state = resolveBrowserNodeWebviewControllerState(context);\n const entry = {\n attachedListeners: [],\n context,\n controller: null as unknown as BrowserNodeWebviewController,\n listeners: new Set(),\n refCount: 0,\n registeredGuestId: null,\n registeringGuestId: null,\n state,\n webview: null\n } as BrowserNodeWebviewControllerEntry;\n\n entry.controller = {\n dismissDevToolsContextMenu() {\n setBrowserNodeDevToolsContextMenu(entry, null);\n },\n getState() {\n return entry.state;\n },\n async openDevToolsFromContextMenu() {\n setBrowserNodeDevToolsContextMenu(entry, null);\n try {\n await entry.context.feature.hostApi.openDevTools?.({\n nodeId: entry.context.nodeId\n });\n } catch (error) {\n reportBrowserNodeWebviewDiagnostic(\n entry,\n \"devtools.open.failed\",\n {\n error: error instanceof Error ? error.message : String(error),\n webContentsId: readBrowserNodeWebContentsId(entry.webview),\n webviewPartition: entry.state.webviewPartition\n },\n \"warn\"\n );\n throw error;\n }\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n scheduleBrowserNodeGuestUnregister(entry);\n detachBrowserNodeWebview(entry);\n webviewControllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n setWebview(element) {\n if (entry.webview === element) {\n return;\n }\n detachBrowserNodeWebview(entry);\n entry.webview = element;\n attachBrowserNodeWebview(entry);\n },\n sync() {\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n }\n };\n\n return entry;\n}\n\nfunction resolveBrowserNodeWebviewControllerState(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerState {\n const webviewPartition = resolveBrowserSessionPartition({\n profileId: context.profileId,\n sessionMode: context.sessionMode,\n sessionPartition: context.sessionPartition\n });\n return {\n devToolsContextMenu: null,\n shouldRenderWebview: context.lifecycle !== \"cold\",\n webviewKey: `${context.nodeId}:${webviewPartition}`,\n webviewPartition,\n webviewSrc: browserNodeInitialWebviewSrc\n };\n}\n\nfunction reconcileBrowserNodeWebviewControllerState(\n entry: BrowserNodeWebviewControllerEntry,\n options: {\n allowHostEffects: boolean;\n notifyListeners: boolean;\n rebindWebview: boolean;\n }\n): void {\n const nextState = resolveBrowserNodeWebviewControllerState(entry.context);\n const changed =\n entry.state.devToolsContextMenu !== nextState.devToolsContextMenu ||\n entry.state.shouldRenderWebview !== nextState.shouldRenderWebview ||\n entry.state.webviewKey !== nextState.webviewKey ||\n entry.state.webviewPartition !== nextState.webviewPartition ||\n entry.state.webviewSrc !== nextState.webviewSrc;\n\n if (options.allowHostEffects) {\n if (entry.context.lifecycle === \"cold\") {\n scheduleBrowserNodeGuestUnregister(entry);\n } else {\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n void entry.context.feature.hostApi\n .prepareSession({\n navigationPolicy: entry.context.navigationPolicy,\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode,\n sessionPartition: entry.context.sessionPartition\n })\n .catch(() => undefined);\n }\n }\n\n if (!changed) {\n if (\n options.rebindWebview &&\n entry.webview &&\n entry.attachedListeners.length === 0\n ) {\n attachBrowserNodeWebview(entry);\n }\n return;\n }\n\n entry.state = nextState;\n detachBrowserNodeWebview(entry);\n attachBrowserNodeWebview(entry);\n if (options.notifyListeners) {\n notifyBrowserNodeWebviewControllerListeners(entry);\n }\n}\n\nfunction setBrowserNodeDevToolsContextMenu(\n entry: BrowserNodeWebviewControllerEntry,\n devToolsContextMenu: BrowserNodeWebviewContextMenuPoint | null\n): void {\n if (\n entry.state.devToolsContextMenu?.x === devToolsContextMenu?.x &&\n entry.state.devToolsContextMenu?.y === devToolsContextMenu?.y\n ) {\n return;\n }\n entry.state = {\n ...entry.state,\n devToolsContextMenu\n };\n notifyBrowserNodeWebviewControllerListeners(entry);\n}\n\nfunction notifyBrowserNodeWebviewControllerListeners(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction clearPendingBrowserNodeGuestUnregister(nodeId: string): void {\n const timerId = pendingUnregisterTimersByNodeId.get(nodeId);\n if (timerId !== undefined) {\n globalThis.clearTimeout(timerId);\n pendingUnregisterTimersByNodeId.delete(nodeId);\n }\n pendingGuestIdsByNodeId.delete(nodeId);\n}\n\nfunction scheduleBrowserNodeGuestUnregister(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const guestId = entry.registeredGuestId;\n const nodeId = entry.context.nodeId;\n entry.registeringGuestId = null;\n if (guestId === null) {\n clearPendingBrowserNodeGuestUnregister(nodeId);\n return;\n }\n\n entry.registeredGuestId = null;\n clearPendingBrowserNodeGuestUnregister(nodeId);\n pendingGuestIdsByNodeId.set(nodeId, guestId);\n const timerId = globalThis.setTimeout(() => {\n pendingUnregisterTimersByNodeId.delete(nodeId);\n const pendingGuestId = pendingGuestIdsByNodeId.get(nodeId);\n pendingGuestIdsByNodeId.delete(nodeId);\n if (\n typeof pendingGuestId !== \"number\" ||\n !Number.isFinite(pendingGuestId)\n ) {\n return;\n }\n\n void entry.context.feature.hostApi\n .unregisterGuest({\n nodeId: entry.context.nodeId,\n webContentsId: pendingGuestId\n })\n .catch(() => undefined);\n }, browserGuestUnregisterGraceMs);\n pendingUnregisterTimersByNodeId.set(nodeId, timerId);\n}\n\nfunction detachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n if (!entry.webview) {\n entry.attachedListeners = [];\n return;\n }\n for (const record of entry.attachedListeners) {\n entry.webview.removeEventListener(record.event, record.listener);\n }\n entry.attachedListeners = [];\n}\n\nfunction attachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const webview = entry.webview;\n if (!webview || !entry.state.shouldRenderWebview) {\n return;\n }\n\n const registerGuest = async (): Promise<void> => {\n const guestId = webview.getWebContentsId?.();\n if (\n typeof guestId !== \"number\" ||\n !Number.isFinite(guestId) ||\n guestId <= 0 ||\n entry.registeredGuestId === guestId ||\n entry.registeringGuestId === guestId\n ) {\n return;\n }\n\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n entry.registeringGuestId = guestId;\n try {\n await entry.context.feature.hostApi.registerGuest({\n navigationPolicy: entry.context.navigationPolicy,\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode,\n sessionPartition: entry.context.sessionPartition,\n webContentsId: guestId\n });\n entry.registeredGuestId = guestId;\n } finally {\n if (entry.registeringGuestId === guestId) {\n entry.registeringGuestId = null;\n }\n }\n };\n\n const handleDidAttach: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleDomReady: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleGuestInteraction: EventListener = () => {\n entry.context.onGuestInteraction?.();\n };\n const handleDevToolsContextMenu: EventListener = (event) => {\n const hasNativeContextMenu =\n entry.context.feature.hostApi.showDevToolsContextMenu !== undefined;\n const hasInlineContextMenu =\n entry.context.feature.hostApi.openDevTools !== undefined;\n if (!hasNativeContextMenu && !hasInlineContextMenu) {\n return;\n }\n event.preventDefault();\n const point = resolveBrowserNodeContextMenuPoint(event, webview);\n if (hasNativeContextMenu) {\n void entry.context.feature.hostApi\n .showDevToolsContextMenu?.({\n label: entry.context.feature.i18n.t(\"actions.openDevTools\"),\n nodeId: entry.context.nodeId,\n point\n })\n .catch((error: unknown) => {\n reportBrowserNodeWebviewDiagnostic(\n entry,\n \"devtools.native-context-menu.failed\",\n {\n error: error instanceof Error ? error.message : String(error),\n webContentsId: readBrowserNodeWebContentsId(webview),\n webviewPartition: entry.state.webviewPartition\n },\n \"warn\"\n );\n });\n return;\n }\n setBrowserNodeDevToolsContextMenu(entry, point);\n };\n\n const records = [\n { event: \"did-attach\", listener: handleDidAttach },\n { event: \"dom-ready\", listener: handleDomReady },\n { event: \"context-menu\", listener: handleDevToolsContextMenu },\n { event: \"contextmenu\", listener: handleDevToolsContextMenu },\n { event: \"focus\", listener: handleGuestInteraction },\n { event: \"ipc-message\", listener: handleGuestInteraction }\n ];\n for (const record of records) {\n webview.addEventListener(record.event, record.listener);\n }\n entry.attachedListeners = records;\n}\n\nfunction resolveBrowserNodeContextMenuPoint(\n event: Event,\n webview: BrowserNodeWebviewTag\n): BrowserNodeWebviewContextMenuPoint {\n const eventWithPoint = event as Event & {\n clientX?: unknown;\n clientY?: unknown;\n params?: { x?: unknown; y?: unknown };\n };\n const clientX = readFiniteNumber(eventWithPoint.clientX);\n const clientY = readFiniteNumber(eventWithPoint.clientY);\n if (clientX !== null && clientY !== null) {\n return { x: clientX, y: clientY };\n }\n\n const paramX = readFiniteNumber(eventWithPoint.params?.x);\n const paramY = readFiniteNumber(eventWithPoint.params?.y);\n if (paramX !== null && paramY !== null) {\n return { x: paramX, y: paramY };\n }\n\n const rect = webview.getBoundingClientRect();\n return {\n x: rect.left,\n y: rect.top\n };\n}\n\nfunction readFiniteNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction readBrowserNodeWebContentsId(\n webview: BrowserNodeWebviewTag | null\n): number | null {\n const webContentsId = webview?.getWebContentsId?.();\n return typeof webContentsId === \"number\" && Number.isFinite(webContentsId)\n ? webContentsId\n : null;\n}\n\nfunction reportBrowserNodeWebviewDiagnostic(\n entry: BrowserNodeWebviewControllerEntry,\n event: string,\n details: Record<string, unknown>,\n level: \"debug\" | \"info\" | \"warn\" | \"error\" = \"info\"\n): void {\n entry.context.feature.reportDiagnostic?.({\n details: {\n ...details,\n nodeId: entry.context.nodeId\n },\n event,\n level\n });\n}\n"],"mappings":";;;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,aAAAA,YAAW,QAAQ,gBAAgB;;;ACd5C,SAAS,WAAW,eAAe;AACnC,SAAS,gCAAgC;;;ACoDzC,IAAM,qBAAqB,oBAAI,IAAwC;AAEhE,SAAS,6BAA6B,OASnB;AACxB,QAAM,WAAW,mBAAmB,IAAI,MAAM,MAAM;AACpD,QAAM,QACJ,YACA,iCAAiC;AAAA,IAC/B,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM;AAAA,IACf,kBAAkB,MAAM;AAAA,IACxB,QAAQ,MAAM;AAAA,IACd,WAAW,MAAM,aAAa;AAAA,IAC9B,aAAa,MAAM,eAAe;AAAA,IAClC,kBAAkB,MAAM;AAAA,IACxB,gBAAgB,MAAM,kBAAkB;AAAA,EAC1C,CAAC;AAEH,QAAM,UAAU;AAAA,IACd,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM;AAAA,IACf,kBAAkB,MAAM;AAAA,IACxB,QAAQ,MAAM;AAAA,IACd,WAAW,MAAM,aAAa;AAAA,IAC9B,aAAa,MAAM,eAAe;AAAA,IAClC,kBAAkB,MAAM;AAAA,IACxB,gBAAgB,MAAM,kBAAkB;AAAA,EAC1C;AAEA,MAAI,CAAC,UAAU;AACb,uBAAmB,IAAI,MAAM,QAAQ,KAAK;AAAA,EAC5C;AAEA,sCAAoC,OAAO;AAAA,IACzC,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,EACnB,CAAC;AAED,SAAO,MAAM;AACf;AAEA,SAAS,iCACP,SAC4B;AAC5B,QAAM,UAAU,QAAQ,QAAQ,aAAa,aAAa,QAAQ,MAAM;AACxE,QAAM,aAAa,6BAA6B,SAAS,QAAQ,UAAU;AAC3E,QAAM,QAAQ;AAAA,IACZ,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ;AAAA,IACA,uBAAuB;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,IACA,WAAW,oBAAI,IAAI;AAAA,IACnB,0BAA0B;AAAA,IAC1B,UAAU;AAAA,IACV,oBAAoB;AAAA,IACpB,OAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa;AAAA,IACjB,WAAW;AACT,aAAO,MAAM;AAAA,IACf;AAAA,IACA,SAAS;AACP,aAAO,MAAM,QAAQ,QAAQ,QAAQ,OAAO;AAAA,QAC1C,QAAQ,MAAM,QAAQ;AAAA,MACxB,CAAC;AAAA,IACH;AAAA,IACA,YAAY;AACV,aAAO,MAAM,QAAQ,QAAQ,QAAQ,UAAU;AAAA,QAC7C,QAAQ,MAAM,QAAQ;AAAA,MACxB,CAAC;AAAA,IACH;AAAA,IACA,SAAS;AACP,aAAO,MAAM,QAAQ,QAAQ,QAAQ,OAAO;AAAA,QAC1C,QAAQ,MAAM,QAAQ;AAAA,MACxB,CAAC;AAAA,IACH;AAAA,IACA,UAAU;AACR,YAAM,WAAW,KAAK,IAAI,GAAG,MAAM,WAAW,CAAC;AAC/C,UAAI,MAAM,WAAW,GAAG;AACtB;AAAA,MACF;AAEA,YAAM,mBAAmB;AACzB,YAAM,mBAAmB;AACzB,YAAM,qBAAqB;AAC3B,YAAM,qBAAqB;AAC3B,yBAAmB,OAAO,MAAM,QAAQ,MAAM;AAAA,IAChD;AAAA,IACA,SAAS;AACP,YAAM,YAAY;AAClB,UAAI,MAAM,WAAW,GAAG;AACtB;AAAA,MACF;AAEA,UAAI,CAAC,mBAAmB,IAAI,MAAM,QAAQ,MAAM,GAAG;AACjD,2BAAmB,IAAI,MAAM,QAAQ,QAAQ,KAAK;AAAA,MACpD;AACA,YAAM,mBAAmB,MAAM,QAAQ,QAAQ,QAAQ;AACvD,YAAM,qBAAqB,MAAM,QAAQ,QAAQ,aAAa;AAAA,QAC5D,MAAM;AACJ,8CAAoC,OAAO;AAAA,YACzC,mBAAmB;AAAA,YACnB,iBAAiB;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF;AACA,0CAAoC,OAAO;AAAA,QACzC,mBAAmB;AAAA,QACnB,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,IACA,YAAY,SAAS;AACnB,UAAI,MAAM,MAAM,aAAa,SAAS;AACpC;AAAA,MACF;AAEA,YAAM,QAAQ;AAAA,QACZ,GAAG,MAAM;AAAA,QACT,UAAU;AAAA,MACZ;AACA,2CAAqC,KAAK;AAAA,IAC5C;AAAA,IACA,OAAO;AACL,0CAAoC,OAAO;AAAA,QACzC,mBAAmB;AAAA,QACnB,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,UAAU;AAClB,YAAM,UAAU,IAAI,QAAQ;AAC5B,aAAO,MAAM;AACX,cAAM,UAAU,OAAO,QAAQ;AAAA,MACjC;AAAA,IACF;AAAA,IACA,MAAM,iBAAiB;AACrB,YAAM,WAAW,MAAM,QAAQ,QAAQ;AAAA,QACrC,MAAM,MAAM;AAAA,MACd;AACA,UAAI,CAAC,SAAS,KAAK;AACjB;AAAA,MACF;AAEA,UAAI,MAAM,MAAM,aAAa,SAAS,KAAK;AACzC,cAAM,QAAQ;AAAA,UACZ,GAAG,MAAM;AAAA,UACT,UAAU,SAAS;AAAA,QACrB;AACA,6CAAqC,KAAK;AAAA,MAC5C;AAEA,YAAM,MAAM,QAAQ,QAAQ,QAAQ,SAAS;AAAA,QAC3C,kBAAkB,MAAM,QAAQ;AAAA,QAChC,QAAQ,MAAM,QAAQ;AAAA,QACtB,KAAK,SAAS;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oCACP,SACA,YACe;AACf,QAAM,aAAa,WAAW,KAAK;AACnC,MACE,QAAQ,cAAc,UACtB,QAAQ,UAAU,QAClB,WAAW,WAAW,KACtB,eAAe,eACf;AACA,WAAO;AAAA,EACT;AAEA,QAAM,uBAAuB,8BAA8B,UAAU;AACrE,QAAM,uBAAuB,QAAQ,MACjC,8BAA8B,QAAQ,GAAG,IACzC;AACJ,SAAO,yBAAyB,QAC9B,yBAAyB,uBACvB,aACA;AACN;AAEA,SAAS,qCACP,OACM;AACN,aAAW,YAAY,MAAM,WAAW;AACtC,aAAS;AAAA,EACX;AACF;AAEA,SAAS,6BACP,SACA,YACQ;AACR,QAAM,qBAAqB,QAAQ,KAAK,KAAK,KAAK;AAClD,SAAO,mBAAmB,SAAS,IAAI,qBAAqB;AAC9D;AAEA,SAAS,oCACP,OACA,SAIM;AACN,QAAM,UAAU,MAAM,QAAQ,QAAQ,aAAa;AAAA,IACjD,MAAM,QAAQ;AAAA,EAChB;AACA,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,MAAM,QAAQ;AAAA,EAChB;AACA,QAAM,eACJ,eAAe,MAAM,MAAM,aAAa,aAAa,MAAM,MAAM;AAEnE,QAAM,UACJ,MAAM,MAAM,YAAY,WACxB,MAAM,MAAM,eAAe,cAC3B,MAAM,MAAM,aAAa;AAE3B,MAAI,SAAS;AACX,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,UAAU;AAAA,MACV;AAAA,IACF;AACA,QAAI,QAAQ,iBAAiB;AAC3B,2CAAqC,KAAK;AAAA,IAC5C;AAAA,EACF;AAEA,MAAI,QAAQ,mBAAmB;AAC7B,SAAK,mCAAmC,KAAK,EAAE,MAAM,MAAM,MAAS;AAAA,EACtE;AACF;AAEA,eAAe,mCACb,OACe;AACf,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM;AACV,QAAM,aAAa,WAAW,KAAK;AACnC,QAAM,uBAAuB,kCAAkC,UAAU;AACzE,QAAM,uBAAuB,MAAM,MAAM,QAAQ,MAC7C,kCAAkC,MAAM,MAAM,QAAQ,GAAG,IACzD;AACJ,QAAM,yBAAyB,MAAM,MAAM,QAAQ,cAAc;AACjE,QAAM,uBACJ,kBACA,MAAM,MAAM,QAAQ,cAAc,UAClC,yBAAyB,SACxB,yBAAyB,wBACxB,MAAM,MAAM,QAAQ,UAAU,SAChC,MAAM,0BAA0B;AAClC,MACE,WAAW,WAAW,KACtB,eAAe,iBACf,MAAM,MAAM,QAAQ,aACpB,MAAM,6BAA6B,cAClC,CAAC,0BAA0B,CAAC,wBAC5B,0BACC,MAAM,MAAM,QAAQ,UAAU,QAC9B,MAAM,0BAA0B,YAClC;AACA;AAAA,EACF;AAEA,QAAM,2BAA2B;AACjC,MAAI;AACF,UAAM,QAAQ,QAAQ,SAAS;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP,CAAC;AACD,UAAM,wBAAwB;AAAA,EAChC,UAAE;AACA,QAAI,MAAM,6BAA6B,YAAY;AACjD,YAAM,2BAA2B;AAAA,IACnC;AAAA,EACF;AACF;;;AD/VO,SAAS,yBAAyB,OAStC;AACD,QAAM,aAAa;AAAA,IACjB,MACE,6BAA6B;AAAA,MAC3B,YAAY,MAAM;AAAA,MAClB,SAAS,MAAM;AAAA,MACf,kBAAkB,MAAM;AAAA,MACxB,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM,aAAa;AAAA,MAC9B,aAAa,MAAM,eAAe;AAAA,MAClC,kBAAkB,MAAM;AAAA,MACxB,gBAAgB,MAAM,kBAAkB;AAAA,IAC1C,CAAC;AAAA,IACH;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAEA,YAAU,MAAM;AACd,eAAW,OAAO;AAClB,WAAO,MAAM;AACX,iBAAW,QAAQ;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,YAAU,MAAM;AACd,eAAW,KAAK;AAAA,EAClB,GAAG;AAAA,IACD;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR,CAAC;AACD,QAAM,QAAQ,yBAAqD;AAAA,IACjE,cAAc;AACZ,aAAO,WAAW,SAAS;AAAA,IAC7B;AAAA,IACA,UAAU,UAAU;AAClB,aAAO,WAAW,UAAU,QAAQ;AAAA,IACtC;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;;;AE/EA,SAAS,aAAa,aAAAC,YAAW,WAAAC,gBAAe;AAChD,SAAS,4BAAAC,iCAAgC;;;ACQzC,IAAM,gCAAgC;AACtC,IAAM,+BAA+B;AAqDrC,IAAM,4BAA4B,oBAAI,IAGpC;AACF,IAAM,0BAA0B,oBAAI,IAAoB;AACxD,IAAM,kCAAkC,oBAAI,IAG1C;AAEK,SAAS,oCAAoC,OAUnB;AAC/B,QAAM,WAAW,0BAA0B,IAAI,MAAM,MAAM;AAC3D,QAAM,QACJ,YACA,wCAAwC;AAAA,IACtC,SAAS,MAAM;AAAA,IACf,YAAY,MAAM;AAAA,IAClB,WAAW,MAAM;AAAA,IACjB,kBAAkB,MAAM;AAAA,IACxB,QAAQ,MAAM;AAAA,IACd,oBAAoB,MAAM;AAAA,IAC1B,WAAW,MAAM;AAAA,IACjB,aAAa,MAAM;AAAA,IACnB,kBAAkB,MAAM;AAAA,EAC1B,CAAC;AAEH,QAAM,UAAU;AAAA,IACd,SAAS,MAAM;AAAA,IACf,YAAY,MAAM;AAAA,IAClB,WAAW,MAAM;AAAA,IACjB,kBAAkB,MAAM;AAAA,IACxB,QAAQ,MAAM;AAAA,IACd,oBAAoB,MAAM;AAAA,IAC1B,WAAW,MAAM;AAAA,IACjB,aAAa,MAAM;AAAA,IACnB,kBAAkB,MAAM;AAAA,EAC1B;AACA,MAAI,CAAC,UAAU;AACb,8BAA0B,IAAI,MAAM,QAAQ,KAAK;AAAA,EACnD;AACA,SAAO,MAAM;AACf;AAEA,SAAS,wCACP,SACmC;AACnC,QAAM,QAAQ,yCAAyC,OAAO;AAC9D,QAAM,QAAQ;AAAA,IACZ,mBAAmB,CAAC;AAAA,IACpB;AAAA,IACA,YAAY;AAAA,IACZ,WAAW,oBAAI,IAAI;AAAA,IACnB,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB;AAAA,IACA,SAAS;AAAA,EACX;AAEA,QAAM,aAAa;AAAA,IACjB,6BAA6B;AAC3B,wCAAkC,OAAO,IAAI;AAAA,IAC/C;AAAA,IACA,WAAW;AACT,aAAO,MAAM;AAAA,IACf;AAAA,IACA,MAAM,8BAA8B;AAClC,wCAAkC,OAAO,IAAI;AAC7C,UAAI;AACF,cAAM,MAAM,QAAQ,QAAQ,QAAQ,eAAe;AAAA,UACjD,QAAQ,MAAM,QAAQ;AAAA,QACxB,CAAC;AAAA,MACH,SAAS,OAAO;AACd;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,YACE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAC5D,eAAe,6BAA6B,MAAM,OAAO;AAAA,YACzD,kBAAkB,MAAM,MAAM;AAAA,UAChC;AAAA,UACA;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,UAAU;AACR,YAAM,WAAW,KAAK,IAAI,GAAG,MAAM,WAAW,CAAC;AAC/C,UAAI,MAAM,WAAW,GAAG;AACtB;AAAA,MACF;AACA,yCAAmC,KAAK;AACxC,+BAAyB,KAAK;AAC9B,gCAA0B,OAAO,MAAM,QAAQ,MAAM;AAAA,IACvD;AAAA,IACA,SAAS;AACP,YAAM,YAAY;AAClB,UAAI,MAAM,WAAW,GAAG;AACtB;AAAA,MACF;AACA,iDAA2C,OAAO;AAAA,QAChD,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,IACA,WAAW,SAAS;AAClB,UAAI,MAAM,YAAY,SAAS;AAC7B;AAAA,MACF;AACA,+BAAyB,KAAK;AAC9B,YAAM,UAAU;AAChB,+BAAyB,KAAK;AAAA,IAChC;AAAA,IACA,OAAO;AACL,iDAA2C,OAAO;AAAA,QAChD,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,QACjB,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,IACA,UAAU,UAAU;AAClB,YAAM,UAAU,IAAI,QAAQ;AAC5B,aAAO,MAAM;AACX,cAAM,UAAU,OAAO,QAAQ;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,yCACP,SACmC;AACnC,QAAM,mBAAmB,+BAA+B;AAAA,IACtD,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA,IACrB,kBAAkB,QAAQ;AAAA,EAC5B,CAAC;AACD,SAAO;AAAA,IACL,qBAAqB;AAAA,IACrB,qBAAqB,QAAQ,cAAc;AAAA,IAC3C,YAAY,GAAG,QAAQ,MAAM,IAAI,gBAAgB;AAAA,IACjD;AAAA,IACA,YAAY;AAAA,EACd;AACF;AAEA,SAAS,2CACP,OACA,SAKM;AACN,QAAM,YAAY,yCAAyC,MAAM,OAAO;AACxE,QAAM,UACJ,MAAM,MAAM,wBAAwB,UAAU,uBAC9C,MAAM,MAAM,wBAAwB,UAAU,uBAC9C,MAAM,MAAM,eAAe,UAAU,cACrC,MAAM,MAAM,qBAAqB,UAAU,oBAC3C,MAAM,MAAM,eAAe,UAAU;AAEvC,MAAI,QAAQ,kBAAkB;AAC5B,QAAI,MAAM,QAAQ,cAAc,QAAQ;AACtC,yCAAmC,KAAK;AAAA,IAC1C,OAAO;AACL,6CAAuC,MAAM,QAAQ,MAAM;AAC3D,WAAK,MAAM,QAAQ,QAAQ,QACxB,eAAe;AAAA,QACd,kBAAkB,MAAM,QAAQ;AAAA,QAChC,QAAQ,MAAM,QAAQ;AAAA,QACtB,WAAW,MAAM,QAAQ;AAAA,QACzB,aAAa,MAAM,QAAQ;AAAA,QAC3B,kBAAkB,MAAM,QAAQ;AAAA,MAClC,CAAC,EACA,MAAM,MAAM,MAAS;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,QACE,QAAQ,iBACR,MAAM,WACN,MAAM,kBAAkB,WAAW,GACnC;AACA,+BAAyB,KAAK;AAAA,IAChC;AACA;AAAA,EACF;AAEA,QAAM,QAAQ;AACd,2BAAyB,KAAK;AAC9B,2BAAyB,KAAK;AAC9B,MAAI,QAAQ,iBAAiB;AAC3B,gDAA4C,KAAK;AAAA,EACnD;AACF;AAEA,SAAS,kCACP,OACA,qBACM;AACN,MACE,MAAM,MAAM,qBAAqB,MAAM,qBAAqB,KAC5D,MAAM,MAAM,qBAAqB,MAAM,qBAAqB,GAC5D;AACA;AAAA,EACF;AACA,QAAM,QAAQ;AAAA,IACZ,GAAG,MAAM;AAAA,IACT;AAAA,EACF;AACA,8CAA4C,KAAK;AACnD;AAEA,SAAS,4CACP,OACM;AACN,aAAW,YAAY,MAAM,WAAW;AACtC,aAAS;AAAA,EACX;AACF;AAEA,SAAS,uCAAuC,QAAsB;AACpE,QAAM,UAAU,gCAAgC,IAAI,MAAM;AAC1D,MAAI,YAAY,QAAW;AACzB,eAAW,aAAa,OAAO;AAC/B,oCAAgC,OAAO,MAAM;AAAA,EAC/C;AACA,0BAAwB,OAAO,MAAM;AACvC;AAEA,SAAS,mCACP,OACM;AACN,QAAM,UAAU,MAAM;AACtB,QAAM,SAAS,MAAM,QAAQ;AAC7B,QAAM,qBAAqB;AAC3B,MAAI,YAAY,MAAM;AACpB,2CAAuC,MAAM;AAC7C;AAAA,EACF;AAEA,QAAM,oBAAoB;AAC1B,yCAAuC,MAAM;AAC7C,0BAAwB,IAAI,QAAQ,OAAO;AAC3C,QAAM,UAAU,WAAW,WAAW,MAAM;AAC1C,oCAAgC,OAAO,MAAM;AAC7C,UAAM,iBAAiB,wBAAwB,IAAI,MAAM;AACzD,4BAAwB,OAAO,MAAM;AACrC,QACE,OAAO,mBAAmB,YAC1B,CAAC,OAAO,SAAS,cAAc,GAC/B;AACA;AAAA,IACF;AAEA,SAAK,MAAM,QAAQ,QAAQ,QACxB,gBAAgB;AAAA,MACf,QAAQ,MAAM,QAAQ;AAAA,MACtB,eAAe;AAAA,IACjB,CAAC,EACA,MAAM,MAAM,MAAS;AAAA,EAC1B,GAAG,6BAA6B;AAChC,kCAAgC,IAAI,QAAQ,OAAO;AACrD;AAEA,SAAS,yBACP,OACM;AACN,MAAI,CAAC,MAAM,SAAS;AAClB,UAAM,oBAAoB,CAAC;AAC3B;AAAA,EACF;AACA,aAAW,UAAU,MAAM,mBAAmB;AAC5C,UAAM,QAAQ,oBAAoB,OAAO,OAAO,OAAO,QAAQ;AAAA,EACjE;AACA,QAAM,oBAAoB,CAAC;AAC7B;AAEA,SAAS,yBACP,OACM;AACN,QAAM,UAAU,MAAM;AACtB,MAAI,CAAC,WAAW,CAAC,MAAM,MAAM,qBAAqB;AAChD;AAAA,EACF;AAEA,QAAM,gBAAgB,YAA2B;AAC/C,UAAM,UAAU,QAAQ,mBAAmB;AAC3C,QACE,OAAO,YAAY,YACnB,CAAC,OAAO,SAAS,OAAO,KACxB,WAAW,KACX,MAAM,sBAAsB,WAC5B,MAAM,uBAAuB,SAC7B;AACA;AAAA,IACF;AAEA,2CAAuC,MAAM,QAAQ,MAAM;AAC3D,UAAM,qBAAqB;AAC3B,QAAI;AACF,YAAM,MAAM,QAAQ,QAAQ,QAAQ,cAAc;AAAA,QAChD,kBAAkB,MAAM,QAAQ;AAAA,QAChC,QAAQ,MAAM,QAAQ;AAAA,QACtB,WAAW,MAAM,QAAQ;AAAA,QACzB,aAAa,MAAM,QAAQ;AAAA,QAC3B,kBAAkB,MAAM,QAAQ;AAAA,QAChC,eAAe;AAAA,MACjB,CAAC;AACD,YAAM,oBAAoB;AAAA,IAC5B,UAAE;AACA,UAAI,MAAM,uBAAuB,SAAS;AACxC,cAAM,qBAAqB;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAEA,QAAM,kBAAiC,MAAM;AAC3C,SAAK,cAAc,EAAE,MAAM,MAAM,MAAS;AAAA,EAC5C;AACA,QAAM,iBAAgC,MAAM;AAC1C,SAAK,cAAc,EAAE,MAAM,MAAM,MAAS;AAAA,EAC5C;AACA,QAAM,yBAAwC,MAAM;AAClD,UAAM,QAAQ,qBAAqB;AAAA,EACrC;AACA,QAAM,4BAA2C,CAAC,UAAU;AAC1D,UAAM,uBACJ,MAAM,QAAQ,QAAQ,QAAQ,4BAA4B;AAC5D,UAAM,uBACJ,MAAM,QAAQ,QAAQ,QAAQ,iBAAiB;AACjD,QAAI,CAAC,wBAAwB,CAAC,sBAAsB;AAClD;AAAA,IACF;AACA,UAAM,eAAe;AACrB,UAAM,QAAQ,mCAAmC,OAAO,OAAO;AAC/D,QAAI,sBAAsB;AACxB,WAAK,MAAM,QAAQ,QAAQ,QACxB,0BAA0B;AAAA,QACzB,OAAO,MAAM,QAAQ,QAAQ,KAAK,EAAE,sBAAsB;AAAA,QAC1D,QAAQ,MAAM,QAAQ;AAAA,QACtB;AAAA,MACF,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,YACE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAC5D,eAAe,6BAA6B,OAAO;AAAA,YACnD,kBAAkB,MAAM,MAAM;AAAA,UAChC;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AACH;AAAA,IACF;AACA,sCAAkC,OAAO,KAAK;AAAA,EAChD;AAEA,QAAM,UAAU;AAAA,IACd,EAAE,OAAO,cAAc,UAAU,gBAAgB;AAAA,IACjD,EAAE,OAAO,aAAa,UAAU,eAAe;AAAA,IAC/C,EAAE,OAAO,gBAAgB,UAAU,0BAA0B;AAAA,IAC7D,EAAE,OAAO,eAAe,UAAU,0BAA0B;AAAA,IAC5D,EAAE,OAAO,SAAS,UAAU,uBAAuB;AAAA,IACnD,EAAE,OAAO,eAAe,UAAU,uBAAuB;AAAA,EAC3D;AACA,aAAW,UAAU,SAAS;AAC5B,YAAQ,iBAAiB,OAAO,OAAO,OAAO,QAAQ;AAAA,EACxD;AACA,QAAM,oBAAoB;AAC5B;AAEA,SAAS,mCACP,OACA,SACoC;AACpC,QAAM,iBAAiB;AAKvB,QAAM,UAAU,iBAAiB,eAAe,OAAO;AACvD,QAAM,UAAU,iBAAiB,eAAe,OAAO;AACvD,MAAI,YAAY,QAAQ,YAAY,MAAM;AACxC,WAAO,EAAE,GAAG,SAAS,GAAG,QAAQ;AAAA,EAClC;AAEA,QAAM,SAAS,iBAAiB,eAAe,QAAQ,CAAC;AACxD,QAAM,SAAS,iBAAiB,eAAe,QAAQ,CAAC;AACxD,MAAI,WAAW,QAAQ,WAAW,MAAM;AACtC,WAAO,EAAE,GAAG,QAAQ,GAAG,OAAO;AAAA,EAChC;AAEA,QAAM,OAAO,QAAQ,sBAAsB;AAC3C,SAAO;AAAA,IACL,GAAG,KAAK;AAAA,IACR,GAAG,KAAK;AAAA,EACV;AACF;AAEA,SAAS,iBAAiB,OAA+B;AACvD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;AAEA,SAAS,6BACP,SACe;AACf,QAAM,gBAAgB,SAAS,mBAAmB;AAClD,SAAO,OAAO,kBAAkB,YAAY,OAAO,SAAS,aAAa,IACrE,gBACA;AACN;AAEA,SAAS,mCACP,OACA,OACA,SACA,QAA6C,QACvC;AACN,QAAM,QAAQ,QAAQ,mBAAmB;AAAA,IACvC,SAAS;AAAA,MACP,GAAG;AAAA,MACH,QAAQ,MAAM,QAAQ;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;AD5eO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAmBE;AACA,QAAM,aAAaC;AAAA,IACjB,MACE,oCAAoC;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,EAAAC,WAAU,MAAM;AACd,eAAW,OAAO;AAClB,WAAO,MAAM;AACX,iBAAW,QAAQ;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,UAAU,CAAC;AAEf,EAAAA,WAAU,MAAM;AACd,eAAW,KAAK;AAAA,EAClB,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,QAAQC,0BAA4D;AAAA,IACxE,cAAc;AACZ,aAAO,WAAW,SAAS;AAAA,IAC7B;AAAA,IACA,UAAU,UAAU;AAClB,aAAO,WAAW,UAAU,QAAQ;AAAA,IACtC;AAAA,EACF,CAAC;AAED,QAAM,gBAAgB;AAAA,IACpB,CAAC,YAA0C;AACzC,iBAAW,WAAW,OAAO;AAAA,IAC/B;AAAA,IACA,CAAC,UAAU;AAAA,EACb;AACA,QAAM,6BAA6B,YAAY,MAAM;AACnD,eAAW,2BAA2B;AAAA,EACxC,GAAG,CAAC,UAAU,CAAC;AACf,QAAM,8BAA8B,YAAY,MAAM;AACpD,WAAO,WAAW,4BAA4B;AAAA,EAChD,GAAG,CAAC,UAAU,CAAC;AAEf,SAAO;AAAA,IACL,qBAAqB,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,qBAAqB,MAAM;AAAA,IAC3B;AAAA,IACA,YAAY,MAAM;AAAA,IAClB,kBAAkB,MAAM;AAAA,IACxB,YAAY,MAAM;AAAA,EACpB;AACF;;;AHEQ,cAsEU,YAtEV;AAnGR,IAAM,kCAAkC;AAgBjC,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,iBAAiB;AACnB,GAAkC;AAChC,QAAM,EAAE,YAAY,MAAM,IAAI,yBAAyB;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,UAAU,MAAM;AACtB,QAAM,sBAAsB;AAAA,IAC1B,MAAM,QAAQ,KAAK,KAAK,KAAK;AAAA,EAC/B;AACA,QAAM,eAAe,QAAQ,QACzB,8BAA8B,SAAS,QAAQ,KAAK,IACpD;AACJ,QAAM,cAAc,QAAQ,QACxB,6BAA6B,SAAS,QAAQ,KAAK,IACnD;AACJ,QAAM,qBAAqB,iBAAiB;AAC5C,QAAM,kBAAkB,QAAQ,QAAQ,eACpC,QAAQ,oBAAoB,MAAM,UAAU,EAAE,MAC9C;AACJ,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,sBAAsB;AAAA,IACxB;AAAA,IACA,YAAY,MAAM;AAAA,IAClB,WAAW,QAAQ;AAAA,IACnB;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,EAAAC,WAAU,MAAM;AACd,UAAM,eAAe,MAAM,QAAQ,KAAK,KAAK,KAAK;AAClD,QACE,CAAC,eACD,MAAM,QAAQ,aACd,MAAM,QAAQ,SACd,aAAa,WAAW,KACxB,iBAAiB,iBACjB,oBAAoB,YAAY,cAChC;AACA;AAAA,IACF;AAEA,wBAAoB,UAAU;AAC9B,gBAAY,YAAY;AAAA,EAC1B,GAAG;AAAA,IACD;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ;AAAA,EAChB,CAAC;AAED,SACE,qBAAC,SAAI,WAAU,6EACZ;AAAA,iBACC;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,QAAQ;AAAA,QACnB,cAAc,QAAQ;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB;AAAA,QACA,QAAQ,QAAQ,cAAc;AAAA,QAC9B,WAAW,QAAQ;AAAA,QACnB,kBAAkB,CAAC,YAAY,WAAW,YAAY,OAAO;AAAA,QAC7D;AAAA,QACA,aAAa,MAAM;AACjB,eAAK,WAAW,eAAe,EAAE,MAAM,MAAM,MAAS;AAAA,QACxD;AAAA,QACA,gBACE,kBACI,MAAM;AACJ,eAAK,QAAQ,QACV,eAAe,EAAE,KAAK,gBAAgB,CAAC,EACvC,MAAM,MAAM,MAAS;AAAA,QAC1B,IACA;AAAA,QAEN,UAAU,MAAM;AACd,eAAK,WAAW,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,QAChD;AAAA,QACA,aAAa,MAAM;AACjB,eAAK,WAAW,UAAU,EAAE,MAAM,MAAM,MAAS;AAAA,QACnD;AAAA,QACA,UAAU,MAAM;AACd,eAAK,WAAW,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,QAChD;AAAA;AAAA,IACF,IACE;AAAA,IACJ,qBAAC,SAAI,WAAU,wEACZ;AAAA,4BACC;AAAA,QAAC;AAAA;AAAA,UACC,aAAa;AAAA,UAEb,KAAK;AAAA,UACL,WAAW;AAAA,YACT;AAAA,YACA,qBAAqB,+BAA+B;AAAA,UACtD;AAAA,UACA,6BAA0B;AAAA,UAC1B,WAAW;AAAA,UACX,KAAK;AAAA;AAAA,QARA;AAAA,MASP,IACE;AAAA,MACH,eACC,oBAAC,SAAI,WAAU,8GACb;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,aAAU;AAAA,UAEV;AAAA,gCAAC,SAAI,WAAU,sNACb,8BAAC,oBAAiB,WAAU,UAAS,GACvC;AAAA,YACA,oBAAC,SAAI,WAAU,yDACZ,kBAAQ,KAAK,EAAE,YAAY,GAC9B;AAAA,YACA,oBAAC,SAAI,WAAU,qEACZ,wBACH;AAAA,YACC,cACC,oBAAC,SAAI,WAAU,sIACZ,uBACH,IACE;AAAA,YACH,kBACC,oBAAC,SAAI,WAAU,yDACb;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS,MAAM;AACb,uBAAK,QAAQ,QACV,eAAe,EAAE,KAAK,gBAAgB,CAAC,EACvC,MAAM,MAAM,MAAS;AAAA,gBAC1B;AAAA,gBAEA;AAAA,sCAAC,cAAW,WAAU,YAAW;AAAA,kBAChC,QAAQ,KAAK,EAAE,sBAAsB;AAAA;AAAA;AAAA,YACxC,GACF,IACE;AAAA;AAAA;AAAA,MACN,GACF,IACE;AAAA,MACH,sBACC;AAAA,QAAC;AAAA;AAAA,UACC,MAAI;AAAA,UACJ,WAAU;AAAA,UACV,iBAAe;AAAA,UACf,6BAA2B;AAAA,UAC3B,WAAW;AAAA,UACX,WAAW;AAAA,YACT,MAAM;AAAA,YACN,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,eAAe;AAAA,cACb,OAAO;AAAA,cACP,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,UAEA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,GAAG,mBAAmB,QAAQ;AAAA,cACzC,MAAK;AAAA,cACL,SAAS,MAAM;AACb,qBAAK,4BAA4B,EAAE,MAAM,MAAM,MAAS;AAAA,cAC1D;AAAA,cAEC,kBAAQ,KAAK,EAAE,sBAAsB;AAAA;AAAA,UACxC;AAAA;AAAA,MACF,IACE;AAAA,OACN;AAAA,KACF;AAEJ;AAaO,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAiD;AAC/C,QAAM,EAAE,YAAY,MAAM,IAAI,yBAAyB;AAAA,IACrD;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,UAAU,MAAM;AACtB,QAAM,kBAAkB,QAAQ,QAAQ,eACpC,QAAQ,oBAAoB,MAAM,UAAU,EAAE,MAC9C;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,QAAQ;AAAA,MACnB,cAAc,QAAQ;AAAA,MACtB;AAAA,MACA;AAAA,MACA,UAAU,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ,cAAc;AAAA,MAC9B,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA,kBAAkB,CAAC,YAAY,WAAW,YAAY,OAAO;AAAA,MAC7D;AAAA,MACA,aAAa,MAAM;AACjB,aAAK,WAAW,eAAe,EAAE,MAAM,MAAM,MAAS;AAAA,MACxD;AAAA,MACA,gBACE,kBACI,MAAM;AACJ,aAAK,QAAQ,QACV,eAAe,EAAE,KAAK,gBAAgB,CAAC,EACvC,MAAM,MAAM,MAAS;AAAA,MAC1B,IACA;AAAA,MAEN,UAAU,MAAM;AACd,aAAK,WAAW,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,MAChD;AAAA,MACA,aAAa,MAAM;AACjB,aAAK,WAAW,UAAU,EAAE,MAAM,MAAM,MAAS;AAAA,MACnD;AAAA,MACA,UAAU,MAAM;AACd,aAAK,WAAW,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,MAChD;AAAA,MACA,YAAY;AAAA;AAAA,EACd;AAEJ;AAEO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AACf,GAmBgB;AACd,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,SAAS,CAAC;AAE9D,QAAM,eAAe,MAAY;AAC/B,0BAAsB,CAAC,eAAe,aAAa,CAAC;AACpD,aAAS;AAAA,EACX;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,aAAa,2BAA2B;AAAA,QACxC;AAAA,MACF;AAAA,MACA,4BAAyB;AAAA,MACzB,eAAe,CAAC,UAAU;AACxB,YACE,MAAM,kBAAkB,WACxB,MAAM,OAAO,QAAQ,SAAS,GAC9B;AACA;AAAA,QACF;AACA,cAAM,gBAAgB;AACtB,yBAAiB,gBAAgB,KAAK;AAAA,MACxC;AAAA,MAEA;AAAA,6BAAC,SAAI,WAAU,kCACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,UAAU,CAAC;AAAA,cACX,OAAO,QAAQ,KAAK,EAAE,cAAc;AAAA,cACpC,SAAS;AAAA,cAET,8BAAC,iBAAc,WAAU,eAAc;AAAA;AAAA,UACzC;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,UAAU,CAAC;AAAA,cACX,OAAO,QAAQ,KAAK,EAAE,iBAAiB;AAAA,cACvC,SAAS;AAAA,cAET,8BAAC,kBAAe,WAAU,eAAc;AAAA;AAAA,UAC1C;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,QAAQ,KAAK,EAAE,gBAAgB;AAAA,cACtC,SAAS;AAAA,cAET;AAAA,gBAAC;AAAA;AAAA,kBAEC,WAAW;AAAA,oBACT;AAAA,oBACA,qBAAqB,KACnB;AAAA,kBACJ;AAAA;AAAA,gBALK;AAAA,cAMP;AAAA;AAAA,UACF;AAAA,WACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACE,GAAG;AAAA,YACJ,WAAU;AAAA,YACV,iCAA8B;AAAA,YAC9B,yBAAsB;AAAA,YACtB,eAAY;AAAA;AAAA,QACd;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,UAAU,CAAC,UAAU;AACnB,oBAAM,eAAe;AACrB,oBAAM,gBAAgB;AACtB,0BAAY;AAAA,YACd;AAAA,YAEA;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,cAAY,QAAQ,KAAK,EAAE,cAAc;AAAA,kBACzC,WAAU;AAAA,kBACV,aAAa,QAAQ,KAAK,EAAE,oBAAoB;AAAA,kBAChD,MAAK;AAAA,kBACL,OAAO;AAAA,kBACP,UAAU,CAAC,UAAU,iBAAiB,MAAM,OAAO,KAAK;AAAA,kBACxD,SAAS;AAAA;AAAA,cACX;AAAA,cACC,YACC,oBAAC,eAAY,WAAU,uHAAsH,IAC3I;AAAA;AAAA;AAAA,QACN;AAAA,QACC,iBACC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,QAAQ,KAAK,EAAE,sBAAsB;AAAA,YAC5C,SAAS;AAAA,YAET,8BAAC,cAAW,WAAU,eAAc;AAAA;AAAA,QACtC,IACE;AAAA,QACH,iBACC,qBAAC,SAAI,WAAU,6CACZ;AAAA,mBACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,cAAY,QAAQ,KAAK,EAAE,YAAY;AAAA,cAEtC,kBAAQ,KAAK,EAAE,YAAY;AAAA;AAAA,UAC9B,IACE;AAAA,UACJ;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,gBAAgB,CAAC,UAAU;AACzB,oBACE,CAAC,kBACD,EAAE,MAAM,kBAAkB,YAC1B,CAAC,MAAM,OAAO,QAAQ,iCAAiC,GACvD;AACA;AAAA,gBACF;AACA,+BAAe;AAAA,cACjB;AAAA,cAEC;AAAA;AAAA,UACH;AAAA,WACF,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,8BACP,SACA,OACQ;AACR,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,QAAQ,KAAK,EAAE,qBAAqB,MAAM,MAAM;AAAA,IACzD,KAAK;AACH,UAAI,MAAM,UAAU,MAAM,OAAO,eAAe,QAAW;AACzD,eAAO,QAAQ,KAAK;AAAA,UAClB;AAAA,UACA,MAAM;AAAA,QACR;AAAA,MACF;AACA,aAAO,QAAQ,KAAK,EAAE,2BAA2B,MAAM,MAAM;AAAA,IAC/D,KAAK;AACH,aAAO,QAAQ,KAAK,EAAE,8BAA8B,MAAM,MAAM;AAAA,IAClE,KAAK;AACH,aAAO,QAAQ,KAAK,EAAE,yBAAyB,MAAM,MAAM;AAAA,EAC/D;AACF;AAEA,SAAS,6BACP,SACA,OACe;AACf,MAAI,MAAM,SAAS,uBAAuB,CAAC,MAAM,QAAQ;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAM,OAAO;AAChC,MAAI,OAAO,eAAe,UAAU;AAClC,WAAO,QAAQ,KAAK,EAAE,qBAAqB,EAAE,WAAW,CAAC;AAAA,EAC3D;AAEA,QAAM,YAAY,MAAM,OAAO;AAC/B,MAAI,OAAO,cAAc,UAAU;AACjC,WAAO,QAAQ,KAAK,EAAE,oBAAoB,EAAE,UAAU,CAAC;AAAA,EACzD;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY;AAAA,MACZ,WAAU;AAAA,MACV;AAAA,MACA,MAAK;AAAA,MACL,OAAO;AAAA,MACP,MAAK;AAAA,MACL,SAAQ;AAAA,MACR;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;","names":["useEffect","useEffect","useMemo","useExternalStoreSnapshot","useMemo","useEffect","useExternalStoreSnapshot","useEffect"]}