diff --git a/docs/errors/DTK0052.md b/docs/errors/DTK0052.md new file mode 100644 index 00000000..953086cc --- /dev/null +++ b/docs/errors/DTK0052.md @@ -0,0 +1,24 @@ +--- +outline: deep +--- +# DTK0052: Launcher Process Exited Before Ready + +## Message + +> The "`{id}`" launcher process exited with code `{exitCode}` before its server was ready. + +## Cause + +A server launcher built with [`createProcessLauncher`](/kit/dock-system) spawns a child process and waits for its server to become reachable before swapping the dock to an iframe. This diagnostic is raised when the process **exits first** — the launcher races the readiness probe against the process's own exit, so a process that dies on startup (a build error, a missing config, no matching files) fails fast instead of blocking on a probe that can never succeed. + +## Example + +Starting the Vitest UI in a project with no test files: `vitest --ui` prints `No test files found` and exits with code 1 before its server ever binds. + +## Fix + +Open the launcher's terminal session to read the process output, resolve the underlying failure, then use **Retry** on the launcher card. + +## Source + +- [`packages/kit/src/node/create-process-launcher.ts`](https://github.com/vitejs/devtools/blob/main/packages/kit/src/node/create-process-launcher.ts) — the `serve` launch flow throws this when the process's `getResult()` settles before `onReady` resolves. diff --git a/docs/errors/index.md b/docs/errors/index.md index 47eecb41..9a10d1a5 100644 --- a/docs/errors/index.md +++ b/docs/errors/index.md @@ -33,6 +33,7 @@ Emitted by `@vitejs/devtools` and `@vitejs/devtools-kit`. | [DTK0032](./DTK0032) | error | Dock Launch Error | | [DTK0050](./DTK0050) | error | Integration Install Failed | | [DTK0051](./DTK0051) | warn | Connection Meta Serve Failed | +| [DTK0052](./DTK0052) | error | Launcher Process Exited Before Ready | Hub-side diagnostics for docks, terminals, messages, and commands live upstream in `@devframes/hub` under the `DF8xxx` range — see the [Devframe error reference](https://devfra.me/errors/). diff --git a/docs/kit/dock-system.md b/docs/kit/dock-system.md index 26655c67..ec893eb4 100644 --- a/docs/kit/dock-system.md +++ b/docs/kit/dock-system.md @@ -89,6 +89,12 @@ interface DockEntry { description?: string buttonStart?: string buttonLoading?: string + /** Bound command id — the launch button, palette, and keybinding share it */ + command?: string + /** Terminal session this launcher tracks (enables "View in Terminal") */ + terminalSessionId?: string + /** Author-set single line of progress/status, shown inline on the card */ + digest?: string } /** JsonRenderer handle created by ctx.createJsonRenderer() (for type: 'json-render') */ ui?: JsonRenderer @@ -301,6 +307,92 @@ ctx.docks.register({ }) ``` +### Binding a command + +Point `launcher.command` at a registered command so the launch button, the command palette, and any keybinding all run one handler. `command` is the serializable launch path, so `onLaunch` is optional: + +```ts +const COMMAND_ID = 'my-plugin:start' +ctx.commands.register({ id: COMMAND_ID, title: 'Start My App', handler: start }) + +ctx.docks.register({ + id: 'my-launcher', + title: 'My App', + icon: 'ph:rocket-launch-duotone', + type: 'launcher', + launcher: { + title: 'Start My App', + command: COMMAND_ID, + }, +}) +``` + +### Tracking a terminal session + +When the launch spawns a process, tie the launcher to its terminal session. Set `terminalSessionId` to surface a **View in Terminal** action (which opens the Terminals dock focused on that session), and set `digest` to a short status of the process — its progress, not its raw output: + +```ts +const session = await ctx.terminals.startChildProcess( + { command: 'vite', args: ['dev'], cwd }, + { id: 'my-app:dev', title: 'Dev Server' }, +) + +ctx.docks.update({ + id: 'my-launcher', + title: 'My App', + icon: 'ph:rocket-launch-duotone', + type: 'launcher', + launcher: { + title: 'Start My App', + status: 'loading', + terminalSessionId: 'my-app:dev', + digest: 'Waiting for the server…', + }, +}) +``` + +The **View in Terminal** action calls the hub's `hub:docks:activate` RPC (devframe 0.7.3+), which switches the host shell to the Terminals dock and focuses the tracked session — where the full output lives. + +`createProcessLauncher` composes all of the above (register + command binding + `prepare` + spawn + digest + session navigation) in one call. A plain **terminal launcher** stays a launcher while a long-running process runs: + +```ts +import { createProcessLauncher } from '@vitejs/devtools-kit/node' + +createProcessLauncher({ + id: 'my-app', + title: 'My App', + icon: 'ph:rocket-launch-duotone', + process: { command: 'vite', args: ['dev'], cwd: process.cwd() }, +}) +``` + +Pass `serve.onReady` for the common **server launcher** shape — run some commands, start a server, then replace the card with an iframe embedding it. The card shows a status while `onReady` resolves the URL, then the dock swaps to the iframe: + +```ts +let url: string + +createProcessLauncher({ + id: 'my-ui', + title: 'My UI', + icon: 'ph:browser-duotone', + // Optional: run setup (e.g. install an optional dep) before spawning. + prepare: async () => { + /* install-on-demand */ + }, + process: async () => { + const port = await getPort() + url = `http://localhost:${port}/` + return { command: 'my-ui', args: ['--port', String(port)], cwd: process.cwd() } + }, + serve: { + onReady: async () => { + await waitForServer(url) + return url + }, + }, +}) +``` + ## JSON render panels JSON render panels describe a UI as a JSON spec on the server — the client renders it from a built-in component library. This is the shortest path to a DevTools panel: server-side TypeScript only. diff --git a/packages/core/src/client/webcomponents/.generated/css.ts b/packages/core/src/client/webcomponents/.generated/css.ts index d730d286..de8fd0f5 100644 --- a/packages/core/src/client/webcomponents/.generated/css.ts +++ b/packages/core/src/client/webcomponents/.generated/css.ts @@ -1,3 +1,3 @@ /* eslint-disable eslint-comments/no-unlimited-disable */ /* eslint-disable */ -export default "*{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:after{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:before{--un-content:\"\"}:after{--un-content:\"\"}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button{-webkit-appearance:button;background-color:transparent;background-image:none}[type=button]{-webkit-appearance:button;background-color:transparent;background-image:none}[type=reset]{-webkit-appearance:button;background-color:transparent;background-image:none}[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::placeholder{opacity:1;color:#9ca3af}textarea::placeholder{opacity:1;color:#9ca3af}button{cursor:pointer}[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--un-text-opacity:100%}#vite-devtools-anchor{z-index:2147483644;box-sizing:border-box;transform-origin:50%;width:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:15px;position:fixed;transform:translate(-50%,-50%)rotate(0)}#vite-devtools-anchor #vite-devtools-dock-container{width:max-content;height:var(--vite-devtools-dock-height,40px);min-width:var(--vite-devtools-dock-min-width,100px);display:flex;position:absolute;top:0;left:0;transform:translate(-50%,-50%)}#vite-devtools-anchor.vite-devtools-vertical #vite-devtools-dock-container{transition-property:all;transition-duration:.5s;transition-timing-function:cubic-bezier(.4,0,.2,1);transform:translate(-50%,-50%)rotate(90deg)}#vite-devtools-anchor #vite-devtools-dock{touch-action:none;user-select:none;--vdt-backdrop-blur:blur(7px);height:100%;backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia);--vdt-text-opacity:1;color:rgba(51,51,51,var(--vdt-text-opacity));--vdt-shadow:var(--vdt-shadow-inset) 0 1px 3px 0 var(--vdt-shadow-color,rgba(0,0,0,.1)),var(--vdt-shadow-inset) 0 1px 2px -1px var(--vdt-shadow-color,rgba(0,0,0,.1));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow);height:var(--vite-devtools-dock-height,40px);width:calc-size(max-content, size);background-color:rgba(255,255,255,.5);-webkit-border-radius:9999px;border-radius:9999px;margin:auto;transition-property:all;transition-duration:.5s;transition-timing-function:cubic-bezier(.4,0,.2,1)}@media (prefers-color-scheme:dark){#vite-devtools-anchor #vite-devtools-dock{--vdt-text-opacity:1;color:rgba(255,255,255,var(--vdt-text-opacity));background-color:rgba(17,17,17,.5)}}#vite-devtools-anchor.vite-devtools-minimized #vite-devtools-dock{width:var(--vite-devtools-dock-minimized-size,22px);height:var(--vite-devtools-dock-minimized-size,22px);padding:2px 0}#vite-devtools-anchor.vite-devtools-minimized .vite-devtools-dock-bracket{opacity:.5;width:.375rem}#vite-devtools-anchor:hover #vite-devtools-glowing{opacity:.6}#vite-devtools-anchor #vite-devtools-glowing{pointer-events:none;z-index:-1;opacity:0;width:var(--vite-devtools-dock-glow-size,160px);height:var(--vite-devtools-dock-glow-size,160px);filter:blur(var(--vite-devtools-dock-glow-blur,60px));background-image:linear-gradient(45deg,#61d9ff,#6b84fd,#715ebd);-webkit-border-radius:9999px;border-radius:9999px;transition-property:all;transition-duration:1s;transition-timing-function:cubic-bezier(0,0,.2,1);position:absolute;top:0;left:0;transform:translate(-50%,-50%)}@media print{#vite-devtools-anchor{display:none}}.vite-devtools-resize-handle-horizontal{cursor:ns-resize;-webkit-border-radius:.375rem;border-radius:.375rem;height:10px;margin-top:-5px;margin-bottom:-5px;position:absolute;left:6px;right:6px}.vite-devtools-resize-handle-vertical{cursor:ew-resize;-webkit-border-radius:.375rem;border-radius:.375rem;width:10px;margin-left:-5px;margin-right:-5px;position:absolute;top:6px;bottom:0}.vite-devtools-resize-handle-corner{-webkit-border-radius:.375rem;border-radius:.375rem;width:14px;height:14px;margin:-6px;position:absolute}.vite-devtools-resize-handle{z-index:30}.vite-devtools-resize-handle:hover{background-color:rgba(156,163,175,.1)}@keyframes vite-devtools-shake{0%,to{transform:translate(0)}20%,60%{transform:translate(-5px)}40%,80%{transform:translate(5px)}}.vite-devtools-shake{animation:.4s cubic-bezier(.36,.07,.19,.97) vite-devtools-shake}@media (prefers-reduced-motion:reduce){.vite-devtools-shake{animation:none}}*{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }:before{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }:after{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }::backdrop{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }.i-fluent-emoji-flat-warning{background:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 32 32' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none'%3E%3Cpath fill='%23FFB02E' d='m14.839 5.668l-12.66 21.93c-.51.89.13 2.01 1.16 2.01h25.32c1.03 0 1.67-1.11 1.16-2.01l-12.66-21.93c-.52-.89-1.8-.89-2.32 0'/%3E%3Cpath fill='%23000' d='M14.599 21.498a1.4 1.4 0 1 0 2.8-.01v-9.16c0-.77-.62-1.4-1.4-1.4c-.77 0-1.4.62-1.4 1.4zm2.8 3.98a1.4 1.4 0 1 1-2.8 0a1.4 1.4 0 0 1 2.8 0'/%3E%3C/g%3E%3C/svg%3E\") 0 0/100% 100% no-repeat;width:1em;height:1em}.i-ph-arrow-clockwise{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M240 56v48a8 8 0 0 1-8 8h-48a8 8 0 0 1 0-16h27.4l-26.59-24.36l-.25-.24a80 80 0 1 0-1.67 114.78a8 8 0 0 1 11 11.63A95.44 95.44 0 0 1 128 224h-1.32a96 96 0 1 1 69.07-164L224 85.8V56a8 8 0 1 1 16 0'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrow-clockwise-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 128a88 88 0 1 1-88-88a88 88 0 0 1 88 88' opacity='.2'/%3E%3Cpath d='M240 56v48a8 8 0 0 1-8 8h-48a8 8 0 0 1 0-16h27.4l-26.59-24.36l-.25-.24a80 80 0 1 0-1.67 114.78a8 8 0 0 1 11 11.63A95.44 95.44 0 0 1 128 224h-1.32a96 96 0 1 1 69.07-164L224 85.8V56a8 8 0 1 1 16 0'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrow-counter-clockwise{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M224 128a96 96 0 0 1-94.71 96H128a95.38 95.38 0 0 1-65.9-26.2a8 8 0 0 1 11-11.63a80 80 0 1 0-1.67-114.78a3 3 0 0 1-.26.25L44.59 96H72a8 8 0 0 1 0 16H24a8 8 0 0 1-8-8V56a8 8 0 0 1 16 0v29.8L60.25 60A96 96 0 0 1 224 128'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrow-square-out-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M184 80v128a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8V80a8 8 0 0 1 8-8h128a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M224 104a8 8 0 0 1-16 0V59.32l-66.33 66.34a8 8 0 0 1-11.32-11.32L196.68 48H152a8 8 0 0 1 0-16h64a8 8 0 0 1 8 8Zm-40 24a8 8 0 0 0-8 8v72H48V80h72a8 8 0 0 0 0-16H48a16 16 0 0 0-16 16v128a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-72a8 8 0 0 0-8-8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrows-counter-clockwise-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 128a88 88 0 1 1-88-88a88 88 0 0 1 88 88' opacity='.2'/%3E%3Cpath d='M88 104H40a8 8 0 0 1-8-8V48a8 8 0 0 1 16 0v28.69l14.63-14.63A95.43 95.43 0 0 1 130 33.94h.53a95.36 95.36 0 0 1 67.07 27.33a8 8 0 0 1-11.18 11.44a79.52 79.52 0 0 0-55.89-22.77h-.45a79.56 79.56 0 0 0-56.14 23.43L59.31 88H88a8 8 0 0 1 0 16m128 48h-48a8 8 0 0 0 0 16h28.69l-14.63 14.63a79.56 79.56 0 0 1-56.13 23.43h-.45a79.52 79.52 0 0 1-55.89-22.77a8 8 0 1 0-11.18 11.44a95.36 95.36 0 0 0 67.07 27.33h.52a95.43 95.43 0 0 0 67.36-28.12L208 179.31V208a8 8 0 0 0 16 0v-48a8 8 0 0 0-8-8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrows-out-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M208 48v160H48V48Z' opacity='.2'/%3E%3Cpath d='M216 48v48a8 8 0 0 1-16 0V67.31l-42.34 42.35a8 8 0 0 1-11.32-11.32L188.69 56H160a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8M98.34 146.34L56 188.69V160a8 8 0 0 0-16 0v48a8 8 0 0 0 8 8h48a8 8 0 0 0 0-16H67.31l42.35-42.34a8 8 0 0 0-11.32-11.32M208 152a8 8 0 0 0-8 8v28.69l-42.34-42.35a8 8 0 0 0-11.32 11.32L188.69 200H160a8 8 0 0 0 0 16h48a8 8 0 0 0 8-8v-48a8 8 0 0 0-8-8M67.31 56H96a8 8 0 0 0 0-16H48a8 8 0 0 0-8 8v48a8 8 0 0 0 16 0V67.31l42.34 42.35a8 8 0 0 0 11.32-11.32Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-cards-three-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 104v96a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8v-96a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M208 88H48a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16m0 112H48v-96h160zM48 64a8 8 0 0 1 8-8h144a8 8 0 0 1 0 16H56a8 8 0 0 1-8-8m16-32a8 8 0 0 1 8-8h112a8 8 0 0 1 0 16H72a8 8 0 0 1-8-8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-down{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m213.66 101.66l-80 80a8 8 0 0 1-11.32 0l-80-80a8 8 0 0 1 11.32-11.32L128 164.69l74.34-74.35a8 8 0 0 1 11.32 11.32'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-left{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M165.66 202.34a8 8 0 0 1-11.32 11.32l-80-80a8 8 0 0 1 0-11.32l80-80a8 8 0 0 1 11.32 11.32L91.31 128Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-right{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m181.66 133.66l-80 80a8 8 0 0 1-11.32-11.32L164.69 128L90.34 53.66a8 8 0 0 1 11.32-11.32l80 80a8 8 0 0 1 0 11.32'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-up{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M213.66 165.66a8 8 0 0 1-11.32 0L128 91.31l-74.34 74.35a8 8 0 0 1-11.32-11.32l80-80a8 8 0 0 1 11.32 0l80 80a8 8 0 0 1 0 11.32'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-check-bold{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m232.49 80.49l-128 128a12 12 0 0 1-17 0l-56-56a12 12 0 1 1 17-17L96 183L215.51 63.51a12 12 0 0 1 17 17Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-check-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M232 56v144a16 16 0 0 1-16 16H40a16 16 0 0 1-16-16V56a16 16 0 0 1 16-16h176a16 16 0 0 1 16 16' opacity='.2'/%3E%3Cpath d='m205.66 85.66l-96 96a8 8 0 0 1-11.32 0l-40-40a8 8 0 0 1 11.32-11.32L104 164.69l90.34-90.35a8 8 0 0 1 11.32 11.32'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-circle-notch{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M232 128a104 104 0 0 1-208 0c0-41 23.81-78.36 60.66-95.27a8 8 0 0 1 6.68 14.54C60.15 61.59 40 93.27 40 128a88 88 0 0 0 176 0c0-34.73-20.15-66.41-51.34-80.73a8 8 0 0 1 6.68-14.54C208.19 49.64 232 87 232 128'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-dots-six-vertical{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M104 60a12 12 0 1 1-12-12a12 12 0 0 1 12 12m60 12a12 12 0 1 0-12-12a12 12 0 0 0 12 12m-72 44a12 12 0 1 0 12 12a12 12 0 0 0-12-12m72 0a12 12 0 1 0 12 12a12 12 0 0 0-12-12m-72 68a12 12 0 1 0 12 12a12 12 0 0 0-12-12m72 0a12 12 0 1 0 12 12a12 12 0 0 0-12-12'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-eye-slash{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M53.92 34.62a8 8 0 1 0-11.84 10.76l19.24 21.17C25 88.84 9.38 123.2 8.69 124.76a8 8 0 0 0 0 6.5c.35.79 8.82 19.57 27.65 38.4C61.43 194.74 93.12 208 128 208a127.1 127.1 0 0 0 52.07-10.83l22 24.21a8 8 0 1 0 11.84-10.76Zm47.33 75.84l41.67 45.85a32 32 0 0 1-41.67-45.85M128 192c-30.78 0-57.67-11.19-79.93-33.25A133.2 133.2 0 0 1 25 128c4.69-8.79 19.66-33.39 47.35-49.38l18 19.75a48 48 0 0 0 63.66 70l14.73 16.2A112 112 0 0 1 128 192m6-95.43a8 8 0 0 1 3-15.72a48.16 48.16 0 0 1 38.77 42.64a8 8 0 0 1-7.22 8.71a6 6 0 0 1-.75 0a8 8 0 0 1-8-7.26A32.09 32.09 0 0 0 134 96.57m113.28 34.69c-.42.94-10.55 23.37-33.36 43.8a8 8 0 1 1-10.67-11.92a132.8 132.8 0 0 0 27.8-35.14a133.2 133.2 0 0 0-23.12-30.77C185.67 75.19 158.78 64 128 64a118.4 118.4 0 0 0-19.36 1.57A8 8 0 1 1 106 49.79A134 134 0 0 1 128 48c34.88 0 66.57 13.26 91.66 38.35c18.83 18.83 27.3 37.62 27.65 38.41a8 8 0 0 1 0 6.5Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-eye-slash-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M128 56c-80 0-112 72-112 72s32 72 112 72s112-72 112-72s-32-72-112-72m0 112a40 40 0 1 1 40-40a40 40 0 0 1-40 40' opacity='.2'/%3E%3Cpath d='M53.92 34.62a8 8 0 1 0-11.84 10.76l19.24 21.17C25 88.84 9.38 123.2 8.69 124.76a8 8 0 0 0 0 6.5c.35.79 8.82 19.57 27.65 38.4C61.43 194.74 93.12 208 128 208a127.1 127.1 0 0 0 52.07-10.83l22 24.21a8 8 0 1 0 11.84-10.76Zm47.33 75.84l41.67 45.85a32 32 0 0 1-41.67-45.85M128 192c-30.78 0-57.67-11.19-79.93-33.25A133.2 133.2 0 0 1 25 128c4.69-8.79 19.66-33.39 47.35-49.38l18 19.75a48 48 0 0 0 63.66 70l14.73 16.2A112 112 0 0 1 128 192m6-95.43a8 8 0 0 1 3-15.72a48.16 48.16 0 0 1 38.77 42.64a8 8 0 0 1-7.22 8.71a6 6 0 0 1-.75 0a8 8 0 0 1-8-7.26A32.09 32.09 0 0 0 134 96.57m113.28 34.69c-.42.94-10.55 23.37-33.36 43.8a8 8 0 1 1-10.67-11.92a132.8 132.8 0 0 0 27.8-35.14a133.2 133.2 0 0 0-23.12-30.77C185.67 75.19 158.78 64 128 64a118.4 118.4 0 0 0-19.36 1.57A8 8 0 1 1 106 49.79A134 134 0 0 1 128 48c34.88 0 66.57 13.26 91.66 38.35c18.83 18.83 27.3 37.62 27.65 38.41a8 8 0 0 1 0 6.5Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-globe{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M128 24a104 104 0 1 0 104 104A104.12 104.12 0 0 0 128 24m88 104a87.6 87.6 0 0 1-3.33 24h-38.51a157.4 157.4 0 0 0 0-48h38.51a87.6 87.6 0 0 1 3.33 24m-114 40h52a115.1 115.1 0 0 1-26 45a115.3 115.3 0 0 1-26-45m-3.9-16a140.8 140.8 0 0 1 0-48h59.88a140.8 140.8 0 0 1 0 48ZM40 128a87.6 87.6 0 0 1 3.33-24h38.51a157.4 157.4 0 0 0 0 48H43.33A87.6 87.6 0 0 1 40 128m114-40h-52a115.1 115.1 0 0 1 26-45a115.3 115.3 0 0 1 26 45m52.33 0h-35.62a135.3 135.3 0 0 0-22.3-45.6A88.29 88.29 0 0 1 206.37 88Zm-98.74-45.6A135.3 135.3 0 0 0 85.29 88H49.63a88.29 88.29 0 0 1 57.96-45.6M49.63 168h35.66a135.3 135.3 0 0 0 22.3 45.6A88.29 88.29 0 0 1 49.63 168m98.78 45.6a135.3 135.3 0 0 0 22.3-45.6h35.66a88.29 88.29 0 0 1-57.96 45.6'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-keyboard-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M232 64v128a8 8 0 0 1-8 8H32a8 8 0 0 1-8-8V64a8 8 0 0 1 8-8h192a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M224 48H32a16 16 0 0 0-16 16v128a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16V64a16 16 0 0 0-16-16m0 144H32V64h192zm-16-64a8 8 0 0 1-8 8H56a8 8 0 0 1 0-16h144a8 8 0 0 1 8 8m0-32a8 8 0 0 1-8 8H56a8 8 0 0 1 0-16h144a8 8 0 0 1 8 8M72 160a8 8 0 0 1-8 8h-8a8 8 0 0 1 0-16h8a8 8 0 0 1 8 8m96 0a8 8 0 0 1-8 8H96a8 8 0 0 1 0-16h64a8 8 0 0 1 8 8m40 0a8 8 0 0 1-8 8h-8a8 8 0 0 1 0-16h8a8 8 0 0 1 8 8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-layout-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M104 104v104H40a8 8 0 0 1-8-8v-96Z' opacity='.2'/%3E%3Cpath d='M216 40H40a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h176a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 16v40H40V56ZM40 112h56v88H40Zm176 88H112v-88h104z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-magnifying-glass-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M192 112a80 80 0 1 1-80-80a80 80 0 0 1 80 80' opacity='.2'/%3E%3Cpath d='m229.66 218.34l-50.06-50.06a88.21 88.21 0 1 0-11.32 11.31l50.06 50.07a8 8 0 0 0 11.32-11.32M40 112a72 72 0 1 1 72 72a72.08 72.08 0 0 1-72-72'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-paint-brush-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 32c0 32.81-31.64 67.43-58.64 91.05A84.4 84.4 0 0 0 133 90.64c23.57-27 58.19-58.64 91-58.64' opacity='.2'/%3E%3Cpath d='M232 32a8 8 0 0 0-8-8c-44.08 0-89.31 49.71-114.43 82.63A60 60 0 0 0 32 164c0 30.88-19.54 44.73-20.47 45.37A8 8 0 0 0 16 224h76a60 60 0 0 0 57.37-77.57C182.3 121.31 232 76.08 232 32M92 208H34.63C41.38 198.41 48 183.92 48 164a44 44 0 1 1 44 44m32.42-94.45q5.14-6.66 10.09-12.55A76.2 76.2 0 0 1 155 121.49q-5.9 4.94-12.55 10.09a60.5 60.5 0 0 0-18.03-18.03m42.7-2.68a92.6 92.6 0 0 0-22-22c31.78-34.53 55.75-45 69.9-47.91c-2.85 14.16-13.37 38.13-47.9 69.91'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-push-pin{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m235.32 81.37l-60.69-60.68a16 16 0 0 0-22.63 0l-53.63 53.8c-10.66-3.34-35-7.37-60.4 13.14a16 16 0 0 0-1.29 23.78L85 159.71l-42.66 42.63a8 8 0 0 0 11.32 11.32L96.29 171l48.29 48.29A16 16 0 0 0 155.9 224h1.13a15.93 15.93 0 0 0 11.64-6.33c19.64-26.1 17.75-47.32 13.19-60L235.33 104a16 16 0 0 0-.01-22.63M224 92.69l-57.27 57.46a8 8 0 0 0-1.49 9.22c9.46 18.93-1.8 38.59-9.34 48.62L48 100.08c12.08-9.74 23.64-12.31 32.48-12.31A40.1 40.1 0 0 1 96.81 91a8 8 0 0 0 9.25-1.51L163.32 32L224 92.68Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-push-pin-fill{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m235.33 104l-53.47 53.65c4.56 12.67 6.45 33.89-13.19 60A15.93 15.93 0 0 1 157 224h-1.13a16 16 0 0 1-11.32-4.69L96.29 171l-42.63 42.66a8 8 0 0 1-11.32-11.32L85 159.71l-48.3-48.3A16 16 0 0 1 38 87.63c25.42-20.51 49.75-16.48 60.4-13.14L152 20.7a16 16 0 0 1 22.63 0l60.69 60.68a16 16 0 0 1 .01 22.62'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-rocket-launch-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M184 120v61.65a8 8 0 0 1-2.34 5.65l-34.35 34.35a8 8 0 0 1-13.57-4.53L128 176Zm-48-48H74.35a8 8 0 0 0-5.65 2.34l-34.35 34.35a8 8 0 0 0 4.53 13.57L80 128ZM40 216c37.65 0 50.69-19.69 54.56-28.18l-26.38-26.38C59.69 165.31 40 178.35 40 216' opacity='.2'/%3E%3Cpath d='M223.85 47.12a16 16 0 0 0-15-15c-12.58-.75-44.73.4-71.41 27.07L132.69 64H74.36A15.9 15.9 0 0 0 63 68.68L28.7 103a16 16 0 0 0 9.07 27.16l38.47 5.37l44.21 44.21l5.37 38.49a15.94 15.94 0 0 0 10.78 12.92a16.1 16.1 0 0 0 5.1.83a15.9 15.9 0 0 0 11.3-4.68l34.32-34.3a15.9 15.9 0 0 0 4.68-11.36v-58.33l4.77-4.77c26.68-26.68 27.83-58.83 27.08-71.42M74.36 80h42.33l-39.53 39.52L40 114.34Zm74.41-9.45a76.65 76.65 0 0 1 59.11-22.47a76.46 76.46 0 0 1-22.42 59.16L128 164.68L91.32 128ZM176 181.64L141.67 216l-5.19-37.17L176 139.31Zm-74.16 9.5C97.34 201 82.29 224 40 224a8 8 0 0 1-8-8c0-42.29 23-57.34 32.86-61.85a8 8 0 0 1 6.64 14.56c-6.43 2.93-20.62 12.36-23.12 38.91c26.55-2.5 36-16.69 38.91-23.12a8 8 0 1 1 14.56 6.64Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-shield-check-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 56v56c0 96-88 120-88 120s-88-24-88-120V56a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M208 40H48a16 16 0 0 0-16 16v56c0 52.72 25.52 84.67 46.93 102.19c23.06 18.86 46 25.26 47 25.53a8 8 0 0 0 4.2 0c1-.27 23.91-6.67 47-25.53C198.48 196.67 224 164.72 224 112V56a16 16 0 0 0-16-16m0 72c0 37.07-13.66 67.16-40.6 89.42a129.3 129.3 0 0 1-39.4 22.2a128.3 128.3 0 0 1-38.92-21.81C61.82 179.51 48 149.3 48 112V56h160ZM82.34 141.66a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 11.32l-56 56a8 8 0 0 1-11.32 0Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-sign-out-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 56v144a16 16 0 0 1-16 16H48V40h160a16 16 0 0 1 16 16' opacity='.2'/%3E%3Cpath d='M120 216a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8V40a8 8 0 0 1 8-8h64a8 8 0 0 1 0 16H56v160h56a8 8 0 0 1 8 8m109.66-93.66l-40-40a8 8 0 0 0-11.32 11.32L204.69 120H112a8 8 0 0 0 0 16h92.69l-26.35 26.34a8 8 0 0 0 11.32 11.32l40-40a8 8 0 0 0 0-11.32'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-spinner-gap-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M136 32v32a8 8 0 0 1-16 0V32a8 8 0 0 1 16 0m88 88h-32a8 8 0 0 0 0 16h32a8 8 0 0 0 0-16m-45.09 47.6a8 8 0 0 0-11.31 11.31l22.62 22.63a8 8 0 0 0 11.32-11.32ZM128 184a8 8 0 0 0-8 8v32a8 8 0 0 0 16 0v-32a8 8 0 0 0-8-8m-50.91-16.4l-22.63 22.62a8 8 0 0 0 11.32 11.32l22.62-22.63a8 8 0 0 0-11.31-11.31M72 128a8 8 0 0 0-8-8H32a8 8 0 0 0 0 16h32a8 8 0 0 0 8-8m-6.22-73.54a8 8 0 0 0-11.32 11.32L77.09 88.4A8 8 0 0 0 88.4 77.09Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-square-half-bottom-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M208 128v72a8 8 0 0 1-8 8H56a8 8 0 0 1-8-8v-72Z' opacity='.2'/%3E%3Cpath d='M200 40H56a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h144a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 16v64H56V56Zm0 144H56v-64h144z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-warning-duotone,.i-ph\\:warning-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M215.46 216H40.54c-12.62 0-20.54-13.21-14.41-23.91l87.46-151.87c6.3-11 22.52-11 28.82 0l87.46 151.87c6.13 10.7-1.79 23.91-14.41 23.91' opacity='.2'/%3E%3Cpath d='M236.8 188.09L149.35 36.22a24.76 24.76 0 0 0-42.7 0L19.2 188.09a23.51 23.51 0 0 0 0 23.72A24.35 24.35 0 0 0 40.55 224h174.9a24.35 24.35 0 0 0 21.33-12.19a23.51 23.51 0 0 0 .02-23.72m-13.87 15.71a8.5 8.5 0 0 1-7.48 4.2H40.55a8.5 8.5 0 0 1-7.48-4.2a7.59 7.59 0 0 1 0-7.72l87.45-151.87a8.75 8.75 0 0 1 15 0l87.45 151.87a7.59 7.59 0 0 1-.04 7.72M120 144v-40a8 8 0 0 1 16 0v40a8 8 0 0 1-16 0m20 36a12 12 0 1 1-12-12a12 12 0 0 1 12 12'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-wrench-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 96a64 64 0 0 1-94.94 56L73 217a24 24 0 0 1-34-34l65-56.06a64 64 0 0 1 80-90.29L144 80l5.66 26.34L176 112l43.35-40A63.8 63.8 0 0 1 224 96' opacity='.2'/%3E%3Cpath d='M226.76 69a8 8 0 0 0-12.84-2.88l-40.3 37.19l-17.23-3.7l-3.7-17.23l37.19-40.3A8 8 0 0 0 187 29.24A72 72 0 0 0 88 96a72.3 72.3 0 0 0 6 28.94L33.79 177c-.15.12-.29.26-.43.39a32 32 0 0 0 45.26 45.26c.13-.13.27-.28.39-.42L131.06 162A72 72 0 0 0 232 96a71.6 71.6 0 0 0-5.24-27M160 152a56.14 56.14 0 0 1-27.07-7a8 8 0 0 0-9.92 1.77l-55.9 64.74a16 16 0 0 1-22.62-22.62L109.18 133a8 8 0 0 0 1.77-9.93a56 56 0 0 1 58.36-82.31l-31.2 33.81a8 8 0 0 0-1.94 7.1l5.66 26.33a8 8 0 0 0 6.14 6.14l26.35 5.66a8 8 0 0 0 7.1-1.94l33.81-31.2A56.06 56.06 0 0 1 160 152'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-x{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M205.66 194.34a8 8 0 0 1-11.32 11.32L128 139.31l-66.34 66.35a8 8 0 0 1-11.32-11.32L116.69 128L50.34 61.66a8 8 0 0 1 11.32-11.32L128 116.69l66.34-66.35a8 8 0 0 1 11.32 11.32L139.31 128Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:bug-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M208 128v16a80 80 0 0 1-160 0v-16Z' opacity='.2'/%3E%3Cpath d='M144 92a12 12 0 1 1 12 12a12 12 0 0 1-12-12m-44-12a12 12 0 1 0 12 12a12 12 0 0 0-12-12m116 64a87.8 87.8 0 0 1-3 23l22.24 9.72A8 8 0 0 1 232 192a7.9 7.9 0 0 1-3.2-.67L207.38 182a88 88 0 0 1-158.76 0l-21.42 9.33a7.9 7.9 0 0 1-3.2.67a8 8 0 0 1-3.2-15.33L43 167a87.8 87.8 0 0 1-3-23v-8H16a8 8 0 0 1 0-16h24v-8a87.8 87.8 0 0 1 3-23l-22.2-9.67a8 8 0 1 1 6.4-14.66L48.62 74a88 88 0 0 1 158.76 0l21.42-9.36a8 8 0 0 1 6.4 14.66L213 89.05a87.8 87.8 0 0 1 3 23v8h24a8 8 0 0 1 0 16h-24ZM56 120h144v-8a72 72 0 0 0-144 0Zm64 95.54V136H56v8a72.08 72.08 0 0 0 64 71.54M200 144v-8h-64v79.54A72.08 72.08 0 0 0 200 144'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:check-circle-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M173.66 98.34a8 8 0 0 1 0 11.32l-56 56a8 8 0 0 1-11.32 0l-24-24a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 0M232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:globe-simple-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M128 24a104 104 0 1 0 104 104A104.12 104.12 0 0 0 128 24m87.62 96h-39.83c-1.79-36.51-15.85-62.33-27.38-77.6a88.19 88.19 0 0 1 67.22 77.6ZM96.23 136h63.54c-2.31 41.61-22.23 67.11-31.77 77c-9.55-9.9-29.46-35.4-31.77-77m0-16c2.31-41.61 22.23-67.11 31.77-77c9.55 9.93 29.46 35.43 31.77 77Zm11.36-77.6C96.06 57.67 82 83.49 80.21 120H40.37a88.19 88.19 0 0 1 67.22-77.6M40.37 136h39.84c1.82 36.51 15.85 62.33 27.38 77.6A88.19 88.19 0 0 1 40.37 136m108 77.6c11.53-15.27 25.56-41.09 27.38-77.6h39.84a88.19 88.19 0 0 1-67.18 77.6Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:hexagon-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 80.18v95.64a8 8 0 0 1-4.16 7l-88 48.18a8 8 0 0 1-7.68 0l-88-48.18a8 8 0 0 1-4.16-7V80.18a8 8 0 0 1 4.16-7l88-48.18a8 8 0 0 1 7.68 0l88 48.18a8 8 0 0 1 4.16 7' opacity='.2'/%3E%3Cpath d='m223.68 66.15l-88-48.15a15.88 15.88 0 0 0-15.36 0l-88 48.17a16 16 0 0 0-8.32 14v95.64a16 16 0 0 0 8.32 14l88 48.17a15.88 15.88 0 0 0 15.36 0l88-48.17a16 16 0 0 0 8.32-14V80.18a16 16 0 0 0-8.32-14.03M216 175.82L128 224l-88-48.18V80.18L128 32l88 48.17Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:info-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M144 176a8 8 0 0 1-8 8a16 16 0 0 1-16-16v-40a8 8 0 0 1 0-16a16 16 0 0 1 16 16v40a8 8 0 0 1 8 8m88-48A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88m-92-32a12 12 0 1 0-12-12a12 12 0 0 0 12 12'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:x-circle-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M165.66 101.66L139.31 128l26.35 26.34a8 8 0 0 1-11.32 11.32L128 139.31l-26.34 26.35a8 8 0 0 1-11.32-11.32L116.69 128l-26.35-26.34a8 8 0 0 1 11.32-11.32L128 116.69l26.34-26.35a8 8 0 0 1 11.32 11.32M232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-svg-spinners-8-dots-rotate{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg%3E%3Ccircle cx='3' cy='12' r='2' fill='currentColor'/%3E%3Ccircle cx='21' cy='12' r='2' fill='currentColor'/%3E%3Ccircle cx='12' cy='21' r='2' fill='currentColor'/%3E%3Ccircle cx='12' cy='3' r='2' fill='currentColor'/%3E%3Ccircle cx='5.64' cy='5.64' r='2' fill='currentColor'/%3E%3Ccircle cx='18.36' cy='18.36' r='2' fill='currentColor'/%3E%3Ccircle cx='5.64' cy='18.36' r='2' fill='currentColor'/%3E%3Ccircle cx='18.36' cy='5.64' r='2' fill='currentColor'/%3E%3CanimateTransform attributeName='transform' dur='1.5s' repeatCount='indefinite' type='rotate' values='0 12 12;360 12 12'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.container{width:100%}.z-command-palette{z-index:2147483646}.z-floating-anchor{z-index:2147483644}.z-floating-tooltip{z-index:2147483645}.border-base{--vdt-border-opacity:.13;border-color:rgba(136,136,136,var(--vdt-border-opacity))}.hover\\:border-base:hover{--vdt-border-opacity:.13;border-color:rgba(136,136,136,var(--vdt-border-opacity))}.bg-active{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.bg-base{--vdt-bg-opacity:1;background-color:rgba(255,255,255,var(--vdt-bg-opacity))}.bg-glass{--vdt-backdrop-blur:blur(7px);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia);background-color:rgba(255,255,255,.5)}.bg-glass\\:75{--vdt-backdrop-blur:blur(7px);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia);background-color:rgba(255,255,255,.75)}.bg-secondary{--vdt-bg-opacity:1;background-color:rgba(238,238,238,var(--vdt-bg-opacity))}.hover\\:bg-active:hover{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.color-base{--vdt-text-opacity:1;color:rgba(38,38,38,var(--vdt-text-opacity))}@media (prefers-color-scheme:dark){.bg-base{--vdt-bg-opacity:1;background-color:rgba(17,17,17,var(--vdt-bg-opacity))}.bg-glass{background-color:rgba(17,17,17,.5)}.bg-glass\\:75{background-color:rgba(17,17,17,.75)}.bg-secondary{--vdt-bg-opacity:1;background-color:rgba(34,34,34,var(--vdt-bg-opacity))}.color-base{--vdt-text-opacity:1;color:rgba(229,229,229,var(--vdt-text-opacity))}}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.disabled\\:pointer-events-none:disabled{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{top:0;bottom:0;left:0;right:0}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.bottom-4px{bottom:4px}.left--1{left:-.25rem}.left-0{left:0}.left-1\\/2{left:50%}.left-2{left:.5rem}.left-5px{left:5px}.right--1{right:-.25rem}.right--1px{right:-1px}.right-0{right:0}.right-0\\.5{right:.125rem}.right-2{right:.5rem}.right-4{right:1rem}.top--32px{top:-32px}.top-0\\.5{top:.125rem}.top-1{top:.25rem}.top-1\\/2{top:50%}.top-4px{top:4px}.z--1{z-index:-1}.z-2147483647{z-index:2147483647}.grid{display:grid}.cols-\\[max-content_1fr\\]{grid-template-columns:max-content 1fr}.m-auto,.ma{margin:auto}.m1{margin:.25rem}.mx--1{margin-left:-.25rem;margin-right:-.25rem}.mx--2{margin-left:-.5rem;margin-right:-.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my0\\.5{margin-top:.125rem;margin-bottom:.125rem}.mb-1\\.5{margin-bottom:.375rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-2{margin-left:.5rem}.ml-6{margin-left:1.5rem}.mr-1{margin-right:.25rem}.mt-0\\.5{margin-top:.125rem}.mt-1\\.5{margin-top:.375rem}.mt-6,.mt6{margin-top:1.5rem}.mt2{margin-top:.5rem}.mt4{margin-top:1rem}.box-border{box-sizing:border-box}.inline{display:inline}.block{display:block}.hidden{display:none}.h-0\\.5{height:.125rem}.h-1\\.5{height:.375rem}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-20px{height:20px}.h-24{height:6rem}.h-3{height:.75rem}.h-3\\.5{height:.875rem}.h-4{height:1rem}.h-4\\.5{height:1.125rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\\[60vh\\]{max-height:60vh}.max-w-108{max-width:27rem}.max-w-200{max-width:50rem}.max-w-220px{max-width:220px}.max-w-64{max-width:16rem}.max-w-92{max-width:23rem}.max-w-96{max-width:24rem}.min-h-0{min-height:0}.min-h-5{min-height:1.25rem}.min-w-0{min-width:0}.min-w-28{min-width:7rem}.min-w-36{min-width:9rem}.min-w-44{min-width:11rem}.w-\\[40px\\]{width:40px}.w-1\\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-2\\.5{width:.625rem}.w-20px{width:20px}.w-24{width:6rem}.w-2px{width:2px}.w-3{width:.75rem}.w-3\\.5{width:.875rem}.w-4{width:1rem}.w-4\\.5{width:1.125rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-96{width:24rem}.w-fit{width:fit-content}.w-full{width:100%}.w-lg{width:32rem}.w-max{width:max-content}.w-px{width:1px}.w-screen{width:100vw}.flex{display:flex}.inline-flex{display:inline-flex}.flex-1{flex:1}.flex-auto{flex:auto}.flex-none{flex:none}.shrink-0{flex-shrink:0}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.-translate-y-2{--vdt-translate-y:-.5rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x--1\\/2{--vdt-translate-x:-50%;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x-1{--vdt-translate-x:.25rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x-4{--vdt-translate-x:1rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x-5{--vdt-translate-x:1.25rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-y--1\\/2{--vdt-translate-y:-50%;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-y-0{--vdt-translate-y:0;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate--45{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:-45deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-0{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:0deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-180{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:180deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-270{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:270deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-90{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:90deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-100{--vdt-scale-x:1;--vdt-scale-y:1;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-120{--vdt-scale-x:1.2;--vdt-scale-y:1.2;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-98{--vdt-scale-x:.98;--vdt-scale-y:.98;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.hover\\:scale-110:hover{--vdt-scale-x:1.1;--vdt-scale-y:1.1;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-y--100{--vdt-scale-y:-1;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.transform{transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-not-allowed{cursor:not-allowed}.cursor-grab{cursor:grab}.select-none{user-select:none}.resize{resize:both}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-0\\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-2{column-gap:.5rem}.gap-y-0\\.5{row-gap:.125rem}.space-y-0\\.5>:not([hidden])~:not([hidden]){--vdt-space-y-reverse:0;margin-top:calc(.125rem * calc(1 - var(--vdt-space-y-reverse)));margin-bottom:calc(.125rem * var(--vdt-space-y-reverse))}.of-hidden,.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.of-x-hidden{overflow-x:hidden}.of-y-auto{overflow-y:auto}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.whitespace-pre-wrap{white-space:pre-wrap}.ws-nowrap{white-space:nowrap}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-0{border-bottom-width:0}.border-b-1\\.5{border-bottom-width:1.5px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-r-1\\.5{border-right-width:1.5px}.border-t{border-top-width:1px}.border-t-0{border-top-width:0}.last\\:border-b-0:last-child{border-bottom-width:0}.border-amber\\/20{border-color:rgba(251,191,36,.2)}.border-current{border-color:currentColor}.border-primary-400\\/60{border-color:rgba(144,163,254,.6)}.border-primary\\/30{border-color:rgba(107,132,253,.3)}.border-red-500\\/70{border-color:rgba(239,68,68,.7)}.border-transparent{border-color:transparent}.focus-within\\:border-gray\\/15:focus-within{border-color:rgba(156,163,175,.15)}.hover\\:border-gray\\/10:hover{border-color:rgba(156,163,175,.1)}.focus\\:border-primary-500:focus{--vdt-border-opacity:1;border-color:rgba(107,132,253,var(--vdt-border-opacity))}.focus\\:border-primary\\/40:focus{border-color:rgba(107,132,253,.4)}.border-t-transparent{border-top-color:transparent}.rounded{-webkit-border-radius:.25rem;border-radius:.25rem}.rounded-full{-webkit-border-radius:9999px;border-radius:9999px}.rounded-lg{-webkit-border-radius:.5rem;border-radius:.5rem}.rounded-md{-webkit-border-radius:.375rem;border-radius:.375rem}.rounded-xl{-webkit-border-radius:.75rem;border-radius:.75rem}.rounded-r{-webkit-border-top-right-radius:.25rem;border-top-right-radius:.25rem;-webkit-border-bottom-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-t-md{-webkit-border-top-left-radius:.375rem;border-top-left-radius:.375rem;-webkit-border-top-right-radius:.375rem;border-top-right-radius:.375rem}.bg-\\[\\#8881\\]{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.bg-amber{--vdt-bg-opacity:1;background-color:rgba(251,191,36,var(--vdt-bg-opacity))}.bg-amber\\/10{background-color:rgba(251,191,36,.1)}.bg-black\\/30{background-color:rgba(0,0,0,.3)}.bg-blue{--vdt-bg-opacity:1;background-color:rgba(96,165,250,var(--vdt-bg-opacity))}.bg-blue\\/10{background-color:rgba(96,165,250,.1)}.bg-gray{--vdt-bg-opacity:1;background-color:rgba(156,163,175,var(--vdt-bg-opacity))}.bg-gray-6{--vdt-bg-opacity:1;background-color:rgba(75,85,99,var(--vdt-bg-opacity))}.bg-gray\\/10{background-color:rgba(156,163,175,.1)}.bg-gray\\/20{background-color:rgba(156,163,175,.2)}.bg-gray\\/3{background-color:rgba(156,163,175,.03)}.bg-gray\\/30{background-color:rgba(156,163,175,.3)}.bg-gray\\/5{background-color:rgba(156,163,175,.05)}.bg-green{--vdt-bg-opacity:1;background-color:rgba(74,222,128,var(--vdt-bg-opacity))}.bg-orange\\/10{background-color:rgba(251,146,60,.1)}.bg-primary{--vdt-bg-opacity:1;background-color:rgba(107,132,253,var(--vdt-bg-opacity))}.bg-primary-500\\/20,.bg-primary\\/20{background-color:rgba(107,132,253,.2)}.bg-primary-600{--vdt-bg-opacity:1;background-color:rgba(94,116,223,var(--vdt-bg-opacity))}.bg-primary\\/10{background-color:rgba(107,132,253,.1)}.bg-primary\\/15{background-color:rgba(107,132,253,.15)}.bg-red{--vdt-bg-opacity:1;background-color:rgba(248,113,113,var(--vdt-bg-opacity))}.bg-red-500\\/12{background-color:rgba(239,68,68,.12)}.bg-red\\/10{background-color:rgba(248,113,113,.1)}.bg-transparent{background-color:transparent}.bg-white{--vdt-bg-opacity:1;background-color:rgba(255,255,255,var(--vdt-bg-opacity))}.bg-white\\/50{background-color:rgba(255,255,255,.5)}.hover\\:bg-\\[\\#8881\\]:hover{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.hover\\:bg-\\[\\#8882\\]:hover{--vdt-bg-opacity:.13;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.hover\\:bg-\\[\\#8883\\]:hover{--vdt-bg-opacity:.2;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.hover\\:bg-gray\\/10:hover{background-color:rgba(156,163,175,.1)}.hover\\:bg-gray\\/15:hover{background-color:rgba(156,163,175,.15)}.hover\\:bg-gray\\/20:hover{background-color:rgba(156,163,175,.2)}.hover\\:bg-gray\\/5:hover{background-color:rgba(156,163,175,.05)}.hover\\:bg-orange\\/20:hover{background-color:rgba(251,146,60,.2)}.hover\\:bg-primary-700:hover{--vdt-bg-opacity:1;background-color:rgba(77,95,182,var(--vdt-bg-opacity))}.hover\\:bg-primary\\/20:hover{background-color:rgba(107,132,253,.2)}.hover\\:bg-primary\\/25:hover{background-color:rgba(107,132,253,.25)}.hover\\:bg-red-500\\/20:hover{background-color:rgba(239,68,68,.2)}.hover\\:bg-red\\/20:hover{background-color:rgba(248,113,113,.2)}.fill-black{--vdt-fill-opacity:1;fill:rgba(0,0,0,var(--vdt-fill-opacity))}.fill-hex-08060D{--vdt-fill-opacity:1;fill:rgba(8,6,13,var(--vdt-fill-opacity))}.p-0\\.5{padding:.125rem}.p-1\\.5,.p1\\.5{padding:.375rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p1{padding:.25rem}.p2{padding:.5rem}.p6{padding:1.5rem}.p8{padding:2rem}.px,.px-4,.px4{padding-left:1rem;padding-right:1rem}.px-0\\.5{padding-left:.125rem;padding-right:.125rem}.px-1,.px1{padding-left:.25rem;padding-right:.25rem}.px-1\\.5{padding-left:.375rem;padding-right:.375rem}.px-2,.px2{padding-left:.5rem;padding-right:.5rem}.px-2\\.5{padding-left:.625rem;padding-right:.625rem}.px-3,.px3{padding-left:.75rem;padding-right:.75rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-top:0;padding-bottom:0}.py-0\\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1,.py1{padding-top:.25rem;padding-bottom:.25rem}.py-1\\.5,.py1\\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2,.py2{padding-top:.5rem;padding-bottom:.5rem}.py-2\\.5,.py2\\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb2\\.5{padding-bottom:.625rem}.pl-6{padding-left:1.5rem}.pt-\\[20vh\\]{padding-top:20vh}.pt-6{padding-top:1.5rem}.pt2{padding-top:.5rem}.text-center{text-align:center}.text-left{text-align:left}.indent{text-indent:1.5rem}.text-\\[10px\\]{font-size:10px}.text-\\[15px\\]{font-size:15px}.text-0\\.6em{font-size:.6em}.text-2\\.75{font-size:.6875rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-amber{--vdt-text-opacity:1;color:rgba(251,191,36,var(--vdt-text-opacity))}.text-amber-800{--vdt-text-opacity:1;color:rgba(146,64,14,var(--vdt-text-opacity))}.text-blue{--vdt-text-opacity:1;color:rgba(96,165,250,var(--vdt-text-opacity))}.text-gray{--vdt-text-opacity:1;color:rgba(156,163,175,var(--vdt-text-opacity))}.text-green{--vdt-text-opacity:1;color:rgba(74,222,128,var(--vdt-text-opacity))}.text-green-800{--vdt-text-opacity:1;color:rgba(22,101,52,var(--vdt-text-opacity))}.text-orange{--vdt-text-opacity:1;color:rgba(251,146,60,var(--vdt-text-opacity))}.text-primary{--vdt-text-opacity:1;color:rgba(107,132,253,var(--vdt-text-opacity))}.text-primary-600{--vdt-text-opacity:1;color:rgba(94,116,223,var(--vdt-text-opacity))}.text-primary-700{--vdt-text-opacity:1;color:rgba(77,95,182,var(--vdt-text-opacity))}.text-red{--vdt-text-opacity:1;color:rgba(248,113,113,var(--vdt-text-opacity))}.text-red-500{--vdt-text-opacity:1;color:rgba(239,68,68,var(--vdt-text-opacity))}.text-red-600{--vdt-text-opacity:1;color:rgba(220,38,38,var(--vdt-text-opacity))}.text-white{--vdt-text-opacity:1;color:rgba(255,255,255,var(--vdt-text-opacity))}.font-bold{font-weight:700}.font-medium{font-weight:500}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.tabular-nums{--vdt-numeric-spacing:tabular-nums;font-variant-numeric:var(--vdt-ordinal) var(--vdt-slashed-zero) var(--vdt-numeric-figure) var(--vdt-numeric-spacing) var(--vdt-numeric-fraction)}.line-through{text-decoration-line:line-through}.tab{tab-size:4}.caret-primary-500{--vdt-caret-opacity:1;caret-color:rgba(107,132,253,var(--vdt-caret-opacity))}.op0,.opacity-0{opacity:0}.op100,.opacity-100{opacity:1}.group:hover .group-hover\\:opacity-100{opacity:1}.op25{opacity:.25}.op30{opacity:.3}.op40{opacity:.4}.op50{opacity:.5}.group:hover .group-hover\\:op50{opacity:.5}.op60{opacity:.6}.op60\\!{opacity:.6!important}.op70{opacity:.7}.op75{opacity:.75}.op80{opacity:.8}.hover\\:op100:hover{opacity:1}.hover\\:op60:hover{opacity:.6}.hover\\:op70:hover{opacity:.7}.hover\\:op80:hover{opacity:.8}.disabled\\:op40:disabled{opacity:.4}.disabled\\:op50:disabled{opacity:.5}.shadow{--vdt-shadow:var(--vdt-shadow-inset) 0 1px 3px 0 var(--vdt-shadow-color,rgba(0,0,0,.1)),var(--vdt-shadow-inset) 0 1px 2px -1px var(--vdt-shadow-color,rgba(0,0,0,.1));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.shadow-sm{--vdt-shadow:var(--vdt-shadow-inset) 0 1px 2px 0 var(--vdt-shadow-color,rgba(0,0,0,.05));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.shadow-xl{--vdt-shadow:var(--vdt-shadow-inset) 0 20px 25px -5px var(--vdt-shadow-color,rgba(0,0,0,.1)),var(--vdt-shadow-inset) 0 8px 10px -6px var(--vdt-shadow-color,rgba(0,0,0,.1));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.outline{outline-style:solid}.outline-none{outline-offset:2px;outline:2px solid transparent}.ring-1\\.5{--vdt-ring-width:1.5px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.focus\\:ring-1:focus{--vdt-ring-width:1px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.focus\\:ring-3:focus{--vdt-ring-width:3px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.focus-visible\\:ring-3:focus-visible{--vdt-ring-width:3px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.ring-purple\\/50{--vdt-ring-color:rgba(192,132,252,.5)}.focus\\:ring-primary-500\\/25:focus{--vdt-ring-color:rgba(107,132,253,.25)}.focus\\:ring-primary\\/30:focus{--vdt-ring-color:rgba(107,132,253,.3)}.focus-visible\\:ring-primary-500\\/30:focus-visible{--vdt-ring-color:rgba(107,132,253,.3)}.focus-visible\\:ring-primary-500\\/40:focus-visible{--vdt-ring-color:rgba(107,132,253,.4)}.focus-visible\\:ring-red-500\\/30:focus-visible{--vdt-ring-color:rgba(239,68,68,.3)}.backdrop-blur-0{--vdt-backdrop-blur:blur(0);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia)}.backdrop-blur-1{--vdt-backdrop-blur:blur(1px);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia)}.blur-2xl{--vdt-blur:blur(40px);filter:var(--vdt-blur) var(--vdt-brightness) var(--vdt-contrast) var(--vdt-drop-shadow) var(--vdt-grayscale) var(--vdt-hue-rotate) var(--vdt-invert) var(--vdt-saturate) var(--vdt-sepia)}.saturate-0{--vdt-saturate:saturate(0);filter:var(--vdt-blur) var(--vdt-brightness) var(--vdt-contrast) var(--vdt-drop-shadow) var(--vdt-grayscale) var(--vdt-hue-rotate) var(--vdt-invert) var(--vdt-saturate) var(--vdt-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-property:transform;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.delay-200{transition-delay:.2s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}@media (prefers-color-scheme:dark){.dark-hidden{display:none}.dark\\:border-primary-400\\/50{border-color:rgba(144,163,254,.5)}.dark\\:bg-black\\/30{background-color:rgba(0,0,0,.3)}.dark\\:bg-black\\/45{background-color:rgba(0,0,0,.45)}.dark\\:fill-hex-fff,.dark\\:fill-white{--vdt-fill-opacity:1;fill:rgba(255,255,255,var(--vdt-fill-opacity))}.dark\\:text-amber-200{--vdt-text-opacity:1;color:rgba(253,230,138,var(--vdt-text-opacity))}.dark\\:text-green-200{--vdt-text-opacity:1;color:rgba(187,247,208,var(--vdt-text-opacity))}.dark\\:text-primary-300{--vdt-text-opacity:1;color:rgba(181,194,254,var(--vdt-text-opacity))}.dark\\:text-red-400{--vdt-text-opacity:1;color:rgba(248,113,113,var(--vdt-text-opacity))}}@media (prefers-color-scheme:light){.light-hidden{display:none}}@media (min-width:640px){.sm\\:gap-2\\.5{gap:.625rem}}" +export default "*{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:before{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:after{box-sizing:border-box;border-style:solid;border-width:0;border-color:var(--un-default-border-color,#e5e7eb)}:before{--un-content:\"\"}:after{--un-content:\"\"}html{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button{-webkit-appearance:button;background-color:transparent;background-image:none}[type=button]{-webkit-appearance:button;background-color:transparent;background-image:none}[type=reset]{-webkit-appearance:button;background-color:transparent;background-image:none}[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::placeholder{opacity:1;color:#9ca3af}textarea::placeholder{opacity:1;color:#9ca3af}button{cursor:pointer}[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--un-text-opacity:100%}#vite-devtools-anchor{z-index:2147483644;box-sizing:border-box;transform-origin:50%;width:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:15px;position:fixed;transform:translate(-50%,-50%)rotate(0)}#vite-devtools-anchor #vite-devtools-dock-container{width:max-content;height:var(--vite-devtools-dock-height,40px);min-width:var(--vite-devtools-dock-min-width,100px);display:flex;position:absolute;top:0;left:0;transform:translate(-50%,-50%)}#vite-devtools-anchor.vite-devtools-vertical #vite-devtools-dock-container{transition-property:all;transition-duration:.5s;transition-timing-function:cubic-bezier(.4,0,.2,1);transform:translate(-50%,-50%)rotate(90deg)}#vite-devtools-anchor #vite-devtools-dock{touch-action:none;user-select:none;--vdt-backdrop-blur:blur(7px);height:100%;backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia);--vdt-text-opacity:1;color:rgba(51,51,51,var(--vdt-text-opacity));--vdt-shadow:var(--vdt-shadow-inset) 0 1px 3px 0 var(--vdt-shadow-color,rgba(0,0,0,.1)),var(--vdt-shadow-inset) 0 1px 2px -1px var(--vdt-shadow-color,rgba(0,0,0,.1));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow);height:var(--vite-devtools-dock-height,40px);width:calc-size(max-content, size);background-color:rgba(255,255,255,.5);-webkit-border-radius:9999px;border-radius:9999px;margin:auto;transition-property:all;transition-duration:.5s;transition-timing-function:cubic-bezier(.4,0,.2,1)}@media (prefers-color-scheme:dark){#vite-devtools-anchor #vite-devtools-dock{--vdt-text-opacity:1;color:rgba(255,255,255,var(--vdt-text-opacity));background-color:rgba(17,17,17,.5)}}#vite-devtools-anchor.vite-devtools-minimized #vite-devtools-dock{width:var(--vite-devtools-dock-minimized-size,22px);height:var(--vite-devtools-dock-minimized-size,22px);padding:2px 0}#vite-devtools-anchor.vite-devtools-minimized .vite-devtools-dock-bracket{opacity:.5;width:.375rem}#vite-devtools-anchor:hover #vite-devtools-glowing{opacity:.6}#vite-devtools-anchor #vite-devtools-glowing{pointer-events:none;z-index:-1;opacity:0;width:var(--vite-devtools-dock-glow-size,160px);height:var(--vite-devtools-dock-glow-size,160px);filter:blur(var(--vite-devtools-dock-glow-blur,60px));background-image:linear-gradient(45deg,#61d9ff,#6b84fd,#715ebd);-webkit-border-radius:9999px;border-radius:9999px;transition-property:all;transition-duration:1s;transition-timing-function:cubic-bezier(0,0,.2,1);position:absolute;top:0;left:0;transform:translate(-50%,-50%)}@media print{#vite-devtools-anchor{display:none}}.vite-devtools-resize-handle-horizontal{cursor:ns-resize;-webkit-border-radius:.375rem;border-radius:.375rem;height:10px;margin-top:-5px;margin-bottom:-5px;position:absolute;left:6px;right:6px}.vite-devtools-resize-handle-vertical{cursor:ew-resize;-webkit-border-radius:.375rem;border-radius:.375rem;width:10px;margin-left:-5px;margin-right:-5px;position:absolute;top:6px;bottom:0}.vite-devtools-resize-handle-corner{-webkit-border-radius:.375rem;border-radius:.375rem;width:14px;height:14px;margin:-6px;position:absolute}.vite-devtools-resize-handle{z-index:30}.vite-devtools-resize-handle:hover{background-color:rgba(156,163,175,.1)}@keyframes vite-devtools-shake{0%,to{transform:translate(0)}20%,60%{transform:translate(-5px)}40%,80%{transform:translate(5px)}}.vite-devtools-shake{animation:.4s cubic-bezier(.36,.07,.19,.97) vite-devtools-shake}@media (prefers-reduced-motion:reduce){.vite-devtools-shake{animation:none}}*{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }:before{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }:after{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }::backdrop{--vdt-rotate:0;--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-scale-x:1;--vdt-scale-y:1;--vdt-scale-z:1;--vdt-skew-x:0;--vdt-skew-y:0;--vdt-translate-x:0;--vdt-translate-y:0;--vdt-translate-z:0;--vdt-pan-x: ;--vdt-pan-y: ;--vdt-pinch-zoom: ;--vdt-scroll-snap-strictness:proximity;--vdt-ordinal: ;--vdt-slashed-zero: ;--vdt-numeric-figure: ;--vdt-numeric-spacing: ;--vdt-numeric-fraction: ;--vdt-border-spacing-x:0;--vdt-border-spacing-y:0;--vdt-ring-offset-shadow:0 0 transparent;--vdt-ring-shadow:0 0 transparent;--vdt-shadow-inset: ;--vdt-shadow:0 0 transparent;--vdt-ring-inset: ;--vdt-ring-offset-width:0px;--vdt-ring-offset-color:#fff;--vdt-ring-width:0px;--vdt-ring-color:rgba(147,197,253,.5);--vdt-blur: ;--vdt-brightness: ;--vdt-contrast: ;--vdt-drop-shadow: ;--vdt-grayscale: ;--vdt-hue-rotate: ;--vdt-invert: ;--vdt-saturate: ;--vdt-sepia: ;--vdt-backdrop-blur: ;--vdt-backdrop-brightness: ;--vdt-backdrop-contrast: ;--vdt-backdrop-grayscale: ;--vdt-backdrop-hue-rotate: ;--vdt-backdrop-invert: ;--vdt-backdrop-opacity: ;--vdt-backdrop-saturate: ;--vdt-backdrop-sepia: }.i-fluent-emoji-flat-warning{background:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 32 32' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none'%3E%3Cpath fill='%23FFB02E' d='m14.839 5.668l-12.66 21.93c-.51.89.13 2.01 1.16 2.01h25.32c1.03 0 1.67-1.11 1.16-2.01l-12.66-21.93c-.52-.89-1.8-.89-2.32 0'/%3E%3Cpath fill='%23000' d='M14.599 21.498a1.4 1.4 0 1 0 2.8-.01v-9.16c0-.77-.62-1.4-1.4-1.4c-.77 0-1.4.62-1.4 1.4zm2.8 3.98a1.4 1.4 0 1 1-2.8 0a1.4 1.4 0 0 1 2.8 0'/%3E%3C/g%3E%3C/svg%3E\") 0 0/100% 100% no-repeat;width:1em;height:1em}.i-ph-arrow-clockwise{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M240 56v48a8 8 0 0 1-8 8h-48a8 8 0 0 1 0-16h27.4l-26.59-24.36l-.25-.24a80 80 0 1 0-1.67 114.78a8 8 0 0 1 11 11.63A95.44 95.44 0 0 1 128 224h-1.32a96 96 0 1 1 69.07-164L224 85.8V56a8 8 0 1 1 16 0'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrow-clockwise-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 128a88 88 0 1 1-88-88a88 88 0 0 1 88 88' opacity='.2'/%3E%3Cpath d='M240 56v48a8 8 0 0 1-8 8h-48a8 8 0 0 1 0-16h27.4l-26.59-24.36l-.25-.24a80 80 0 1 0-1.67 114.78a8 8 0 0 1 11 11.63A95.44 95.44 0 0 1 128 224h-1.32a96 96 0 1 1 69.07-164L224 85.8V56a8 8 0 1 1 16 0'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrow-counter-clockwise{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M224 128a96 96 0 0 1-94.71 96H128a95.38 95.38 0 0 1-65.9-26.2a8 8 0 0 1 11-11.63a80 80 0 1 0-1.67-114.78a3 3 0 0 1-.26.25L44.59 96H72a8 8 0 0 1 0 16H24a8 8 0 0 1-8-8V56a8 8 0 0 1 16 0v29.8L60.25 60A96 96 0 0 1 224 128'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrow-square-out-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M184 80v128a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8V80a8 8 0 0 1 8-8h128a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M224 104a8 8 0 0 1-16 0V59.32l-66.33 66.34a8 8 0 0 1-11.32-11.32L196.68 48H152a8 8 0 0 1 0-16h64a8 8 0 0 1 8 8Zm-40 24a8 8 0 0 0-8 8v72H48V80h72a8 8 0 0 0 0-16H48a16 16 0 0 0-16 16v128a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-72a8 8 0 0 0-8-8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrows-counter-clockwise-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 128a88 88 0 1 1-88-88a88 88 0 0 1 88 88' opacity='.2'/%3E%3Cpath d='M88 104H40a8 8 0 0 1-8-8V48a8 8 0 0 1 16 0v28.69l14.63-14.63A95.43 95.43 0 0 1 130 33.94h.53a95.36 95.36 0 0 1 67.07 27.33a8 8 0 0 1-11.18 11.44a79.52 79.52 0 0 0-55.89-22.77h-.45a79.56 79.56 0 0 0-56.14 23.43L59.31 88H88a8 8 0 0 1 0 16m128 48h-48a8 8 0 0 0 0 16h28.69l-14.63 14.63a79.56 79.56 0 0 1-56.13 23.43h-.45a79.52 79.52 0 0 1-55.89-22.77a8 8 0 1 0-11.18 11.44a95.36 95.36 0 0 0 67.07 27.33h.52a95.43 95.43 0 0 0 67.36-28.12L208 179.31V208a8 8 0 0 0 16 0v-48a8 8 0 0 0-8-8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-arrows-out-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M208 48v160H48V48Z' opacity='.2'/%3E%3Cpath d='M216 48v48a8 8 0 0 1-16 0V67.31l-42.34 42.35a8 8 0 0 1-11.32-11.32L188.69 56H160a8 8 0 0 1 0-16h48a8 8 0 0 1 8 8M98.34 146.34L56 188.69V160a8 8 0 0 0-16 0v48a8 8 0 0 0 8 8h48a8 8 0 0 0 0-16H67.31l42.35-42.34a8 8 0 0 0-11.32-11.32M208 152a8 8 0 0 0-8 8v28.69l-42.34-42.35a8 8 0 0 0-11.32 11.32L188.69 200H160a8 8 0 0 0 0 16h48a8 8 0 0 0 8-8v-48a8 8 0 0 0-8-8M67.31 56H96a8 8 0 0 0 0-16H48a8 8 0 0 0-8 8v48a8 8 0 0 0 16 0V67.31l42.34 42.35a8 8 0 0 0 11.32-11.32Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-cards-three-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 104v96a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8v-96a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M208 88H48a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16m0 112H48v-96h160zM48 64a8 8 0 0 1 8-8h144a8 8 0 0 1 0 16H56a8 8 0 0 1-8-8m16-32a8 8 0 0 1 8-8h112a8 8 0 0 1 0 16H72a8 8 0 0 1-8-8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-down{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m213.66 101.66l-80 80a8 8 0 0 1-11.32 0l-80-80a8 8 0 0 1 11.32-11.32L128 164.69l74.34-74.35a8 8 0 0 1 11.32 11.32'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-left{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M165.66 202.34a8 8 0 0 1-11.32 11.32l-80-80a8 8 0 0 1 0-11.32l80-80a8 8 0 0 1 11.32 11.32L91.31 128Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-right{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m181.66 133.66l-80 80a8 8 0 0 1-11.32-11.32L164.69 128L90.34 53.66a8 8 0 0 1 11.32-11.32l80 80a8 8 0 0 1 0 11.32'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-caret-up{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M213.66 165.66a8 8 0 0 1-11.32 0L128 91.31l-74.34 74.35a8 8 0 0 1-11.32-11.32l80-80a8 8 0 0 1 11.32 0l80 80a8 8 0 0 1 0 11.32'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-check-bold{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m232.49 80.49l-128 128a12 12 0 0 1-17 0l-56-56a12 12 0 1 1 17-17L96 183L215.51 63.51a12 12 0 0 1 17 17Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-check-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M232 56v144a16 16 0 0 1-16 16H40a16 16 0 0 1-16-16V56a16 16 0 0 1 16-16h176a16 16 0 0 1 16 16' opacity='.2'/%3E%3Cpath d='m205.66 85.66l-96 96a8 8 0 0 1-11.32 0l-40-40a8 8 0 0 1 11.32-11.32L104 164.69l90.34-90.35a8 8 0 0 1 11.32 11.32'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-circle-notch{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M232 128a104 104 0 0 1-208 0c0-41 23.81-78.36 60.66-95.27a8 8 0 0 1 6.68 14.54C60.15 61.59 40 93.27 40 128a88 88 0 0 0 176 0c0-34.73-20.15-66.41-51.34-80.73a8 8 0 0 1 6.68-14.54C208.19 49.64 232 87 232 128'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-dots-six-vertical{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M104 60a12 12 0 1 1-12-12a12 12 0 0 1 12 12m60 12a12 12 0 1 0-12-12a12 12 0 0 0 12 12m-72 44a12 12 0 1 0 12 12a12 12 0 0 0-12-12m72 0a12 12 0 1 0 12 12a12 12 0 0 0-12-12m-72 68a12 12 0 1 0 12 12a12 12 0 0 0-12-12m72 0a12 12 0 1 0 12 12a12 12 0 0 0-12-12'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-eye-slash{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M53.92 34.62a8 8 0 1 0-11.84 10.76l19.24 21.17C25 88.84 9.38 123.2 8.69 124.76a8 8 0 0 0 0 6.5c.35.79 8.82 19.57 27.65 38.4C61.43 194.74 93.12 208 128 208a127.1 127.1 0 0 0 52.07-10.83l22 24.21a8 8 0 1 0 11.84-10.76Zm47.33 75.84l41.67 45.85a32 32 0 0 1-41.67-45.85M128 192c-30.78 0-57.67-11.19-79.93-33.25A133.2 133.2 0 0 1 25 128c4.69-8.79 19.66-33.39 47.35-49.38l18 19.75a48 48 0 0 0 63.66 70l14.73 16.2A112 112 0 0 1 128 192m6-95.43a8 8 0 0 1 3-15.72a48.16 48.16 0 0 1 38.77 42.64a8 8 0 0 1-7.22 8.71a6 6 0 0 1-.75 0a8 8 0 0 1-8-7.26A32.09 32.09 0 0 0 134 96.57m113.28 34.69c-.42.94-10.55 23.37-33.36 43.8a8 8 0 1 1-10.67-11.92a132.8 132.8 0 0 0 27.8-35.14a133.2 133.2 0 0 0-23.12-30.77C185.67 75.19 158.78 64 128 64a118.4 118.4 0 0 0-19.36 1.57A8 8 0 1 1 106 49.79A134 134 0 0 1 128 48c34.88 0 66.57 13.26 91.66 38.35c18.83 18.83 27.3 37.62 27.65 38.41a8 8 0 0 1 0 6.5Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-eye-slash-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M128 56c-80 0-112 72-112 72s32 72 112 72s112-72 112-72s-32-72-112-72m0 112a40 40 0 1 1 40-40a40 40 0 0 1-40 40' opacity='.2'/%3E%3Cpath d='M53.92 34.62a8 8 0 1 0-11.84 10.76l19.24 21.17C25 88.84 9.38 123.2 8.69 124.76a8 8 0 0 0 0 6.5c.35.79 8.82 19.57 27.65 38.4C61.43 194.74 93.12 208 128 208a127.1 127.1 0 0 0 52.07-10.83l22 24.21a8 8 0 1 0 11.84-10.76Zm47.33 75.84l41.67 45.85a32 32 0 0 1-41.67-45.85M128 192c-30.78 0-57.67-11.19-79.93-33.25A133.2 133.2 0 0 1 25 128c4.69-8.79 19.66-33.39 47.35-49.38l18 19.75a48 48 0 0 0 63.66 70l14.73 16.2A112 112 0 0 1 128 192m6-95.43a8 8 0 0 1 3-15.72a48.16 48.16 0 0 1 38.77 42.64a8 8 0 0 1-7.22 8.71a6 6 0 0 1-.75 0a8 8 0 0 1-8-7.26A32.09 32.09 0 0 0 134 96.57m113.28 34.69c-.42.94-10.55 23.37-33.36 43.8a8 8 0 1 1-10.67-11.92a132.8 132.8 0 0 0 27.8-35.14a133.2 133.2 0 0 0-23.12-30.77C185.67 75.19 158.78 64 128 64a118.4 118.4 0 0 0-19.36 1.57A8 8 0 1 1 106 49.79A134 134 0 0 1 128 48c34.88 0 66.57 13.26 91.66 38.35c18.83 18.83 27.3 37.62 27.65 38.41a8 8 0 0 1 0 6.5Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-globe{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M128 24a104 104 0 1 0 104 104A104.12 104.12 0 0 0 128 24m88 104a87.6 87.6 0 0 1-3.33 24h-38.51a157.4 157.4 0 0 0 0-48h38.51a87.6 87.6 0 0 1 3.33 24m-114 40h52a115.1 115.1 0 0 1-26 45a115.3 115.3 0 0 1-26-45m-3.9-16a140.8 140.8 0 0 1 0-48h59.88a140.8 140.8 0 0 1 0 48ZM40 128a87.6 87.6 0 0 1 3.33-24h38.51a157.4 157.4 0 0 0 0 48H43.33A87.6 87.6 0 0 1 40 128m114-40h-52a115.1 115.1 0 0 1 26-45a115.3 115.3 0 0 1 26 45m52.33 0h-35.62a135.3 135.3 0 0 0-22.3-45.6A88.29 88.29 0 0 1 206.37 88Zm-98.74-45.6A135.3 135.3 0 0 0 85.29 88H49.63a88.29 88.29 0 0 1 57.96-45.6M49.63 168h35.66a135.3 135.3 0 0 0 22.3 45.6A88.29 88.29 0 0 1 49.63 168m98.78 45.6a135.3 135.3 0 0 0 22.3-45.6h35.66a88.29 88.29 0 0 1-57.96 45.6'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-keyboard-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M232 64v128a8 8 0 0 1-8 8H32a8 8 0 0 1-8-8V64a8 8 0 0 1 8-8h192a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M224 48H32a16 16 0 0 0-16 16v128a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16V64a16 16 0 0 0-16-16m0 144H32V64h192zm-16-64a8 8 0 0 1-8 8H56a8 8 0 0 1 0-16h144a8 8 0 0 1 8 8m0-32a8 8 0 0 1-8 8H56a8 8 0 0 1 0-16h144a8 8 0 0 1 8 8M72 160a8 8 0 0 1-8 8h-8a8 8 0 0 1 0-16h8a8 8 0 0 1 8 8m96 0a8 8 0 0 1-8 8H96a8 8 0 0 1 0-16h64a8 8 0 0 1 8 8m40 0a8 8 0 0 1-8 8h-8a8 8 0 0 1 0-16h8a8 8 0 0 1 8 8'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-layout-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M104 104v104H40a8 8 0 0 1-8-8v-96Z' opacity='.2'/%3E%3Cpath d='M216 40H40a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h176a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 16v40H40V56ZM40 112h56v88H40Zm176 88H112v-88h104z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-magnifying-glass-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M192 112a80 80 0 1 1-80-80a80 80 0 0 1 80 80' opacity='.2'/%3E%3Cpath d='m229.66 218.34l-50.06-50.06a88.21 88.21 0 1 0-11.32 11.31l50.06 50.07a8 8 0 0 0 11.32-11.32M40 112a72 72 0 1 1 72 72a72.08 72.08 0 0 1-72-72'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-paint-brush-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 32c0 32.81-31.64 67.43-58.64 91.05A84.4 84.4 0 0 0 133 90.64c23.57-27 58.19-58.64 91-58.64' opacity='.2'/%3E%3Cpath d='M232 32a8 8 0 0 0-8-8c-44.08 0-89.31 49.71-114.43 82.63A60 60 0 0 0 32 164c0 30.88-19.54 44.73-20.47 45.37A8 8 0 0 0 16 224h76a60 60 0 0 0 57.37-77.57C182.3 121.31 232 76.08 232 32M92 208H34.63C41.38 198.41 48 183.92 48 164a44 44 0 1 1 44 44m32.42-94.45q5.14-6.66 10.09-12.55A76.2 76.2 0 0 1 155 121.49q-5.9 4.94-12.55 10.09a60.5 60.5 0 0 0-18.03-18.03m42.7-2.68a92.6 92.6 0 0 0-22-22c31.78-34.53 55.75-45 69.9-47.91c-2.85 14.16-13.37 38.13-47.9 69.91'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-push-pin{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m235.32 81.37l-60.69-60.68a16 16 0 0 0-22.63 0l-53.63 53.8c-10.66-3.34-35-7.37-60.4 13.14a16 16 0 0 0-1.29 23.78L85 159.71l-42.66 42.63a8 8 0 0 0 11.32 11.32L96.29 171l48.29 48.29A16 16 0 0 0 155.9 224h1.13a15.93 15.93 0 0 0 11.64-6.33c19.64-26.1 17.75-47.32 13.19-60L235.33 104a16 16 0 0 0-.01-22.63M224 92.69l-57.27 57.46a8 8 0 0 0-1.49 9.22c9.46 18.93-1.8 38.59-9.34 48.62L48 100.08c12.08-9.74 23.64-12.31 32.48-12.31A40.1 40.1 0 0 1 96.81 91a8 8 0 0 0 9.25-1.51L163.32 32L224 92.68Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-push-pin-fill{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='m235.33 104l-53.47 53.65c4.56 12.67 6.45 33.89-13.19 60A15.93 15.93 0 0 1 157 224h-1.13a16 16 0 0 1-11.32-4.69L96.29 171l-42.63 42.66a8 8 0 0 1-11.32-11.32L85 159.71l-48.3-48.3A16 16 0 0 1 38 87.63c25.42-20.51 49.75-16.48 60.4-13.14L152 20.7a16 16 0 0 1 22.63 0l60.69 60.68a16 16 0 0 1 .01 22.62'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-rocket-launch-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M184 120v61.65a8 8 0 0 1-2.34 5.65l-34.35 34.35a8 8 0 0 1-13.57-4.53L128 176Zm-48-48H74.35a8 8 0 0 0-5.65 2.34l-34.35 34.35a8 8 0 0 0 4.53 13.57L80 128ZM40 216c37.65 0 50.69-19.69 54.56-28.18l-26.38-26.38C59.69 165.31 40 178.35 40 216' opacity='.2'/%3E%3Cpath d='M223.85 47.12a16 16 0 0 0-15-15c-12.58-.75-44.73.4-71.41 27.07L132.69 64H74.36A15.9 15.9 0 0 0 63 68.68L28.7 103a16 16 0 0 0 9.07 27.16l38.47 5.37l44.21 44.21l5.37 38.49a15.94 15.94 0 0 0 10.78 12.92a16.1 16.1 0 0 0 5.1.83a15.9 15.9 0 0 0 11.3-4.68l34.32-34.3a15.9 15.9 0 0 0 4.68-11.36v-58.33l4.77-4.77c26.68-26.68 27.83-58.83 27.08-71.42M74.36 80h42.33l-39.53 39.52L40 114.34Zm74.41-9.45a76.65 76.65 0 0 1 59.11-22.47a76.46 76.46 0 0 1-22.42 59.16L128 164.68L91.32 128ZM176 181.64L141.67 216l-5.19-37.17L176 139.31Zm-74.16 9.5C97.34 201 82.29 224 40 224a8 8 0 0 1-8-8c0-42.29 23-57.34 32.86-61.85a8 8 0 0 1 6.64 14.56c-6.43 2.93-20.62 12.36-23.12 38.91c26.55-2.5 36-16.69 38.91-23.12a8 8 0 1 1 14.56 6.64Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-shield-check-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M216 56v56c0 96-88 120-88 120s-88-24-88-120V56a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8' opacity='.2'/%3E%3Cpath d='M208 40H48a16 16 0 0 0-16 16v56c0 52.72 25.52 84.67 46.93 102.19c23.06 18.86 46 25.26 47 25.53a8 8 0 0 0 4.2 0c1-.27 23.91-6.67 47-25.53C198.48 196.67 224 164.72 224 112V56a16 16 0 0 0-16-16m0 72c0 37.07-13.66 67.16-40.6 89.42a129.3 129.3 0 0 1-39.4 22.2a128.3 128.3 0 0 1-38.92-21.81C61.82 179.51 48 149.3 48 112V56h160ZM82.34 141.66a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 11.32l-56 56a8 8 0 0 1-11.32 0Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-sign-out-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 56v144a16 16 0 0 1-16 16H48V40h160a16 16 0 0 1 16 16' opacity='.2'/%3E%3Cpath d='M120 216a8 8 0 0 1-8 8H48a8 8 0 0 1-8-8V40a8 8 0 0 1 8-8h64a8 8 0 0 1 0 16H56v160h56a8 8 0 0 1 8 8m109.66-93.66l-40-40a8 8 0 0 0-11.32 11.32L204.69 120H112a8 8 0 0 0 0 16h92.69l-26.35 26.34a8 8 0 0 0 11.32 11.32l40-40a8 8 0 0 0 0-11.32'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-spinner-gap-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M136 32v32a8 8 0 0 1-16 0V32a8 8 0 0 1 16 0m88 88h-32a8 8 0 0 0 0 16h32a8 8 0 0 0 0-16m-45.09 47.6a8 8 0 0 0-11.31 11.31l22.62 22.63a8 8 0 0 0 11.32-11.32ZM128 184a8 8 0 0 0-8 8v32a8 8 0 0 0 16 0v-32a8 8 0 0 0-8-8m-50.91-16.4l-22.63 22.62a8 8 0 0 0 11.32 11.32l22.62-22.63a8 8 0 0 0-11.31-11.31M72 128a8 8 0 0 0-8-8H32a8 8 0 0 0 0 16h32a8 8 0 0 0 8-8m-6.22-73.54a8 8 0 0 0-11.32 11.32L77.09 88.4A8 8 0 0 0 88.4 77.09Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-square-half-bottom-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M208 128v72a8 8 0 0 1-8 8H56a8 8 0 0 1-8-8v-72Z' opacity='.2'/%3E%3Cpath d='M200 40H56a16 16 0 0 0-16 16v144a16 16 0 0 0 16 16h144a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16m0 16v64H56V56Zm0 144H56v-64h144z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-warning-duotone,.i-ph\\:warning-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M215.46 216H40.54c-12.62 0-20.54-13.21-14.41-23.91l87.46-151.87c6.3-11 22.52-11 28.82 0l87.46 151.87c6.13 10.7-1.79 23.91-14.41 23.91' opacity='.2'/%3E%3Cpath d='M236.8 188.09L149.35 36.22a24.76 24.76 0 0 0-42.7 0L19.2 188.09a23.51 23.51 0 0 0 0 23.72A24.35 24.35 0 0 0 40.55 224h174.9a24.35 24.35 0 0 0 21.33-12.19a23.51 23.51 0 0 0 .02-23.72m-13.87 15.71a8.5 8.5 0 0 1-7.48 4.2H40.55a8.5 8.5 0 0 1-7.48-4.2a7.59 7.59 0 0 1 0-7.72l87.45-151.87a8.75 8.75 0 0 1 15 0l87.45 151.87a7.59 7.59 0 0 1-.04 7.72M120 144v-40a8 8 0 0 1 16 0v40a8 8 0 0 1-16 0m20 36a12 12 0 1 1-12-12a12 12 0 0 1 12 12'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-wrench-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 96a64 64 0 0 1-94.94 56L73 217a24 24 0 0 1-34-34l65-56.06a64 64 0 0 1 80-90.29L144 80l5.66 26.34L176 112l43.35-40A63.8 63.8 0 0 1 224 96' opacity='.2'/%3E%3Cpath d='M226.76 69a8 8 0 0 0-12.84-2.88l-40.3 37.19l-17.23-3.7l-3.7-17.23l37.19-40.3A8 8 0 0 0 187 29.24A72 72 0 0 0 88 96a72.3 72.3 0 0 0 6 28.94L33.79 177c-.15.12-.29.26-.43.39a32 32 0 0 0 45.26 45.26c.13-.13.27-.28.39-.42L131.06 162A72 72 0 0 0 232 96a71.6 71.6 0 0 0-5.24-27M160 152a56.14 56.14 0 0 1-27.07-7a8 8 0 0 0-9.92 1.77l-55.9 64.74a16 16 0 0 1-22.62-22.62L109.18 133a8 8 0 0 0 1.77-9.93a56 56 0 0 1 58.36-82.31l-31.2 33.81a8 8 0 0 0-1.94 7.1l5.66 26.33a8 8 0 0 0 6.14 6.14l26.35 5.66a8 8 0 0 0 7.1-1.94l33.81-31.2A56.06 56.06 0 0 1 160 152'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph-x{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M205.66 194.34a8 8 0 0 1-11.32 11.32L128 139.31l-66.34 66.35a8 8 0 0 1-11.32-11.32L116.69 128L50.34 61.66a8 8 0 0 1 11.32-11.32L128 116.69l66.34-66.35a8 8 0 0 1 11.32 11.32L139.31 128Z'/%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:bug-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M208 128v16a80 80 0 0 1-160 0v-16Z' opacity='.2'/%3E%3Cpath d='M144 92a12 12 0 1 1 12 12a12 12 0 0 1-12-12m-44-12a12 12 0 1 0 12 12a12 12 0 0 0-12-12m116 64a87.8 87.8 0 0 1-3 23l22.24 9.72A8 8 0 0 1 232 192a7.9 7.9 0 0 1-3.2-.67L207.38 182a88 88 0 0 1-158.76 0l-21.42 9.33a7.9 7.9 0 0 1-3.2.67a8 8 0 0 1-3.2-15.33L43 167a87.8 87.8 0 0 1-3-23v-8H16a8 8 0 0 1 0-16h24v-8a87.8 87.8 0 0 1 3-23l-22.2-9.67a8 8 0 1 1 6.4-14.66L48.62 74a88 88 0 0 1 158.76 0l21.42-9.36a8 8 0 0 1 6.4 14.66L213 89.05a87.8 87.8 0 0 1 3 23v8h24a8 8 0 0 1 0 16h-24ZM56 120h144v-8a72 72 0 0 0-144 0Zm64 95.54V136H56v8a72.08 72.08 0 0 0 64 71.54M200 144v-8h-64v79.54A72.08 72.08 0 0 0 200 144'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:check-circle-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M173.66 98.34a8 8 0 0 1 0 11.32l-56 56a8 8 0 0 1-11.32 0l-24-24a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 0M232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:globe-simple-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M128 24a104 104 0 1 0 104 104A104.12 104.12 0 0 0 128 24m87.62 96h-39.83c-1.79-36.51-15.85-62.33-27.38-77.6a88.19 88.19 0 0 1 67.22 77.6ZM96.23 136h63.54c-2.31 41.61-22.23 67.11-31.77 77c-9.55-9.9-29.46-35.4-31.77-77m0-16c2.31-41.61 22.23-67.11 31.77-77c9.55 9.93 29.46 35.43 31.77 77Zm11.36-77.6C96.06 57.67 82 83.49 80.21 120H40.37a88.19 88.19 0 0 1 67.22-77.6M40.37 136h39.84c1.82 36.51 15.85 62.33 27.38 77.6A88.19 88.19 0 0 1 40.37 136m108 77.6c11.53-15.27 25.56-41.09 27.38-77.6h39.84a88.19 88.19 0 0 1-67.18 77.6Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:hexagon-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 80.18v95.64a8 8 0 0 1-4.16 7l-88 48.18a8 8 0 0 1-7.68 0l-88-48.18a8 8 0 0 1-4.16-7V80.18a8 8 0 0 1 4.16-7l88-48.18a8 8 0 0 1 7.68 0l88 48.18a8 8 0 0 1 4.16 7' opacity='.2'/%3E%3Cpath d='m223.68 66.15l-88-48.15a15.88 15.88 0 0 0-15.36 0l-88 48.17a16 16 0 0 0-8.32 14v95.64a16 16 0 0 0 8.32 14l88 48.17a15.88 15.88 0 0 0 15.36 0l88-48.17a16 16 0 0 0 8.32-14V80.18a16 16 0 0 0-8.32-14.03M216 175.82L128 224l-88-48.18V80.18L128 32l88 48.17Z'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:info-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M144 176a8 8 0 0 1-8 8a16 16 0 0 1-16-16v-40a8 8 0 0 1 0-16a16 16 0 0 1 16 16v40a8 8 0 0 1 8 8m88-48A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88m-92-32a12 12 0 1 0-12-12a12 12 0 0 0 12 12'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-ph\\:x-circle-duotone{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='currentColor'%3E%3Cpath d='M224 128a96 96 0 1 1-96-96a96 96 0 0 1 96 96' opacity='.2'/%3E%3Cpath d='M165.66 101.66L139.31 128l26.35 26.34a8 8 0 0 1-11.32 11.32L128 139.31l-26.34 26.35a8 8 0 0 1-11.32-11.32L116.69 128l-26.35-26.34a8 8 0 0 1 11.32-11.32L128 116.69l26.34-26.35a8 8 0 0 1 11.32 11.32M232 128A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-svg-spinners-3-dots-fade{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Ccircle cx='4' cy='12' r='3' fill='currentColor'%3E%3Canimate id='SVG7x14Dcom' fill='freeze' attributeName='opacity' begin='0;SVGqSjG0dUp.end-0.25s' dur='0.75s' values='1;.2'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3' fill='currentColor' opacity='.4'%3E%3Canimate fill='freeze' attributeName='opacity' begin='SVG7x14Dcom.begin+0.15s' dur='0.75s' values='1;.2'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3' fill='currentColor' opacity='.3'%3E%3Canimate id='SVGqSjG0dUp' fill='freeze' attributeName='opacity' begin='SVG7x14Dcom.begin+0.3s' dur='0.75s' values='1;.2'/%3E%3C/circle%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.i-svg-spinners-8-dots-rotate{--vdt-icon:url(\"data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg%3E%3Ccircle cx='3' cy='12' r='2' fill='currentColor'/%3E%3Ccircle cx='21' cy='12' r='2' fill='currentColor'/%3E%3Ccircle cx='12' cy='21' r='2' fill='currentColor'/%3E%3Ccircle cx='12' cy='3' r='2' fill='currentColor'/%3E%3Ccircle cx='5.64' cy='5.64' r='2' fill='currentColor'/%3E%3Ccircle cx='18.36' cy='18.36' r='2' fill='currentColor'/%3E%3Ccircle cx='5.64' cy='18.36' r='2' fill='currentColor'/%3E%3Ccircle cx='18.36' cy='5.64' r='2' fill='currentColor'/%3E%3CanimateTransform attributeName='transform' dur='1.5s' repeatCount='indefinite' type='rotate' values='0 12 12;360 12 12'/%3E%3C/g%3E%3C/svg%3E\");-webkit-mask:var(--vdt-icon) no-repeat;mask:var(--vdt-icon) no-repeat;color:inherit;background-color:currentColor;width:1em;height:1em;mask-size:100% 100%}.container{width:100%}.z-command-palette{z-index:2147483646}.z-floating-anchor{z-index:2147483644}.z-floating-tooltip{z-index:2147483645}.border-base{--vdt-border-opacity:.13;border-color:rgba(136,136,136,var(--vdt-border-opacity))}.hover\\:border-base:hover{--vdt-border-opacity:.13;border-color:rgba(136,136,136,var(--vdt-border-opacity))}.bg-active{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.bg-base{--vdt-bg-opacity:1;background-color:rgba(255,255,255,var(--vdt-bg-opacity))}.bg-glass{--vdt-backdrop-blur:blur(7px);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia);background-color:rgba(255,255,255,.5)}.bg-glass\\:75{--vdt-backdrop-blur:blur(7px);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia);background-color:rgba(255,255,255,.75)}.bg-secondary{--vdt-bg-opacity:1;background-color:rgba(238,238,238,var(--vdt-bg-opacity))}.hover\\:bg-active:hover{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.color-base{--vdt-text-opacity:1;color:rgba(38,38,38,var(--vdt-text-opacity))}@media (prefers-color-scheme:dark){.bg-base{--vdt-bg-opacity:1;background-color:rgba(17,17,17,var(--vdt-bg-opacity))}.bg-glass{background-color:rgba(17,17,17,.5)}.bg-glass\\:75{background-color:rgba(17,17,17,.75)}.bg-secondary{--vdt-bg-opacity:1;background-color:rgba(34,34,34,var(--vdt-bg-opacity))}.color-base{--vdt-text-opacity:1;color:rgba(229,229,229,var(--vdt-text-opacity))}}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.disabled\\:pointer-events-none:disabled{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{top:0;bottom:0;left:0;right:0}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.bottom-4px{bottom:4px}.left--1{left:-.25rem}.left-0{left:0}.left-1\\/2{left:50%}.left-2{left:.5rem}.left-5px{left:5px}.right--1{right:-.25rem}.right--1px{right:-1px}.right-0{right:0}.right-0\\.5{right:.125rem}.right-2{right:.5rem}.right-4{right:1rem}.top--32px{top:-32px}.top-0\\.5{top:.125rem}.top-1{top:.25rem}.top-1\\/2{top:50%}.top-4px{top:4px}.z--1{z-index:-1}.z-2147483647{z-index:2147483647}.grid{display:grid}.cols-\\[max-content_1fr\\]{grid-template-columns:max-content 1fr}.m-auto,.ma{margin:auto}.m1{margin:.25rem}.mx--1{margin-left:-.25rem;margin-right:-.25rem}.mx--2{margin-left:-.5rem;margin-right:-.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my0\\.5{margin-top:.125rem;margin-bottom:.125rem}.mb-1\\.5{margin-bottom:.375rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-2{margin-left:.5rem}.ml-6{margin-left:1.5rem}.mr-1{margin-right:.25rem}.mt-0\\.5{margin-top:.125rem}.mt-1\\.5{margin-top:.375rem}.mt-6,.mt6{margin-top:1.5rem}.mt2{margin-top:.5rem}.mt4{margin-top:1rem}.box-border{box-sizing:border-box}.inline{display:inline}.block{display:block}.hidden{display:none}.h-0\\.5{height:.125rem}.h-1\\.5{height:.375rem}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-20px{height:20px}.h-24{height:6rem}.h-3{height:.75rem}.h-3\\.5{height:.875rem}.h-4{height:1rem}.h-4\\.5{height:1.125rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\\[60vh\\]{max-height:60vh}.max-w-108{max-width:27rem}.max-w-200{max-width:50rem}.max-w-220px{max-width:220px}.max-w-64{max-width:16rem}.max-w-92{max-width:23rem}.max-w-96{max-width:24rem}.max-w-full{max-width:100%}.min-h-0{min-height:0}.min-h-5{min-height:1.25rem}.min-w-0{min-width:0}.min-w-28{min-width:7rem}.min-w-36{min-width:9rem}.min-w-44{min-width:11rem}.w-\\[40px\\]{width:40px}.w-1\\.5{width:.375rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-2\\.5{width:.625rem}.w-20px{width:20px}.w-24{width:6rem}.w-2px{width:2px}.w-3{width:.75rem}.w-3\\.5{width:.875rem}.w-4{width:1rem}.w-4\\.5{width:1.125rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-96{width:24rem}.w-fit{width:fit-content}.w-full{width:100%}.w-lg{width:32rem}.w-max{width:max-content}.w-px{width:1px}.w-screen{width:100vw}.flex{display:flex}.inline-flex{display:inline-flex}.flex-1{flex:1}.flex-auto{flex:auto}.flex-none{flex:none}.shrink-0{flex-shrink:0}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.-translate-y-2{--vdt-translate-y:-.5rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x--1\\/2{--vdt-translate-x:-50%;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x-1{--vdt-translate-x:.25rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x-4{--vdt-translate-x:1rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-x-5{--vdt-translate-x:1.25rem;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-y--1\\/2{--vdt-translate-y:-50%;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.translate-y-0{--vdt-translate-y:0;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate--45{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:-45deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-0{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:0deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-180{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:180deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-270{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:270deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.rotate-90{--vdt-rotate-x:0;--vdt-rotate-y:0;--vdt-rotate-z:0;--vdt-rotate:90deg;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-100{--vdt-scale-x:1;--vdt-scale-y:1;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-120{--vdt-scale-x:1.2;--vdt-scale-y:1.2;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-98{--vdt-scale-x:.98;--vdt-scale-y:.98;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.hover\\:scale-110:hover{--vdt-scale-x:1.1;--vdt-scale-y:1.1;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.scale-y--100{--vdt-scale-y:-1;transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}.transform{transform:translateX(var(--vdt-translate-x)) translateY(var(--vdt-translate-y)) translateZ(var(--vdt-translate-z)) rotate(var(--vdt-rotate)) rotateX(var(--vdt-rotate-x)) rotateY(var(--vdt-rotate-y)) rotateZ(var(--vdt-rotate-z)) skewX(var(--vdt-skew-x)) skewY(var(--vdt-skew-y)) scaleX(var(--vdt-scale-x)) scaleY(var(--vdt-scale-y)) scaleZ(var(--vdt-scale-z))}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-not-allowed{cursor:not-allowed}.cursor-grab{cursor:grab}.select-none{user-select:none}.resize{resize:both}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-0\\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-2{column-gap:.5rem}.gap-y-0\\.5{row-gap:.125rem}.space-y-0\\.5>:not([hidden])~:not([hidden]){--vdt-space-y-reverse:0;margin-top:calc(.125rem * calc(1 - var(--vdt-space-y-reverse)));margin-bottom:calc(.125rem * var(--vdt-space-y-reverse))}.of-hidden,.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.of-x-hidden{overflow-x:hidden}.of-y-auto{overflow-y:auto}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.whitespace-pre-wrap{white-space:pre-wrap}.ws-nowrap{white-space:nowrap}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-0{border-bottom-width:0}.border-b-1\\.5{border-bottom-width:1.5px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-r-1\\.5{border-right-width:1.5px}.border-t{border-top-width:1px}.border-t-0{border-top-width:0}.last\\:border-b-0:last-child{border-bottom-width:0}.border-amber\\/20{border-color:rgba(251,191,36,.2)}.border-current{border-color:currentColor}.border-primary-400\\/60{border-color:rgba(144,163,254,.6)}.border-primary\\/30{border-color:rgba(107,132,253,.3)}.border-red-500\\/70{border-color:rgba(239,68,68,.7)}.border-transparent{border-color:transparent}.focus-within\\:border-gray\\/15:focus-within{border-color:rgba(156,163,175,.15)}.hover\\:border-gray\\/10:hover{border-color:rgba(156,163,175,.1)}.focus\\:border-primary-500:focus{--vdt-border-opacity:1;border-color:rgba(107,132,253,var(--vdt-border-opacity))}.focus\\:border-primary\\/40:focus{border-color:rgba(107,132,253,.4)}.border-t-transparent{border-top-color:transparent}.rounded{-webkit-border-radius:.25rem;border-radius:.25rem}.rounded-full{-webkit-border-radius:9999px;border-radius:9999px}.rounded-lg{-webkit-border-radius:.5rem;border-radius:.5rem}.rounded-md{-webkit-border-radius:.375rem;border-radius:.375rem}.rounded-xl{-webkit-border-radius:.75rem;border-radius:.75rem}.rounded-r{-webkit-border-top-right-radius:.25rem;border-top-right-radius:.25rem;-webkit-border-bottom-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-t-md{-webkit-border-top-left-radius:.375rem;border-top-left-radius:.375rem;-webkit-border-top-right-radius:.375rem;border-top-right-radius:.375rem}.bg-\\[\\#8881\\]{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.bg-amber{--vdt-bg-opacity:1;background-color:rgba(251,191,36,var(--vdt-bg-opacity))}.bg-amber\\/10{background-color:rgba(251,191,36,.1)}.bg-black\\/30{background-color:rgba(0,0,0,.3)}.bg-blue{--vdt-bg-opacity:1;background-color:rgba(96,165,250,var(--vdt-bg-opacity))}.bg-blue\\/10{background-color:rgba(96,165,250,.1)}.bg-gray{--vdt-bg-opacity:1;background-color:rgba(156,163,175,var(--vdt-bg-opacity))}.bg-gray-6{--vdt-bg-opacity:1;background-color:rgba(75,85,99,var(--vdt-bg-opacity))}.bg-gray\\/10{background-color:rgba(156,163,175,.1)}.bg-gray\\/20{background-color:rgba(156,163,175,.2)}.bg-gray\\/3{background-color:rgba(156,163,175,.03)}.bg-gray\\/30{background-color:rgba(156,163,175,.3)}.bg-gray\\/5{background-color:rgba(156,163,175,.05)}.bg-green{--vdt-bg-opacity:1;background-color:rgba(74,222,128,var(--vdt-bg-opacity))}.bg-orange\\/10{background-color:rgba(251,146,60,.1)}.bg-primary{--vdt-bg-opacity:1;background-color:rgba(107,132,253,var(--vdt-bg-opacity))}.bg-primary-500\\/20,.bg-primary\\/20{background-color:rgba(107,132,253,.2)}.bg-primary-600{--vdt-bg-opacity:1;background-color:rgba(94,116,223,var(--vdt-bg-opacity))}.bg-primary\\/10{background-color:rgba(107,132,253,.1)}.bg-primary\\/15{background-color:rgba(107,132,253,.15)}.bg-red{--vdt-bg-opacity:1;background-color:rgba(248,113,113,var(--vdt-bg-opacity))}.bg-red-500\\/12{background-color:rgba(239,68,68,.12)}.bg-red\\/10{background-color:rgba(248,113,113,.1)}.bg-transparent{background-color:transparent}.bg-white{--vdt-bg-opacity:1;background-color:rgba(255,255,255,var(--vdt-bg-opacity))}.bg-white\\/50{background-color:rgba(255,255,255,.5)}.hover\\:bg-\\[\\#8881\\]:hover{--vdt-bg-opacity:.07;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.hover\\:bg-\\[\\#8882\\]:hover{--vdt-bg-opacity:.13;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.hover\\:bg-\\[\\#8883\\]:hover{--vdt-bg-opacity:.2;background-color:rgba(136,136,136,var(--vdt-bg-opacity))}.hover\\:bg-gray\\/10:hover{background-color:rgba(156,163,175,.1)}.hover\\:bg-gray\\/15:hover{background-color:rgba(156,163,175,.15)}.hover\\:bg-gray\\/20:hover{background-color:rgba(156,163,175,.2)}.hover\\:bg-gray\\/5:hover{background-color:rgba(156,163,175,.05)}.hover\\:bg-orange\\/20:hover{background-color:rgba(251,146,60,.2)}.hover\\:bg-primary-700:hover{--vdt-bg-opacity:1;background-color:rgba(77,95,182,var(--vdt-bg-opacity))}.hover\\:bg-primary\\/20:hover{background-color:rgba(107,132,253,.2)}.hover\\:bg-primary\\/25:hover{background-color:rgba(107,132,253,.25)}.hover\\:bg-red-500\\/20:hover{background-color:rgba(239,68,68,.2)}.hover\\:bg-red\\/20:hover{background-color:rgba(248,113,113,.2)}.fill-black{--vdt-fill-opacity:1;fill:rgba(0,0,0,var(--vdt-fill-opacity))}.fill-hex-08060D{--vdt-fill-opacity:1;fill:rgba(8,6,13,var(--vdt-fill-opacity))}.p-0\\.5{padding:.125rem}.p-1\\.5,.p1\\.5{padding:.375rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p1{padding:.25rem}.p2{padding:.5rem}.p6{padding:1.5rem}.p8{padding:2rem}.px,.px-4,.px4{padding-left:1rem;padding-right:1rem}.px-0\\.5{padding-left:.125rem;padding-right:.125rem}.px-1,.px1{padding-left:.25rem;padding-right:.25rem}.px-1\\.5{padding-left:.375rem;padding-right:.375rem}.px-2,.px2{padding-left:.5rem;padding-right:.5rem}.px-2\\.5{padding-left:.625rem;padding-right:.625rem}.px-3,.px3{padding-left:.75rem;padding-right:.75rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0{padding-top:0;padding-bottom:0}.py-0\\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1,.py1{padding-top:.25rem;padding-bottom:.25rem}.py-1\\.5,.py1\\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2,.py2{padding-top:.5rem;padding-bottom:.5rem}.py-2\\.5,.py2\\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb2\\.5{padding-bottom:.625rem}.pl-6{padding-left:1.5rem}.pt-\\[20vh\\]{padding-top:20vh}.pt-6{padding-top:1.5rem}.pt2{padding-top:.5rem}.text-center{text-align:center}.text-left{text-align:left}.indent{text-indent:1.5rem}.text-balance{text-wrap:balance}.text-\\[10px\\]{font-size:10px}.text-\\[15px\\]{font-size:15px}.text-0\\.6em{font-size:.6em}.text-2\\.75{font-size:.6875rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-amber{--vdt-text-opacity:1;color:rgba(251,191,36,var(--vdt-text-opacity))}.text-amber-800{--vdt-text-opacity:1;color:rgba(146,64,14,var(--vdt-text-opacity))}.text-blue{--vdt-text-opacity:1;color:rgba(96,165,250,var(--vdt-text-opacity))}.text-gray{--vdt-text-opacity:1;color:rgba(156,163,175,var(--vdt-text-opacity))}.text-green{--vdt-text-opacity:1;color:rgba(74,222,128,var(--vdt-text-opacity))}.text-green-800{--vdt-text-opacity:1;color:rgba(22,101,52,var(--vdt-text-opacity))}.text-orange{--vdt-text-opacity:1;color:rgba(251,146,60,var(--vdt-text-opacity))}.text-primary{--vdt-text-opacity:1;color:rgba(107,132,253,var(--vdt-text-opacity))}.text-primary-600{--vdt-text-opacity:1;color:rgba(94,116,223,var(--vdt-text-opacity))}.text-primary-700{--vdt-text-opacity:1;color:rgba(77,95,182,var(--vdt-text-opacity))}.text-red{--vdt-text-opacity:1;color:rgba(248,113,113,var(--vdt-text-opacity))}.text-red-500{--vdt-text-opacity:1;color:rgba(239,68,68,var(--vdt-text-opacity))}.text-red-600{--vdt-text-opacity:1;color:rgba(220,38,38,var(--vdt-text-opacity))}.text-white{--vdt-text-opacity:1;color:rgba(255,255,255,var(--vdt-text-opacity))}.font-bold{font-weight:700}.font-medium{font-weight:500}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.tabular-nums{--vdt-numeric-spacing:tabular-nums;font-variant-numeric:var(--vdt-ordinal) var(--vdt-slashed-zero) var(--vdt-numeric-figure) var(--vdt-numeric-spacing) var(--vdt-numeric-fraction)}.line-through{text-decoration-line:line-through}.tab{tab-size:4}.caret-primary-500{--vdt-caret-opacity:1;caret-color:rgba(107,132,253,var(--vdt-caret-opacity))}.op0,.opacity-0{opacity:0}.op100,.opacity-100{opacity:1}.group:hover .group-hover\\:opacity-100{opacity:1}.op25{opacity:.25}.op30{opacity:.3}.op40{opacity:.4}.op50{opacity:.5}.group:hover .group-hover\\:op50{opacity:.5}.op60{opacity:.6}.op60\\!{opacity:.6!important}.op70{opacity:.7}.op75{opacity:.75}.op80{opacity:.8}.hover\\:op100:hover{opacity:1}.hover\\:op60:hover{opacity:.6}.hover\\:op70:hover{opacity:.7}.hover\\:op80:hover{opacity:.8}.disabled\\:op40:disabled{opacity:.4}.disabled\\:op50:disabled{opacity:.5}.shadow{--vdt-shadow:var(--vdt-shadow-inset) 0 1px 3px 0 var(--vdt-shadow-color,rgba(0,0,0,.1)),var(--vdt-shadow-inset) 0 1px 2px -1px var(--vdt-shadow-color,rgba(0,0,0,.1));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.shadow-sm{--vdt-shadow:var(--vdt-shadow-inset) 0 1px 2px 0 var(--vdt-shadow-color,rgba(0,0,0,.05));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.shadow-xl{--vdt-shadow:var(--vdt-shadow-inset) 0 20px 25px -5px var(--vdt-shadow-color,rgba(0,0,0,.1)),var(--vdt-shadow-inset) 0 8px 10px -6px var(--vdt-shadow-color,rgba(0,0,0,.1));box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.outline{outline-style:solid}.outline-none{outline-offset:2px;outline:2px solid transparent}.ring-1\\.5{--vdt-ring-width:1.5px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.focus\\:ring-1:focus{--vdt-ring-width:1px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.focus\\:ring-3:focus{--vdt-ring-width:3px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.focus-visible\\:ring-3:focus-visible{--vdt-ring-width:3px;--vdt-ring-offset-shadow:var(--vdt-ring-inset) 0 0 0 var(--vdt-ring-offset-width) var(--vdt-ring-offset-color);--vdt-ring-shadow:var(--vdt-ring-inset) 0 0 0 calc(var(--vdt-ring-width) + var(--vdt-ring-offset-width)) var(--vdt-ring-color);box-shadow:var(--vdt-ring-offset-shadow), var(--vdt-ring-shadow), var(--vdt-shadow)}.ring-purple\\/50{--vdt-ring-color:rgba(192,132,252,.5)}.focus\\:ring-primary-500\\/25:focus{--vdt-ring-color:rgba(107,132,253,.25)}.focus\\:ring-primary\\/30:focus{--vdt-ring-color:rgba(107,132,253,.3)}.focus-visible\\:ring-primary-500\\/30:focus-visible{--vdt-ring-color:rgba(107,132,253,.3)}.focus-visible\\:ring-primary-500\\/40:focus-visible{--vdt-ring-color:rgba(107,132,253,.4)}.focus-visible\\:ring-red-500\\/30:focus-visible{--vdt-ring-color:rgba(239,68,68,.3)}.backdrop-blur-0{--vdt-backdrop-blur:blur(0);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia)}.backdrop-blur-1{--vdt-backdrop-blur:blur(1px);backdrop-filter:var(--vdt-backdrop-blur) var(--vdt-backdrop-brightness) var(--vdt-backdrop-contrast) var(--vdt-backdrop-grayscale) var(--vdt-backdrop-hue-rotate) var(--vdt-backdrop-invert) var(--vdt-backdrop-opacity) var(--vdt-backdrop-saturate) var(--vdt-backdrop-sepia)}.blur-2xl{--vdt-blur:blur(40px);filter:var(--vdt-blur) var(--vdt-brightness) var(--vdt-contrast) var(--vdt-drop-shadow) var(--vdt-grayscale) var(--vdt-hue-rotate) var(--vdt-invert) var(--vdt-saturate) var(--vdt-sepia)}.saturate-0{--vdt-saturate:saturate(0);filter:var(--vdt-blur) var(--vdt-brightness) var(--vdt-contrast) var(--vdt-drop-shadow) var(--vdt-grayscale) var(--vdt-hue-rotate) var(--vdt-invert) var(--vdt-saturate) var(--vdt-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-property:transform;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.delay-200{transition-delay:.2s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}@media (prefers-color-scheme:dark){.dark-hidden{display:none}.dark\\:border-primary-400\\/50{border-color:rgba(144,163,254,.5)}.dark\\:bg-black\\/30{background-color:rgba(0,0,0,.3)}.dark\\:bg-black\\/45{background-color:rgba(0,0,0,.45)}.dark\\:fill-hex-fff,.dark\\:fill-white{--vdt-fill-opacity:1;fill:rgba(255,255,255,var(--vdt-fill-opacity))}.dark\\:text-amber-200{--vdt-text-opacity:1;color:rgba(253,230,138,var(--vdt-text-opacity))}.dark\\:text-green-200{--vdt-text-opacity:1;color:rgba(187,247,208,var(--vdt-text-opacity))}.dark\\:text-primary-300{--vdt-text-opacity:1;color:rgba(181,194,254,var(--vdt-text-opacity))}.dark\\:text-red-400{--vdt-text-opacity:1;color:rgba(248,113,113,var(--vdt-text-opacity))}}@media (prefers-color-scheme:light){.light-hidden{display:none}}@media (min-width:640px){.sm\\:gap-2\\.5{gap:.625rem}}" diff --git a/packages/core/src/client/webcomponents/components/views/ViewLauncher.stories.ts b/packages/core/src/client/webcomponents/components/views/ViewLauncher.stories.ts index e74439ad..f66a6297 100644 --- a/packages/core/src/client/webcomponents/components/views/ViewLauncher.stories.ts +++ b/packages/core/src/client/webcomponents/components/views/ViewLauncher.stories.ts @@ -4,7 +4,10 @@ import { h } from 'vue' import { mountWithContext } from '../../stories/story-helpers' import ViewLauncher from './ViewLauncher.vue' -function launcher(status: 'idle' | 'loading' | 'error' | 'success'): DevToolsViewLauncher { +function launcher( + status: 'idle' | 'loading' | 'error' | 'success', + extras: Partial = {}, +): DevToolsViewLauncher { return { id: 'launcher', type: 'launcher', @@ -14,6 +17,7 @@ function launcher(status: 'idle' | 'loading' | 'error' | 'success'): DevToolsVie title: 'Launch My Cool App', description: 'Start the dev server and open it here.', status, + ...extras, }, } as DevToolsViewLauncher } @@ -38,10 +42,13 @@ const meta = { export default meta type Story = StoryObj -function launcherStory(status: 'idle' | 'loading' | 'error' | 'success'): Story { +function launcherStory( + status: 'idle' | 'loading' | 'error' | 'success', + extras: Partial = {}, +): Story { return { render: () => ({ - setup: () => mountWithContext({}, ctx => stage(h(ViewLauncher, { context: ctx, entry: launcher(status) }))), + setup: () => mountWithContext({}, ctx => stage(h(ViewLauncher, { context: ctx, entry: launcher(status, extras) }))), }), } } @@ -49,4 +56,16 @@ function launcherStory(status: 'idle' | 'loading' | 'error' | 'success'): Story export const Idle: Story = launcherStory('idle') export const Loading: Story = launcherStory('loading') export const Success: Story = launcherStory('success') -export const Error: Story = launcherStory('error') + +// A failed launch surfaces the reason and offers a clickable Retry. +export const Error: Story = launcherStory('error', { + error: 'No test files found, exiting with code 1', +}) + +// A launcher tracking a terminal session: it shows the process's progress and +// offers to jump to that session in the Terminals dock. +export const WithProgress: Story = launcherStory('loading', { + buttonLoading: 'Starting…', + terminalSessionId: 'my-app:dev', + digest: 'Waiting for the server…', +}) diff --git a/packages/core/src/client/webcomponents/components/views/ViewLauncher.vue b/packages/core/src/client/webcomponents/components/views/ViewLauncher.vue index 6b51ecf4..754d2dbd 100644 --- a/packages/core/src/client/webcomponents/components/views/ViewLauncher.vue +++ b/packages/core/src/client/webcomponents/components/views/ViewLauncher.vue @@ -1,6 +1,7 @@ diff --git a/packages/core/src/client/webcomponents/state/__tests__/context-cache.test.ts b/packages/core/src/client/webcomponents/state/__tests__/context-cache.test.ts index fa0b6096..a1f44e80 100644 --- a/packages/core/src/client/webcomponents/state/__tests__/context-cache.test.ts +++ b/packages/core/src/client/webcomponents/state/__tests__/context-cache.test.ts @@ -23,6 +23,9 @@ function createMockRpc(entries: DevToolsDockEntry[] = []): DevToolsRpcClient { }) return { + client: { + register: () => () => {}, + }, sharedState: { get: async (key: string) => { if (key === 'devframe:docks') diff --git a/packages/core/src/client/webcomponents/state/context.ts b/packages/core/src/client/webcomponents/state/context.ts index f7d11f16..f86a736a 100644 --- a/packages/core/src/client/webcomponents/state/context.ts +++ b/packages/core/src/client/webcomponents/state/context.ts @@ -1,4 +1,4 @@ -import type { DevToolsClientCommand, DevToolsDockEntry } from '@vitejs/devtools-kit' +import type { DevToolsClientCommand, DevToolsDockEntry, DevToolsRpcClientFunctions } from '@vitejs/devtools-kit' import type { CommandsContext, DevToolsRpcClient, DockClientScriptContext, DockEntryState, DockPanelStorage, DocksContext } from '@vitejs/devtools-kit/client' import type { SharedState } from 'devframe/utils/shared-state' import type { WhenContext } from 'devframe/utils/when' @@ -113,6 +113,22 @@ export async function createDocksContext( return switchEntry(id) } + // Honor cross-iframe dock-activation requests (devframe 0.7.3). A mounted + // plugin — or our own launcher's "View in Terminal" action — calls the + // `hub:docks:activate` RPC; the hub broadcasts `devframe:docks:activate` to + // every client. Our shell runs its own dock machinery rather than hub's + // client host, so we handle the broadcast here and switch the active dock + // ourselves. The target dock (e.g. Terminals) reads `activation.params` to + // focus a specific session. + rpc.client.register({ + name: 'devframe:docks:activate' satisfies keyof DevToolsRpcClientFunctions, + type: 'action', + handler: (activation: { dockId: string, params?: Record }) => { + if (activation?.dockId) + switchEntry(activation.dockId) + }, + }) + let _settingsStorePromise: Promise> | undefined const getSettingsStore = async () => { if (!_settingsStorePromise) { diff --git a/packages/core/src/node/rpc/index.ts b/packages/core/src/node/rpc/index.ts index 8c24d15e..a8d4988a 100644 --- a/packages/core/src/node/rpc/index.ts +++ b/packages/core/src/node/rpc/index.ts @@ -49,17 +49,22 @@ export type BuiltinServerFunctionsDump = { [K in keyof BuiltinServerFunctionsStatic]: Awaited> } -declare module '@vitejs/devtools-kit' { - export interface DevToolsRpcServerFunctions extends BuiltinServerFunctions {} +// devframe ≥0.7.4 declares its RPC name maps inside a bundled chunk that the +// public entrypoints re-export, so augmentation must target `devframe/types` +// directly — a renamed re-export (the kit's `DevTools*` alias) no longer +// merges. `@devframes/hub` augments the same module. `hub:docks:activate` is +// now declared by the hub itself, so we no longer declare it here. +declare module 'devframe/types' { + interface DevframeRpcServerFunctions extends BuiltinServerFunctions {} // @keep-sorted // `devframe:auth:revoked` and `devframe:rpc:client-state:*` are declared // upstream by devframe; `devframe:messages:updated` / `devframe:terminals:updated` // by `@devframes/hub`. We only declare what is Vite-DevTools-specific here. - export interface DevToolsRpcClientFunctions {} + interface DevframeRpcClientFunctions {} // @keep-sorted - export interface DevToolsRpcSharedStates { + interface DevframeRpcSharedStates { 'devframe:commands': DevToolsServerCommandEntry[] 'devframe:docks': DevToolsDockEntry[] 'devframe:user-settings': DevToolsDocksUserSettings diff --git a/packages/core/src/node/rpc/internal/docks-on-launch.test.ts b/packages/core/src/node/rpc/internal/docks-on-launch.test.ts new file mode 100644 index 00000000..3642c49c --- /dev/null +++ b/packages/core/src/node/rpc/internal/docks-on-launch.test.ts @@ -0,0 +1,72 @@ +import { describe, expect, it, vi } from 'vitest' +import { docksOnLaunch } from './docks-on-launch' + +interface FakeLauncher { + id: string + type: string + title: string + icon: string + launcher: { title: string, status: string, error?: string, onLaunch: () => Promise } +} + +function fakeContext(entry: FakeLauncher): { handler: (id: string) => Promise, store: Map } { + const store = new Map([[entry.id, entry]]) + const context = { + docks: { + values: () => [...store.values()], + update: (e: FakeLauncher) => store.set(e.id, e), + }, + } + const setup = docksOnLaunch.setup as (ctx: any) => { handler: (id: string) => Promise } + const { handler } = setup(context) + return { handler, store } +} + +describe('docksOnLaunch', () => { + it('re-runs onLaunch on a subsequent call so a failed launch can be retried', async () => { + const onLaunch = vi.fn<() => Promise>() + .mockRejectedValueOnce(new Error('No test files found')) + .mockResolvedValueOnce(undefined) + + const { handler, store } = fakeContext({ + id: 'my-app', + type: 'launcher', + title: 'My App', + icon: 'ph:rocket-launch-duotone', + launcher: { title: 'My App', status: 'idle', onLaunch }, + }) + + // First launch fails → error state, with the failure message surfaced. + await handler('my-app') + expect(onLaunch).toHaveBeenCalledTimes(1) + expect(store.get('my-app')!.launcher.status).toBe('error') + expect(store.get('my-app')!.launcher.error).toBe('No test files found') + + // Retry re-runs the launch (the in-flight cache was cleared on settle). + await handler('my-app') + expect(onLaunch).toHaveBeenCalledTimes(2) + expect(store.get('my-app')!.launcher.status).toBe('success') + }) + + it('de-dupes concurrent launches of the same entry', async () => { + let resolve!: () => void + const onLaunch = vi.fn(() => new Promise((r) => { + resolve = r + })) + + const { handler } = fakeContext({ + id: 'my-app', + type: 'launcher', + title: 'My App', + icon: 'ph:rocket-launch-duotone', + launcher: { title: 'My App', status: 'idle', onLaunch }, + }) + + const a = handler('my-app') + const b = handler('my-app') + resolve() + await Promise.all([a, b]) + + expect(onLaunch).toHaveBeenCalledTimes(1) + }) +}) diff --git a/packages/core/src/node/rpc/internal/docks-on-launch.ts b/packages/core/src/node/rpc/internal/docks-on-launch.ts index 0e6b50da..5fd1ba56 100644 --- a/packages/core/src/node/rpc/internal/docks-on-launch.ts +++ b/packages/core/src/node/rpc/internal/docks-on-launch.ts @@ -5,9 +5,12 @@ export const docksOnLaunch = defineRpcFunction({ name: 'devtoolskit:internal:docks:on-launch', type: 'action', setup: (context) => { - const launchMap = new Map>() + const launchMap = new Map>() return { handler: async (entryId: string) => { + // De-dupe concurrent launches of the same entry, but only while one is + // in flight — the entry is removed once it settles so a later click + // (e.g. Retry after a failure) starts a fresh launch. if (launchMap.has(entryId)) { return launchMap.get(entryId)! } @@ -19,39 +22,62 @@ export const docksOnLaunch = defineRpcFunction({ if (entry.type !== 'launcher') { throw diagnostics.DTK0031({ id: entryId }) } - try { - context.docks.update({ - ...entry, - launcher: { - ...entry.launcher, - status: 'loading', - }, - }) - const promise = entry.launcher.onLaunch() - launchMap.set(entryId, promise) - const result = await promise - const newEntry = context.docks.values().find(entry => entry.id === entryId) || entry - if (newEntry.type === 'launcher') { + + const run = (async () => { + try { context.docks.update({ - ...newEntry, + ...entry, launcher: { - ...newEntry.launcher, - status: 'success', + ...entry.launcher, + status: 'loading', + error: undefined, }, }) + // devframe ≥0.7.4 made `onLaunch` optional in favour of a bound + // `command` (the serializable launch path). Prefer the in-process + // handler; fall back to executing the command. + const { onLaunch, command } = entry.launcher + const result = onLaunch + ? await onLaunch() + : command + ? await context.commands.execute(command) + : undefined + // The launch may have replaced the entry (e.g. swapped to an + // iframe); only stamp success while it is still a launcher. + const newEntry = context.docks.values().find(entry => entry.id === entryId) || entry + if (newEntry.type === 'launcher') { + context.docks.update({ + ...newEntry, + launcher: { + ...newEntry.launcher, + status: 'success', + }, + }) + } + return result + } + catch (error) { + diagnostics.DTK0032({ id: entryId, cause: error }) + const newEntry = context.docks.values().find(entry => entry.id === entryId) || entry + if (newEntry.type === 'launcher') { + context.docks.update({ + ...newEntry, + launcher: { + ...newEntry.launcher, + status: 'error', + error: error instanceof Error ? error.message : String(error), + }, + }) + } } - return result + })() + + launchMap.set(entryId, run) + try { + return await run } - catch (error) { - diagnostics.DTK0032({ id: entryId, cause: error }) - context.docks.update({ - ...entry, - launcher: { - ...entry.launcher, - status: 'error', - error: error instanceof Error ? error.message : String(error), - }, - }) + finally { + launchMap.delete(entryId) } }, } diff --git a/packages/core/src/node/ws.ts b/packages/core/src/node/ws.ts index 55fa678b..c0a47acb 100644 --- a/packages/core/src/node/ws.ts +++ b/packages/core/src/node/ws.ts @@ -3,6 +3,7 @@ import type { ConnectionMeta, DevToolsNodeRpcSession, DevToolsRpcClientFunctions import type { Peer } from 'crossws' import type { RpcFunctionsHost } from 'devframe/node' import type { WsRpcTransportOptions } from 'devframe/rpc/transports/ws-server' +import type { DevframeNodeRpcSessionMeta } from 'devframe/types' import type { Server as NodeHttpServer } from 'node:http' import { AsyncLocalStorage } from 'node:async_hooks' import process from 'node:process' @@ -41,8 +42,19 @@ function buildWsUrl({ host, port, https }: { host: string, port: number, https: return `${protocol}://${reachableHost}:${port}` } +/** + * devframe keeps these wiring members `@internal`, off the public + * {@link RpcFunctionsHost} type (devframe ≥0.7.5). This custom WS transport + * sets them directly, so we reach them through a narrow local shape. + */ +interface RpcFunctionsHostInternals { + _rpcGroup: unknown + _asyncStorage: unknown + _emitSessionDisconnected: (meta: DevframeNodeRpcSessionMeta) => void +} + export async function createWsServer(options: CreateWsServerOptions) { - const rpcHost = options.context.rpc as unknown as RpcFunctionsHost + const rpcHost = options.context.rpc as unknown as RpcFunctionsHost & RpcFunctionsHostInternals const host = options.websocket.host const https = await resolveHttpsConfig(options.websocket.https === false ? undefined : (options.websocket.https ?? options.context.viteConfig.server.https)) diff --git a/packages/kit/src/constants.ts b/packages/kit/src/constants.ts index 0894f181..a4c9a1e5 100644 --- a/packages/kit/src/constants.ts +++ b/packages/kit/src/constants.ts @@ -48,6 +48,14 @@ export const DEVTOOLS_VITEPLUS_GROUP_ID = '~viteplus' */ export const DEVTOOLS_INSPECTOR_DOCK_ID = 'devframes-plugin-inspect' +/** + * Dock id of the built-in Terminals feed (from `@devframes/plugin-terminals`). + * A launcher tracking a terminal session targets this dock via + * `hub:docks:activate({ dockId, params: { sessionId } })` to jump the user + * straight to that session's output. + */ +export const DEVTOOLS_TERMINALS_DOCK_ID = 'devframes-plugin-terminals' + export const DEFAULT_CATEGORIES_ORDER: Record = { 'default': 0, 'app': 100, diff --git a/packages/kit/src/node/create-install-launcher.test.ts b/packages/kit/src/node/create-install-launcher.test.ts index 922aa908..0b1aa479 100644 --- a/packages/kit/src/node/create-install-launcher.test.ts +++ b/packages/kit/src/node/create-install-launcher.test.ts @@ -17,6 +17,7 @@ function fakeCtx(opts: { viteServer?: boolean } = {}): { registered: Map } { const registered = new Map() + const commandHandlers = new Map any>() const ctx = { cwd: '/project', viteServer: opts.viteServer ? {} : undefined, @@ -24,6 +25,13 @@ function fakeCtx(opts: { viteServer?: boolean } = {}): { register: (e: FakeDock) => registered.set(e.id, e), update: (e: FakeDock) => registered.set(e.id, e), }, + commands: { + register: (c: { id: string, handler?: (...args: any[]) => any }) => { + if (c.handler) + commandHandlers.set(c.id, c.handler) + }, + execute: (id: string, ...args: any[]) => commandHandlers.get(id)?.(...args), + }, } as unknown as ViteDevToolsNodeContext return { ctx, registered } } @@ -57,11 +65,27 @@ describe('createInstallLauncher', () => { expect(dock.groupId).toBe('~viteplus') expect(dock.launcher.status).toBe('idle') expect(dock.launcher.buttonStart).toBe('Install Rolldown DevTools') - expect(typeof dock.launcher.onLaunch).toBe('function') + // The launch action is the bound command (the serializable path); no + // in-process onLaunch is set. + expect(dock.launcher.command).toBe('vite:devtools:install:rolldown') + expect(dock.launcher.onLaunch).toBeUndefined() }) - it('installs only the missing packages in a single dev-dependency call', async () => { + it('binds the install action to a command that drives the launch', async () => { const { ctx, registered } = fakeCtx({ viteServer: true }) + isPackageExists.mockReturnValue(true) + + await mount(ctx, baseOptions) + + // The launcher advertises its bound command id… + expect(registered.get('rolldown')!.launcher.command).toBe('vite:devtools:install:rolldown') + // …and executing that command runs the install handler. + await ctx.commands.execute('vite:devtools:install:rolldown') + expect(isPackageExists).toHaveBeenCalled() + }) + + it('installs only the missing packages in a single dev-dependency call', async () => { + const { ctx } = fakeCtx({ viteServer: true }) // `vitest` already present; the two devtools packages are missing. isPackageExists.mockImplementation((name: string) => name === 'vitest') @@ -73,7 +97,7 @@ describe('createInstallLauncher', () => { install: ['vitest', '@vitejs/devtools-vitest@^0.4.1', '@vitest/ui'], }) - await registered.get('vitest')!.launcher.onLaunch() + await ctx.commands.execute('vite:devtools:install:vitest') expect(addDependency).toHaveBeenCalledTimes(1) expect(addDependency).toHaveBeenCalledWith( @@ -83,11 +107,11 @@ describe('createInstallLauncher', () => { }) it('skips install entirely when nothing is missing', async () => { - const { ctx, registered } = fakeCtx({ viteServer: true }) + const { ctx } = fakeCtx({ viteServer: true }) isPackageExists.mockReturnValue(true) await mount(ctx, baseOptions) - await registered.get('rolldown')!.launcher.onLaunch() + await ctx.commands.execute('vite:devtools:install:rolldown') expect(addDependency).not.toHaveBeenCalled() }) @@ -98,7 +122,7 @@ describe('createInstallLauncher', () => { addDependency.mockResolvedValue(undefined) await mount(ctx, baseOptions) - await registered.get('rolldown')!.launcher.onLaunch() + await ctx.commands.execute('vite:devtools:install:rolldown') const dock = registered.get('rolldown')! expect(dock.launcher.status).toBe('success') @@ -111,18 +135,18 @@ describe('createInstallLauncher', () => { addDependency.mockResolvedValue(undefined) await mount(ctx, baseOptions) - await registered.get('rolldown')!.launcher.onLaunch() + await ctx.commands.execute('vite:devtools:install:rolldown') expect(registered.get('rolldown')!.launcher.description).toContain('vite-devtools') }) it('throws DTK0050 when the install fails', async () => { - const { ctx, registered } = fakeCtx({ viteServer: true }) + const { ctx } = fakeCtx({ viteServer: true }) isPackageExists.mockReturnValue(false) addDependency.mockRejectedValue(new Error('network down')) await mount(ctx, baseOptions) - await expect(registered.get('rolldown')!.launcher.onLaunch()).rejects.toThrow(/Failed to install/) + await expect(ctx.commands.execute('vite:devtools:install:rolldown')).rejects.toThrow(/Failed to install/) }) }) diff --git a/packages/kit/src/node/create-install-launcher.ts b/packages/kit/src/node/create-install-launcher.ts index a57d7745..833883ee 100644 --- a/packages/kit/src/node/create-install-launcher.ts +++ b/packages/kit/src/node/create-install-launcher.ts @@ -1,4 +1,5 @@ import type { DevframeDockEntryIcon } from '@devframes/hub/types' +import type { DevToolsViewLauncher } from '../types/docks' import type { PluginWithDevTools } from '../types/vite-augment' import type { ViteDevToolsNodeContext } from '../types/vite-plugin' import process from 'node:process' @@ -74,7 +75,17 @@ export function createInstallLauncher(options: InstallLauncherOptions): PluginWi setup(ctx: ViteDevToolsNodeContext) { const cwd = ctx.cwd ?? process.cwd() - ctx.docks.register({ + // Bind the install action to a command so it fires from the launch + // button, the command palette, and any keybinding — one handler. + const commandId = `vite:devtools:install:${id}` + ctx.commands.register({ + id: commandId, + title: `Install ${label}`, + icon, + handler: launch, + }) + + ctx.docks.register({ id, title, groupId, @@ -87,7 +98,9 @@ export function createInstallLauncher(options: InstallLauncherOptions): PluginWi buttonStart: `Install ${label}`, buttonLoading: 'Installing…', status: 'idle', - onLaunch: launch, + // The bound command is the launch action; the on-launch bridge + // falls back to it, so no in-process `onLaunch` is needed. + command: commandId, }, }) @@ -123,9 +136,9 @@ export function createInstallLauncher(options: InstallLauncherOptions): PluginWi status: 'success', description: `${label} installed. ${restartHint}`, buttonStart: 'Installed', - // Re-click is idempotent: the packages are present now, so - // `launch` installs nothing and just re-affirms the message. - onLaunch: launch, + // Re-click is idempotent: the packages are present now, so the + // command installs nothing and just re-affirms the message. + command: commandId, }, }) } diff --git a/packages/kit/src/node/create-process-launcher.test.ts b/packages/kit/src/node/create-process-launcher.test.ts new file mode 100644 index 00000000..94558532 --- /dev/null +++ b/packages/kit/src/node/create-process-launcher.test.ts @@ -0,0 +1,159 @@ +import type { ViteDevToolsNodeContext } from '../types/vite-plugin' +import { describe, expect, it, vi } from 'vitest' +import { createProcessLauncher } from './create-process-launcher' + +interface FakeDock { id: string, type: string, launcher?: any } + +function fakeCtx(): { + ctx: ViteDevToolsNodeContext + registered: Map + commands: Map any> + sessions: Map + resolveExit: (code: number) => void +} { + const registered = new Map() + const commands = new Map any>() + const sessions = new Map() + let resolveExit!: (code: number) => void + const result = new Promise<{ exitCode: number }>((resolve) => { + resolveExit = (exitCode: number) => resolve({ exitCode }) + }) + + const ctx = { + cwd: '/project', + docks: { + register: (e: FakeDock) => registered.set(e.id, e), + update: (e: FakeDock) => registered.set(e.id, e), + }, + commands: { + register: (c: { id: string, handler?: (...a: any[]) => any }) => { + if (c.handler) + commands.set(c.id, c.handler) + }, + execute: (id: string, ...a: any[]) => commands.get(id)?.(...a), + }, + terminals: { + sessions, + startChildProcess: vi.fn(async (_exec, meta: { id: string }) => { + sessions.set(meta.id, { status: 'running' }) + return { + getResult: () => result, + terminate: async () => {}, + } + }), + }, + } as unknown as ViteDevToolsNodeContext + + return { ctx, registered, commands, sessions, resolveExit } +} + +const baseOptions = { + id: 'my-app', + title: 'My App', + icon: 'ph:rocket-launch-duotone', + process: { command: 'vite', args: ['dev'], cwd: '/project' }, +} + +async function mount(ctx: ViteDevToolsNodeContext, options: Parameters[0]): Promise { + await createProcessLauncher(options).devtools!.setup!(ctx) +} + +describe('createProcessLauncher', () => { + it('registers an idle launcher bound to a launch command', async () => { + const { ctx, registered, commands } = fakeCtx() + await mount(ctx, baseOptions) + + const dock = registered.get('my-app')! + expect(dock.type).toBe('launcher') + expect(dock.launcher.status).toBe('idle') + expect(dock.launcher.command).toBe('my-app:launch') + // No session is tracked before launch. + expect(dock.launcher.terminalSessionId).toBeUndefined() + expect(commands.has('my-app:launch')).toBe(true) + }) + + it('spawns the process, tracks its session, and shows running progress', async () => { + const { ctx, registered } = fakeCtx() + await mount(ctx, baseOptions) + + // Launch via the bound command (what the palette / button both do). + await ctx.commands.execute('my-app:launch') + + expect((ctx.terminals as any).startChildProcess).toHaveBeenCalledOnce() + const dock = registered.get('my-app')! + expect(dock.launcher.status).toBe('success') + expect(dock.launcher.terminalSessionId).toBe('my-app') + expect(dock.launcher.digest).toBe('Running') + }) + + it('is idempotent while the session is running', async () => { + const { ctx } = fakeCtx() + await mount(ctx, baseOptions) + + await ctx.commands.execute('my-app:launch') + await ctx.commands.execute('my-app:launch') + + expect((ctx.terminals as any).startChildProcess).toHaveBeenCalledOnce() + }) + + it('marks the launcher errored when the process exits non-zero', async () => { + const { ctx, registered, resolveExit } = fakeCtx() + await mount(ctx, baseOptions) + + await ctx.commands.execute('my-app:launch') + resolveExit(1) + await Promise.resolve() + await Promise.resolve() + + expect(registered.get('my-app')!.launcher.status).toBe('error') + }) + + it('swaps the launcher to an iframe once a server launcher is ready', async () => { + const { ctx, registered } = fakeCtx() + await mount(ctx, { + ...baseOptions, + serve: { + onReady: async () => 'http://localhost:5173/', + }, + }) + + await ctx.commands.execute('my-app:launch') + + const dock = registered.get('my-app')! + expect(dock.type).toBe('iframe') + expect((dock as any).url).toBe('http://localhost:5173/') + }) + + it('fails fast to an error when a server launcher exits before it is ready', async () => { + const { ctx, registered, resolveExit } = fakeCtx() + await mount(ctx, { + ...baseOptions, + // A readiness probe that would otherwise hang forever. + serve: { onReady: () => new Promise(() => {}) }, + }) + + const launch = ctx.commands.execute('my-app:launch') + resolveExit(1) + await (launch as Promise).catch(() => {}) + + const dock = registered.get('my-app')! + expect(dock.type).toBe('launcher') + expect(dock.launcher.status).toBe('error') + expect(dock.launcher.error).toContain('exited with code 1') + }) + + it('re-shows the iframe when a running server launcher is invoked again', async () => { + const { ctx, registered } = fakeCtx() + await mount(ctx, { + ...baseOptions, + serve: { onReady: async () => 'http://localhost:5173/' }, + }) + + await ctx.commands.execute('my-app:launch') + // Session stays running; a second invoke re-swaps without respawning. + await ctx.commands.execute('my-app:launch') + + expect((ctx.terminals as any).startChildProcess).toHaveBeenCalledOnce() + expect(registered.get('my-app')!.type).toBe('iframe') + }) +}) diff --git a/packages/kit/src/node/create-process-launcher.ts b/packages/kit/src/node/create-process-launcher.ts new file mode 100644 index 00000000..d440ee87 --- /dev/null +++ b/packages/kit/src/node/create-process-launcher.ts @@ -0,0 +1,260 @@ +import type { DevframeDockEntryIcon } from '@devframes/hub/types' +import type { DevToolsCommandKeybinding } from '../types/commands' +import type { DevToolsViewIframe, DevToolsViewLauncher } from '../types/docks' +import type { DevToolsChildProcessExecuteOptions, DevToolsChildProcessTerminalSession } from '../types/terminals' +import type { PluginWithDevTools } from '../types/vite-augment' +import type { ViteDevToolsNodeContext } from '../types/vite-plugin' +import { diagnostics } from './diagnostics' + +type Awaitable = T | Promise + +export interface ProcessLauncherOptions { + /** Dock id. Also the default terminal-session id and command-id base. */ + id: string + /** Dock rail title. */ + title: string + /** Dock + launcher icon — a served URL or an Iconify `collection:name`. */ + icon: DevframeDockEntryIcon + /** Dock group id, e.g. `DEVTOOLS_VITEPLUS_GROUP_ID`. */ + groupId?: string + /** Launcher card title. Defaults to {@link ProcessLauncherOptions.title}. */ + label?: string + /** Launcher card description. */ + description?: string + /** Launch button copy. */ + buttonStart?: string + buttonLoading?: string + /** + * The child process spawned when the launcher is invoked. Pass a function to + * resolve it lazily on each launch — e.g. to pick a free port and build args. + */ + process: DevToolsChildProcessExecuteOptions | (() => Awaitable) + /** + * Runs once per launch, before the process is spawned. Use it for on-demand + * setup such as installing an optional dependency. Throwing here surfaces on + * the launcher as an error (and rejects the bound command). + */ + prepare?: () => Awaitable + /** + * Turn the launcher into an embedded server view. After the process spawns, + * `onReady` runs (do your own readiness probing there) and resolves the URL + * to embed; the dock then swaps from a launcher to an iframe at that URL. The + * card streams the startup digest while `onReady` is pending. Omit to keep a + * plain terminal-tailing launcher. + */ + serve?: { + onReady: (session: DevToolsChildProcessTerminalSession) => Awaitable + } + /** + * Command binding. The launch action is registered as a command so it fires + * from the launch button, the palette, and any keybinding. Defaults the + * command id to `${id}:launch`. + */ + command?: { + id?: string + title?: string + icon?: DevframeDockEntryIcon + keybindings?: DevToolsCommandKeybinding[] + } + /** Terminal-session metadata. Session id defaults to {@link ProcessLauncherOptions.id}. */ + session?: { + id?: string + title?: string + icon?: DevframeDockEntryIcon + } + /** Vite plugin name. Defaults to `vite:devtools:process-launcher:${id}`. */ + name?: string +} + +/** + * Build a launcher dock for a child process — the composed form of the launcher + * primitives. It registers the launcher, binds a command to the launch action, + * runs an optional `prepare` step, spawns the process into a terminal session, + * reflects the process's progress/status on the card, and exposes the session + * so the card's "View in Terminal" action can jump to its full output. + * + * Two shapes, one call: + * + * - **Terminal launcher** (no `serve`): the launcher *stays* a launcher while a + * long-running process runs (dev servers, watchers, builds), tailing its + * output as a digest. + * - **Server launcher** (`serve.onReady`): run some commands, start a server, + * then replace the card with an iframe embedding the server — the digest + * streams startup logs until `onReady` resolves the URL, then the dock swaps + * to the iframe. + * + * ```ts + * // Terminal launcher + * createProcessLauncher({ + * id: 'my-app', + * title: 'My App', + * icon: 'ph:rocket-launch-duotone', + * process: { command: 'vite', args: ['dev'], cwd: process.cwd() }, + * }) + * + * // Server launcher (spawn → wait → embed) + * let url: string + * createProcessLauncher({ + * id: 'my-ui', + * title: 'My UI', + * icon: 'ph:browser-duotone', + * process: async () => { + * const port = await getPort() + * url = `http://localhost:${port}/` + * return { command: 'my-ui', args: ['--port', String(port)], cwd: process.cwd() } + * }, + * serve: { onReady: async () => { await waitForServer(url); return url } }, + * }) + * ``` + */ +export function createProcessLauncher(options: ProcessLauncherOptions): PluginWithDevTools { + const { + id, + title, + icon, + groupId, + label = title, + description, + buttonStart, + buttonLoading, + process: executeOptions, + prepare, + serve, + name, + } = options + + const sessionId = options.session?.id ?? id + const commandId = options.command?.id ?? `${id}:launch` + + return { + name: name ?? `vite:devtools:process-launcher:${id}`, + devtools: { + setup(ctx: ViteDevToolsNodeContext) { + let session: DevToolsChildProcessTerminalSession | undefined + // Remembered once a server launcher has swapped to its iframe, so a + // re-invocation while it is still running re-shows the embed. + let servedUrl: string | undefined + + // Re-render the whole launcher entry — the hub sync replaces it + // wholesale — with the current status and (once running) the tracked + // session + a short progress line. + function entry( + status: DevToolsViewLauncher['launcher']['status'], + extras: { tracking?: boolean, progress?: string, error?: string } = {}, + ): DevToolsViewLauncher { + return { + id, + title, + groupId, + icon, + type: 'launcher', + launcher: { + title: label, + description, + icon, + buttonStart, + buttonLoading, + status, + error: extras.error, + // The bound command is the launch action (button, palette, and + // keybinding resolve to it); the on-launch bridge falls back to + // it, so no in-process `onLaunch` is needed. + command: commandId, + ...(extras.tracking ? { terminalSessionId: sessionId } : {}), + // Hub's author-set `digest` — a short line of progress/status. + ...(extras.progress ? { digest: extras.progress } : {}), + }, + } + } + + function swapToIframe(url: string): void { + const iframe: DevToolsViewIframe = { id, title, groupId, icon, type: 'iframe', url } + ctx.docks.update(iframe) + } + + ctx.commands.register({ + id: commandId, + title: options.command?.title ?? label, + icon: options.command?.icon ?? icon, + keybindings: options.command?.keybindings, + handler: launch, + }) + + ctx.docks.register(entry('idle')) + + async function launch(): Promise { + // A live session is left running: re-show the embed for a server + // launcher, otherwise no-op (don't disturb an in-flight launch). + if (ctx.terminals.sessions.get(sessionId)?.status === 'running') { + if (serve && servedUrl) + swapToIframe(servedUrl) + return + } + + try { + await prepare?.() + + if (session) + await session.terminate().catch(() => {}) + + const execute = typeof executeOptions === 'function' ? await executeOptions() : executeOptions + session = await ctx.terminals.startChildProcess(execute, { + id: sessionId, + title: options.session?.title ?? label, + icon: options.session?.icon ?? 'ph:terminal-window-duotone', + }) + + if (serve) { + // Booting: still 'loading', with a status line while we wait. + ctx.docks.update(entry('loading', { tracking: true, progress: 'Waiting for the server…' })) + + // Wait for the server — but fail fast if the process exits first + // (e.g. a build error), instead of blocking on a readiness probe + // that will never succeed. + const activeSession = session + const readyPromise = (async () => serve.onReady(activeSession))() + const exitPromise = (async () => { + const result = await activeSession.getResult() + throw diagnostics.DTK0052({ id, exitCode: result.exitCode }) + })() + // Whichever promise loses the race keeps running (a readiness + // probe polling on, or a watch process staying up); swallow its + // late settlement so it never becomes an unhandled rejection. + readyPromise.catch(() => {}) + exitPromise.catch(() => {}) + + const url = await Promise.race([readyPromise, exitPromise]) + servedUrl = url + swapToIframe(url) + return + } + + // Terminal launcher: it's now running. Reflect its outcome once it + // exits, keeping the session link so its output stays openable. + // `getResult()` is a bare PromiseLike, so handle rejection inline. + ctx.docks.update(entry('success', { tracking: true, progress: 'Running' })) + const trackedSession = session + void trackedSession.getResult().then( + (result) => { + ctx.docks.update( + result.exitCode === 0 + ? entry('success', { tracking: true, progress: 'Finished' }) + : entry('error', { tracking: true, error: `Process exited with code ${result.exitCode ?? 'null'}.` }), + ) + }, + () => {}, + ) + } + catch (error) { + // Surface the failure on the card (covers palette/keybinding launches + // too, which don't pass through the on-launch bridge) and re-throw so + // the button path's bridge reflects it as well. The card stays a + // launcher, so its button becomes Retry. + ctx.docks.update(entry('error', { tracking: true, error: error instanceof Error ? error.message : String(error) })) + throw error + } + } + }, + }, + } +} diff --git a/packages/kit/src/node/diagnostics.ts b/packages/kit/src/node/diagnostics.ts index cc38dae7..22408a7e 100644 --- a/packages/kit/src/node/diagnostics.ts +++ b/packages/kit/src/node/diagnostics.ts @@ -16,5 +16,10 @@ export const diagnostics = /* #__PURE__ */ defineDiagnostics({ why: (p: { base: string }) => `Failed to serve the RPC connection meta at "${p.base}".`, fix: 'The devframe SPA mounted at this base cannot discover the RPC endpoint. Check the dev server logs for the underlying cause and reload.', }, + DTK0052: { + why: (p: { id: string, exitCode: number | undefined }) => + `The "${p.id}" launcher process exited with code ${p.exitCode ?? 'null'} before its server was ready.`, + fix: 'Check the launcher\'s terminal session output for the failure, then use Retry.', + }, }, }) diff --git a/packages/kit/src/node/index.ts b/packages/kit/src/node/index.ts index 3ca62f33..44c2a940 100644 --- a/packages/kit/src/node/index.ts +++ b/packages/kit/src/node/index.ts @@ -1,6 +1,7 @@ export * from './context' export * from './create-install-launcher' export * from './create-plugin-from-devframe' +export * from './create-process-launcher' export * from './utils' export * from './vite-host' diff --git a/packages/kit/src/types/docks.ts b/packages/kit/src/types/docks.ts index 80865d2e..c3dfa864 100644 --- a/packages/kit/src/types/docks.ts +++ b/packages/kit/src/types/docks.ts @@ -2,11 +2,13 @@ import type { DevframeDockEntryCategory } from '@devframes/hub/types' export type { ClientScriptEntry, + DevframeDockActivation as DevToolsDockActivation, DevframeDockEntriesGrouped as DevToolsDockEntriesGrouped, DevframeDockEntry as DevToolsDockEntry, DevframeDockEntryBase as DevToolsDockEntryBase, DevframeDockEntryIcon as DevToolsDockEntryIcon, DevframeDocksHost as DevToolsDockHost, + DevframeDocksActiveState as DevToolsDocksActiveState, DevframeDockUserEntry as DevToolsDockUserEntry, DevframeViewAction as DevToolsViewAction, DevframeViewBuiltin as DevToolsViewBuiltin, diff --git a/packages/oxc/src/node/rpc/index.ts b/packages/oxc/src/node/rpc/index.ts index 42c38da2..345299ab 100644 --- a/packages/oxc/src/node/rpc/index.ts +++ b/packages/oxc/src/node/rpc/index.ts @@ -5,7 +5,6 @@ import { overview } from './functions/overview' import { oxlintGetConfigFile } from './functions/oxlint-get-config-file' import { oxfmtGetConfigFile } from './functions/oxfmt-get-config-file' import { openInEditor } from './functions/open-in-editor' -import '@vitejs/devtools-kit' export const rpcFunctions = [ oxlintListSessions, @@ -18,6 +17,8 @@ export const rpcFunctions = [ export type ServerFunctions = RpcDefinitionsToFunctions -declare module '@vitejs/devtools-kit' { - export interface DevToolsRpcServerFunctions extends ServerFunctions {} +// devframe ≥0.7.4: augment the canonical `devframe/types` module directly +// (renamed re-exports like the kit's `DevTools*` alias no longer merge). +declare module 'devframe/types' { + interface DevframeRpcServerFunctions extends ServerFunctions {} } diff --git a/packages/rolldown/package.json b/packages/rolldown/package.json index 86607271..50af3bb5 100644 --- a/packages/rolldown/package.json +++ b/packages/rolldown/package.json @@ -54,6 +54,7 @@ "comlink": "catalog:frontend", "d3": "catalog:frontend", "d3-hierarchy": "catalog:frontend", + "devframe": "catalog:deps", "diff-match-patch-es": "catalog:frontend", "floating-vue": "catalog:frontend", "fuse.js": "catalog:frontend", diff --git a/packages/rolldown/src/node/rpc/index.ts b/packages/rolldown/src/node/rpc/index.ts index e13418f6..67dc5a69 100644 --- a/packages/rolldown/src/node/rpc/index.ts +++ b/packages/rolldown/src/node/rpc/index.ts @@ -40,6 +40,8 @@ export type ServerFunctionsDump = { [K in keyof ServerFunctionsStatic]: Awaited> } -declare module '@vitejs/devtools-kit' { - export interface DevToolsRpcServerFunctions extends ServerFunctions {} +// devframe ≥0.7.4: augment the canonical `devframe/types` module directly +// (renamed re-exports like the kit's `DevTools*` alias no longer merge). +declare module 'devframe/types' { + interface DevframeRpcServerFunctions extends ServerFunctions {} } diff --git a/packages/vite/package.json b/packages/vite/package.json index d15b4421..ca002750 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -56,6 +56,7 @@ "@vueuse/nuxt": "catalog:build", "comlink": "catalog:frontend", "d3-hierarchy": "catalog:frontend", + "devframe": "catalog:deps", "diff-match-patch-es": "catalog:frontend", "floating-vue": "catalog:frontend", "fuse.js": "catalog:frontend", diff --git a/packages/vite/src/node/rpc/index.ts b/packages/vite/src/node/rpc/index.ts index 941d7bd2..939d38a8 100644 --- a/packages/vite/src/node/rpc/index.ts +++ b/packages/vite/src/node/rpc/index.ts @@ -42,10 +42,12 @@ export const rpcFunctions = [ export type ServerFunctions = RpcDefinitionsToFunctions -declare module '@vitejs/devtools-kit' { - export interface DevToolsRpcServerFunctions extends ServerFunctions {} +// devframe ≥0.7.4: augment the canonical `devframe/types` module directly +// (renamed re-exports like the kit's `DevTools*` alias no longer merge). +declare module 'devframe/types' { + interface DevframeRpcServerFunctions extends ServerFunctions {} - export interface DevToolsRpcSharedStates { + interface DevframeRpcSharedStates { 'vite:inspect:module-updated': ViteInspectModuleUpdatedState } } diff --git a/packages/vitest/src/node/plugin.ts b/packages/vitest/src/node/plugin.ts index 42b55cd0..a8c2a28c 100644 --- a/packages/vitest/src/node/plugin.ts +++ b/packages/vitest/src/node/plugin.ts @@ -1,6 +1,7 @@ import type { PluginWithDevTools } from '@vitejs/devtools-kit' import process from 'node:process' import { DEVTOOLS_VITEPLUS_GROUP_ID } from '@vitejs/devtools-kit/constants' +import { createProcessLauncher } from '@vitejs/devtools-kit/node' import { getPort } from 'get-port-please' import { isPackageExists } from 'local-pkg' import { addDependency } from 'nypm' @@ -20,15 +21,18 @@ const READY_TIMEOUT = 30_000 * A slim launcher for the Vitest UI, surfaced in the "Vite+" dock group. * * The dock only appears when the project depends on `vitest`. Clicking it - * installs `@vitest/ui` on demand (as a devDependency), spawns - * `vitest --ui` on a free port, waits for the server, then swaps the dock - * entry to an iframe embedding Vitest's own UI. + * installs `@vitest/ui` on demand (as a devDependency), spawns `vitest --ui` + * on a free port, streams the startup output as a digest, then swaps the dock + * entry to an iframe embedding Vitest's own UI once the server is ready. + * + * This is the canonical "run commands, start a server, then embed it" launcher + * built on the kit's `createProcessLauncher`. */ export function DevToolsVitestUI(): PluginWithDevTools { return { name: 'vite:devtools:vitest-ui', devtools: { - setup(ctx) { + async setup(ctx) { const cwd = ctx.cwd ?? process.cwd() // Hide the dock entirely when the project has no Vitest. @@ -40,95 +44,63 @@ export function DevToolsVitestUI(): PluginWithDevTools { const icon = `${VITEST_DEVTOOLS_BASE}favicon.svg` const hasUi = isPackageExists('@vitest/ui', { paths: [cwd] }) - // Remembered once the UI server is up, so a second launch reuses it. - let uiUrl: string | undefined - // The spawned child-process session (carries `terminate()`); the - // sessions map only exposes the base session shape. - let uiSession: Awaited> | undefined + // The chosen URL, shared between the spawn spec and the readiness probe. + let url: string - ctx.docks.register({ + const launcher = createProcessLauncher({ id: DOCK_ID, title: 'Vitest', groupId: DEVTOOLS_VITEPLUS_GROUP_ID, icon, - type: 'launcher', - launcher: { + label: 'Vitest UI', + description: hasUi + ? 'Start the Vitest UI and view it inside DevTools.' + : 'Install `@vitest/ui` (as a devDependency) and view it inside DevTools.', + buttonStart: hasUi ? 'Start Vitest UI' : 'Install @vitest/ui & start', + buttonLoading: 'Starting Vitest UI…', + command: { id: 'vite:devtools:vitest:start-ui', title: 'Start Vitest UI', icon }, + session: { + id: SESSION_ID, title: 'Vitest UI', - description: hasUi - ? 'Start the Vitest UI and view it inside DevTools.' - : 'Install `@vitest/ui` (as a devDependency) and view it inside DevTools.', - icon, - buttonStart: hasUi ? 'Start Vitest UI' : 'Install @vitest/ui & start', - buttonLoading: 'Starting Vitest UI…', - status: 'idle', - onLaunch: () => launch(), + // The Terminals panel maps session icons to a UnoCSS icon class + // (`toIconClass`) and can only render icons its SPA statically + // built. A served URL (like the dock favicon) or an unlisted icon + // renders blank, so use a terminal icon the SPA ships. + icon: 'ph:terminal-window-duotone', }, - }) - - async function launch(): Promise { - // Idempotent: reuse a still-running server instead of re-spawning. - // The sessions map reflects live status; `uiSession` holds the - // child-process handle we terminate before a fresh spawn. - const existing = ctx.terminals.sessions.get(SESSION_ID) - if (existing?.status === 'running' && uiUrl) { - swapToIframe(uiUrl) - return - } - // Install `@vitest/ui` on demand (devDependency) when missing. - if (!isPackageExists('@vitest/ui', { paths: [cwd] })) { - try { - await addDependency('@vitest/ui', { cwd, dev: true }) + prepare: async () => { + if (!isPackageExists('@vitest/ui', { paths: [cwd] })) { + try { + await addDependency('@vitest/ui', { cwd, dev: true }) + } + catch (error) { + throw diagnostics.VTDT0001({ error: error instanceof Error ? error.message : String(error) }) + } } - catch (error) { - throw diagnostics.VTDT0001({ error: error instanceof Error ? error.message : String(error) }) - } - } - - const port = await getPort({ port: PREFERRED_PORT, portRange: [PREFERRED_PORT, PREFERRED_PORT + 500] }) - const url = `http://localhost:${port}/${VITEST_UI_PATH}` - - // A dead session may linger — terminate it before re-spawning. - if (uiSession) - await uiSession.terminate().catch(() => {}) - - uiSession = await ctx.terminals.startChildProcess( - { + }, + process: async () => { + const port = await getPort({ port: PREFERRED_PORT, portRange: [PREFERRED_PORT, PREFERRED_PORT + 500] }) + url = `http://localhost:${port}/${VITEST_UI_PATH}` + return { command: 'vitest', // `--ui` runs in watch mode (needed for a persistent server); // `--no-open` keeps Vitest from opening a separate browser tab // since we embed it in the DevTools iframe instead. args: ['--ui', '--no-open', '--api.port', String(port)], cwd, + } + }, + serve: { + onReady: async () => { + if (!(await waitForServer(url, READY_TIMEOUT))) + throw diagnostics.VTDT0002({ url, timeout: READY_TIMEOUT }) + return url }, - { - id: SESSION_ID, - title: 'Vitest UI', - // The Terminals panel maps session icons to a UnoCSS icon class - // (`toIconClass`) and can only render icons its SPA statically - // built. A served URL (like the dock favicon) or an unlisted - // icon renders blank, so use a terminal icon the SPA ships. - icon: 'ph:terminal-window-duotone', - }, - ) - - if (!(await waitForServer(url, READY_TIMEOUT))) - throw diagnostics.VTDT0002({ url, timeout: READY_TIMEOUT }) - - uiUrl = url - swapToIframe(url) - } + }, + }) - function swapToIframe(url: string): void { - ctx.docks.update({ - id: DOCK_ID, - title: 'Vitest', - groupId: DEVTOOLS_VITEPLUS_GROUP_ID, - icon, - type: 'iframe', - url, - }) - } + await launcher.devtools!.setup!(ctx) }, }, } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 77708dc7..0b2700e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,17 +44,17 @@ catalogs: version: 0.3.1 deps: '@devframes/hub': - specifier: ^0.7.2 - version: 0.7.2 + specifier: ^0.7.5 + version: 0.7.5 '@devframes/plugin-inspect': - specifier: ^0.7.2 - version: 0.7.2 + specifier: ^0.7.4 + version: 0.7.5 '@devframes/plugin-messages': - specifier: ^0.7.2 - version: 0.7.2 + specifier: ^0.7.4 + version: 0.7.4 '@devframes/plugin-terminals': - specifier: ^0.7.2 - version: 0.7.2 + specifier: ^0.7.4 + version: 0.7.5 actionspack: specifier: ^0.1.5 version: 0.1.5 @@ -65,8 +65,8 @@ catalogs: specifier: ^4.0.0 version: 4.0.0 devframe: - specifier: ^0.7.2 - version: 0.7.2 + specifier: ^0.7.5 + version: 0.7.5 diff: specifier: ^9.0.0 version: 9.0.0 @@ -505,7 +505,7 @@ importers: version: 3.2.4(@vitejs/devtools@0.3.4)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3)) '@nuxt/eslint': specifier: catalog:devtools - version: 1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + version: 1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) '@nuxt/icon': specifier: catalog:build version: 2.3.1(magicast@0.5.2)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3)) @@ -646,7 +646,7 @@ importers: version: 5.0.2(change-case@5.4.4)(focus-trap@8.2.2)(fuse.js@7.5.0)(idb-keyval@6.3.0)(vite@8.1.4(@types/node@25.0.3)(@vitejs/devtools@packages+core)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0))(vitepress@2.0.0-alpha.18(@types/node@25.0.3)(@vitejs/devtools@packages+core)(change-case@5.4.4)(esbuild@0.28.1)(fuse.js@7.5.0)(idb-keyval@6.3.0)(jiti@2.7.0)(postcss@8.5.16)(terser@5.44.1)(tsx@4.23.1)(typescript@6.0.3)(yaml@2.9.0))(vue@3.5.39(typescript@6.0.3)) devframe: specifier: catalog:deps - version: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + version: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) mermaid: specifier: catalog:docs version: 11.16.0 @@ -790,16 +790,16 @@ importers: dependencies: '@devframes/hub': specifier: catalog:deps - version: 0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)) + version: 0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)) '@devframes/plugin-inspect': specifier: catalog:deps - version: 0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.4) + version: 0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.4) '@devframes/plugin-messages': specifier: catalog:deps - version: 0.7.2(@devframes/hub@0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)))(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(vite@8.1.4) + version: 0.7.4(@devframes/hub@0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)))(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(vite@8.1.4) '@devframes/plugin-terminals': specifier: catalog:deps - version: 0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.4) + version: 0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.4) '@vitejs/devtools-kit': specifier: workspace:* version: link:../kit @@ -814,7 +814,7 @@ importers: version: 7.0.0 devframe: specifier: catalog:deps - version: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + version: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) h3: specifier: catalog:deps version: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.15)) @@ -893,10 +893,10 @@ importers: dependencies: '@devframes/hub': specifier: catalog:deps - version: 0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)) + version: 0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)) devframe: specifier: catalog:deps - version: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + version: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) local-pkg: specifier: catalog:deps version: 1.2.1 @@ -936,7 +936,7 @@ importers: version: 4.3.1 devframe: specifier: catalog:deps - version: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + version: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) gunshi: specifier: catalog:deps version: 0.36.0 @@ -1077,6 +1077,9 @@ importers: d3-hierarchy: specifier: catalog:frontend version: 3.1.2 + devframe: + specifier: catalog:deps + version: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) diff-match-patch-es: specifier: catalog:frontend version: 1.0.1 @@ -1204,6 +1207,9 @@ importers: d3-hierarchy: specifier: catalog:frontend version: 3.1.2 + devframe: + specifier: catalog:deps + version: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) diff-match-patch-es: specifier: catalog:frontend version: 1.0.1 @@ -1310,7 +1316,7 @@ importers: version: 6.0.7(vite@8.1.4(@types/node@25.0.3)(@vitejs/devtools@packages+core)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0))(vue@3.5.39(typescript@5.9.3)) devframe: specifier: catalog:deps - version: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@5.9.3) + version: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@5.9.3) storybook: specifier: catalog:storybook version: 10.5.0(@types/react@19.2.17)(prettier@2.8.8)(react@19.2.7) @@ -1613,10 +1619,10 @@ packages: peerDependencies: devframe: 0.6.2 - '@devframes/hub@0.7.2': - resolution: {integrity: sha512-DaVfHf5QsNhUtVdHUciOhnsycX6sk+XXJs5D4oXXAwATNSETC8l4he9dKcdiKxqAiQ0eTU0TUmNYFyBsRslBfw==} + '@devframes/hub@0.7.5': + resolution: {integrity: sha512-+DSelDB/zQOyVGL8e9txvspVOvJKcNMyq6cR9bzzPMal7K9hOkedD6whR3X6EmwFjQjAOvQN1Xrm+0WWz5NPgw==} peerDependencies: - devframe: 0.7.2 + devframe: 0.7.5 '@devframes/plugin-inspect@0.6.2': resolution: {integrity: sha512-sXPWu/FII13lBx9zQFVXD9w9sey57ii7LN23YiD/1neF3tVG9bZ/ZHmGjST+1qvCcszGAGKmMROBK6RlfGYWog==} @@ -1628,11 +1634,11 @@ packages: vite: optional: true - '@devframes/plugin-inspect@0.7.2': - resolution: {integrity: sha512-dasuNL1rGwzXqzdi2MwdVJek4XBIm1ap3ucXdkBANBi4uAgCTVf+ZZPdZJdk6l/3JBvQHHFbyFAEiSdnEIBWUA==} + '@devframes/plugin-inspect@0.7.5': + resolution: {integrity: sha512-t9dt5TjLMSLVtyTtSPzciptZhOeaK2lUfSyZ169fKhaJem38gsJdej5NKEyuWP3T3CDdtH/zqiFyEAef8bk/ng==} hasBin: true peerDependencies: - devframe: 0.7.2 + devframe: 0.7.5 vite: ^8.1.4 peerDependenciesMeta: vite: @@ -1649,12 +1655,12 @@ packages: vite: optional: true - '@devframes/plugin-messages@0.7.2': - resolution: {integrity: sha512-f8LNaIaeB6Gi4f5Rl/9CkeU6ce95P1abd6dAM9SohEgnRbb4jt5wkll3ftnGVRWbwGM+o4iLxS2xMe4yAhIwtg==} + '@devframes/plugin-messages@0.7.4': + resolution: {integrity: sha512-v/GX++nsF8T863pkAmFDsEt3IhBeBdw7KQZ8RbIdLei7z9bx6OE3yXm3r06OFs0jSSol9tJFNs7k/R1ILoDj8w==} hasBin: true peerDependencies: - '@devframes/hub': 0.7.2 - devframe: 0.7.2 + '@devframes/hub': 0.7.4 + devframe: 0.7.4 vite: ^8.1.4 peerDependenciesMeta: vite: @@ -1670,11 +1676,11 @@ packages: vite: optional: true - '@devframes/plugin-terminals@0.7.2': - resolution: {integrity: sha512-XfVCSCvL4wNoIzmgKeYsUiPjnCmWQWTolyeHX89eG7KYkMI8a/aJ3LaprznjW7N2Og7C50y2i0DMj/4Sidq7FA==} + '@devframes/plugin-terminals@0.7.5': + resolution: {integrity: sha512-4gQaR2u0WLWGnylpfBO3UfyeqIQq9tWQUq8El9YJgi9DrZyBI74LH2MRwr+Y6SkZPFNmPWpaDgpjY+GeX4bVUg==} hasBin: true peerDependencies: - devframe: 0.7.2 + devframe: 0.7.5 vite: ^8.1.4 peerDependenciesMeta: vite: @@ -5828,14 +5834,6 @@ packages: srvx: optional: true - crossws@0.4.9: - resolution: {integrity: sha512-iWx+1OMSG2aOHpjyf9AESOzkwsVdS49cXM9dVrI2PDhxU5l2RIWE/KG56gk4BbAnsMoycvniJ9OnOxO9LRzHVA==} - peerDependencies: - srvx: '>=0.11.5' - peerDependenciesMeta: - srvx: - optional: true - css-select@5.2.2: resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} @@ -6161,8 +6159,8 @@ packages: '@modelcontextprotocol/sdk': optional: true - devframe@0.7.2: - resolution: {integrity: sha512-M67ky6eMtU3wbwNjDOXcpYJr5tqqjsf+B2r4/5bKppFdGu1HXnedqHl6UYhuV4AedFAYbsuHrKBAREE+oVYCZg==} + devframe@0.7.5: + resolution: {integrity: sha512-NdP655Am1VGTwt5ynArBmX4gs7MDdGy0fBqQngZLfs0HPhz7vveODUu01YDP/nEH7uIo+fVCieIYeITmJl/P/A==} peerDependencies: '@modelcontextprotocol/sdk': ^1.0.0 cac: ^7.0.0 @@ -10090,10 +10088,10 @@ snapshots: '@colordx/core@5.4.3': {} - '@devframes/hub@0.5.4(devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': + '@devframes/hub@0.5.4(devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': dependencies: birpc: 4.0.0 - devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) nostics: 0.2.0(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) pathe: 2.0.3 perfect-debounce: 2.1.0 @@ -10121,11 +10119,11 @@ snapshots: tinyexec: 1.2.4 zigpty: 0.2.1 - '@devframes/hub@0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))': + '@devframes/hub@0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))': dependencies: birpc: 4.0.0 destr: 2.0.5 - devframe: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + devframe: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) nostics: 1.1.4 pathe: 2.0.3 perfect-debounce: 2.1.0 @@ -10143,11 +10141,11 @@ snapshots: - valibot optional: true - '@devframes/plugin-inspect@0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.4)': + '@devframes/plugin-inspect@0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(valibot@1.4.2(typescript@6.0.3))(vite@8.1.4)': dependencies: '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) cac: 7.0.0 - devframe: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + devframe: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) nostics: 1.1.4 optionalDependencies: vite: 8.1.4(@types/node@25.0.3)(@vitejs/devtools@0.3.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) @@ -10163,11 +10161,11 @@ snapshots: vite: 8.1.4(@types/node@25.0.3)(@vitejs/devtools@0.4.1)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) optional: true - '@devframes/plugin-messages@0.7.2(@devframes/hub@0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)))(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(vite@8.1.4)': + '@devframes/plugin-messages@0.7.4(@devframes/hub@0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)))(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(vite@8.1.4)': dependencies: - '@devframes/hub': 0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)) + '@devframes/hub': 0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3)) cac: 7.0.0 - devframe: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + devframe: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) nostics: 1.1.4 optionalDependencies: vite: 8.1.4(@types/node@25.0.3)(@vitejs/devtools@0.3.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.44.1)(tsx@4.23.1)(yaml@2.9.0) @@ -10187,12 +10185,12 @@ snapshots: - typescript optional: true - '@devframes/plugin-terminals@0.7.2(devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.4)': + '@devframes/plugin-terminals@0.7.5(devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3))(typescript@6.0.3)(vite@8.1.4)': dependencies: '@xterm/addon-fit': 0.11.0 '@xterm/xterm': 6.0.0 cac: 7.0.0 - devframe: 0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) + devframe: 0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3) nostics: 1.1.4 pathe: 2.0.3 valibot: 1.4.2(typescript@6.0.3) @@ -10405,12 +10403,12 @@ snapshots: dependencies: '@eslint/core': 1.2.1 - '@eslint/config-inspector@3.0.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': + '@eslint/config-inspector@3.0.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': dependencies: ansis: 4.3.1 cac: 7.0.0 chokidar: 5.0.0 - devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) eslint: 10.7.0(jiti@2.7.0) jiti: 2.7.0 tinyglobby: 0.2.17 @@ -10829,7 +10827,7 @@ snapshots: which: 6.0.1 ws: 8.21.0 optionalDependencies: - '@vitejs/devtools': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@vitejs/devtools': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) transitivePeerDependencies: - bufferutil - supports-color @@ -10919,9 +10917,9 @@ snapshots: - supports-color - typescript - '@nuxt/eslint@1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': + '@nuxt/eslint@1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(magicast@0.5.2)(oxc-parser@0.133.0)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': dependencies: - '@eslint/config-inspector': 3.0.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@eslint/config-inspector': 3.0.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(eslint@10.7.0(jiti@2.7.0))(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) '@nuxt/devtools-kit': 3.2.4(magicast@0.5.2)(vite@8.1.4) '@nuxt/eslint-config': 1.16.0(@typescript-eslint/utils@8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3))(@vue/compiler-sfc@3.5.39)(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) '@nuxt/eslint-plugin': 1.16.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) @@ -13362,11 +13360,11 @@ snapshots: - rollup - supports-color - '@vitejs/devtools-kit@0.3.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': + '@vitejs/devtools-kit@0.3.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': dependencies: - '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) birpc: 4.0.0 - devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) mlly: 1.8.2 nostics: 1.1.4 pathe: 2.0.3 @@ -13401,18 +13399,18 @@ snapshots: - srvx - typescript - '@vitejs/devtools-rolldown@0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1))': + '@vitejs/devtools-rolldown@0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1))': dependencies: '@floating-ui/dom': 1.8.0 '@rolldown/debug': 1.1.5 - '@vitejs/devtools-kit': 0.3.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@vitejs/devtools-kit': 0.3.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) birpc: 4.0.0 cac: 7.0.0 d3-shape: 3.2.0 - devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) diff: 9.0.0 get-port-please: 3.2.0 - h3: 2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15)) + h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.15)) mlly: 1.8.2 mrmime: 2.0.1 nostics: 1.1.4 @@ -13479,15 +13477,15 @@ snapshots: - vue optional: true - '@vitejs/devtools@0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': + '@vitejs/devtools@0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1))': dependencies: - '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) - '@vitejs/devtools-kit': 0.3.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) - '@vitejs/devtools-rolldown': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1)) + '@devframes/hub': 0.5.4(devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@vitejs/devtools-kit': 0.3.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@vitejs/devtools-rolldown': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(vue@3.5.39(typescript@6.0.3))(webpack@5.104.1(esbuild@0.28.1)) birpc: 4.0.0 cac: 7.0.0 - devframe: 0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) - h3: 2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15)) + devframe: 0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.15)) mlly: 1.8.2 nostics: 1.1.4 obug: 2.1.3 @@ -14586,10 +14584,6 @@ snapshots: optionalDependencies: srvx: 0.11.15 - crossws@0.4.9(srvx@0.11.15): - optionalDependencies: - srvx: 0.11.15 - css-select@5.2.2: dependencies: boolbase: 1.0.0 @@ -14900,12 +14894,12 @@ snapshots: devalue@5.8.1: {} - devframe@0.5.4(crossws@0.4.9(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)): + devframe@0.5.4(crossws@0.4.10(srvx@0.11.15))(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)): dependencies: '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) birpc: 4.0.0 cac: 7.0.0 - h3: 2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15)) + h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.15)) mrmime: 2.0.1 nostics: 0.2.0(esbuild@0.28.1)(rolldown@1.1.5)(rollup@4.60.2)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) pathe: 2.0.3 @@ -14943,7 +14937,7 @@ snapshots: - srvx - typescript - devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@5.9.3): + devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@5.9.3): dependencies: '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) birpc: 4.0.0 @@ -14961,7 +14955,7 @@ snapshots: - srvx - typescript - devframe@0.7.2(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3): + devframe@0.7.5(cac@7.0.0)(srvx@0.11.15)(typescript@6.0.3): dependencies: '@valibot/to-json-schema': 1.7.1(valibot@1.4.2(typescript@6.0.3)) birpc: 4.0.0 @@ -15737,13 +15731,6 @@ snapshots: optionalDependencies: crossws: 0.4.10(srvx@0.11.15) - h3@2.0.1-rc.22(crossws@0.4.9(srvx@0.11.15)): - dependencies: - rou3: 0.8.1 - srvx: 0.11.15 - optionalDependencies: - crossws: 0.4.9(srvx@0.11.15) - hachure-fill@0.5.2: {} has-flag@4.0.0: {} @@ -16142,7 +16129,7 @@ snapshots: '@parcel/watcher-wasm': 2.5.6 citty: 0.2.2 consola: 3.4.2 - crossws: 0.4.9(srvx@0.11.15) + crossws: 0.4.10(srvx@0.11.15) defu: 6.1.7 get-port-please: 3.2.0 h3: 1.15.11 @@ -18770,7 +18757,7 @@ snapshots: tree-kill: 1.2.2 unconfig-core: 7.5.0 optionalDependencies: - '@vitejs/devtools': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@vitejs/devtools': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) publint: 0.3.21 tsx: 4.23.1 typescript: 6.0.3 @@ -19456,7 +19443,7 @@ snapshots: tinyglobby: 0.2.17 optionalDependencies: '@types/node': 25.0.3 - '@vitejs/devtools': 0.3.4(crossws@0.4.9(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) + '@vitejs/devtools': 0.3.4(crossws@0.4.10(srvx@0.11.15))(db0@0.3.4)(esbuild@0.28.1)(idb-keyval@6.3.0)(ioredis@5.10.1)(rolldown@1.1.5)(rollup@4.60.2)(typescript@6.0.3)(vite@8.1.4)(webpack@5.104.1(esbuild@0.28.1)) esbuild: 0.28.1 fsevents: 2.3.3 jiti: 2.7.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index dd0bdc3a..e7185830 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -59,16 +59,16 @@ catalogs: unrun: ^0.3.1 vite: ^8.1.4 deps: - '@devframes/hub': ^0.7.2 - '@devframes/plugin-inspect': ^0.7.2 - '@devframes/plugin-messages': ^0.7.2 - '@devframes/plugin-terminals': ^0.7.2 + '@devframes/hub': ^0.7.5 + '@devframes/plugin-inspect': ^0.7.4 + '@devframes/plugin-messages': ^0.7.4 + '@devframes/plugin-terminals': ^0.7.4 '@rolldown/debug': ^1.1.5 actionspack: ^0.1.5 ansis: ^4.3.1 birpc: ^4.0.0 cac: ^7.0.0 - devframe: ^0.7.2 + devframe: ^0.7.5 diff: ^9.0.0 envinfo: ^7.21.0 get-port-please: ^3.2.0 diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts index 00e445dd..20792104 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts @@ -8,6 +8,7 @@ export declare const DEVTOOLS_DOCK_IMPORTS_VIRTUAL_ID: string; export declare const DEVTOOLS_INSPECTOR_DOCK_ID: string; export declare const DEVTOOLS_MOUNT_PATH: string; export declare const DEVTOOLS_MOUNT_PATH_NO_TRAILING_SLASH: string; +export declare const DEVTOOLS_TERMINALS_DOCK_ID: string; export declare const DEVTOOLS_VITEPLUS_GROUP_ID: string; export declare const DEVTOOLS_WS_PATH: string; export declare const DEVTOOLS_WS_ROUTE: string; diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js index 2f2cf2a4..60d24978 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js @@ -8,6 +8,7 @@ export var DEVTOOLS_DOCK_IMPORTS_VIRTUAL_ID /* const */ export var DEVTOOLS_INSPECTOR_DOCK_ID /* const */ export var DEVTOOLS_MOUNT_PATH /* const */ export var DEVTOOLS_MOUNT_PATH_NO_TRAILING_SLASH /* const */ +export var DEVTOOLS_TERMINALS_DOCK_ID /* const */ export var DEVTOOLS_VITEPLUS_GROUP_ID /* const */ export var DEVTOOLS_WS_PATH /* const */ export var DEVTOOLS_WS_ROUTE /* const */ diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts index 73a78af0..77539c11 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/index.snapshot.d.ts @@ -54,11 +54,13 @@ export { DevToolsCommandsHostEvents } export { DevToolsDiagnosticsDefinition } export { DevToolsDiagnosticsHost } export { DevToolsDiagnosticsLogger } +export { DevToolsDockActivation } export { DevToolsDockEntriesGrouped } export { DevToolsDockEntry } export { DevToolsDockEntryBase } export { DevToolsDockEntryIcon } export { DevToolsDockHost } +export { DevToolsDocksActiveState } export { DevToolsDocksUserSettings } export { DevToolsDockUserEntry } export { DevToolsHost } diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.d.ts index 27e5bbf1..80c31e4c 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.d.ts @@ -35,6 +35,33 @@ export interface KitNodeContext extends DevframeHubContext { readonly viteConfig?: ResolvedConfig; readonly viteServer?: ViteDevServer; } +export interface ProcessLauncherOptions { + id: string; + title: string; + icon: DevframeDockEntryIcon; + groupId?: string; + label?: string; + description?: string; + buttonStart?: string; + buttonLoading?: string; + process: DevToolsChildProcessExecuteOptions | (() => Awaitable); + prepare?: () => Awaitable; + serve?: { + onReady: (_: DevToolsChildProcessTerminalSession) => Awaitable; + }; + command?: { + id?: string; + title?: string; + icon?: DevframeDockEntryIcon; + keybindings?: DevToolsCommandKeybinding[]; + }; + session?: { + id?: string; + title?: string; + icon?: DevframeDockEntryIcon; + }; + name?: string; +} export interface ViteDevToolsHost extends DevframeHost { provideConnectionMeta: (_: () => ConnectionMeta | Promise) => void; } @@ -44,6 +71,7 @@ export interface ViteDevToolsHost extends DevframeHost { export declare function createInstallLauncher(_: InstallLauncherOptions): PluginWithDevTools; export declare function createKitContext(_: CreateKitContextOptions): Promise; export declare function createPluginFromDevframe(_: DevframeDefinition, _?: CreatePluginFromDevframeOptions): PluginWithDevTools; +export declare function createProcessLauncher(_: ProcessLauncherOptions): PluginWithDevTools; export declare function createSimpleClientScript(_: string | ((_: any) => void)): ClientScriptEntry; export declare function createViteDevToolsHost(_: CreateViteDevToolsHostOptions): ViteDevToolsHost; // #endregion diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.js b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.js index c635df7c..6a399fae 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.js +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/node.snapshot.js @@ -5,6 +5,7 @@ export function createInstallLauncher(_) {} export async function createKitContext(_) {} export function createPluginFromDevframe(_, _) {} +export function createProcessLauncher(_) {} export function createSimpleClientScript(_) {} export function createViteDevToolsHost(_) {} // #endregion