From 549eeff91fced2bd6696ea165757e812c65c307f Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:24 -0600 Subject: [PATCH 01/14] feat(action-buttons): add shared action button package Introduce ActionBar, Button, ActionMenu, SplitButton, and Actions with JOO color variants for PageShell identity and local chrome. --- components/action-buttons/.gitignore | 1 + components/action-buttons/AGENTS.md | 41 + components/action-buttons/CHANGELOG.md | 12 + components/action-buttons/LICENSE | 21 + components/action-buttons/README.md | 97 + components/action-buttons/dist/index.d.ts | 156 + components/action-buttons/dist/index.js | 348 ++ components/action-buttons/dist/index.js.map | 1 + components/action-buttons/dist/styles.css | 354 ++ components/action-buttons/package-lock.json | 4389 +++++++++++++++++ components/action-buttons/package.json | 74 + .../action-buttons/src/ActionButtons.test.tsx | 183 + .../src/components/ActionBar.tsx | 17 + .../src/components/ActionIcon.tsx | 15 + .../src/components/ActionMenu.tsx | 80 + .../action-buttons/src/components/Actions.tsx | 68 + .../action-buttons/src/components/Button.tsx | 69 + .../src/components/SplitButton.tsx | 53 + .../src/components/ui/dropdown-menu.tsx | 63 + components/action-buttons/src/index.ts | 27 + components/action-buttons/src/intent.ts | 71 + components/action-buttons/src/lib/cn.ts | 6 + components/action-buttons/src/styles.css | 354 ++ components/action-buttons/src/types.ts | 141 + components/action-buttons/tsconfig.json | 16 + components/action-buttons/tsup.config.ts | 11 + components/action-buttons/vitest.config.ts | 8 + 27 files changed, 6676 insertions(+) create mode 100644 components/action-buttons/.gitignore create mode 100644 components/action-buttons/AGENTS.md create mode 100644 components/action-buttons/CHANGELOG.md create mode 100644 components/action-buttons/LICENSE create mode 100644 components/action-buttons/README.md create mode 100644 components/action-buttons/dist/index.d.ts create mode 100644 components/action-buttons/dist/index.js create mode 100644 components/action-buttons/dist/index.js.map create mode 100644 components/action-buttons/dist/styles.css create mode 100644 components/action-buttons/package-lock.json create mode 100644 components/action-buttons/package.json create mode 100644 components/action-buttons/src/ActionButtons.test.tsx create mode 100644 components/action-buttons/src/components/ActionBar.tsx create mode 100644 components/action-buttons/src/components/ActionIcon.tsx create mode 100644 components/action-buttons/src/components/ActionMenu.tsx create mode 100644 components/action-buttons/src/components/Actions.tsx create mode 100644 components/action-buttons/src/components/Button.tsx create mode 100644 components/action-buttons/src/components/SplitButton.tsx create mode 100644 components/action-buttons/src/components/ui/dropdown-menu.tsx create mode 100644 components/action-buttons/src/index.ts create mode 100644 components/action-buttons/src/intent.ts create mode 100644 components/action-buttons/src/lib/cn.ts create mode 100644 components/action-buttons/src/styles.css create mode 100644 components/action-buttons/src/types.ts create mode 100644 components/action-buttons/tsconfig.json create mode 100644 components/action-buttons/tsup.config.ts create mode 100644 components/action-buttons/vitest.config.ts diff --git a/components/action-buttons/.gitignore b/components/action-buttons/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/components/action-buttons/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/components/action-buttons/AGENTS.md b/components/action-buttons/AGENTS.md new file mode 100644 index 0000000..bd5b9f0 --- /dev/null +++ b/components/action-buttons/AGENTS.md @@ -0,0 +1,41 @@ +# action-buttons package agents + +@jooservices/react-action-buttons — ActionBar, Button, ActionMenu, SplitButton. + +## Paths + +- Source: `components/action-buttons/src` +- Entry: `components/action-buttons/src/index.ts` +- Build output: `components/action-buttons/dist` (committed) + +## Commands + +```bash +cd components/action-buttons +npm install # first time +npm run typecheck +npm test +npm run build +``` + +## Peers + +`react`, `react-dom`, `lucide-react` + +## Placement with PageShell (required) + +When used on a `PageShell` page: + +1. **Primary / global view actions** → only `PageShellIdentity` `actions` (Primary action). **No exceptions.** +2. Compose with `ActionBar` + `Button` / `ActionMenu` / `SplitButton`. +3. Prefer `intent` + `ACTION_COLOR_GUIDE` as developer guidance; explicit `variant` wins. +4. **Isolated** buttons (filters, row menus, empty states) may use this package elsewhere — they are not Primary action and must not replace Identity CTAs. +5. **ConfigPanel:** Create / New / Publish / Export → Identity only; call `ConfigPanelHandle.openCreate()` from the Identity Create button (`components/config/AGENTS.md`). + +See `components/content/AGENTS.md` for the full PageShell placement rule. + +## Docs + +- User guide: `docs/02-user-guide/08-react-action-buttons.md` (consumer API — do not send humans to `src/`) +- Package README: `components/action-buttons/README.md` +- Root policy: `AGENTS.md` diff --git a/components/action-buttons/CHANGELOG.md b/components/action-buttons/CHANGELOG.md new file mode 100644 index 0000000..2a49329 --- /dev/null +++ b/components/action-buttons/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +All notable changes to this package are documented in this file. + +## [Unreleased] + +### Added + +- Docs/AGENTS: Primary action placement — view CTAs only in `PageShellIdentity` → `actions` via this package +- Initial `@jooservices/react-action-buttons` package: `Button`, `ActionBar`, `ActionMenu`, `SplitButton`, `Actions` +- Bootstrap-inspired colors (JOO cyan-tuned): `primary`, `secondary`, `success`, `danger`, `warning`, `info`, `light`, `dark`, plus `outline` / `ghost`; `BUTTON_VARIANTS` gallery export +- `ACTION_COLOR_GUIDE` — recommended action → color (`intent` guides; `variant` wins); `apply`/`publish` → `dark`; leading `icon` support diff --git a/components/action-buttons/LICENSE b/components/action-buttons/LICENSE new file mode 100644 index 0000000..e630730 --- /dev/null +++ b/components/action-buttons/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 JOOservices + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/action-buttons/README.md b/components/action-buttons/README.md new file mode 100644 index 0000000..b93e97e --- /dev/null +++ b/components/action-buttons/README.md @@ -0,0 +1,97 @@ +# @jooservices/react-action-buttons + +Shared action button primitives — separate or grouped bars, dropdown menus, and split buttons. + +## Install + +```bash +pnpm add "github:jooservices/react#v1.0.0&path:components/action-buttons" +``` + +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). + +## Setup + +```ts +import "@jooservices/react-action-buttons/styles.css"; +``` + +## Button colors (Bootstrap-inspired, JOO cyan-tuned) + +| Variant | Look | +|---------|------| +| `primary` | Cyan brand CTA | +| `secondary` | Solid gray | +| `success` | Green | +| `danger` | Red (`destructive` alias) | +| `warning` | Amber | +| `info` | Lighter cyan | +| `light` | Soft surface | +| `dark` | Near-black strong CTA (former solid primary look) | +| `outline` | Bordered (default) | +| `ghost` | Transparent | + +Export `BUTTON_VARIANTS` for galleries. + +## Placement with PageShell (required) + +**Primary / global view actions** → `PageShellIdentity` → `actions` only. **No exceptions.** + +```tsx +import { ActionBar, Button } from "@jooservices/react-action-buttons"; +import { PageShellIdentity } from "@jooservices/react-content"; + + + + + } +/> +``` + +Other uses of this package (filters, row menus, empty states) are **local / isolated** — never a substitute for Identity Primary action. See `components/content/AGENTS.md`. + +## Action → color guide (not enforced) + +`intent` is optional. **`variant` always wins** when set. + +| Intent | Suggested | +|--------|-----------| +| `create`, `save` | `primary` | +| `edit` | `secondary` | +| `export`, `cancel` | `outline` | +| `more`, `view` | `ghost` | +| `apply`, `publish` | `dark` | +| `delete`, `remove` | `danger` | + +## Usage + +```tsx +import { ActionBar, BUTTON_VARIANTS, Button } from "@jooservices/react-action-buttons"; + + + {BUTTON_VARIANTS.map((variant) => ( + + ))} +; +``` + +## API + +| Export | Description | +|--------|-------------| +| `Button` | `variant`, optional `intent` + `icon`, sizes `sm`\|`md`\|`icon` | +| `ActionBar` | `layout`: `separate` (default) / `group` | +| `ActionMenu` | Trigger + `items: ActionItem[]` | +| `SplitButton` | Primary `onClick` + overflow `items` | +| `Actions` | Declarative `ActionDescriptor[]` (`single` \| `menu` \| `split`) | +| `BUTTON_VARIANTS` | Ordered gallery list | +| `ACTION_COLOR_GUIDE` | Recommended intent → color | + +Full prop tables and recipes: `docs/02-user-guide/08-react-action-buttons.md`. diff --git a/components/action-buttons/dist/index.d.ts b/components/action-buttons/dist/index.d.ts new file mode 100644 index 0000000..ebe14cd --- /dev/null +++ b/components/action-buttons/dist/index.d.ts @@ -0,0 +1,156 @@ +import * as react from 'react'; +import { ReactNode, ButtonHTMLAttributes } from 'react'; + +/** Semantic action hint — see `ACTION_COLOR_GUIDE` (guidance only). */ +type ActionIntent = "create" | "save" | "edit" | "export" | "cancel" | "more" | "view" | "apply" | "publish" | "delete" | "remove"; +type ActionItemVariant = "default" | "danger" | "destructive"; +type ActionItem = { + label: string; + icon?: ReactNode; + onClick: () => void; + disabled?: boolean; + /** Suggested action kind (color guide). Overridden by `variant` when set. */ + intent?: ActionIntent; + variant?: ActionItemVariant; +}; +/** + * Bootstrap-inspired solid colors (JOO-tuned) plus outline/ghost utilities. + * Gallery order: primary → secondary → success → danger → warning → info → light → dark → outline → ghost + */ +type ButtonVariant = "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark" | "outline" | "ghost" +/** @deprecated Prefer `danger` */ + | "destructive"; +type ButtonSize = "sm" | "md" | "icon"; +type ActionBarLayout = "separate" | "group"; +type ActionBarProps = { + children: ReactNode; + layout?: ActionBarLayout; + className?: string; +}; +type ButtonProps = ButtonHTMLAttributes & { + /** + * Optional action hint for developers / docs. When `variant` is omitted, + * color defaults from `ACTION_COLOR_GUIDE`. Explicit `variant` always wins. + */ + intent?: ActionIntent; + /** Explicit color. Always wins over `intent` when provided. */ + variant?: ButtonVariant; + size?: ButtonSize; + /** Leading icon (Lucide or custom). Shown beside label; alone when `size="icon"`. */ + icon?: ReactNode; + asChild?: boolean; + className?: string; +}; +type ActionMenuProps = { + label: string; + items: ActionItem[]; + icon?: ReactNode; + disabled?: boolean; + intent?: ActionIntent; + variant?: ButtonVariant; + size?: ButtonSize; + className?: string; +}; +type SplitButtonProps = { + label: string; + onClick: () => void; + items: ActionItem[]; + icon?: ReactNode; + disabled?: boolean; + intent?: ActionIntent; + variant?: ButtonVariant; + size?: Exclude; + className?: string; + menuLabel?: string; +}; +type ActionDescriptorBase = { + label: string; + icon?: ReactNode; + disabled?: boolean; + intent?: ActionIntent; + variant?: ButtonVariant; +}; +type ActionDescriptor = (ActionDescriptorBase & { + type: "single"; + onClick: () => void; + size?: ButtonSize; +}) | (ActionDescriptorBase & { + type: "menu"; + items: ActionItem[]; + size?: ButtonSize; +}) | (ActionDescriptorBase & { + type: "split"; + onClick: () => void; + items: ActionItem[]; + size?: Exclude; + menuLabel?: string; +}); +type ActionsProps = { + items: ActionDescriptor[]; + layout?: ActionBarLayout; + className?: string; +}; +/** All variants shown in demos / docs (Bootstrap-like + outline/ghost). */ +declare const BUTTON_VARIANTS: ButtonVariant[]; + +declare function ActionBar({ children, layout, className }: ActionBarProps): react.JSX.Element; + +declare function Actions({ items, layout, className }: ActionsProps): react.JSX.Element | null; + +declare function ActionMenu({ label, items, icon, disabled, intent, variant, size, className, }: ActionMenuProps): react.JSX.Element; + +declare function Button({ className, intent, variant, size, icon, asChild, type, children, ...props }: ButtonProps): react.JSX.Element; + +declare function SplitButton({ label, onClick, items, icon, disabled, intent, variant, size, className, menuLabel, }: SplitButtonProps): react.JSX.Element; + +/** + * Developer guide — recommended action → color. + * Not enforced: pass `variant` explicitly to override. + * + * | Intent | Suggested color | Typical use | + * |------------------------|-----------------|--------------------------------| + * | `create`, `save` | primary | Add / persist (cyan brand CTA) | + * | `edit` | secondary | Soft gray modify | + * | `export`, `cancel` | outline | Bordered alternate | + * | `more`, `view` | ghost | Quiet / overflow | + * | `apply`, `publish` | dark | Strong neutral CTA (near-black)| + * | `delete`, `remove` | danger | Irreversible remove | + */ +declare const ACTION_COLOR_GUIDE: { + readonly create: "primary"; + readonly save: "primary"; + readonly edit: "secondary"; + readonly export: "outline"; + readonly cancel: "outline"; + readonly more: "ghost"; + readonly view: "ghost"; + readonly apply: "dark"; + readonly publish: "dark"; + readonly delete: "danger"; + readonly remove: "danger"; +}; +/** @deprecated Use `ACTION_COLOR_GUIDE` — same map, guidance only. */ +declare const ACTION_INTENT_VARIANT: { + readonly create: "primary"; + readonly save: "primary"; + readonly edit: "secondary"; + readonly export: "outline"; + readonly cancel: "outline"; + readonly more: "ghost"; + readonly view: "ghost"; + readonly apply: "dark"; + readonly publish: "dark"; + readonly delete: "danger"; + readonly remove: "danger"; +}; +/** + * Resolve button color: explicit `variant` always wins. + * `intent` only suggests a default when `variant` is omitted. + */ +declare function resolveButtonVariant(intent: ActionIntent | undefined, variant: ButtonVariant | undefined, fallback?: ButtonVariant): ButtonVariant; +/** + * Menu row tone: explicit `variant` wins; `intent` suggests danger for delete/remove. + */ +declare function resolveMenuItemVariant(intent: ActionIntent | undefined, variant: "default" | "danger" | "destructive" | undefined): "default" | "destructive"; + +export { ACTION_COLOR_GUIDE, ACTION_INTENT_VARIANT, ActionBar, type ActionBarLayout, type ActionBarProps, type ActionDescriptor, type ActionIntent, type ActionItem, type ActionItemVariant, ActionMenu, type ActionMenuProps, Actions, type ActionsProps, BUTTON_VARIANTS, Button, type ButtonProps, type ButtonSize, type ButtonVariant, SplitButton, type SplitButtonProps, resolveButtonVariant, resolveMenuItemVariant }; diff --git a/components/action-buttons/dist/index.js b/components/action-buttons/dist/index.js new file mode 100644 index 0000000..d751a76 --- /dev/null +++ b/components/action-buttons/dist/index.js @@ -0,0 +1,348 @@ +import { clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; +import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; +import { ChevronDown } from 'lucide-react'; +import { Slot } from '@radix-ui/react-slot'; +import { cva } from 'class-variance-authority'; +import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; + +// src/lib/cn.ts +function cn(...inputs) { + return twMerge(clsx(inputs)); +} +function ActionBar({ children, layout = "separate", className }) { + return /* @__PURE__ */ jsx( + "div", + { + className: cn( + "joo-ab-bar", + layout === "group" && "joo-ab-bar--group", + className + ), + role: "group", + children + } + ); +} + +// src/intent.ts +var ACTION_COLOR_GUIDE = { + create: "primary", + save: "primary", + edit: "secondary", + export: "outline", + cancel: "outline", + more: "ghost", + view: "ghost", + apply: "dark", + publish: "dark", + delete: "danger", + remove: "danger" +}; +var ACTION_INTENT_VARIANT = ACTION_COLOR_GUIDE; +function resolveButtonVariant(intent, variant, fallback = "outline") { + if (variant === "destructive") { + return "danger"; + } + if (variant) { + return variant; + } + if (intent) { + return ACTION_COLOR_GUIDE[intent]; + } + return fallback; +} +function resolveMenuItemVariant(intent, variant) { + if (variant === "danger" || variant === "destructive") { + return "destructive"; + } + if (variant === "default") { + return "default"; + } + if (intent === "delete" || intent === "remove") { + return "destructive"; + } + return "default"; +} +function ActionIcon({ icon, className }) { + if (!icon) { + return null; + } + return /* @__PURE__ */ jsx("span", { className: cn("joo-ab-icon", className), "aria-hidden": true, children: icon }); +} +var buttonVariants = cva("joo-ab-btn", { + variants: { + variant: { + primary: "joo-ab-btn--primary", + secondary: "joo-ab-btn--secondary", + success: "joo-ab-btn--success", + danger: "joo-ab-btn--danger", + warning: "joo-ab-btn--warning", + info: "joo-ab-btn--info", + light: "joo-ab-btn--light", + dark: "joo-ab-btn--dark", + outline: "joo-ab-btn--outline", + ghost: "joo-ab-btn--ghost", + destructive: "joo-ab-btn--danger" + }, + size: { + sm: "joo-ab-btn--sm", + md: "joo-ab-btn--md", + icon: "joo-ab-btn--icon" + } + }, + defaultVariants: { + variant: "outline", + size: "sm" + } +}); +function Button({ + className, + intent, + variant, + size = "sm", + icon, + asChild = false, + type = "button", + children, + ...props +}) { + const resolved = resolveButtonVariant(intent, variant); + const Comp = asChild ? Slot : "button"; + const iconOnly = size === "icon"; + return /* @__PURE__ */ jsx( + Comp, + { + type: asChild ? void 0 : type, + className: cn(buttonVariants({ variant: resolved, size }), className), + "data-intent": intent, + ...props, + children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [ + icon ? /* @__PURE__ */ jsx(ActionIcon, { icon }) : null, + iconOnly ? null : children, + iconOnly && !children ? /* @__PURE__ */ jsx("span", { className: "joo-ab-sr-only", children: props["aria-label"] }) : null + ] }) + } + ); +} +var DropdownMenu = DropdownMenuPrimitive.Root; +var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; +function DropdownMenuContent({ + className, + sideOffset = 4, + ...props +}) { + return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx( + DropdownMenuPrimitive.Content, + { + sideOffset, + className: cn("joo-ab-dropdown-content", className), + ...props + } + ) }); +} +function DropdownMenuLabel({ + className, + ...props +}) { + return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Label, { className: cn("joo-ab-dropdown-label", className), ...props }); +} +function DropdownMenuSeparator({ + className, + ...props +}) { + return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Separator, { className: cn("joo-ab-dropdown-separator", className), ...props }); +} +function DropdownMenuItem({ + className, + inset, + variant = "default", + ...props +}) { + return /* @__PURE__ */ jsx( + DropdownMenuPrimitive.Item, + { + className: cn( + "joo-ab-dropdown-item", + variant === "destructive" && "joo-ab-dropdown-item--destructive", + inset && "joo-ab-dropdown-item--inset", + className + ), + ...props + } + ); +} +function MenuItems({ items, menuLabel }) { + return /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [ + menuLabel ? /* @__PURE__ */ jsxs(Fragment, { children: [ + /* @__PURE__ */ jsx(DropdownMenuLabel, { children: menuLabel }), + /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) + ] }) : null, + items.map((item) => /* @__PURE__ */ jsxs( + DropdownMenuItem, + { + disabled: item.disabled, + variant: resolveMenuItemVariant(item.intent, item.variant), + onSelect: (event) => { + event.preventDefault(); + item.onClick(); + }, + children: [ + item.icon ? /* @__PURE__ */ jsx(ActionIcon, { icon: item.icon }) : null, + item.label + ] + }, + item.label + )) + ] }); +} +function ActionMenu({ + label, + items, + icon, + disabled, + intent = "more", + variant, + size = "sm", + className +}) { + const iconOnly = size === "icon"; + return /* @__PURE__ */ jsxs(DropdownMenu, { children: [ + /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx( + Button, + { + intent, + variant, + size, + icon, + disabled, + className, + "aria-label": label, + children: iconOnly ? null : /* @__PURE__ */ jsxs(Fragment, { children: [ + label, + /* @__PURE__ */ jsx(ChevronDown, { className: "joo-ab-chevron", "aria-hidden": true }) + ] }) + } + ) }), + /* @__PURE__ */ jsx(MenuItems, { items, menuLabel: label }) + ] }); +} +function SplitButton({ + label, + onClick, + items, + icon, + disabled, + intent = "save", + variant, + size = "sm", + className, + menuLabel +}) { + return /* @__PURE__ */ jsxs("div", { className: cn("joo-ab-split", className), "data-intent": intent, children: [ + /* @__PURE__ */ jsx( + Button, + { + type: "button", + intent, + variant, + size, + icon, + disabled, + onClick, + className: "joo-ab-split-main", + children: label + } + ), + /* @__PURE__ */ jsxs(DropdownMenu, { children: [ + /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx( + Button, + { + type: "button", + intent, + variant, + size, + disabled, + className: "joo-ab-split-trigger", + "aria-label": menuLabel ?? `${label} options`, + children: /* @__PURE__ */ jsx(ChevronDown, { className: "joo-ab-chevron", "aria-hidden": true }) + } + ) }), + /* @__PURE__ */ jsx(MenuItems, { items, menuLabel: menuLabel ?? label }) + ] }) + ] }); +} +function Actions({ items, layout = "separate", className }) { + if (items.length === 0) { + return null; + } + return /* @__PURE__ */ jsx(ActionBar, { layout, className, children: items.map((item, index) => { + const key = `${item.type}-${item.label}-${index}`; + if (item.type === "single") { + const iconOnly = item.size === "icon"; + return /* @__PURE__ */ jsx( + Button, + { + intent: item.intent, + variant: item.variant, + size: item.size ?? "sm", + icon: item.icon, + disabled: item.disabled, + onClick: item.onClick, + "aria-label": item.label, + title: item.label, + children: iconOnly ? null : item.label + }, + key + ); + } + if (item.type === "menu") { + return /* @__PURE__ */ jsx( + ActionMenu, + { + label: item.label, + items: item.items, + icon: item.icon, + disabled: item.disabled, + intent: item.intent ?? "more", + variant: item.variant, + size: item.size + }, + key + ); + } + return /* @__PURE__ */ jsx( + SplitButton, + { + label: item.label, + onClick: item.onClick, + items: item.items, + icon: item.icon, + disabled: item.disabled, + intent: item.intent ?? "save", + variant: item.variant, + size: item.size, + menuLabel: item.menuLabel + }, + key + ); + }) }); +} + +// src/types.ts +var BUTTON_VARIANTS = [ + "primary", + "secondary", + "success", + "danger", + "warning", + "info", + "light", + "dark", + "outline", + "ghost" +]; + +export { ACTION_COLOR_GUIDE, ACTION_INTENT_VARIANT, ActionBar, ActionMenu, Actions, BUTTON_VARIANTS, Button, SplitButton, resolveButtonVariant, resolveMenuItemVariant }; +//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/components/action-buttons/dist/index.js.map b/components/action-buttons/dist/index.js.map new file mode 100644 index 0000000..017904c --- /dev/null +++ b/components/action-buttons/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/lib/cn.ts","../src/components/ActionBar.tsx","../src/intent.ts","../src/components/ActionIcon.tsx","../src/components/Button.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/ActionMenu.tsx","../src/components/SplitButton.tsx","../src/components/Actions.tsx","../src/types.ts"],"names":["jsx","jsxs","Fragment","ChevronDown"],"mappings":";;;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACFO,SAAS,UAAU,EAAE,QAAA,EAAU,MAAA,GAAS,UAAA,EAAY,WAAU,EAAmB;AACtF,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,YAAA;AAAA,QACA,WAAW,OAAA,IAAW,mBAAA;AAAA,QACtB;AAAA,OACF;AAAA,MACA,IAAA,EAAK,OAAA;AAAA,MAEJ;AAAA;AAAA,GACH;AAEJ;;;ACDO,IAAM,kBAAA,GAAqB;AAAA,EAChC,MAAA,EAAQ,SAAA;AAAA,EACR,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,WAAA;AAAA,EACN,MAAA,EAAQ,SAAA;AAAA,EACR,MAAA,EAAQ,SAAA;AAAA,EACR,IAAA,EAAM,OAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,KAAA,EAAO,MAAA;AAAA,EACP,OAAA,EAAS,MAAA;AAAA,EACT,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ;AACV;AAGO,IAAM,qBAAA,GAAwB;AAM9B,SAAS,oBAAA,CACd,MAAA,EACA,OAAA,EACA,QAAA,GAA0B,SAAA,EACX;AACf,EAAA,IAAI,YAAY,aAAA,EAAe;AAC7B,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,OAAO,OAAA;AAAA,EACT;AACA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,OAAO,mBAAmB,MAAM,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,QAAA;AACT;AAKO,SAAS,sBAAA,CACd,QACA,OAAA,EAC2B;AAC3B,EAAA,IAAI,OAAA,KAAY,QAAA,IAAY,OAAA,KAAY,aAAA,EAAe;AACrD,IAAA,OAAO,aAAA;AAAA,EACT;AACA,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,OAAO,SAAA;AAAA,EACT;AACA,EAAA,IAAI,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,QAAA,EAAU;AAC9C,IAAA,OAAO,aAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA;AACT;AClEO,SAAS,UAAA,CAAW,EAAE,IAAA,EAAM,SAAA,EAAU,EAA4C;AACvF,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBACEA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,eAAe,SAAS,CAAA,EAAG,aAAA,EAAW,IAAA,EACvD,QAAA,EAAA,IAAA,EACH,CAAA;AAEJ;ACNA,IAAM,cAAA,GAAiB,IAAI,YAAA,EAAc;AAAA,EACvC,QAAA,EAAU;AAAA,IACR,OAAA,EAAS;AAAA,MACP,OAAA,EAAS,qBAAA;AAAA,MACT,SAAA,EAAW,uBAAA;AAAA,MACX,OAAA,EAAS,qBAAA;AAAA,MACT,MAAA,EAAQ,oBAAA;AAAA,MACR,OAAA,EAAS,qBAAA;AAAA,MACT,IAAA,EAAM,kBAAA;AAAA,MACN,KAAA,EAAO,mBAAA;AAAA,MACP,IAAA,EAAM,kBAAA;AAAA,MACN,OAAA,EAAS,qBAAA;AAAA,MACT,KAAA,EAAO,mBAAA;AAAA,MACP,WAAA,EAAa;AAAA,KACf;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,EAAA,EAAI,gBAAA;AAAA,MACJ,EAAA,EAAI,gBAAA;AAAA,MACJ,IAAA,EAAM;AAAA;AACR,GACF;AAAA,EACA,eAAA,EAAiB;AAAA,IACf,OAAA,EAAS,SAAA;AAAA,IACT,IAAA,EAAM;AAAA;AAEV,CAAC,CAAA;AAEM,SAAS,MAAA,CAAO;AAAA,EACrB,SAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,IAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,IAAA,GAAO,QAAA;AAAA,EACP,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,MAAM,QAAA,GAAW,oBAAA,CAAqB,MAAA,EAAQ,OAAO,CAAA;AACrD,EAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,QAAA;AAC9B,EAAA,MAAM,WAAW,IAAA,KAAS,MAAA;AAE1B,EAAA,uBACEA,GAAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,UAAU,MAAA,GAAY,IAAA;AAAA,MAC5B,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,QAAA,EAAU,IAAA,EAAM,CAAA,EAAG,SAAS,CAAA;AAAA,MACpE,aAAA,EAAa,MAAA;AAAA,MACZ,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA,OAAA,GACC,2BAEA,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,QAAA,IAAA,mBAAOA,GAAAA,CAAC,UAAA,EAAA,EAAW,IAAA,EAAY,CAAA,GAAK,IAAA;AAAA,QACpC,WAAW,IAAA,GAAO,QAAA;AAAA,QAClB,QAAA,IAAY,CAAC,QAAA,mBAAWA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAA,KAAA,CAAM,YAAY,CAAA,EAAE,CAAA,GAAU;AAAA,OAAA,EAC3F;AAAA;AAAA,GAEJ;AAEJ;AC/DO,IAAM,YAAA,GAAqC,qBAAA,CAAA,IAAA;AAC3C,IAAM,mBAAA,GAA4C,qBAAA,CAAA,OAAA;AAIlD,SAAS,mBAAA,CAAoB;AAAA,EAClC,SAAA;AAAA,EACA,UAAA,GAAa,CAAA;AAAA,EACb,GAAG;AACL,CAAA,EAAyE;AACvE,EAAA,uBACEA,GAAAA,CAAuB,qBAAA,CAAA,MAAA,EAAtB,EACC,QAAA,kBAAAA,GAAAA;AAAA,IAAuB,qBAAA,CAAA,OAAA;AAAA,IAAtB;AAAA,MACC,UAAA;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,yBAAA,EAA2B,SAAS,CAAA;AAAA,MACjD,GAAG;AAAA;AAAA,GACN,EACF,CAAA;AAEJ;AAEO,SAAS,iBAAA,CAAkB;AAAA,EAChC,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAuE;AACrE,EAAA,uBAAOA,GAAAA,CAAuB,qBAAA,CAAA,KAAA,EAAtB,EAA4B,SAAA,EAAW,GAAG,uBAAA,EAAyB,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AACpG;AAEO,SAAS,qBAAA,CAAsB;AAAA,EACpC,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA2E;AACzE,EAAA,uBACEA,GAAAA,CAAuB,qBAAA,CAAA,SAAA,EAAtB,EAAgC,SAAA,EAAW,GAAG,2BAAA,EAA6B,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAEvG;AAEO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,SAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,GAAG;AACL,CAAA,EAGG;AACD,EAAA,uBACEA,GAAAA;AAAA,IAAuB,qBAAA,CAAA,IAAA;AAAA,IAAtB;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,sBAAA;AAAA,QACA,YAAY,aAAA,IAAiB,mCAAA;AAAA,QAC7B,KAAA,IAAS,6BAAA;AAAA,QACT;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AC/CA,SAAS,SAAA,CAAU,EAAE,KAAA,EAAO,SAAA,EAAU,EAAgD;AACpF,EAAA,uBACEC,IAAAA,CAAC,mBAAA,EAAA,EAAoB,KAAA,EAAM,KAAA,EACxB,QAAA,EAAA;AAAA,IAAA,SAAA,mBACCA,IAAAA,CAAAC,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,sBAAAF,GAAAA,CAAC,qBAAmB,QAAA,EAAA,SAAA,EAAU,CAAA;AAAA,sBAC9BA,IAAC,qBAAA,EAAA,EAAsB;AAAA,KAAA,EACzB,CAAA,GACE,IAAA;AAAA,IACH,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,qBACVC,IAAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QAEC,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,OAAA,EAAS,sBAAA,CAAuB,IAAA,CAAK,MAAA,EAAQ,KAAK,OAAO,CAAA;AAAA,QACzD,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,IAAA,CAAK,OAAA,EAAQ;AAAA,QACf,CAAA;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,uBAAOD,GAAAA,CAAC,cAAW,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA,GAAK,IAAA;AAAA,UAC9C,IAAA,CAAK;AAAA;AAAA,OAAA;AAAA,MATD,IAAA,CAAK;AAAA,KAWb;AAAA,GAAA,EACH,CAAA;AAEJ;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,OAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,WAAW,IAAA,KAAS,MAAA;AAE1B,EAAA,uBACEC,KAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAD,GAAAA,CAAC,mBAAA,EAAA,EAAoB,OAAA,EAAO,IAAA,EAC1B,QAAA,kBAAAA,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QACA,QAAA;AAAA,QACA,SAAA;AAAA,QACA,YAAA,EAAY,KAAA;AAAA,QAEX,QAAA,EAAA,QAAA,GAAW,IAAA,mBACVC,IAAAA,CAAAC,UAAA,EACG,QAAA,EAAA;AAAA,UAAA,KAAA;AAAA,0BACDF,GAAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAU,gBAAA,EAAiB,eAAW,IAAA,EAAC;AAAA,SAAA,EACtD;AAAA;AAAA,KAEJ,EACF,CAAA;AAAA,oBACAA,GAAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAc,WAAW,KAAA,EAAO;AAAA,GAAA,EAC7C,CAAA;AAEJ;ACrEO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA,GAAS,MAAA;AAAA,EACT,OAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,SAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,uBACEC,KAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,cAAA,EAAgB,SAAS,CAAA,EAAG,aAAA,EAAa,MAAA,EAC1D,QAAA,EAAA;AAAA,oBAAAD,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,MAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA,EAAU,mBAAA;AAAA,QAET,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,oBACAC,KAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAD,GAAAA,CAAC,mBAAA,EAAA,EAAoB,OAAA,EAAO,IAAA,EAC1B,QAAA,kBAAAA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,MAAA;AAAA,UACA,OAAA;AAAA,UACA,IAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAA,EAAU,sBAAA;AAAA,UACV,YAAA,EAAY,SAAA,IAAa,CAAA,EAAG,KAAK,CAAA,QAAA,CAAA;AAAA,UAEjC,0BAAAA,GAAAA,CAACG,WAAAA,EAAA,EAAY,SAAA,EAAU,gBAAA,EAAiB,eAAW,IAAA,EAAC;AAAA;AAAA,OACtD,EACF,CAAA;AAAA,sBACAH,GAAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAc,SAAA,EAAW,aAAa,KAAA,EAAO;AAAA,KAAA,EAC1D;AAAA,GAAA,EACF,CAAA;AAEJ;AC9CO,SAAS,QAAQ,EAAE,KAAA,EAAO,MAAA,GAAS,UAAA,EAAY,WAAU,EAAiB;AAC/E,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBACEA,IAAC,SAAA,EAAA,EAAU,MAAA,EAAgB,WACxB,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,KAAU;AAC1B,IAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,IAAI,IAAI,IAAA,CAAK,KAAK,IAAI,KAAK,CAAA,CAAA;AAE/C,IAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,MAAA,MAAM,QAAA,GAAW,KAAK,IAAA,KAAS,MAAA;AAC/B,MAAA,uBACEA,GAAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAEC,QAAQ,IAAA,CAAK,MAAA;AAAA,UACb,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,IAAA,EAAM,KAAK,IAAA,IAAQ,IAAA;AAAA,UACnB,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,cAAY,IAAA,CAAK,KAAA;AAAA,UACjB,OAAO,IAAA,CAAK,KAAA;AAAA,UAEX,QAAA,EAAA,QAAA,GAAW,OAAO,IAAA,CAAK;AAAA,SAAA;AAAA,QAVnB;AAAA,OAWP;AAAA,IAEJ;AAEA,IAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAQ;AACxB,MAAA,uBACEA,GAAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UAEC,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,OAAO,IAAA,CAAK,KAAA;AAAA,UACZ,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,UAAU,IAAA,CAAK,QAAA;AAAA,UACf,MAAA,EAAQ,KAAK,MAAA,IAAU,MAAA;AAAA,UACvB,SAAS,IAAA,CAAK,OAAA;AAAA,UACd,MAAM,IAAA,CAAK;AAAA,SAAA;AAAA,QAPN;AAAA,OAQP;AAAA,IAEJ;AAEA,IAAA,uBACEA,GAAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QAEC,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,MAAA,EAAQ,KAAK,MAAA,IAAU,MAAA;AAAA,QACvB,SAAS,IAAA,CAAK,OAAA;AAAA,QACd,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,WAAW,IAAA,CAAK;AAAA,OAAA;AAAA,MATX;AAAA,KAUP;AAAA,EAEJ,CAAC,CAAA,EACH,CAAA;AAEJ;;;AC8DO,IAAM,eAAA,GAAmC;AAAA,EAC9C,SAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { cn } from \"../lib/cn\";\nimport type { ActionBarProps } from \"../types\";\n\nexport function ActionBar({ children, layout = \"separate\", className }: ActionBarProps) {\n return (\n \n {children}\n \n );\n}\n","import type { ActionIntent, ButtonVariant } from \"./types\";\n\n/**\n * Developer guide — recommended action → color.\n * Not enforced: pass `variant` explicitly to override.\n *\n * | Intent | Suggested color | Typical use |\n * |------------------------|-----------------|--------------------------------|\n * | `create`, `save` | primary | Add / persist (cyan brand CTA) |\n * | `edit` | secondary | Soft gray modify |\n * | `export`, `cancel` | outline | Bordered alternate |\n * | `more`, `view` | ghost | Quiet / overflow |\n * | `apply`, `publish` | dark | Strong neutral CTA (near-black)|\n * | `delete`, `remove` | danger | Irreversible remove |\n */\nexport const ACTION_COLOR_GUIDE = {\n create: \"primary\",\n save: \"primary\",\n edit: \"secondary\",\n export: \"outline\",\n cancel: \"outline\",\n more: \"ghost\",\n view: \"ghost\",\n apply: \"dark\",\n publish: \"dark\",\n delete: \"danger\",\n remove: \"danger\",\n} as const satisfies Record;\n\n/** @deprecated Use `ACTION_COLOR_GUIDE` — same map, guidance only. */\nexport const ACTION_INTENT_VARIANT = ACTION_COLOR_GUIDE;\n\n/**\n * Resolve button color: explicit `variant` always wins.\n * `intent` only suggests a default when `variant` is omitted.\n */\nexport function resolveButtonVariant(\n intent: ActionIntent | undefined,\n variant: ButtonVariant | undefined,\n fallback: ButtonVariant = \"outline\",\n): ButtonVariant {\n if (variant === \"destructive\") {\n return \"danger\";\n }\n if (variant) {\n return variant;\n }\n if (intent) {\n return ACTION_COLOR_GUIDE[intent];\n }\n return fallback;\n}\n\n/**\n * Menu row tone: explicit `variant` wins; `intent` suggests danger for delete/remove.\n */\nexport function resolveMenuItemVariant(\n intent: ActionIntent | undefined,\n variant: \"default\" | \"danger\" | \"destructive\" | undefined,\n): \"default\" | \"destructive\" {\n if (variant === \"danger\" || variant === \"destructive\") {\n return \"destructive\";\n }\n if (variant === \"default\") {\n return \"default\";\n }\n if (intent === \"delete\" || intent === \"remove\") {\n return \"destructive\";\n }\n return \"default\";\n}\n","import type { ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn\";\n\nexport function ActionIcon({ icon, className }: { icon: ReactNode; className?: string }) {\n if (!icon) {\n return null;\n }\n\n return (\n \n {icon}\n \n );\n}\n","import { Slot } from \"@radix-ui/react-slot\";\nimport { cva } from \"class-variance-authority\";\n\nimport { resolveButtonVariant } from \"../intent\";\nimport { cn } from \"../lib/cn\";\nimport type { ButtonProps } from \"../types\";\nimport { ActionIcon } from \"./ActionIcon\";\n\nconst buttonVariants = cva(\"joo-ab-btn\", {\n variants: {\n variant: {\n primary: \"joo-ab-btn--primary\",\n secondary: \"joo-ab-btn--secondary\",\n success: \"joo-ab-btn--success\",\n danger: \"joo-ab-btn--danger\",\n warning: \"joo-ab-btn--warning\",\n info: \"joo-ab-btn--info\",\n light: \"joo-ab-btn--light\",\n dark: \"joo-ab-btn--dark\",\n outline: \"joo-ab-btn--outline\",\n ghost: \"joo-ab-btn--ghost\",\n destructive: \"joo-ab-btn--danger\",\n },\n size: {\n sm: \"joo-ab-btn--sm\",\n md: \"joo-ab-btn--md\",\n icon: \"joo-ab-btn--icon\",\n },\n },\n defaultVariants: {\n variant: \"outline\",\n size: \"sm\",\n },\n});\n\nexport function Button({\n className,\n intent,\n variant,\n size = \"sm\",\n icon,\n asChild = false,\n type = \"button\",\n children,\n ...props\n}: ButtonProps) {\n const resolved = resolveButtonVariant(intent, variant);\n const Comp = asChild ? Slot : \"button\";\n const iconOnly = size === \"icon\";\n\n return (\n \n {asChild ? (\n children\n ) : (\n <>\n {icon ? : null}\n {iconOnly ? null : children}\n {iconOnly && !children ? {props[\"aria-label\"]} : null}\n \n )}\n \n );\n}\n","import * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport const DropdownMenu = DropdownMenuPrimitive.Root;\nexport const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\nexport const DropdownMenuGroup = DropdownMenuPrimitive.Group;\nexport const DropdownMenuPortal = DropdownMenuPrimitive.Portal;\n\nexport function DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentPropsWithoutRef) {\n return (\n \n \n \n );\n}\n\nexport function DropdownMenuLabel({\n className,\n ...props\n}: React.ComponentPropsWithoutRef) {\n return ;\n}\n\nexport function DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentPropsWithoutRef) {\n return (\n \n );\n}\n\nexport function DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentPropsWithoutRef & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n \n );\n}\n","import { ChevronDown } from \"lucide-react\";\n\nimport { resolveMenuItemVariant } from \"../intent\";\nimport type { ActionItem, ActionMenuProps } from \"../types\";\nimport { ActionIcon } from \"./ActionIcon\";\nimport { Button } from \"./Button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"./ui/dropdown-menu\";\n\nfunction MenuItems({ items, menuLabel }: { items: ActionItem[]; menuLabel?: string }) {\n return (\n \n {menuLabel ? (\n <>\n {menuLabel}\n \n \n ) : null}\n {items.map((item) => (\n {\n event.preventDefault();\n item.onClick();\n }}\n >\n {item.icon ? : null}\n {item.label}\n \n ))}\n \n );\n}\n\nexport function ActionMenu({\n label,\n items,\n icon,\n disabled,\n intent = \"more\",\n variant,\n size = \"sm\",\n className,\n}: ActionMenuProps) {\n const iconOnly = size === \"icon\";\n\n return (\n \n \n \n {iconOnly ? null : (\n <>\n {label}\n \n \n )}\n \n \n \n \n );\n}\n\nexport { MenuItems };\n","import { ChevronDown } from \"lucide-react\";\n\nimport { cn } from \"../lib/cn\";\nimport type { SplitButtonProps } from \"../types\";\nimport { Button } from \"./Button\";\nimport { MenuItems } from \"./ActionMenu\";\nimport { DropdownMenu, DropdownMenuTrigger } from \"./ui/dropdown-menu\";\n\nexport function SplitButton({\n label,\n onClick,\n items,\n icon,\n disabled,\n intent = \"save\",\n variant,\n size = \"sm\",\n className,\n menuLabel,\n}: SplitButtonProps) {\n return (\n
\n \n {label}\n \n \n \n \n \n \n \n \n \n
\n );\n}\n","import type { ActionsProps } from \"../types\";\nimport { ActionBar } from \"./ActionBar\";\nimport { ActionMenu } from \"./ActionMenu\";\nimport { Button } from \"./Button\";\nimport { SplitButton } from \"./SplitButton\";\n\nexport function Actions({ items, layout = \"separate\", className }: ActionsProps) {\n if (items.length === 0) {\n return null;\n }\n\n return (\n \n {items.map((item, index) => {\n const key = `${item.type}-${item.label}-${index}`;\n\n if (item.type === \"single\") {\n const iconOnly = item.size === \"icon\";\n return (\n \n {iconOnly ? null : item.label}\n \n );\n }\n\n if (item.type === \"menu\") {\n return (\n \n );\n }\n\n return (\n \n );\n })}\n \n );\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\n/** Semantic action hint — see `ACTION_COLOR_GUIDE` (guidance only). */\nexport type ActionIntent =\n | \"create\"\n | \"save\"\n | \"edit\"\n | \"export\"\n | \"cancel\"\n | \"more\"\n | \"view\"\n | \"apply\"\n | \"publish\"\n | \"delete\"\n | \"remove\";\n\nexport type ActionItemVariant = \"default\" | \"danger\" | \"destructive\";\n\nexport type ActionItem = {\n label: string;\n icon?: ReactNode;\n onClick: () => void;\n disabled?: boolean;\n /** Suggested action kind (color guide). Overridden by `variant` when set. */\n intent?: ActionIntent;\n variant?: ActionItemVariant;\n};\n\n/**\n * Bootstrap-inspired solid colors (JOO-tuned) plus outline/ghost utilities.\n * Gallery order: primary → secondary → success → danger → warning → info → light → dark → outline → ghost\n */\nexport type ButtonVariant =\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"danger\"\n | \"warning\"\n | \"info\"\n | \"light\"\n | \"dark\"\n | \"outline\"\n | \"ghost\"\n /** @deprecated Prefer `danger` */\n | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"icon\";\n\nexport type ActionBarLayout = \"separate\" | \"group\";\n\nexport type ActionBarProps = {\n children: ReactNode;\n layout?: ActionBarLayout;\n className?: string;\n};\n\nexport type ButtonProps = ButtonHTMLAttributes & {\n /**\n * Optional action hint for developers / docs. When `variant` is omitted,\n * color defaults from `ACTION_COLOR_GUIDE`. Explicit `variant` always wins.\n */\n intent?: ActionIntent;\n /** Explicit color. Always wins over `intent` when provided. */\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Leading icon (Lucide or custom). Shown beside label; alone when `size=\"icon\"`. */\n icon?: ReactNode;\n asChild?: boolean;\n className?: string;\n};\n\nexport type ActionMenuProps = {\n label: string;\n items: ActionItem[];\n icon?: ReactNode;\n disabled?: boolean;\n intent?: ActionIntent;\n variant?: ButtonVariant;\n size?: ButtonSize;\n className?: string;\n};\n\nexport type SplitButtonProps = {\n label: string;\n onClick: () => void;\n items: ActionItem[];\n icon?: ReactNode;\n disabled?: boolean;\n intent?: ActionIntent;\n variant?: ButtonVariant;\n size?: Exclude;\n className?: string;\n menuLabel?: string;\n};\n\ntype ActionDescriptorBase = {\n label: string;\n icon?: ReactNode;\n disabled?: boolean;\n intent?: ActionIntent;\n variant?: ButtonVariant;\n};\n\nexport type ActionDescriptor =\n | (ActionDescriptorBase & {\n type: \"single\";\n onClick: () => void;\n size?: ButtonSize;\n })\n | (ActionDescriptorBase & {\n type: \"menu\";\n items: ActionItem[];\n size?: ButtonSize;\n })\n | (ActionDescriptorBase & {\n type: \"split\";\n onClick: () => void;\n items: ActionItem[];\n size?: Exclude;\n menuLabel?: string;\n });\n\nexport type ActionsProps = {\n items: ActionDescriptor[];\n layout?: ActionBarLayout;\n className?: string;\n};\n\n/** All variants shown in demos / docs (Bootstrap-like + outline/ghost). */\nexport const BUTTON_VARIANTS: ButtonVariant[] = [\n \"primary\",\n \"secondary\",\n \"success\",\n \"danger\",\n \"warning\",\n \"info\",\n \"light\",\n \"dark\",\n \"outline\",\n \"ghost\",\n];\n"]} \ No newline at end of file diff --git a/components/action-buttons/dist/styles.css b/components/action-buttons/dist/styles.css new file mode 100644 index 0000000..9404dc9 --- /dev/null +++ b/components/action-buttons/dist/styles.css @@ -0,0 +1,354 @@ +:root { + --joo-background: 0 0% 100%; + --joo-foreground: 222.2 84% 4.9%; + --joo-muted: 210 40% 96.1%; + --joo-muted-foreground: 215.4 16.3% 46.9%; + --joo-border: 214.3 31.8% 91.4%; + --joo-primary: 222.2 47.4% 11.2%; + --joo-primary-foreground: 210 40% 98%; + --joo-secondary: 210 40% 96.1%; + --joo-secondary-foreground: 222.2 47.4% 11.2%; + --joo-accent: 210 40% 96.1%; + --joo-accent-foreground: 222.2 47.4% 11.2%; + --joo-destructive: 0 84.2% 60.2%; + --joo-destructive-foreground: 210 40% 98%; + --joo-radius: 0.375rem; + + /* Bootstrap-inspired action button palette (JOO cyan-tuned) */ + --joo-ab-primary: 187 72% 35%; + --joo-ab-primary-foreground: 0 0% 100%; + --joo-ab-secondary: 215 16% 47%; + --joo-ab-secondary-foreground: 0 0% 100%; + --joo-ab-success: 152 55% 36%; + --joo-ab-success-foreground: 0 0% 100%; + --joo-ab-danger: 0 72% 51%; + --joo-ab-danger-foreground: 0 0% 100%; + --joo-ab-warning: 38 92% 50%; + --joo-ab-warning-foreground: 222.2 47.4% 11.2%; + --joo-ab-info: 187 65% 42%; + --joo-ab-info-foreground: 0 0% 100%; + --joo-ab-light: 210 40% 96%; + --joo-ab-light-foreground: 222.2 47.4% 11.2%; + --joo-ab-dark: 222.2 47.4% 11.2%; + --joo-ab-dark-foreground: 210 40% 98%; +} + +.dark { + --joo-background: 222.2 84% 4.9%; + --joo-foreground: 210 40% 98%; + --joo-muted: 217.2 32.6% 17.5%; + --joo-muted-foreground: 215 20.2% 65.1%; + --joo-border: 217.2 32.6% 17.5%; + --joo-primary: 210 40% 98%; + --joo-primary-foreground: 222.2 47.4% 11.2%; + --joo-secondary: 217.2 32.6% 17.5%; + --joo-secondary-foreground: 210 40% 98%; + --joo-accent: 217.2 32.6% 17.5%; + --joo-accent-foreground: 210 40% 98%; + --joo-destructive: 0 62.8% 30.6%; + --joo-destructive-foreground: 210 40% 98%; + + --joo-ab-primary: 187 70% 42%; + --joo-ab-primary-foreground: 222.2 84% 4.9%; + --joo-ab-secondary: 215 16% 55%; + --joo-ab-secondary-foreground: 0 0% 100%; + --joo-ab-success: 152 50% 40%; + --joo-ab-success-foreground: 0 0% 100%; + --joo-ab-danger: 0 65% 55%; + --joo-ab-danger-foreground: 0 0% 100%; + --joo-ab-warning: 38 90% 55%; + --joo-ab-warning-foreground: 222.2 47.4% 11.2%; + --joo-ab-info: 187 60% 48%; + --joo-ab-info-foreground: 222.2 84% 4.9%; + --joo-ab-light: 217.2 32.6% 22%; + --joo-ab-light-foreground: 210 40% 98%; + --joo-ab-dark: 210 40% 98%; + --joo-ab-dark-foreground: 222.2 47.4% 11.2%; +} + +.joo-ab-bar { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; +} + +.joo-ab-bar--group { + gap: 0; +} + +.joo-ab-bar--group > .joo-ab-btn, +.joo-ab-bar--group > .joo-ab-split { + border-radius: 0; +} + +.joo-ab-bar--group > .joo-ab-btn:first-child, +.joo-ab-bar--group > .joo-ab-split:first-child, +.joo-ab-bar--group > .joo-ab-split:first-child .joo-ab-split-main { + border-top-left-radius: var(--joo-radius); + border-bottom-left-radius: var(--joo-radius); +} + +.joo-ab-bar--group > .joo-ab-btn:last-child, +.joo-ab-bar--group > .joo-ab-split:last-child, +.joo-ab-bar--group > .joo-ab-split:last-child .joo-ab-split-trigger { + border-top-right-radius: var(--joo-radius); + border-bottom-right-radius: var(--joo-radius); +} + +.joo-ab-bar--group > .joo-ab-btn + .joo-ab-btn, +.joo-ab-bar--group > .joo-ab-btn + .joo-ab-split, +.joo-ab-bar--group > .joo-ab-split + .joo-ab-btn, +.joo-ab-bar--group > .joo-ab-split + .joo-ab-split { + margin-left: -1px; +} + +.joo-ab-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.375rem; + border-radius: var(--joo-radius); + border: 1px solid transparent; + font-size: 0.875rem; + font-weight: 500; + line-height: 1; + transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; + cursor: pointer; + white-space: nowrap; +} + +.joo-ab-btn:disabled { + opacity: 0.5; + pointer-events: none; + cursor: not-allowed; +} + +.joo-ab-btn--sm { + height: 2rem; + padding: 0 0.75rem; + font-size: 0.8125rem; +} + +.joo-ab-btn--md { + height: 2.25rem; + padding: 0 1rem; + font-size: 0.875rem; +} + +.joo-ab-btn--icon { + height: 2rem; + width: 2rem; + padding: 0; +} + +.joo-ab-btn--primary { + background-color: hsl(var(--joo-ab-primary)); + color: hsl(var(--joo-ab-primary-foreground)); +} + +.joo-ab-btn--primary:hover { + background-color: hsl(var(--joo-ab-primary) / 0.9); +} + +.joo-ab-btn--secondary { + background-color: hsl(var(--joo-ab-secondary)); + color: hsl(var(--joo-ab-secondary-foreground)); +} + +.joo-ab-btn--secondary:hover { + background-color: hsl(var(--joo-ab-secondary) / 0.9); +} + +.joo-ab-btn--success { + background-color: hsl(var(--joo-ab-success)); + color: hsl(var(--joo-ab-success-foreground)); +} + +.joo-ab-btn--success:hover { + background-color: hsl(var(--joo-ab-success) / 0.9); +} + +.joo-ab-btn--danger { + background-color: hsl(var(--joo-ab-danger)); + color: hsl(var(--joo-ab-danger-foreground)); +} + +.joo-ab-btn--danger:hover { + background-color: hsl(var(--joo-ab-danger) / 0.9); +} + +.joo-ab-btn--warning { + background-color: hsl(var(--joo-ab-warning)); + color: hsl(var(--joo-ab-warning-foreground)); +} + +.joo-ab-btn--warning:hover { + background-color: hsl(var(--joo-ab-warning) / 0.9); +} + +.joo-ab-btn--info { + background-color: hsl(var(--joo-ab-info)); + color: hsl(var(--joo-ab-info-foreground)); +} + +.joo-ab-btn--info:hover { + background-color: hsl(var(--joo-ab-info) / 0.9); +} + +.joo-ab-btn--light { + border-color: hsl(var(--joo-border)); + background-color: hsl(var(--joo-ab-light)); + color: hsl(var(--joo-ab-light-foreground)); +} + +.joo-ab-btn--light:hover { + background-color: hsl(var(--joo-ab-light) / 0.85); +} + +.joo-ab-btn--dark { + background-color: hsl(var(--joo-ab-dark)); + color: hsl(var(--joo-ab-dark-foreground)); +} + +.joo-ab-btn--dark:hover { + background-color: hsl(var(--joo-ab-dark) / 0.9); +} + +.joo-ab-btn--outline { + border-color: hsl(var(--joo-border)); + background-color: hsl(var(--joo-background)); + color: hsl(var(--joo-foreground)); +} + +.joo-ab-btn--outline:hover { + background-color: hsl(var(--joo-accent)); + color: hsl(var(--joo-accent-foreground)); +} + +.joo-ab-btn--ghost { + background-color: transparent; + color: hsl(var(--joo-foreground)); +} + +.joo-ab-btn--ghost:hover { + background-color: hsl(var(--joo-accent)); + color: hsl(var(--joo-accent-foreground)); +} + +.joo-ab-chevron { + width: 0.875rem; + height: 0.875rem; + flex-shrink: 0; +} + +.joo-ab-icon { + display: inline-flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 1rem; + height: 1rem; +} + +.joo-ab-icon > svg { + width: 1rem; + height: 1rem; +} + +.joo-ab-sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +.joo-ab-split { + display: inline-flex; + align-items: stretch; +} + +.joo-ab-split-main { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.joo-ab-split-trigger { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.joo-ab-split-trigger.joo-ab-btn--sm, +.joo-ab-split-trigger.joo-ab-btn--md { + width: auto; + min-width: 2rem; +} + +.joo-ab-dropdown-content { + z-index: 50; + min-width: 8rem; + overflow: hidden; + border-radius: var(--joo-radius); + border: 1px solid hsl(var(--joo-border)); + background-color: hsl(var(--joo-background)); + color: hsl(var(--joo-foreground)); + padding: 0.25rem; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); +} + +.joo-ab-dropdown-item { + display: flex; + width: 100%; + align-items: center; + gap: 0.5rem; + border-radius: calc(var(--joo-radius) - 2px); + padding: 0.375rem 0.5rem; + font-size: 0.875rem; + cursor: pointer; + outline: none; + border: none; + background: transparent; + color: inherit; + text-align: left; +} + +.joo-ab-dropdown-item:hover, +.joo-ab-dropdown-item[data-highlighted] { + background-color: hsl(var(--joo-accent)); + color: hsl(var(--joo-accent-foreground)); +} + +.joo-ab-dropdown-item--destructive { + color: hsl(var(--joo-destructive)); +} + +.joo-ab-dropdown-item--destructive:hover, +.joo-ab-dropdown-item--destructive[data-highlighted] { + background-color: hsl(var(--joo-destructive) / 0.1); + color: hsl(var(--joo-destructive)); +} + +.joo-ab-dropdown-item--inset { + padding-left: 2rem; +} + +.joo-ab-dropdown-label { + padding: 0.375rem 0.5rem; + font-size: 0.75rem; + font-weight: 600; + color: hsl(var(--joo-muted-foreground)); +} + +.joo-ab-dropdown-separator { + margin: 0.25rem -0.25rem; + height: 1px; + background-color: hsl(var(--joo-border)); +} diff --git a/components/action-buttons/package-lock.json b/components/action-buttons/package-lock.json new file mode 100644 index 0000000..7298b4b --- /dev/null +++ b/components/action-buttons/package-lock.json @@ -0,0 +1,4389 @@ +{ + "name": "@jooservices/react-action-buttons", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@jooservices/react-action-buttons", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-slot": "^1.2.4", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^14.6.1", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@adobe/css-tools": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", + "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.0.0", + "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz", + "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.9.tgz", + "integrity": "sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.1.0", + "@csstools/css-calc": "^3.2.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz", + "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@floating-ui/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.8.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", + "license": "MIT" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.5.tgz", + "integrity": "sha512-d86WIWFYNtGA0H/d8exstrTRTp7eWJYlYJbtNofxr/3ljupZYn6EFDG/Qgu/0Kc8v7yMUxySagqJsL1+PdYjWg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.11.tgz", + "integrity": "sha512-Kdil9BB1rIFC/khmf4hC35bn8701AJcizTU7G7cUbEbk5XqqbjDuHW60uUfKqO5WojjZcbAW51Q7P0hRmMLw8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.12.tgz", + "integrity": "sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-slot": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz", + "integrity": "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.0.tgz", + "integrity": "sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz", + "integrity": "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.15.tgz", + "integrity": "sha512-b0XaRlzn2QKuo10XyNgi2DAJDf5XC9d1nD3FJcuvCjbR7+4Ad28zmZsLsqx+hvDEzMnRuZaZxZm9gYObV6RmRA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.5", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-effect-event": "0.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.20.tgz", + "integrity": "sha512-slfm+rRaZRuQBvHq60lXvSVUPhid0IPtjSZzIuUlWZMUs01iYZNlGS3mJgRD3ChLQVBAYlKiL/tFyWGX+dz8Xw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.5", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-menu": "2.1.20", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-controllable-state": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.4.tgz", + "integrity": "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.12.tgz", + "integrity": "sha512-jjk/lqTeNL0azUx5ZYzVrl4NgaDIrdzTNE4mABV9yBFI7FQqN7pIgzV1bTleUezP2QiTGA1BFTqY8MegDgWX9A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-callback-ref": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz", + "integrity": "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.20.tgz", + "integrity": "sha512-VsUrXxFe9d2ScbZF0fR/oPR1+qjyeLs5p0jzG8h90puMoA9bq4SirYlXbE+USRg9Q2qTeJSFNqjw2nts8jJe4w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.5", + "@radix-ui/react-collection": "1.1.12", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.15", + "@radix-ui/react-focus-guards": "1.1.4", + "@radix-ui/react-focus-scope": "1.1.12", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-popper": "1.3.3", + "@radix-ui/react-portal": "1.1.13", + "@radix-ui/react-presence": "1.1.7", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-roving-focus": "1.1.15", + "@radix-ui/react-slot": "1.3.0", + "@radix-ui/react-use-callback-ref": "1.1.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.3.tgz", + "integrity": "sha512-mS7dGpyjv6b+gsDjLF7e0ia1W4Im1B1hSCy2yuXlHuvnZxHKagfDaobt/KAKt27EpZMit2pss8eJBVyVjEWM+g==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.11", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.2", + "@radix-ui/react-use-rect": "1.1.2", + "@radix-ui/react-use-size": "1.1.2", + "@radix-ui/rect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.13.tgz", + "integrity": "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.7.tgz", + "integrity": "sha512-zBZ4QM5XG3JRanDmqXYf3MD6th4AFXFmgU6KNMFzUaV6F3uw9I5/zjMUvFriSEn5ewo1nxuibvyxJdmLlDcslA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.7.tgz", + "integrity": "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.15.tgz", + "integrity": "sha512-40svmmugfM3mUN7VUDGVE1tQGOhyi8enlGD0CNJEcMM36C1f71PKM21DFgNHUfem0XnA+d8H8oN3Z9ZpJjSslg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.5", + "@radix-ui/react-collection": "1.1.12", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-use-is-hydrated": "0.1.1", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.0.tgz", + "integrity": "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz", + "integrity": "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.3.tgz", + "integrity": "sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.3", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz", + "integrity": "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.1.tgz", + "integrity": "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz", + "integrity": "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.2.tgz", + "integrity": "sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.2.tgz", + "integrity": "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.2.tgz", + "integrity": "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==", + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz", + "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^15.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/lucide-react": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.24.0.tgz", + "integrity": "sha512-YT6mBD8lGKkg4nM39enlm94/sfJIiW0YKUT60fBy4YK8tai31ylg1VhGNWxkpSKHo9UagfnZqwIff3HTDQwXeA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", + "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/react-remove-scroll": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.8.tgz", + "integrity": "sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.8" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.8.tgz", + "integrity": "sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsup": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", + "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/vite": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", + "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.16", + "rolldown": "~1.1.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/vitest/node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/components/action-buttons/package.json b/components/action-buttons/package.json new file mode 100644 index 0000000..249afbc --- /dev/null +++ b/components/action-buttons/package.json @@ -0,0 +1,74 @@ +{ + "name": "@jooservices/react-action-buttons", + "version": "0.1.0", + "description": "Shared action button primitives for React \u2014 bars, menus, and split buttons", + "type": "module", + "license": "MIT", + "author": "JOOservices", + "repository": { + "type": "git", + "url": "https://github.com/jooservices/react.git", + "directory": "components/action-buttons" + }, + "keywords": [ + "react", + "actions", + "button", + "dropdown", + "toolbar", + "shadcn" + ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./styles.css": "./dist/styles.css" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "sideEffects": [ + "**/*.css" + ], + "scripts": { + "build": "tsup && cp src/styles.css dist/styles.css", + "typecheck": "tsc --noEmit", + "test": "vitest run", + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" + }, + "dependencies": { + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-slot": "^1.2.4", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^14.6.1", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/components/action-buttons/src/ActionButtons.test.tsx b/components/action-buttons/src/ActionButtons.test.tsx new file mode 100644 index 0000000..6fca444 --- /dev/null +++ b/components/action-buttons/src/ActionButtons.test.tsx @@ -0,0 +1,183 @@ +import { cleanup, render, screen } from "@testing-library/react"; +import userEvent, { PointerEventsCheckLevel } from "@testing-library/user-event"; +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { + ActionBar, + ACTION_COLOR_GUIDE, + ActionMenu, + Actions, + BUTTON_VARIANTS, + Button, + resolveButtonVariant, + SplitButton, +} from "./index"; + +afterEach(() => { + cleanup(); +}); + +function setupUser() { + return userEvent.setup({ pointerEventsCheck: PointerEventsCheckLevel.Never }); +} + +describe("ActionBar", () => { + it("renders separate layout by default", () => { + const { container } = render( + + + + , + ); + + expect(container.querySelector(".joo-ab-bar")).toBeTruthy(); + expect(container.querySelector(".joo-ab-bar--group")).toBeNull(); + }); + + it("applies group layout class", () => { + const { container } = render( + + + + , + ); + + expect(container.querySelector(".joo-ab-bar--group")).toBeTruthy(); + }); +}); + +describe("intent color guide", () => { + it("documents recommended intent → color mapping", () => { + expect(ACTION_COLOR_GUIDE.create).toBe("primary"); + expect(ACTION_COLOR_GUIDE.save).toBe("primary"); + expect(ACTION_COLOR_GUIDE.edit).toBe("secondary"); + expect(ACTION_COLOR_GUIDE.export).toBe("outline"); + expect(ACTION_COLOR_GUIDE.cancel).toBe("outline"); + expect(ACTION_COLOR_GUIDE.more).toBe("ghost"); + expect(ACTION_COLOR_GUIDE.view).toBe("ghost"); + expect(ACTION_COLOR_GUIDE.apply).toBe("dark"); + expect(ACTION_COLOR_GUIDE.publish).toBe("dark"); + expect(ACTION_COLOR_GUIDE.delete).toBe("danger"); + expect(ACTION_COLOR_GUIDE.remove).toBe("danger"); + }); + + it("lets explicit variant win over intent", () => { + expect(resolveButtonVariant("delete", "primary")).toBe("primary"); + expect(resolveButtonVariant("delete", undefined)).toBe("danger"); + expect(resolveButtonVariant(undefined, "secondary")).toBe("secondary"); + expect(resolveButtonVariant(undefined, "destructive")).toBe("danger"); + }); + + it("applies guided intent class and icon on Button", () => { + const { container } = render( + , + ); + + const button = screen.getByRole("button", { name: "Create" }); + expect(button.className).toContain("joo-ab-btn--primary"); + expect(button.getAttribute("data-intent")).toBe("create"); + expect(screen.getByTestId("plus")).toBeTruthy(); + expect(container.querySelector(".joo-ab-icon")).toBeTruthy(); + }); + + it("uses all gallery button color variants", () => { + for (const color of BUTTON_VARIANTS) { + const { unmount } = render(); + const className = + color === "destructive" ? "joo-ab-btn--danger" : `joo-ab-btn--${color}`; + expect(screen.getByRole("button", { name: color }).className).toContain( + color === "destructive" ? "joo-ab-btn--danger" : className, + ); + unmount(); + } + }); +}); + +describe("ActionMenu", () => { + it("opens menu and invokes item onClick", async () => { + const user = setupUser(); + const onExport = vi.fn(); + + render( + , + ); + + await user.click(screen.getByRole("button", { name: "More" })); + await user.click(await screen.findByRole("menuitem", { name: "Export" })); + + expect(onExport).toHaveBeenCalledTimes(1); + }); +}); + +describe("SplitButton", () => { + it("fires primary onClick separately from menu items", async () => { + const user = setupUser(); + const onSave = vi.fn(); + const onDraft = vi.fn(); + + render( + , + ); + + await user.click(screen.getByRole("button", { name: "Save" })); + expect(onSave).toHaveBeenCalledTimes(1); + expect(onDraft).not.toHaveBeenCalled(); + + await user.click(screen.getByRole("button", { name: "Save options" })); + await user.click(await screen.findByRole("menuitem", { name: "Save as draft" })); + expect(onDraft).toHaveBeenCalledTimes(1); + }); +}); + +describe("Actions", () => { + it("renders declarative descriptors with icons and labels", async () => { + const user = setupUser(); + const onEdit = vi.fn(); + const onExport = vi.fn(); + + render( + , + onClick: onEdit, + }, + { + type: "menu", + label: "More", + intent: "more", + items: [{ label: "Export", onClick: onExport, intent: "export" }], + }, + ]} + />, + ); + + expect(screen.getByTestId("edit-icon")).toBeTruthy(); + expect(screen.getByRole("button", { name: "Edit" }).textContent).toContain("Edit"); + + await user.click(screen.getByRole("button", { name: "Edit" })); + expect(onEdit).toHaveBeenCalledTimes(1); + + await user.click(screen.getByRole("button", { name: "More" })); + await user.click(await screen.findByRole("menuitem", { name: "Export" })); + expect(onExport).toHaveBeenCalledTimes(1); + }); + + it("returns null for empty items", () => { + const { container } = render(); + expect(container.firstChild).toBeNull(); + }); +}); diff --git a/components/action-buttons/src/components/ActionBar.tsx b/components/action-buttons/src/components/ActionBar.tsx new file mode 100644 index 0000000..0c5e7d6 --- /dev/null +++ b/components/action-buttons/src/components/ActionBar.tsx @@ -0,0 +1,17 @@ +import { cn } from "../lib/cn"; +import type { ActionBarProps } from "../types"; + +export function ActionBar({ children, layout = "separate", className }: ActionBarProps) { + return ( +
+ {children} +
+ ); +} diff --git a/components/action-buttons/src/components/ActionIcon.tsx b/components/action-buttons/src/components/ActionIcon.tsx new file mode 100644 index 0000000..b3040eb --- /dev/null +++ b/components/action-buttons/src/components/ActionIcon.tsx @@ -0,0 +1,15 @@ +import type { ReactNode } from "react"; + +import { cn } from "../lib/cn"; + +export function ActionIcon({ icon, className }: { icon: ReactNode; className?: string }) { + if (!icon) { + return null; + } + + return ( + + {icon} + + ); +} diff --git a/components/action-buttons/src/components/ActionMenu.tsx b/components/action-buttons/src/components/ActionMenu.tsx new file mode 100644 index 0000000..8edd693 --- /dev/null +++ b/components/action-buttons/src/components/ActionMenu.tsx @@ -0,0 +1,80 @@ +import { ChevronDown } from "lucide-react"; + +import { resolveMenuItemVariant } from "../intent"; +import type { ActionItem, ActionMenuProps } from "../types"; +import { ActionIcon } from "./ActionIcon"; +import { Button } from "./Button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; + +function MenuItems({ items, menuLabel }: { items: ActionItem[]; menuLabel?: string }) { + return ( + + {menuLabel ? ( + <> + {menuLabel} + + + ) : null} + {items.map((item) => ( + { + event.preventDefault(); + item.onClick(); + }} + > + {item.icon ? : null} + {item.label} + + ))} + + ); +} + +export function ActionMenu({ + label, + items, + icon, + disabled, + intent = "more", + variant, + size = "sm", + className, +}: ActionMenuProps) { + const iconOnly = size === "icon"; + + return ( + + + + + + + ); +} + +export { MenuItems }; diff --git a/components/action-buttons/src/components/Actions.tsx b/components/action-buttons/src/components/Actions.tsx new file mode 100644 index 0000000..4cd1738 --- /dev/null +++ b/components/action-buttons/src/components/Actions.tsx @@ -0,0 +1,68 @@ +import type { ActionsProps } from "../types"; +import { ActionBar } from "./ActionBar"; +import { ActionMenu } from "./ActionMenu"; +import { Button } from "./Button"; +import { SplitButton } from "./SplitButton"; + +export function Actions({ items, layout = "separate", className }: ActionsProps) { + if (items.length === 0) { + return null; + } + + return ( + + {items.map((item, index) => { + const key = `${item.type}-${item.label}-${index}`; + + if (item.type === "single") { + const iconOnly = item.size === "icon"; + return ( + + ); + } + + if (item.type === "menu") { + return ( + + ); + } + + return ( + + ); + })} + + ); +} diff --git a/components/action-buttons/src/components/Button.tsx b/components/action-buttons/src/components/Button.tsx new file mode 100644 index 0000000..df7875a --- /dev/null +++ b/components/action-buttons/src/components/Button.tsx @@ -0,0 +1,69 @@ +import { Slot } from "@radix-ui/react-slot"; +import { cva } from "class-variance-authority"; + +import { resolveButtonVariant } from "../intent"; +import { cn } from "../lib/cn"; +import type { ButtonProps } from "../types"; +import { ActionIcon } from "./ActionIcon"; + +const buttonVariants = cva("joo-ab-btn", { + variants: { + variant: { + primary: "joo-ab-btn--primary", + secondary: "joo-ab-btn--secondary", + success: "joo-ab-btn--success", + danger: "joo-ab-btn--danger", + warning: "joo-ab-btn--warning", + info: "joo-ab-btn--info", + light: "joo-ab-btn--light", + dark: "joo-ab-btn--dark", + outline: "joo-ab-btn--outline", + ghost: "joo-ab-btn--ghost", + destructive: "joo-ab-btn--danger", + }, + size: { + sm: "joo-ab-btn--sm", + md: "joo-ab-btn--md", + icon: "joo-ab-btn--icon", + }, + }, + defaultVariants: { + variant: "outline", + size: "sm", + }, +}); + +export function Button({ + className, + intent, + variant, + size = "sm", + icon, + asChild = false, + type = "button", + children, + ...props +}: ButtonProps) { + const resolved = resolveButtonVariant(intent, variant); + const Comp = asChild ? Slot : "button"; + const iconOnly = size === "icon"; + + return ( + + {asChild ? ( + children + ) : ( + <> + {icon ? : null} + {iconOnly ? null : children} + {iconOnly && !children ? {props["aria-label"]} : null} + + )} + + ); +} diff --git a/components/action-buttons/src/components/SplitButton.tsx b/components/action-buttons/src/components/SplitButton.tsx new file mode 100644 index 0000000..a4abbe6 --- /dev/null +++ b/components/action-buttons/src/components/SplitButton.tsx @@ -0,0 +1,53 @@ +import { ChevronDown } from "lucide-react"; + +import { cn } from "../lib/cn"; +import type { SplitButtonProps } from "../types"; +import { Button } from "./Button"; +import { MenuItems } from "./ActionMenu"; +import { DropdownMenu, DropdownMenuTrigger } from "./ui/dropdown-menu"; + +export function SplitButton({ + label, + onClick, + items, + icon, + disabled, + intent = "save", + variant, + size = "sm", + className, + menuLabel, +}: SplitButtonProps) { + return ( +
+ + + + + + + +
+ ); +} diff --git a/components/action-buttons/src/components/ui/dropdown-menu.tsx b/components/action-buttons/src/components/ui/dropdown-menu.tsx new file mode 100644 index 0000000..2f00e11 --- /dev/null +++ b/components/action-buttons/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,63 @@ +import * as React from "react"; +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; + +import { cn } from "../../lib/cn"; + +export const DropdownMenu = DropdownMenuPrimitive.Root; +export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; +export const DropdownMenuGroup = DropdownMenuPrimitive.Group; +export const DropdownMenuPortal = DropdownMenuPrimitive.Portal; + +export function DropdownMenuContent({ + className, + sideOffset = 4, + ...props +}: React.ComponentPropsWithoutRef) { + return ( + + + + ); +} + +export function DropdownMenuLabel({ + className, + ...props +}: React.ComponentPropsWithoutRef) { + return ; +} + +export function DropdownMenuSeparator({ + className, + ...props +}: React.ComponentPropsWithoutRef) { + return ( + + ); +} + +export function DropdownMenuItem({ + className, + inset, + variant = "default", + ...props +}: React.ComponentPropsWithoutRef & { + inset?: boolean; + variant?: "default" | "destructive"; +}) { + return ( + + ); +} diff --git a/components/action-buttons/src/index.ts b/components/action-buttons/src/index.ts new file mode 100644 index 0000000..96242bc --- /dev/null +++ b/components/action-buttons/src/index.ts @@ -0,0 +1,27 @@ +export { ActionBar } from "./components/ActionBar"; +export { Actions } from "./components/Actions"; +export { ActionMenu } from "./components/ActionMenu"; +export { Button } from "./components/Button"; +export { SplitButton } from "./components/SplitButton"; +export { + ACTION_COLOR_GUIDE, + ACTION_INTENT_VARIANT, + resolveButtonVariant, + resolveMenuItemVariant, +} from "./intent"; +export { BUTTON_VARIANTS } from "./types"; + +export type { + ActionBarLayout, + ActionBarProps, + ActionDescriptor, + ActionIntent, + ActionItem, + ActionItemVariant, + ActionMenuProps, + ActionsProps, + ButtonProps, + ButtonSize, + ButtonVariant, + SplitButtonProps, +} from "./types"; diff --git a/components/action-buttons/src/intent.ts b/components/action-buttons/src/intent.ts new file mode 100644 index 0000000..7b85b20 --- /dev/null +++ b/components/action-buttons/src/intent.ts @@ -0,0 +1,71 @@ +import type { ActionIntent, ButtonVariant } from "./types"; + +/** + * Developer guide — recommended action → color. + * Not enforced: pass `variant` explicitly to override. + * + * | Intent | Suggested color | Typical use | + * |------------------------|-----------------|--------------------------------| + * | `create`, `save` | primary | Add / persist (cyan brand CTA) | + * | `edit` | secondary | Soft gray modify | + * | `export`, `cancel` | outline | Bordered alternate | + * | `more`, `view` | ghost | Quiet / overflow | + * | `apply`, `publish` | dark | Strong neutral CTA (near-black)| + * | `delete`, `remove` | danger | Irreversible remove | + */ +export const ACTION_COLOR_GUIDE = { + create: "primary", + save: "primary", + edit: "secondary", + export: "outline", + cancel: "outline", + more: "ghost", + view: "ghost", + apply: "dark", + publish: "dark", + delete: "danger", + remove: "danger", +} as const satisfies Record; + +/** @deprecated Use `ACTION_COLOR_GUIDE` — same map, guidance only. */ +export const ACTION_INTENT_VARIANT = ACTION_COLOR_GUIDE; + +/** + * Resolve button color: explicit `variant` always wins. + * `intent` only suggests a default when `variant` is omitted. + */ +export function resolveButtonVariant( + intent: ActionIntent | undefined, + variant: ButtonVariant | undefined, + fallback: ButtonVariant = "outline", +): ButtonVariant { + if (variant === "destructive") { + return "danger"; + } + if (variant) { + return variant; + } + if (intent) { + return ACTION_COLOR_GUIDE[intent]; + } + return fallback; +} + +/** + * Menu row tone: explicit `variant` wins; `intent` suggests danger for delete/remove. + */ +export function resolveMenuItemVariant( + intent: ActionIntent | undefined, + variant: "default" | "danger" | "destructive" | undefined, +): "default" | "destructive" { + if (variant === "danger" || variant === "destructive") { + return "destructive"; + } + if (variant === "default") { + return "default"; + } + if (intent === "delete" || intent === "remove") { + return "destructive"; + } + return "default"; +} diff --git a/components/action-buttons/src/lib/cn.ts b/components/action-buttons/src/lib/cn.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/components/action-buttons/src/lib/cn.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/components/action-buttons/src/styles.css b/components/action-buttons/src/styles.css new file mode 100644 index 0000000..9404dc9 --- /dev/null +++ b/components/action-buttons/src/styles.css @@ -0,0 +1,354 @@ +:root { + --joo-background: 0 0% 100%; + --joo-foreground: 222.2 84% 4.9%; + --joo-muted: 210 40% 96.1%; + --joo-muted-foreground: 215.4 16.3% 46.9%; + --joo-border: 214.3 31.8% 91.4%; + --joo-primary: 222.2 47.4% 11.2%; + --joo-primary-foreground: 210 40% 98%; + --joo-secondary: 210 40% 96.1%; + --joo-secondary-foreground: 222.2 47.4% 11.2%; + --joo-accent: 210 40% 96.1%; + --joo-accent-foreground: 222.2 47.4% 11.2%; + --joo-destructive: 0 84.2% 60.2%; + --joo-destructive-foreground: 210 40% 98%; + --joo-radius: 0.375rem; + + /* Bootstrap-inspired action button palette (JOO cyan-tuned) */ + --joo-ab-primary: 187 72% 35%; + --joo-ab-primary-foreground: 0 0% 100%; + --joo-ab-secondary: 215 16% 47%; + --joo-ab-secondary-foreground: 0 0% 100%; + --joo-ab-success: 152 55% 36%; + --joo-ab-success-foreground: 0 0% 100%; + --joo-ab-danger: 0 72% 51%; + --joo-ab-danger-foreground: 0 0% 100%; + --joo-ab-warning: 38 92% 50%; + --joo-ab-warning-foreground: 222.2 47.4% 11.2%; + --joo-ab-info: 187 65% 42%; + --joo-ab-info-foreground: 0 0% 100%; + --joo-ab-light: 210 40% 96%; + --joo-ab-light-foreground: 222.2 47.4% 11.2%; + --joo-ab-dark: 222.2 47.4% 11.2%; + --joo-ab-dark-foreground: 210 40% 98%; +} + +.dark { + --joo-background: 222.2 84% 4.9%; + --joo-foreground: 210 40% 98%; + --joo-muted: 217.2 32.6% 17.5%; + --joo-muted-foreground: 215 20.2% 65.1%; + --joo-border: 217.2 32.6% 17.5%; + --joo-primary: 210 40% 98%; + --joo-primary-foreground: 222.2 47.4% 11.2%; + --joo-secondary: 217.2 32.6% 17.5%; + --joo-secondary-foreground: 210 40% 98%; + --joo-accent: 217.2 32.6% 17.5%; + --joo-accent-foreground: 210 40% 98%; + --joo-destructive: 0 62.8% 30.6%; + --joo-destructive-foreground: 210 40% 98%; + + --joo-ab-primary: 187 70% 42%; + --joo-ab-primary-foreground: 222.2 84% 4.9%; + --joo-ab-secondary: 215 16% 55%; + --joo-ab-secondary-foreground: 0 0% 100%; + --joo-ab-success: 152 50% 40%; + --joo-ab-success-foreground: 0 0% 100%; + --joo-ab-danger: 0 65% 55%; + --joo-ab-danger-foreground: 0 0% 100%; + --joo-ab-warning: 38 90% 55%; + --joo-ab-warning-foreground: 222.2 47.4% 11.2%; + --joo-ab-info: 187 60% 48%; + --joo-ab-info-foreground: 222.2 84% 4.9%; + --joo-ab-light: 217.2 32.6% 22%; + --joo-ab-light-foreground: 210 40% 98%; + --joo-ab-dark: 210 40% 98%; + --joo-ab-dark-foreground: 222.2 47.4% 11.2%; +} + +.joo-ab-bar { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; +} + +.joo-ab-bar--group { + gap: 0; +} + +.joo-ab-bar--group > .joo-ab-btn, +.joo-ab-bar--group > .joo-ab-split { + border-radius: 0; +} + +.joo-ab-bar--group > .joo-ab-btn:first-child, +.joo-ab-bar--group > .joo-ab-split:first-child, +.joo-ab-bar--group > .joo-ab-split:first-child .joo-ab-split-main { + border-top-left-radius: var(--joo-radius); + border-bottom-left-radius: var(--joo-radius); +} + +.joo-ab-bar--group > .joo-ab-btn:last-child, +.joo-ab-bar--group > .joo-ab-split:last-child, +.joo-ab-bar--group > .joo-ab-split:last-child .joo-ab-split-trigger { + border-top-right-radius: var(--joo-radius); + border-bottom-right-radius: var(--joo-radius); +} + +.joo-ab-bar--group > .joo-ab-btn + .joo-ab-btn, +.joo-ab-bar--group > .joo-ab-btn + .joo-ab-split, +.joo-ab-bar--group > .joo-ab-split + .joo-ab-btn, +.joo-ab-bar--group > .joo-ab-split + .joo-ab-split { + margin-left: -1px; +} + +.joo-ab-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.375rem; + border-radius: var(--joo-radius); + border: 1px solid transparent; + font-size: 0.875rem; + font-weight: 500; + line-height: 1; + transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; + cursor: pointer; + white-space: nowrap; +} + +.joo-ab-btn:disabled { + opacity: 0.5; + pointer-events: none; + cursor: not-allowed; +} + +.joo-ab-btn--sm { + height: 2rem; + padding: 0 0.75rem; + font-size: 0.8125rem; +} + +.joo-ab-btn--md { + height: 2.25rem; + padding: 0 1rem; + font-size: 0.875rem; +} + +.joo-ab-btn--icon { + height: 2rem; + width: 2rem; + padding: 0; +} + +.joo-ab-btn--primary { + background-color: hsl(var(--joo-ab-primary)); + color: hsl(var(--joo-ab-primary-foreground)); +} + +.joo-ab-btn--primary:hover { + background-color: hsl(var(--joo-ab-primary) / 0.9); +} + +.joo-ab-btn--secondary { + background-color: hsl(var(--joo-ab-secondary)); + color: hsl(var(--joo-ab-secondary-foreground)); +} + +.joo-ab-btn--secondary:hover { + background-color: hsl(var(--joo-ab-secondary) / 0.9); +} + +.joo-ab-btn--success { + background-color: hsl(var(--joo-ab-success)); + color: hsl(var(--joo-ab-success-foreground)); +} + +.joo-ab-btn--success:hover { + background-color: hsl(var(--joo-ab-success) / 0.9); +} + +.joo-ab-btn--danger { + background-color: hsl(var(--joo-ab-danger)); + color: hsl(var(--joo-ab-danger-foreground)); +} + +.joo-ab-btn--danger:hover { + background-color: hsl(var(--joo-ab-danger) / 0.9); +} + +.joo-ab-btn--warning { + background-color: hsl(var(--joo-ab-warning)); + color: hsl(var(--joo-ab-warning-foreground)); +} + +.joo-ab-btn--warning:hover { + background-color: hsl(var(--joo-ab-warning) / 0.9); +} + +.joo-ab-btn--info { + background-color: hsl(var(--joo-ab-info)); + color: hsl(var(--joo-ab-info-foreground)); +} + +.joo-ab-btn--info:hover { + background-color: hsl(var(--joo-ab-info) / 0.9); +} + +.joo-ab-btn--light { + border-color: hsl(var(--joo-border)); + background-color: hsl(var(--joo-ab-light)); + color: hsl(var(--joo-ab-light-foreground)); +} + +.joo-ab-btn--light:hover { + background-color: hsl(var(--joo-ab-light) / 0.85); +} + +.joo-ab-btn--dark { + background-color: hsl(var(--joo-ab-dark)); + color: hsl(var(--joo-ab-dark-foreground)); +} + +.joo-ab-btn--dark:hover { + background-color: hsl(var(--joo-ab-dark) / 0.9); +} + +.joo-ab-btn--outline { + border-color: hsl(var(--joo-border)); + background-color: hsl(var(--joo-background)); + color: hsl(var(--joo-foreground)); +} + +.joo-ab-btn--outline:hover { + background-color: hsl(var(--joo-accent)); + color: hsl(var(--joo-accent-foreground)); +} + +.joo-ab-btn--ghost { + background-color: transparent; + color: hsl(var(--joo-foreground)); +} + +.joo-ab-btn--ghost:hover { + background-color: hsl(var(--joo-accent)); + color: hsl(var(--joo-accent-foreground)); +} + +.joo-ab-chevron { + width: 0.875rem; + height: 0.875rem; + flex-shrink: 0; +} + +.joo-ab-icon { + display: inline-flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 1rem; + height: 1rem; +} + +.joo-ab-icon > svg { + width: 1rem; + height: 1rem; +} + +.joo-ab-sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +.joo-ab-split { + display: inline-flex; + align-items: stretch; +} + +.joo-ab-split-main { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.joo-ab-split-trigger { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.joo-ab-split-trigger.joo-ab-btn--sm, +.joo-ab-split-trigger.joo-ab-btn--md { + width: auto; + min-width: 2rem; +} + +.joo-ab-dropdown-content { + z-index: 50; + min-width: 8rem; + overflow: hidden; + border-radius: var(--joo-radius); + border: 1px solid hsl(var(--joo-border)); + background-color: hsl(var(--joo-background)); + color: hsl(var(--joo-foreground)); + padding: 0.25rem; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); +} + +.joo-ab-dropdown-item { + display: flex; + width: 100%; + align-items: center; + gap: 0.5rem; + border-radius: calc(var(--joo-radius) - 2px); + padding: 0.375rem 0.5rem; + font-size: 0.875rem; + cursor: pointer; + outline: none; + border: none; + background: transparent; + color: inherit; + text-align: left; +} + +.joo-ab-dropdown-item:hover, +.joo-ab-dropdown-item[data-highlighted] { + background-color: hsl(var(--joo-accent)); + color: hsl(var(--joo-accent-foreground)); +} + +.joo-ab-dropdown-item--destructive { + color: hsl(var(--joo-destructive)); +} + +.joo-ab-dropdown-item--destructive:hover, +.joo-ab-dropdown-item--destructive[data-highlighted] { + background-color: hsl(var(--joo-destructive) / 0.1); + color: hsl(var(--joo-destructive)); +} + +.joo-ab-dropdown-item--inset { + padding-left: 2rem; +} + +.joo-ab-dropdown-label { + padding: 0.375rem 0.5rem; + font-size: 0.75rem; + font-weight: 600; + color: hsl(var(--joo-muted-foreground)); +} + +.joo-ab-dropdown-separator { + margin: 0.25rem -0.25rem; + height: 1px; + background-color: hsl(var(--joo-border)); +} diff --git a/components/action-buttons/src/types.ts b/components/action-buttons/src/types.ts new file mode 100644 index 0000000..158df5d --- /dev/null +++ b/components/action-buttons/src/types.ts @@ -0,0 +1,141 @@ +import type { ButtonHTMLAttributes, ReactNode } from "react"; + +/** Semantic action hint — see `ACTION_COLOR_GUIDE` (guidance only). */ +export type ActionIntent = + | "create" + | "save" + | "edit" + | "export" + | "cancel" + | "more" + | "view" + | "apply" + | "publish" + | "delete" + | "remove"; + +export type ActionItemVariant = "default" | "danger" | "destructive"; + +export type ActionItem = { + label: string; + icon?: ReactNode; + onClick: () => void; + disabled?: boolean; + /** Suggested action kind (color guide). Overridden by `variant` when set. */ + intent?: ActionIntent; + variant?: ActionItemVariant; +}; + +/** + * Bootstrap-inspired solid colors (JOO-tuned) plus outline/ghost utilities. + * Gallery order: primary → secondary → success → danger → warning → info → light → dark → outline → ghost + */ +export type ButtonVariant = + | "primary" + | "secondary" + | "success" + | "danger" + | "warning" + | "info" + | "light" + | "dark" + | "outline" + | "ghost" + /** @deprecated Prefer `danger` */ + | "destructive"; + +export type ButtonSize = "sm" | "md" | "icon"; + +export type ActionBarLayout = "separate" | "group"; + +export type ActionBarProps = { + children: ReactNode; + layout?: ActionBarLayout; + className?: string; +}; + +export type ButtonProps = ButtonHTMLAttributes & { + /** + * Optional action hint for developers / docs. When `variant` is omitted, + * color defaults from `ACTION_COLOR_GUIDE`. Explicit `variant` always wins. + */ + intent?: ActionIntent; + /** Explicit color. Always wins over `intent` when provided. */ + variant?: ButtonVariant; + size?: ButtonSize; + /** Leading icon (Lucide or custom). Shown beside label; alone when `size="icon"`. */ + icon?: ReactNode; + asChild?: boolean; + className?: string; +}; + +export type ActionMenuProps = { + label: string; + items: ActionItem[]; + icon?: ReactNode; + disabled?: boolean; + intent?: ActionIntent; + variant?: ButtonVariant; + size?: ButtonSize; + className?: string; +}; + +export type SplitButtonProps = { + label: string; + onClick: () => void; + items: ActionItem[]; + icon?: ReactNode; + disabled?: boolean; + intent?: ActionIntent; + variant?: ButtonVariant; + size?: Exclude; + className?: string; + menuLabel?: string; +}; + +type ActionDescriptorBase = { + label: string; + icon?: ReactNode; + disabled?: boolean; + intent?: ActionIntent; + variant?: ButtonVariant; +}; + +export type ActionDescriptor = + | (ActionDescriptorBase & { + type: "single"; + onClick: () => void; + size?: ButtonSize; + }) + | (ActionDescriptorBase & { + type: "menu"; + items: ActionItem[]; + size?: ButtonSize; + }) + | (ActionDescriptorBase & { + type: "split"; + onClick: () => void; + items: ActionItem[]; + size?: Exclude; + menuLabel?: string; + }); + +export type ActionsProps = { + items: ActionDescriptor[]; + layout?: ActionBarLayout; + className?: string; +}; + +/** All variants shown in demos / docs (Bootstrap-like + outline/ghost). */ +export const BUTTON_VARIANTS: ButtonVariant[] = [ + "primary", + "secondary", + "success", + "danger", + "warning", + "info", + "light", + "dark", + "outline", + "ghost", +]; diff --git a/components/action-buttons/tsconfig.json b/components/action-buttons/tsconfig.json new file mode 100644 index 0000000..974dd00 --- /dev/null +++ b/components/action-buttons/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "isolatedModules": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["src"] +} diff --git a/components/action-buttons/tsup.config.ts b/components/action-buttons/tsup.config.ts new file mode 100644 index 0000000..3f0c75c --- /dev/null +++ b/components/action-buttons/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + dts: true, + sourcemap: true, + clean: true, + external: ["react", "react-dom", "lucide-react"], + treeshake: true, +}); diff --git a/components/action-buttons/vitest.config.ts b/components/action-buttons/vitest.config.ts new file mode 100644 index 0000000..e5d7e16 --- /dev/null +++ b/components/action-buttons/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "jsdom", + setupFiles: [], + }, +}); From 4c8793293838cfa9547b93c169706bab07305426 Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:24 -0600 Subject: [PATCH 02/14] feat(card): add BaseCard and StatCard package --- components/card/.gitignore | 1 + components/card/AGENTS.md | 31 + components/card/CHANGELOG.md | 8 + components/card/LICENSE | 21 + components/card/README.md | 59 + components/card/dist/index.d.ts | 50 + components/card/dist/index.js | 95 + components/card/dist/index.js.map | 1 + components/card/dist/styles.css | 210 ++ components/card/package-lock.json | 3656 +++++++++++++++++++ components/card/package.json | 69 + components/card/src/Card.test.tsx | 55 + components/card/src/components/BaseCard.tsx | 55 + components/card/src/components/StatCard.tsx | 63 + components/card/src/index.ts | 4 + components/card/src/lib/cn.ts | 6 + components/card/src/styles.css | 210 ++ components/card/src/types.ts | 45 + components/card/tsconfig.json | 16 + components/card/tsup.config.ts | 11 + components/card/vitest.config.ts | 8 + 21 files changed, 4674 insertions(+) create mode 100644 components/card/.gitignore create mode 100644 components/card/AGENTS.md create mode 100644 components/card/CHANGELOG.md create mode 100644 components/card/LICENSE create mode 100644 components/card/README.md create mode 100644 components/card/dist/index.d.ts create mode 100644 components/card/dist/index.js create mode 100644 components/card/dist/index.js.map create mode 100644 components/card/dist/styles.css create mode 100644 components/card/package-lock.json create mode 100644 components/card/package.json create mode 100644 components/card/src/Card.test.tsx create mode 100644 components/card/src/components/BaseCard.tsx create mode 100644 components/card/src/components/StatCard.tsx create mode 100644 components/card/src/index.ts create mode 100644 components/card/src/lib/cn.ts create mode 100644 components/card/src/styles.css create mode 100644 components/card/src/types.ts create mode 100644 components/card/tsconfig.json create mode 100644 components/card/tsup.config.ts create mode 100644 components/card/vitest.config.ts diff --git a/components/card/.gitignore b/components/card/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/components/card/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/components/card/AGENTS.md b/components/card/AGENTS.md new file mode 100644 index 0000000..9cba566 --- /dev/null +++ b/components/card/AGENTS.md @@ -0,0 +1,31 @@ +# card package agents + +@jooservices/react-card — BaseCard shell and StatCard metrics. + +## Paths + +- Source: `components/card/src` +- Entry: `components/card/src/index.ts` +- Build output: `components/card/dist` (committed) + +## Commands + +```bash +cd components/card +npm install # first time +npm run typecheck +npm test +npm run build +``` + +After user-visible changes: update `apps/demo` (Dashboard + `/card`) and run `npm run demo:typecheck`. + +## Peers + +`react`, `react-dom`, `lucide-react` + +## Docs + +- User guide: `docs/02-user-guide/09-react-card.md` (consumer API — do not send humans to `src/`) +- Package README: `components/card/README.md` +- Root policy: `AGENTS.md` diff --git a/components/card/CHANGELOG.md b/components/card/CHANGELOG.md new file mode 100644 index 0000000..3d711f1 --- /dev/null +++ b/components/card/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog — @jooservices/react-card + +## [Unreleased] + +### Added + +- `BaseCard` — header (optional icon / title / subtitle / actions), content, footer +- `StatCard` — metric card on BaseCard with `label`, `value`, `subtext`, optional header `icon`, `info` tooltip control, `tone`, `footer` diff --git a/components/card/LICENSE b/components/card/LICENSE new file mode 100644 index 0000000..e630730 --- /dev/null +++ b/components/card/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 JOOservices + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/card/README.md b/components/card/README.md new file mode 100644 index 0000000..692aba9 --- /dev/null +++ b/components/card/README.md @@ -0,0 +1,59 @@ +# @jooservices/react-card + +Shared card primitives: **BaseCard** (header / content / footer shell) and **StatCard** (dashboard metrics). + +## Install + +```bash +pnpm add "github:jooservices/react#v1.0.0&path:components/card" +``` + +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). + +## Usage + +```ts +import "@jooservices/react-card/styles.css"; +import { BaseCard, StatCard } from "@jooservices/react-card"; +import { Boxes } from "lucide-react"; + +} + title="Section" + subtitle="Optional support line" + actions={} + footer="Optional footer" +> + Free content + + +} + info="What this metric means." + tone="cyan" + footer={Docs} +/> +``` + +### BaseCard slots + +| Slot | Prop | Notes | +|------|------|--------| +| Header leading | `icon?` | Optional visual identity | +| Header title | `title?` / `subtitle?` | Left column | +| Header actions | `actions?` | Right; compose with action-buttons when needed | +| Content | `children` | Free body | +| Footer | `footer?` | Divided bottom region | + +### StatCard + +Built on BaseCard. Uses a small uppercase `label`, large `value` (numbers get `toLocaleString()`), optional `subtext`, optional leading `icon`, and optional `info` (CircleHelp control with tooltip explaining the metric). Extra `actions` render after the info control. + +`tone`: `slate` \| `cyan` \| `amber` \| `emerald` \| `rose` (colors the value). + +## Peers + +`react`, `react-dom`, `lucide-react` diff --git a/components/card/dist/index.d.ts b/components/card/dist/index.d.ts new file mode 100644 index 0000000..50a8794 --- /dev/null +++ b/components/card/dist/index.d.ts @@ -0,0 +1,50 @@ +import * as react from 'react'; +import { HTMLAttributes, ReactNode } from 'react'; + +type CardTone = "slate" | "cyan" | "amber" | "emerald" | "rose"; +type BaseCardProps = Omit, "title"> & { + /** Element tag for the card root. */ + as?: "article" | "section" | "div"; + /** Optional leading icon in the header. */ + icon?: ReactNode; + /** Header title (left). */ + title?: ReactNode; + /** Optional supporting line under the title. */ + subtitle?: ReactNode; + /** Optional header actions (right). Prefer ghost/icon controls. */ + actions?: ReactNode; + /** Main body. */ + children?: ReactNode; + /** Optional footer below a divider. */ + footer?: ReactNode; + /** Soft shadow (default true). */ + shadow?: boolean; + className?: string; +}; +type StatCardProps = { + /** Metric label (header). */ + label: string; + /** Large primary value (number or short text). */ + value: ReactNode; + /** Supporting line under the value. */ + subtext?: ReactNode; + /** Optional leading header icon. */ + icon?: ReactNode; + /** + * Metric definition shown via the info control in the header actions slot. + * Renders a CircleHelp / Info button with accessible tooltip. + */ + info?: string; + /** Extra header actions (merged after the built-in info control when `info` is set). */ + actions?: ReactNode; + footer?: ReactNode; + /** Colors the large value. */ + tone?: CardTone; + className?: string; +}; + +declare function BaseCard({ as: Component, icon, title, subtitle, actions, children, footer, shadow, className, ...props }: BaseCardProps): react.JSX.Element; + +declare function StatCard({ label, value, subtext, icon, info, actions, footer, tone, className, }: StatCardProps): react.JSX.Element; + +export { BaseCard, type BaseCardProps, type CardTone, StatCard, type StatCardProps }; diff --git a/components/card/dist/index.js b/components/card/dist/index.js new file mode 100644 index 0000000..2634340 --- /dev/null +++ b/components/card/dist/index.js @@ -0,0 +1,95 @@ +import { clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; +import { jsxs, jsx, Fragment } from 'react/jsx-runtime'; +import { CircleHelp } from 'lucide-react'; + +// src/lib/cn.ts +function cn(...inputs) { + return twMerge(clsx(inputs)); +} +function BaseCard({ + as: Component = "article", + icon, + title, + subtitle, + actions, + children, + footer, + shadow = true, + className, + ...props +}) { + const hasHeader = icon !== void 0 || title !== void 0 || subtitle !== void 0 || actions !== void 0; + return /* @__PURE__ */ jsxs( + Component, + { + className: cn("joo-card", shadow && "joo-card--shadow", className), + ...props, + children: [ + hasHeader ? /* @__PURE__ */ jsxs("div", { className: "joo-card-header", children: [ + /* @__PURE__ */ jsxs("div", { className: "joo-card-header-main", children: [ + (icon !== void 0 || title !== void 0) && /* @__PURE__ */ jsxs("div", { className: "joo-card-header-title-row", children: [ + icon !== void 0 ? /* @__PURE__ */ jsx("span", { className: "joo-card-header-icon", "aria-hidden": typeof icon !== "string", children: icon }) : null, + title !== void 0 ? /* @__PURE__ */ jsx("div", { className: "joo-card-title", children: title }) : null + ] }), + subtitle !== void 0 ? /* @__PURE__ */ jsx("div", { className: "joo-card-subtitle", children: subtitle }) : null + ] }), + actions !== void 0 ? /* @__PURE__ */ jsx("div", { className: "joo-card-actions", children: actions }) : null + ] }) : null, + children !== void 0 && children !== null ? /* @__PURE__ */ jsx("div", { className: "joo-card-content", children }) : null, + footer !== void 0 && footer !== null ? /* @__PURE__ */ jsx("div", { className: "joo-card-footer", children: footer }) : null + ] + } + ); +} +function formatStatValue(value) { + if (typeof value === "number") { + return value.toLocaleString(); + } + return value; +} +function StatCard({ + label, + value, + subtext, + icon, + info, + actions, + footer, + tone = "slate", + className +}) { + const headerActions = info || actions ? /* @__PURE__ */ jsxs(Fragment, { children: [ + info ? /* @__PURE__ */ jsxs("span", { className: "joo-card-info", children: [ + /* @__PURE__ */ jsx( + "button", + { + type: "button", + className: "joo-card-info-trigger", + "aria-label": `About ${label}`, + children: /* @__PURE__ */ jsx(CircleHelp, { className: "joo-card-info-icon", "aria-hidden": true }) + } + ), + /* @__PURE__ */ jsx("span", { role: "tooltip", className: "joo-card-info-tooltip", children: info }) + ] }) : null, + actions + ] }) : void 0; + return /* @__PURE__ */ jsxs( + BaseCard, + { + className: cn("joo-stat-card", className), + icon, + title: /* @__PURE__ */ jsx("span", { className: "joo-stat-card-label", children: label }), + actions: headerActions, + footer, + children: [ + /* @__PURE__ */ jsx("p", { className: cn("joo-stat-card-value", `joo-stat-card-value--${tone}`), children: formatStatValue(value) }), + subtext !== void 0 && subtext !== null ? /* @__PURE__ */ jsx("p", { className: "joo-stat-card-subtext", children: subtext }) : null + ] + } + ); +} + +export { BaseCard, StatCard }; +//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/components/card/dist/index.js.map b/components/card/dist/index.js.map new file mode 100644 index 0000000..7961c98 --- /dev/null +++ b/components/card/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/lib/cn.ts","../src/components/BaseCard.tsx","../src/components/StatCard.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { cn } from \"../lib/cn\";\nimport type { BaseCardProps } from \"../types\";\n\nexport function BaseCard({\n as: Component = \"article\",\n icon,\n title,\n subtitle,\n actions,\n children,\n footer,\n shadow = true,\n className,\n ...props\n}: BaseCardProps) {\n const hasHeader =\n icon !== undefined ||\n title !== undefined ||\n subtitle !== undefined ||\n actions !== undefined;\n\n return (\n \n {hasHeader ? (\n
\n
\n {(icon !== undefined || title !== undefined) && (\n
\n {icon !== undefined ? (\n \n {icon}\n \n ) : null}\n {title !== undefined ?
{title}
: null}\n
\n )}\n {subtitle !== undefined ?
{subtitle}
: null}\n
\n {actions !== undefined ?
{actions}
: null}\n
\n ) : null}\n\n {children !== undefined && children !== null ? (\n
{children}
\n ) : null}\n\n {footer !== undefined && footer !== null ? (\n
{footer}
\n ) : null}\n \n );\n}\n","import { CircleHelp } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport type { StatCardProps } from \"../types\";\nimport { BaseCard } from \"./BaseCard\";\n\nfunction formatStatValue(value: ReactNode): ReactNode {\n if (typeof value === \"number\") {\n return value.toLocaleString();\n }\n return value;\n}\n\nexport function StatCard({\n label,\n value,\n subtext,\n icon,\n info,\n actions,\n footer,\n tone = \"slate\",\n className,\n}: StatCardProps) {\n const headerActions =\n info || actions ? (\n <>\n {info ? (\n \n \n \n \n \n {info}\n \n \n ) : null}\n {actions}\n \n ) : undefined;\n\n return (\n {label}}\n actions={headerActions}\n footer={footer}\n >\n

\n {formatStatValue(value)}\n

\n {subtext !== undefined && subtext !== null ? (\n

{subtext}

\n ) : null}\n \n );\n}\n"]} \ No newline at end of file diff --git a/components/card/dist/styles.css b/components/card/dist/styles.css new file mode 100644 index 0000000..bdfd37d --- /dev/null +++ b/components/card/dist/styles.css @@ -0,0 +1,210 @@ +:root { + --joo-card-bg: 0 0% 100%; + --joo-card-fg: 222.2 84% 4.9%; + --joo-card-muted: 215.4 16.3% 46.9%; + --joo-card-border: 214.3 31.8% 91.4%; + --joo-card-divider: 210 40% 96.1%; + --joo-card-radius: 0.5rem; + --joo-card-tone-slate: 222.2 47.4% 11.2%; + --joo-card-tone-cyan: 192 70% 30%; + --joo-card-tone-amber: 32 80% 36%; + --joo-card-tone-emerald: 160 70% 28%; + --joo-card-tone-rose: 350 70% 40%; +} + +.joo-card { + min-width: 0; + display: flex; + flex-direction: column; + border: 1px solid hsl(var(--joo-card-border)); + border-radius: var(--joo-card-radius); + background: hsl(var(--joo-card-bg)); + color: hsl(var(--joo-card-fg)); +} + +.joo-card--shadow { + box-shadow: 0 1px 2px 0 rgb(15 23 42 / 0.05); +} + +.joo-card-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 0.75rem; + padding: 0.75rem 1rem 0; +} + +.joo-card-header-main { + min-width: 0; + flex: 1; +} + +.joo-card-header-title-row { + display: flex; + align-items: center; + gap: 0.5rem; + min-width: 0; +} + +.joo-card-header-icon { + display: inline-flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + color: hsl(var(--joo-card-muted)); +} + +.joo-card-header-icon svg { + width: 1rem; + height: 1rem; +} + +.joo-card-title { + min-width: 0; + font-size: 0.875rem; + font-weight: 600; + line-height: 1.25; + color: hsl(var(--joo-card-fg)); +} + +.joo-card-subtitle { + margin-top: 0.25rem; + font-size: 0.75rem; + line-height: 1.35; + color: hsl(var(--joo-card-muted)); +} + +.joo-card-actions { + display: flex; + flex-shrink: 0; + flex-wrap: wrap; + align-items: center; + gap: 0.25rem; +} + +.joo-card-content { + min-width: 0; + padding: 0.75rem 1rem 1rem; +} + +.joo-card-header + .joo-card-content { + padding-top: 0.5rem; +} + +.joo-card-footer { + margin-top: auto; + border-top: 1px solid hsl(var(--joo-card-divider)); + padding: 0.5rem 1rem 0.75rem; + font-size: 0.75rem; + line-height: 1.35; + color: hsl(var(--joo-card-muted)); +} + +/* StatCard */ + +.joo-stat-card-label { + font-size: 0.75rem; + font-weight: 500; + letter-spacing: 0.04em; + text-transform: uppercase; + color: hsl(var(--joo-card-muted)); +} + +.joo-stat-card-value { + margin: 0; + font-size: 1.5rem; + font-weight: 600; + line-height: 1.2; + font-variant-numeric: tabular-nums; +} + +.joo-stat-card-value--slate { + color: hsl(var(--joo-card-tone-slate)); +} + +.joo-stat-card-value--cyan { + color: hsl(var(--joo-card-tone-cyan)); +} + +.joo-stat-card-value--amber { + color: hsl(var(--joo-card-tone-amber)); +} + +.joo-stat-card-value--emerald { + color: hsl(var(--joo-card-tone-emerald)); +} + +.joo-stat-card-value--rose { + color: hsl(var(--joo-card-tone-rose)); +} + +.joo-stat-card-subtext { + margin: 0.25rem 0 0; + font-size: 0.75rem; + line-height: 1.35; + color: hsl(var(--joo-card-muted)); +} + +/* Info control (StatCard header action) */ + +.joo-card-info { + position: relative; + display: inline-flex; +} + +.joo-card-info-trigger { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.5rem; + height: 1.5rem; + margin: 0; + padding: 0; + border: 0; + border-radius: 0.375rem; + background: transparent; + color: hsl(var(--joo-card-muted)); + cursor: help; +} + +.joo-card-info-trigger:hover, +.joo-card-info-trigger:focus-visible { + background: hsl(var(--joo-card-divider)); + color: hsl(var(--joo-card-fg)); + outline: none; +} + +.joo-card-info-icon { + width: 0.875rem; + height: 0.875rem; +} + +.joo-card-info-tooltip { + position: absolute; + right: 0; + top: calc(100% + 0.35rem); + z-index: 20; + width: max-content; + max-width: 14rem; + padding: 0.4rem 0.55rem; + border: 1px solid hsl(var(--joo-card-border)); + border-radius: 0.375rem; + background: hsl(var(--joo-card-bg)); + box-shadow: 0 4px 12px rgb(15 23 42 / 0.12); + color: hsl(var(--joo-card-fg)); + font-size: 0.75rem; + font-weight: 400; + letter-spacing: normal; + text-transform: none; + line-height: 1.35; + opacity: 0; + visibility: hidden; + pointer-events: none; + transition: opacity 120ms ease; +} + +.joo-card-info:hover .joo-card-info-tooltip, +.joo-card-info:focus-within .joo-card-info-tooltip { + opacity: 1; + visibility: visible; +} diff --git a/components/card/package-lock.json b/components/card/package-lock.json new file mode 100644 index 0000000..b781167 --- /dev/null +++ b/components/card/package-lock.json @@ -0,0 +1,3656 @@ +{ + "name": "@jooservices/react-card", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@jooservices/react-card", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@adobe/css-tools": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", + "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.0.0", + "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz", + "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.9.tgz", + "integrity": "sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.1.0", + "@csstools/css-calc": "^3.2.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz", + "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz", + "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^15.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/lucide-react": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.24.0.tgz", + "integrity": "sha512-YT6mBD8lGKkg4nM39enlm94/sfJIiW0YKUT60fBy4YK8tai31ylg1VhGNWxkpSKHo9UagfnZqwIff3HTDQwXeA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", + "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.8.tgz", + "integrity": "sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.8" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.8.tgz", + "integrity": "sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/tsup": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", + "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", + "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.16", + "rolldown": "~1.1.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/vitest/node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/components/card/package.json b/components/card/package.json new file mode 100644 index 0000000..e609c63 --- /dev/null +++ b/components/card/package.json @@ -0,0 +1,69 @@ +{ + "name": "@jooservices/react-card", + "version": "0.1.0", + "description": "Shared card primitives for React \u2014 BaseCard shell and StatCard metrics", + "type": "module", + "license": "MIT", + "author": "JOOservices", + "repository": { + "type": "git", + "url": "https://github.com/jooservices/react.git", + "directory": "components/card" + }, + "keywords": [ + "react", + "card", + "stat", + "metric", + "dashboard" + ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./styles.css": "./dist/styles.css" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "sideEffects": [ + "**/*.css" + ], + "scripts": { + "build": "tsup && cp src/styles.css dist/styles.css", + "typecheck": "tsc --noEmit", + "test": "vitest run", + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" + }, + "dependencies": { + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/components/card/src/Card.test.tsx b/components/card/src/Card.test.tsx new file mode 100644 index 0000000..72f01f6 --- /dev/null +++ b/components/card/src/Card.test.tsx @@ -0,0 +1,55 @@ +import { render, screen } from "@testing-library/react"; +import { describe, expect, it } from "vitest"; +import { Boxes } from "lucide-react"; + +import { BaseCard } from "./components/BaseCard"; +import { StatCard } from "./components/StatCard"; + +describe("BaseCard", () => { + it("renders header, content, and footer regions", () => { + render( + } + title="Catalog" + subtitle="Shared surface" + actions={} + footer="Footer note" + > + Body content + , + ); + + expect(screen.getByText("Catalog")).toBeTruthy(); + expect(screen.getByText("Shared surface")).toBeTruthy(); + expect(screen.getByText("Body content")).toBeTruthy(); + expect(screen.getByText("Footer note")).toBeTruthy(); + expect(screen.getByRole("button", { name: "Edit" })).toBeTruthy(); + expect(screen.getByTestId("header-icon")).toBeTruthy(); + }); +}); + +describe("StatCard", () => { + it("renders label, formatted value, subtext, info, and footer", () => { + render( + } + tone="cyan" + footer={Browse docs} + />, + ); + + expect(screen.getByText("Packages")).toBeTruthy(); + expect(screen.getByText("6")).toBeTruthy(); + expect(screen.getByText("Published demos")).toBeTruthy(); + expect(screen.getByRole("button", { name: "About Packages" })).toBeTruthy(); + expect(screen.getByRole("tooltip").textContent).toContain( + "Count of showcase packages in this monorepo.", + ); + expect(screen.getByTestId("stat-icon")).toBeTruthy(); + expect(screen.getByRole("link", { name: "Browse docs" })).toBeTruthy(); + }); +}); diff --git a/components/card/src/components/BaseCard.tsx b/components/card/src/components/BaseCard.tsx new file mode 100644 index 0000000..daeeb69 --- /dev/null +++ b/components/card/src/components/BaseCard.tsx @@ -0,0 +1,55 @@ +import { cn } from "../lib/cn"; +import type { BaseCardProps } from "../types"; + +export function BaseCard({ + as: Component = "article", + icon, + title, + subtitle, + actions, + children, + footer, + shadow = true, + className, + ...props +}: BaseCardProps) { + const hasHeader = + icon !== undefined || + title !== undefined || + subtitle !== undefined || + actions !== undefined; + + return ( + + {hasHeader ? ( +
+
+ {(icon !== undefined || title !== undefined) && ( +
+ {icon !== undefined ? ( + + {icon} + + ) : null} + {title !== undefined ?
{title}
: null} +
+ )} + {subtitle !== undefined ?
{subtitle}
: null} +
+ {actions !== undefined ?
{actions}
: null} +
+ ) : null} + + {children !== undefined && children !== null ? ( +
{children}
+ ) : null} + + {footer !== undefined && footer !== null ? ( +
{footer}
+ ) : null} +
+ ); +} diff --git a/components/card/src/components/StatCard.tsx b/components/card/src/components/StatCard.tsx new file mode 100644 index 0000000..6874b7a --- /dev/null +++ b/components/card/src/components/StatCard.tsx @@ -0,0 +1,63 @@ +import { CircleHelp } from "lucide-react"; +import type { ReactNode } from "react"; + +import { cn } from "../lib/cn"; +import type { StatCardProps } from "../types"; +import { BaseCard } from "./BaseCard"; + +function formatStatValue(value: ReactNode): ReactNode { + if (typeof value === "number") { + return value.toLocaleString(); + } + return value; +} + +export function StatCard({ + label, + value, + subtext, + icon, + info, + actions, + footer, + tone = "slate", + className, +}: StatCardProps) { + const headerActions = + info || actions ? ( + <> + {info ? ( + + + + {info} + + + ) : null} + {actions} + + ) : undefined; + + return ( + {label}} + actions={headerActions} + footer={footer} + > +

+ {formatStatValue(value)} +

+ {subtext !== undefined && subtext !== null ? ( +

{subtext}

+ ) : null} +
+ ); +} diff --git a/components/card/src/index.ts b/components/card/src/index.ts new file mode 100644 index 0000000..ba00236 --- /dev/null +++ b/components/card/src/index.ts @@ -0,0 +1,4 @@ +export { BaseCard } from "./components/BaseCard"; +export { StatCard } from "./components/StatCard"; + +export type { BaseCardProps, CardTone, StatCardProps } from "./types"; diff --git a/components/card/src/lib/cn.ts b/components/card/src/lib/cn.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/components/card/src/lib/cn.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/components/card/src/styles.css b/components/card/src/styles.css new file mode 100644 index 0000000..bdfd37d --- /dev/null +++ b/components/card/src/styles.css @@ -0,0 +1,210 @@ +:root { + --joo-card-bg: 0 0% 100%; + --joo-card-fg: 222.2 84% 4.9%; + --joo-card-muted: 215.4 16.3% 46.9%; + --joo-card-border: 214.3 31.8% 91.4%; + --joo-card-divider: 210 40% 96.1%; + --joo-card-radius: 0.5rem; + --joo-card-tone-slate: 222.2 47.4% 11.2%; + --joo-card-tone-cyan: 192 70% 30%; + --joo-card-tone-amber: 32 80% 36%; + --joo-card-tone-emerald: 160 70% 28%; + --joo-card-tone-rose: 350 70% 40%; +} + +.joo-card { + min-width: 0; + display: flex; + flex-direction: column; + border: 1px solid hsl(var(--joo-card-border)); + border-radius: var(--joo-card-radius); + background: hsl(var(--joo-card-bg)); + color: hsl(var(--joo-card-fg)); +} + +.joo-card--shadow { + box-shadow: 0 1px 2px 0 rgb(15 23 42 / 0.05); +} + +.joo-card-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 0.75rem; + padding: 0.75rem 1rem 0; +} + +.joo-card-header-main { + min-width: 0; + flex: 1; +} + +.joo-card-header-title-row { + display: flex; + align-items: center; + gap: 0.5rem; + min-width: 0; +} + +.joo-card-header-icon { + display: inline-flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + color: hsl(var(--joo-card-muted)); +} + +.joo-card-header-icon svg { + width: 1rem; + height: 1rem; +} + +.joo-card-title { + min-width: 0; + font-size: 0.875rem; + font-weight: 600; + line-height: 1.25; + color: hsl(var(--joo-card-fg)); +} + +.joo-card-subtitle { + margin-top: 0.25rem; + font-size: 0.75rem; + line-height: 1.35; + color: hsl(var(--joo-card-muted)); +} + +.joo-card-actions { + display: flex; + flex-shrink: 0; + flex-wrap: wrap; + align-items: center; + gap: 0.25rem; +} + +.joo-card-content { + min-width: 0; + padding: 0.75rem 1rem 1rem; +} + +.joo-card-header + .joo-card-content { + padding-top: 0.5rem; +} + +.joo-card-footer { + margin-top: auto; + border-top: 1px solid hsl(var(--joo-card-divider)); + padding: 0.5rem 1rem 0.75rem; + font-size: 0.75rem; + line-height: 1.35; + color: hsl(var(--joo-card-muted)); +} + +/* StatCard */ + +.joo-stat-card-label { + font-size: 0.75rem; + font-weight: 500; + letter-spacing: 0.04em; + text-transform: uppercase; + color: hsl(var(--joo-card-muted)); +} + +.joo-stat-card-value { + margin: 0; + font-size: 1.5rem; + font-weight: 600; + line-height: 1.2; + font-variant-numeric: tabular-nums; +} + +.joo-stat-card-value--slate { + color: hsl(var(--joo-card-tone-slate)); +} + +.joo-stat-card-value--cyan { + color: hsl(var(--joo-card-tone-cyan)); +} + +.joo-stat-card-value--amber { + color: hsl(var(--joo-card-tone-amber)); +} + +.joo-stat-card-value--emerald { + color: hsl(var(--joo-card-tone-emerald)); +} + +.joo-stat-card-value--rose { + color: hsl(var(--joo-card-tone-rose)); +} + +.joo-stat-card-subtext { + margin: 0.25rem 0 0; + font-size: 0.75rem; + line-height: 1.35; + color: hsl(var(--joo-card-muted)); +} + +/* Info control (StatCard header action) */ + +.joo-card-info { + position: relative; + display: inline-flex; +} + +.joo-card-info-trigger { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.5rem; + height: 1.5rem; + margin: 0; + padding: 0; + border: 0; + border-radius: 0.375rem; + background: transparent; + color: hsl(var(--joo-card-muted)); + cursor: help; +} + +.joo-card-info-trigger:hover, +.joo-card-info-trigger:focus-visible { + background: hsl(var(--joo-card-divider)); + color: hsl(var(--joo-card-fg)); + outline: none; +} + +.joo-card-info-icon { + width: 0.875rem; + height: 0.875rem; +} + +.joo-card-info-tooltip { + position: absolute; + right: 0; + top: calc(100% + 0.35rem); + z-index: 20; + width: max-content; + max-width: 14rem; + padding: 0.4rem 0.55rem; + border: 1px solid hsl(var(--joo-card-border)); + border-radius: 0.375rem; + background: hsl(var(--joo-card-bg)); + box-shadow: 0 4px 12px rgb(15 23 42 / 0.12); + color: hsl(var(--joo-card-fg)); + font-size: 0.75rem; + font-weight: 400; + letter-spacing: normal; + text-transform: none; + line-height: 1.35; + opacity: 0; + visibility: hidden; + pointer-events: none; + transition: opacity 120ms ease; +} + +.joo-card-info:hover .joo-card-info-tooltip, +.joo-card-info:focus-within .joo-card-info-tooltip { + opacity: 1; + visibility: visible; +} diff --git a/components/card/src/types.ts b/components/card/src/types.ts new file mode 100644 index 0000000..841c7c6 --- /dev/null +++ b/components/card/src/types.ts @@ -0,0 +1,45 @@ +import type { HTMLAttributes, ReactNode } from "react"; + +export type CardTone = "slate" | "cyan" | "amber" | "emerald" | "rose"; + +export type BaseCardProps = Omit, "title"> & { + /** Element tag for the card root. */ + as?: "article" | "section" | "div"; + /** Optional leading icon in the header. */ + icon?: ReactNode; + /** Header title (left). */ + title?: ReactNode; + /** Optional supporting line under the title. */ + subtitle?: ReactNode; + /** Optional header actions (right). Prefer ghost/icon controls. */ + actions?: ReactNode; + /** Main body. */ + children?: ReactNode; + /** Optional footer below a divider. */ + footer?: ReactNode; + /** Soft shadow (default true). */ + shadow?: boolean; + className?: string; +}; + +export type StatCardProps = { + /** Metric label (header). */ + label: string; + /** Large primary value (number or short text). */ + value: ReactNode; + /** Supporting line under the value. */ + subtext?: ReactNode; + /** Optional leading header icon. */ + icon?: ReactNode; + /** + * Metric definition shown via the info control in the header actions slot. + * Renders a CircleHelp / Info button with accessible tooltip. + */ + info?: string; + /** Extra header actions (merged after the built-in info control when `info` is set). */ + actions?: ReactNode; + footer?: ReactNode; + /** Colors the large value. */ + tone?: CardTone; + className?: string; +}; diff --git a/components/card/tsconfig.json b/components/card/tsconfig.json new file mode 100644 index 0000000..974dd00 --- /dev/null +++ b/components/card/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "isolatedModules": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["src"] +} diff --git a/components/card/tsup.config.ts b/components/card/tsup.config.ts new file mode 100644 index 0000000..3f0c75c --- /dev/null +++ b/components/card/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + dts: true, + sourcemap: true, + clean: true, + external: ["react", "react-dom", "lucide-react"], + treeshake: true, +}); diff --git a/components/card/vitest.config.ts b/components/card/vitest.config.ts new file mode 100644 index 0000000..e5d7e16 --- /dev/null +++ b/components/card/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "jsdom", + setupFiles: [], + }, +}); From 06a416f159ab798bc3169859cbd0646b4e5f89b0 Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:24 -0600 Subject: [PATCH 03/14] feat(modal): add compound Modal package --- components/modal/.gitignore | 1 + components/modal/AGENTS.md | 36 + components/modal/CHANGELOG.md | 8 + components/modal/LICENSE | 21 + components/modal/README.md | 54 + components/modal/dist/index.d.ts | 48 + components/modal/dist/index.js | 140 + components/modal/dist/index.js.map | 1 + components/modal/dist/styles.css | 143 + components/modal/package-lock.json | 3656 +++++++++++++++++ components/modal/package.json | 68 + components/modal/src/Modal.test.tsx | 76 + components/modal/src/components/Modal.tsx | 113 + components/modal/src/components/ModalBody.tsx | 6 + .../modal/src/components/ModalFooter.tsx | 6 + .../modal/src/components/ModalHeader.tsx | 48 + .../modal/src/components/modal-context.ts | 17 + components/modal/src/index.ts | 12 + components/modal/src/lib/cn.ts | 6 + components/modal/src/styles.css | 143 + components/modal/src/types.ts | 35 + components/modal/tsconfig.json | 16 + components/modal/tsup.config.ts | 11 + components/modal/vitest.config.ts | 8 + 24 files changed, 4673 insertions(+) create mode 100644 components/modal/.gitignore create mode 100644 components/modal/AGENTS.md create mode 100644 components/modal/CHANGELOG.md create mode 100644 components/modal/LICENSE create mode 100644 components/modal/README.md create mode 100644 components/modal/dist/index.d.ts create mode 100644 components/modal/dist/index.js create mode 100644 components/modal/dist/index.js.map create mode 100644 components/modal/dist/styles.css create mode 100644 components/modal/package-lock.json create mode 100644 components/modal/package.json create mode 100644 components/modal/src/Modal.test.tsx create mode 100644 components/modal/src/components/Modal.tsx create mode 100644 components/modal/src/components/ModalBody.tsx create mode 100644 components/modal/src/components/ModalFooter.tsx create mode 100644 components/modal/src/components/ModalHeader.tsx create mode 100644 components/modal/src/components/modal-context.ts create mode 100644 components/modal/src/index.ts create mode 100644 components/modal/src/lib/cn.ts create mode 100644 components/modal/src/styles.css create mode 100644 components/modal/src/types.ts create mode 100644 components/modal/tsconfig.json create mode 100644 components/modal/tsup.config.ts create mode 100644 components/modal/vitest.config.ts diff --git a/components/modal/.gitignore b/components/modal/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/components/modal/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/components/modal/AGENTS.md b/components/modal/AGENTS.md new file mode 100644 index 0000000..37ea981 --- /dev/null +++ b/components/modal/AGENTS.md @@ -0,0 +1,36 @@ +# modal package agents + +@jooservices/react-modal — compound Modal dialog (Header / Body / Footer). + +## Paths + +- Source: `components/modal/src` +- Entry: `components/modal/src/index.ts` +- Build output: `components/modal/dist` (committed) + +## Commands + +```bash +cd components/modal +npm install # first time +npm run typecheck +npm test +npm run build +``` + +After user-visible changes: update `apps/demo` (`/modal`) and run `npm run demo:typecheck`. + +## Peers + +`react`, `react-dom`, `lucide-react` + +## Notes + +- Does **not** extend BaseCard — overlay/portal/a11y are modal concerns. +- Close control is built into `Modal.Header` (native button + lucide `X`). Footer CTAs compose with `@jooservices/react-action-buttons` in the consumer. + +## Docs + +- User guide: `docs/02-user-guide/10-react-modal.md` (consumer API — do not send humans to `src/`) +- Package README: `components/modal/README.md` +- Root policy: `AGENTS.md` diff --git a/components/modal/CHANGELOG.md b/components/modal/CHANGELOG.md new file mode 100644 index 0000000..71c97a8 --- /dev/null +++ b/components/modal/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog — @jooservices/react-modal + +## [Unreleased] + +### Added + +- `Modal` — portal overlay dialog with sizes `sm` | `md` | `lg` | `xl`, Escape / backdrop close, body scroll lock +- `Modal.Header` / `Modal.Body` / `Modal.Footer` compound regions (built-in close in Header) diff --git a/components/modal/LICENSE b/components/modal/LICENSE new file mode 100644 index 0000000..e630730 --- /dev/null +++ b/components/modal/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 JOOservices + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/modal/README.md b/components/modal/README.md new file mode 100644 index 0000000..d92244f --- /dev/null +++ b/components/modal/README.md @@ -0,0 +1,54 @@ +# @jooservices/react-modal + +Shared **Modal** dialog: portal overlay with compound **Header** / **Body** / **Footer**. + +Does not extend `@jooservices/react-card` — regions mirror card layout for familiarity; overlay, focus, and a11y stay modal-owned. + +## Install + +```bash +pnpm add "github:jooservices/react#v1.0.0&path:components/modal" +``` + +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). + +## Usage + +```ts +import "@jooservices/react-modal/styles.css"; +import { Modal } from "@jooservices/react-modal"; + + setOpen(false)} size="md" titleId="confirm-title"> + + Are you sure? + + + + + +``` + +### Props + +| Prop | Role | +|------|------| +| `open` | Whether the dialog is shown | +| `onClose?` | Backdrop click, Escape, and Header close | +| `closeDisabled?` | Blocks close while true (e.g. submitting) | +| `size?` | `sm` \| `md` \| `lg` \| `xl` (default `md`) | +| `titleId?` | `aria-labelledby` for the dialog | +| `className?` | Overlay class | +| `panelClassName?` | Panel class | +| `zIndexClassName?` | Extra overlay stacking class | + +### Regions + +| Region | Notes | +|--------|--------| +| `Modal.Header` | `title` / `center` / `actions` / `showClose` (default true) | +| `Modal.Body` | Scrollable content | +| `Modal.Footer` | Action row (compose with action-buttons in apps) | + +## Peers + +`react`, `react-dom`, `lucide-react` diff --git a/components/modal/dist/index.d.ts b/components/modal/dist/index.d.ts new file mode 100644 index 0000000..73185a0 --- /dev/null +++ b/components/modal/dist/index.d.ts @@ -0,0 +1,48 @@ +import * as react from 'react'; +import { ReactNode } from 'react'; + +type ModalSize = "sm" | "md" | "lg" | "xl"; +type ModalProps = { + open: boolean; + children: ReactNode; + onClose?: () => void; + closeDisabled?: boolean; + size?: ModalSize; + className?: string; + panelClassName?: string; + titleId?: string; + /** Extra class on the overlay for stacking (e.g. Tailwind `z-[120]`). */ + zIndexClassName?: string; +}; +type ModalHeaderProps = { + title?: ReactNode; + center?: ReactNode; + actions?: ReactNode; + children?: ReactNode; + className?: string; + showClose?: boolean; +}; +type ModalBodyProps = { + children: ReactNode; + className?: string; +}; +type ModalFooterProps = { + children: ReactNode; + className?: string; +}; + +declare function ModalBody({ children, className }: ModalBodyProps): react.JSX.Element; + +declare function ModalFooter({ children, className }: ModalFooterProps): react.JSX.Element; + +declare function ModalHeader({ title, center, actions, children, className, showClose, }: ModalHeaderProps): react.JSX.Element; + +declare function ModalRoot({ open, children, onClose, closeDisabled, size, className, panelClassName, titleId, zIndexClassName, }: ModalProps): react.ReactPortal | null; +type ModalCompound = typeof ModalRoot & { + Header: typeof ModalHeader; + Body: typeof ModalBody; + Footer: typeof ModalFooter; +}; +declare const Modal: ModalCompound; + +export { Modal, ModalBody, type ModalBodyProps, ModalFooter, type ModalFooterProps, ModalHeader, type ModalHeaderProps, type ModalProps, type ModalSize }; diff --git a/components/modal/dist/index.js b/components/modal/dist/index.js new file mode 100644 index 0000000..49f28e8 --- /dev/null +++ b/components/modal/dist/index.js @@ -0,0 +1,140 @@ +import { createContext, useRef, useEffect, useContext } from 'react'; +import { createPortal } from 'react-dom'; +import { clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; +import { jsx, jsxs } from 'react/jsx-runtime'; +import { X } from 'lucide-react'; + +// src/components/Modal.tsx +function cn(...inputs) { + return twMerge(clsx(inputs)); +} +var ModalContext = createContext(null); +function useModalContext() { + const context = useContext(ModalContext); + if (!context) { + throw new Error("Modal subcomponents must be used within "); + } + return context; +} +function ModalBody({ children, className }) { + return /* @__PURE__ */ jsx("div", { className: cn("joo-modal-body", className), children }); +} +function ModalFooter({ children, className }) { + return /* @__PURE__ */ jsx("div", { className: cn("joo-modal-footer", className), children }); +} +function ModalHeader({ + title, + center, + actions, + children, + className, + showClose = true +}) { + const { onClose, closeDisabled, titleId } = useModalContext(); + return /* @__PURE__ */ jsxs("div", { className: cn("joo-modal-header", className), children: [ + /* @__PURE__ */ jsx("div", { className: "joo-modal-header-main", children: title !== void 0 ? /* @__PURE__ */ jsx("h3", { id: titleId, className: "joo-modal-title", children: title }) : children }), + center !== void 0 ? /* @__PURE__ */ jsx("div", { className: "joo-modal-header-center", children: center }) : null, + /* @__PURE__ */ jsxs("div", { className: "joo-modal-header-actions", children: [ + actions, + showClose && onClose ? /* @__PURE__ */ jsx( + "button", + { + type: "button", + className: "joo-modal-close", + onClick: onClose, + "aria-label": "Close", + disabled: closeDisabled, + children: /* @__PURE__ */ jsx(X, { "aria-hidden": true }) + } + ) : null + ] }) + ] }); +} +var sizeClass = { + sm: "joo-modal-panel--sm", + md: "joo-modal-panel--md", + lg: "joo-modal-panel--lg", + xl: "joo-modal-panel--xl" +}; +function ModalRoot({ + open, + children, + onClose, + closeDisabled = false, + size = "md", + className, + panelClassName, + titleId, + zIndexClassName +}) { + const panelRef = useRef(null); + useEffect(() => { + if (!open) { + return; + } + const previousOverflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; + return () => { + document.body.style.overflow = previousOverflow; + }; + }, [open]); + useEffect(() => { + if (!open) { + return; + } + const onKeyDown = (event) => { + if (event.key === "Escape" && !closeDisabled) { + onClose?.(); + } + }; + document.addEventListener("keydown", onKeyDown); + panelRef.current?.focus(); + return () => document.removeEventListener("keydown", onKeyDown); + }, [open, closeDisabled, onClose]); + if (!open || typeof document === "undefined") { + return null; + } + const onOverlayMouseDown = (event) => { + if (event.target === event.currentTarget && !closeDisabled) { + onClose?.(); + } + }; + return createPortal( + /* @__PURE__ */ jsx(ModalContext.Provider, { value: { onClose, closeDisabled, titleId }, children: /* @__PURE__ */ jsx( + "div", + { + className: cn("joo-modal-overlay", zIndexClassName, className), + role: "presentation", + onMouseDown: onOverlayMouseDown, + children: /* @__PURE__ */ jsx( + "div", + { + ref: panelRef, + role: "dialog", + "aria-modal": "true", + "aria-labelledby": titleId, + tabIndex: -1, + className: cn( + "joo-modal-panel", + sizeClass[size], + size === "xl" && "joo-modal-panel--tall", + panelClassName + ), + children + } + ) + } + ) }), + document.body + ); +} +var Modal = Object.assign(ModalRoot, { + Header: ModalHeader, + Body: ModalBody, + Footer: ModalFooter +}); + +export { Modal, ModalBody, ModalFooter, ModalHeader }; +//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/components/modal/dist/index.js.map b/components/modal/dist/index.js.map new file mode 100644 index 0000000..ec64321 --- /dev/null +++ b/components/modal/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/lib/cn.ts","../src/components/modal-context.ts","../src/components/ModalBody.tsx","../src/components/ModalFooter.tsx","../src/components/ModalHeader.tsx","../src/components/Modal.tsx"],"names":["jsx"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { createContext, useContext } from \"react\";\n\nexport type ModalContextValue = {\n onClose?: () => void;\n closeDisabled: boolean;\n titleId?: string;\n};\n\nexport const ModalContext = createContext(null);\n\nexport function useModalContext(): ModalContextValue {\n const context = useContext(ModalContext);\n if (!context) {\n throw new Error(\"Modal subcomponents must be used within \");\n }\n return context;\n}\n","import type { ModalBodyProps } from \"../types\";\nimport { cn } from \"../lib/cn\";\n\nexport function ModalBody({ children, className }: ModalBodyProps) {\n return
{children}
;\n}\n","import type { ModalFooterProps } from \"../types\";\nimport { cn } from \"../lib/cn\";\n\nexport function ModalFooter({ children, className }: ModalFooterProps) {\n return
{children}
;\n}\n","import { X } from \"lucide-react\";\nimport type { ModalHeaderProps } from \"../types\";\nimport { cn } from \"../lib/cn\";\nimport { useModalContext } from \"./modal-context\";\n\nexport function ModalHeader({\n title,\n center,\n actions,\n children,\n className,\n showClose = true,\n}: ModalHeaderProps) {\n const { onClose, closeDisabled, titleId } = useModalContext();\n\n return (\n
\n
\n {title !== undefined ? (\n

\n {title}\n

\n ) : (\n children\n )}\n
\n\n {center !== undefined ? (\n
{center}
\n ) : null}\n\n
\n {actions}\n {showClose && onClose ? (\n \n \n \n ) : null}\n
\n
\n );\n}\n","import {\n useEffect,\n useRef,\n type MouseEvent as ReactMouseEvent,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { cn } from \"../lib/cn\";\nimport type { ModalProps, ModalSize } from \"../types\";\nimport { ModalContext } from \"./modal-context\";\nimport { ModalBody } from \"./ModalBody\";\nimport { ModalFooter } from \"./ModalFooter\";\nimport { ModalHeader } from \"./ModalHeader\";\n\nconst sizeClass: Record = {\n sm: \"joo-modal-panel--sm\",\n md: \"joo-modal-panel--md\",\n lg: \"joo-modal-panel--lg\",\n xl: \"joo-modal-panel--xl\",\n};\n\nfunction ModalRoot({\n open,\n children,\n onClose,\n closeDisabled = false,\n size = \"md\",\n className,\n panelClassName,\n titleId,\n zIndexClassName,\n}: ModalProps) {\n const panelRef = useRef(null);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const previousOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n return () => {\n document.body.style.overflow = previousOverflow;\n };\n }, [open]);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && !closeDisabled) {\n onClose?.();\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n panelRef.current?.focus();\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [open, closeDisabled, onClose]);\n\n if (!open || typeof document === \"undefined\") {\n return null;\n }\n\n const onOverlayMouseDown = (event: ReactMouseEvent) => {\n if (event.target === event.currentTarget && !closeDisabled) {\n onClose?.();\n }\n };\n\n return createPortal(\n \n \n \n {children}\n \n \n ,\n document.body,\n );\n}\n\ntype ModalCompound = typeof ModalRoot & {\n Header: typeof ModalHeader;\n Body: typeof ModalBody;\n Footer: typeof ModalFooter;\n};\n\nexport const Modal = Object.assign(ModalRoot, {\n Header: ModalHeader,\n Body: ModalBody,\n Footer: ModalFooter,\n}) as ModalCompound;\n"]} \ No newline at end of file diff --git a/components/modal/dist/styles.css b/components/modal/dist/styles.css new file mode 100644 index 0000000..73a2660 --- /dev/null +++ b/components/modal/dist/styles.css @@ -0,0 +1,143 @@ +:root { + --joo-modal-bg: 0 0% 100%; + --joo-modal-fg: 222.2 84% 4.9%; + --joo-modal-muted: 215.4 16.3% 46.9%; + --joo-modal-border: 214.3 31.8% 91.4%; + --joo-modal-overlay: 222.2 47.4% 11.2%; + --joo-modal-radius: 0.5rem; + --joo-modal-z: 100; + --joo-modal-max-h: min(90vh, 40rem); + --joo-modal-max-h-tall: min(92vh, 52rem); +} + +.joo-modal-overlay { + position: fixed; + inset: 0; + z-index: var(--joo-modal-z); + display: flex; + align-items: center; + justify-content: center; + padding: 1rem; + background: hsl(var(--joo-modal-overlay) / 0.4); +} + +.joo-modal-panel { + display: flex; + width: 100%; + max-height: var(--joo-modal-max-h); + flex-direction: column; + overflow: hidden; + border: 1px solid hsl(var(--joo-modal-border)); + border-radius: var(--joo-modal-radius); + background: hsl(var(--joo-modal-bg)); + color: hsl(var(--joo-modal-fg)); + box-shadow: + 0 20px 25px -5px rgb(15 23 42 / 0.1), + 0 8px 10px -6px rgb(15 23 42 / 0.1); + outline: none; +} + +.joo-modal-panel--sm { + max-width: 28rem; +} + +.joo-modal-panel--md { + max-width: 32rem; +} + +.joo-modal-panel--lg { + max-width: 42rem; +} + +.joo-modal-panel--xl { + max-width: 56rem; +} + +.joo-modal-panel--tall { + max-height: var(--joo-modal-max-h-tall); +} + +.joo-modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + gap: 0.75rem; + border-bottom: 1px solid hsl(var(--joo-modal-border)); + padding: 0.75rem 1rem; +} + +.joo-modal-header-main { + min-width: 0; + flex: 1; +} + +.joo-modal-title { + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 1.125rem; + font-weight: 600; + line-height: 1.4; + color: hsl(var(--joo-modal-fg)); +} + +.joo-modal-header-center { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; +} + +.joo-modal-header-actions { + display: flex; + flex-shrink: 0; + align-items: center; + gap: 0.25rem; +} + +.joo-modal-close { + display: inline-flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + padding: 0; + border: none; + border-radius: calc(var(--joo-modal-radius) - 0.125rem); + background: transparent; + color: hsl(var(--joo-modal-muted)); + cursor: pointer; +} + +.joo-modal-close:hover:not(:disabled) { + background: hsl(var(--joo-modal-border)); + color: hsl(var(--joo-modal-fg)); +} + +.joo-modal-close:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.joo-modal-close svg { + width: 1.25rem; + height: 1.25rem; +} + +.joo-modal-body { + min-height: 0; + flex: 1; + overflow-y: auto; + padding: 1rem; +} + +.joo-modal-footer { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; + gap: 0.5rem; + border-top: 1px solid hsl(var(--joo-modal-border)); + padding: 0.75rem 1rem; +} diff --git a/components/modal/package-lock.json b/components/modal/package-lock.json new file mode 100644 index 0000000..3abfe1b --- /dev/null +++ b/components/modal/package-lock.json @@ -0,0 +1,3656 @@ +{ + "name": "@jooservices/react-modal", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@jooservices/react-modal", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@adobe/css-tools": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", + "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.0.0", + "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz", + "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.9.tgz", + "integrity": "sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.1.0", + "@csstools/css-calc": "^3.2.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz", + "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz", + "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^15.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/lucide-react": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.24.0.tgz", + "integrity": "sha512-YT6mBD8lGKkg4nM39enlm94/sfJIiW0YKUT60fBy4YK8tai31ylg1VhGNWxkpSKHo9UagfnZqwIff3HTDQwXeA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", + "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.8.tgz", + "integrity": "sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.8" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.8.tgz", + "integrity": "sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/tsup": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", + "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", + "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.16", + "rolldown": "~1.1.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/vitest/node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/components/modal/package.json b/components/modal/package.json new file mode 100644 index 0000000..b7fb013 --- /dev/null +++ b/components/modal/package.json @@ -0,0 +1,68 @@ +{ + "name": "@jooservices/react-modal", + "version": "0.1.0", + "description": "Shared modal dialog primitives for React \u2014 compound Modal with Header, Body, and Footer", + "type": "module", + "license": "MIT", + "author": "JOOservices", + "repository": { + "type": "git", + "url": "https://github.com/jooservices/react.git", + "directory": "components/modal" + }, + "keywords": [ + "react", + "modal", + "dialog", + "overlay" + ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./styles.css": "./dist/styles.css" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "sideEffects": [ + "**/*.css" + ], + "scripts": { + "build": "tsup && cp src/styles.css dist/styles.css", + "typecheck": "tsc --noEmit", + "test": "vitest run", + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" + }, + "dependencies": { + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/components/modal/src/Modal.test.tsx b/components/modal/src/Modal.test.tsx new file mode 100644 index 0000000..cd78f2f --- /dev/null +++ b/components/modal/src/Modal.test.tsx @@ -0,0 +1,76 @@ +import { cleanup, fireEvent, render, screen } from "@testing-library/react"; +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { Modal } from "./components/Modal"; + +afterEach(() => { + cleanup(); +}); + +describe("Modal", () => { + it("renders header, body, and footer when open", () => { + render( + undefined} titleId="demo-title"> + + Modal body copy + + + + + , + ); + + expect(screen.getByRole("dialog")).toBeTruthy(); + expect(screen.getByText("Confirm action")).toBeTruthy(); + expect(screen.getByText("Modal body copy")).toBeTruthy(); + expect(screen.getByRole("button", { name: "Cancel" })).toBeTruthy(); + expect(screen.getByRole("button", { name: "Save" })).toBeTruthy(); + expect(screen.getByRole("button", { name: "Close" })).toBeTruthy(); + }); + + it("does not render when closed", () => { + render( + undefined} titleId="hidden-title"> + + Hidden body + , + ); + + expect(screen.queryByRole("dialog")).toBeNull(); + expect(screen.queryByText("Hidden")).toBeNull(); + }); + + it("calls onClose from Escape and the header close button", () => { + const onClose = vi.fn(); + + render( + + + Press escape + , + ); + + fireEvent.keyDown(document, { key: "Escape" }); + expect(onClose).toHaveBeenCalledTimes(1); + + fireEvent.click(screen.getByRole("button", { name: "Close" })); + expect(onClose).toHaveBeenCalledTimes(2); + }); + + it("ignores close when closeDisabled", () => { + const onClose = vi.fn(); + + render( + + + Submitting… + , + ); + + fireEvent.keyDown(document, { key: "Escape" }); + expect(onClose).not.toHaveBeenCalled(); + expect( + (screen.getByRole("button", { name: "Close" }) as HTMLButtonElement).disabled, + ).toBe(true); + }); +}); diff --git a/components/modal/src/components/Modal.tsx b/components/modal/src/components/Modal.tsx new file mode 100644 index 0000000..3e43d1d --- /dev/null +++ b/components/modal/src/components/Modal.tsx @@ -0,0 +1,113 @@ +import { + useEffect, + useRef, + type MouseEvent as ReactMouseEvent, +} from "react"; +import { createPortal } from "react-dom"; + +import { cn } from "../lib/cn"; +import type { ModalProps, ModalSize } from "../types"; +import { ModalContext } from "./modal-context"; +import { ModalBody } from "./ModalBody"; +import { ModalFooter } from "./ModalFooter"; +import { ModalHeader } from "./ModalHeader"; + +const sizeClass: Record = { + sm: "joo-modal-panel--sm", + md: "joo-modal-panel--md", + lg: "joo-modal-panel--lg", + xl: "joo-modal-panel--xl", +}; + +function ModalRoot({ + open, + children, + onClose, + closeDisabled = false, + size = "md", + className, + panelClassName, + titleId, + zIndexClassName, +}: ModalProps) { + const panelRef = useRef(null); + + useEffect(() => { + if (!open) { + return; + } + + const previousOverflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; + + return () => { + document.body.style.overflow = previousOverflow; + }; + }, [open]); + + useEffect(() => { + if (!open) { + return; + } + + const onKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape" && !closeDisabled) { + onClose?.(); + } + }; + + document.addEventListener("keydown", onKeyDown); + panelRef.current?.focus(); + + return () => document.removeEventListener("keydown", onKeyDown); + }, [open, closeDisabled, onClose]); + + if (!open || typeof document === "undefined") { + return null; + } + + const onOverlayMouseDown = (event: ReactMouseEvent) => { + if (event.target === event.currentTarget && !closeDisabled) { + onClose?.(); + } + }; + + return createPortal( + +
+
+ {children} +
+
+
, + document.body, + ); +} + +type ModalCompound = typeof ModalRoot & { + Header: typeof ModalHeader; + Body: typeof ModalBody; + Footer: typeof ModalFooter; +}; + +export const Modal = Object.assign(ModalRoot, { + Header: ModalHeader, + Body: ModalBody, + Footer: ModalFooter, +}) as ModalCompound; diff --git a/components/modal/src/components/ModalBody.tsx b/components/modal/src/components/ModalBody.tsx new file mode 100644 index 0000000..76fed75 --- /dev/null +++ b/components/modal/src/components/ModalBody.tsx @@ -0,0 +1,6 @@ +import type { ModalBodyProps } from "../types"; +import { cn } from "../lib/cn"; + +export function ModalBody({ children, className }: ModalBodyProps) { + return
{children}
; +} diff --git a/components/modal/src/components/ModalFooter.tsx b/components/modal/src/components/ModalFooter.tsx new file mode 100644 index 0000000..a3d6a3f --- /dev/null +++ b/components/modal/src/components/ModalFooter.tsx @@ -0,0 +1,6 @@ +import type { ModalFooterProps } from "../types"; +import { cn } from "../lib/cn"; + +export function ModalFooter({ children, className }: ModalFooterProps) { + return
{children}
; +} diff --git a/components/modal/src/components/ModalHeader.tsx b/components/modal/src/components/ModalHeader.tsx new file mode 100644 index 0000000..e75cc2e --- /dev/null +++ b/components/modal/src/components/ModalHeader.tsx @@ -0,0 +1,48 @@ +import { X } from "lucide-react"; +import type { ModalHeaderProps } from "../types"; +import { cn } from "../lib/cn"; +import { useModalContext } from "./modal-context"; + +export function ModalHeader({ + title, + center, + actions, + children, + className, + showClose = true, +}: ModalHeaderProps) { + const { onClose, closeDisabled, titleId } = useModalContext(); + + return ( +
+
+ {title !== undefined ? ( +

+ {title} +

+ ) : ( + children + )} +
+ + {center !== undefined ? ( +
{center}
+ ) : null} + +
+ {actions} + {showClose && onClose ? ( + + ) : null} +
+
+ ); +} diff --git a/components/modal/src/components/modal-context.ts b/components/modal/src/components/modal-context.ts new file mode 100644 index 0000000..c4ce214 --- /dev/null +++ b/components/modal/src/components/modal-context.ts @@ -0,0 +1,17 @@ +import { createContext, useContext } from "react"; + +export type ModalContextValue = { + onClose?: () => void; + closeDisabled: boolean; + titleId?: string; +}; + +export const ModalContext = createContext(null); + +export function useModalContext(): ModalContextValue { + const context = useContext(ModalContext); + if (!context) { + throw new Error("Modal subcomponents must be used within "); + } + return context; +} diff --git a/components/modal/src/index.ts b/components/modal/src/index.ts new file mode 100644 index 0000000..506119b --- /dev/null +++ b/components/modal/src/index.ts @@ -0,0 +1,12 @@ +export { Modal } from "./components/Modal"; +export { ModalHeader } from "./components/ModalHeader"; +export { ModalBody } from "./components/ModalBody"; +export { ModalFooter } from "./components/ModalFooter"; + +export type { + ModalBodyProps, + ModalFooterProps, + ModalHeaderProps, + ModalProps, + ModalSize, +} from "./types"; diff --git a/components/modal/src/lib/cn.ts b/components/modal/src/lib/cn.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/components/modal/src/lib/cn.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/components/modal/src/styles.css b/components/modal/src/styles.css new file mode 100644 index 0000000..73a2660 --- /dev/null +++ b/components/modal/src/styles.css @@ -0,0 +1,143 @@ +:root { + --joo-modal-bg: 0 0% 100%; + --joo-modal-fg: 222.2 84% 4.9%; + --joo-modal-muted: 215.4 16.3% 46.9%; + --joo-modal-border: 214.3 31.8% 91.4%; + --joo-modal-overlay: 222.2 47.4% 11.2%; + --joo-modal-radius: 0.5rem; + --joo-modal-z: 100; + --joo-modal-max-h: min(90vh, 40rem); + --joo-modal-max-h-tall: min(92vh, 52rem); +} + +.joo-modal-overlay { + position: fixed; + inset: 0; + z-index: var(--joo-modal-z); + display: flex; + align-items: center; + justify-content: center; + padding: 1rem; + background: hsl(var(--joo-modal-overlay) / 0.4); +} + +.joo-modal-panel { + display: flex; + width: 100%; + max-height: var(--joo-modal-max-h); + flex-direction: column; + overflow: hidden; + border: 1px solid hsl(var(--joo-modal-border)); + border-radius: var(--joo-modal-radius); + background: hsl(var(--joo-modal-bg)); + color: hsl(var(--joo-modal-fg)); + box-shadow: + 0 20px 25px -5px rgb(15 23 42 / 0.1), + 0 8px 10px -6px rgb(15 23 42 / 0.1); + outline: none; +} + +.joo-modal-panel--sm { + max-width: 28rem; +} + +.joo-modal-panel--md { + max-width: 32rem; +} + +.joo-modal-panel--lg { + max-width: 42rem; +} + +.joo-modal-panel--xl { + max-width: 56rem; +} + +.joo-modal-panel--tall { + max-height: var(--joo-modal-max-h-tall); +} + +.joo-modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + gap: 0.75rem; + border-bottom: 1px solid hsl(var(--joo-modal-border)); + padding: 0.75rem 1rem; +} + +.joo-modal-header-main { + min-width: 0; + flex: 1; +} + +.joo-modal-title { + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 1.125rem; + font-weight: 600; + line-height: 1.4; + color: hsl(var(--joo-modal-fg)); +} + +.joo-modal-header-center { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; +} + +.joo-modal-header-actions { + display: flex; + flex-shrink: 0; + align-items: center; + gap: 0.25rem; +} + +.joo-modal-close { + display: inline-flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + padding: 0; + border: none; + border-radius: calc(var(--joo-modal-radius) - 0.125rem); + background: transparent; + color: hsl(var(--joo-modal-muted)); + cursor: pointer; +} + +.joo-modal-close:hover:not(:disabled) { + background: hsl(var(--joo-modal-border)); + color: hsl(var(--joo-modal-fg)); +} + +.joo-modal-close:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.joo-modal-close svg { + width: 1.25rem; + height: 1.25rem; +} + +.joo-modal-body { + min-height: 0; + flex: 1; + overflow-y: auto; + padding: 1rem; +} + +.joo-modal-footer { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: flex-end; + gap: 0.5rem; + border-top: 1px solid hsl(var(--joo-modal-border)); + padding: 0.75rem 1rem; +} diff --git a/components/modal/src/types.ts b/components/modal/src/types.ts new file mode 100644 index 0000000..58b8dc4 --- /dev/null +++ b/components/modal/src/types.ts @@ -0,0 +1,35 @@ +import type { ReactNode } from "react"; + +export type ModalSize = "sm" | "md" | "lg" | "xl"; + +export type ModalProps = { + open: boolean; + children: ReactNode; + onClose?: () => void; + closeDisabled?: boolean; + size?: ModalSize; + className?: string; + panelClassName?: string; + titleId?: string; + /** Extra class on the overlay for stacking (e.g. Tailwind `z-[120]`). */ + zIndexClassName?: string; +}; + +export type ModalHeaderProps = { + title?: ReactNode; + center?: ReactNode; + actions?: ReactNode; + children?: ReactNode; + className?: string; + showClose?: boolean; +}; + +export type ModalBodyProps = { + children: ReactNode; + className?: string; +}; + +export type ModalFooterProps = { + children: ReactNode; + className?: string; +}; diff --git a/components/modal/tsconfig.json b/components/modal/tsconfig.json new file mode 100644 index 0000000..974dd00 --- /dev/null +++ b/components/modal/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "isolatedModules": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["src"] +} diff --git a/components/modal/tsup.config.ts b/components/modal/tsup.config.ts new file mode 100644 index 0000000..3f0c75c --- /dev/null +++ b/components/modal/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + dts: true, + sourcemap: true, + clean: true, + external: ["react", "react-dom", "lucide-react"], + treeshake: true, +}); diff --git a/components/modal/vitest.config.ts b/components/modal/vitest.config.ts new file mode 100644 index 0000000..e5d7e16 --- /dev/null +++ b/components/modal/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "jsdom", + setupFiles: [], + }, +}); From 509b17315a0d33f40a6a9ec3615e06b9eb6de3ef Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:24 -0600 Subject: [PATCH 04/14] feat(toast): add toast API and Toaster package --- components/toast/.gitignore | 1 + components/toast/AGENTS.md | 39 + components/toast/CHANGELOG.md | 11 + components/toast/LICENSE | 21 + components/toast/README.md | 79 + components/toast/dist/index.d.ts | 68 + components/toast/dist/index.js | 331 ++ components/toast/dist/index.js.map | 1 + components/toast/dist/styles.css | 309 ++ components/toast/package-lock.json | 3656 +++++++++++++++++++ components/toast/package.json | 68 + components/toast/src/components/Toaster.tsx | 151 + components/toast/src/index.ts | 18 + components/toast/src/lib/cn.ts | 6 + components/toast/src/store.ts | 238 ++ components/toast/src/styles.css | 309 ++ components/toast/src/toast.test.tsx | 157 + components/toast/src/types.ts | 49 + components/toast/tsconfig.json | 16 + components/toast/tsup.config.ts | 11 + components/toast/vitest.config.ts | 8 + 21 files changed, 5547 insertions(+) create mode 100644 components/toast/.gitignore create mode 100644 components/toast/AGENTS.md create mode 100644 components/toast/CHANGELOG.md create mode 100644 components/toast/LICENSE create mode 100644 components/toast/README.md create mode 100644 components/toast/dist/index.d.ts create mode 100644 components/toast/dist/index.js create mode 100644 components/toast/dist/index.js.map create mode 100644 components/toast/dist/styles.css create mode 100644 components/toast/package-lock.json create mode 100644 components/toast/package.json create mode 100644 components/toast/src/components/Toaster.tsx create mode 100644 components/toast/src/index.ts create mode 100644 components/toast/src/lib/cn.ts create mode 100644 components/toast/src/store.ts create mode 100644 components/toast/src/styles.css create mode 100644 components/toast/src/toast.test.tsx create mode 100644 components/toast/src/types.ts create mode 100644 components/toast/tsconfig.json create mode 100644 components/toast/tsup.config.ts create mode 100644 components/toast/vitest.config.ts diff --git a/components/toast/.gitignore b/components/toast/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/components/toast/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/components/toast/AGENTS.md b/components/toast/AGENTS.md new file mode 100644 index 0000000..e4fbde2 --- /dev/null +++ b/components/toast/AGENTS.md @@ -0,0 +1,39 @@ +# toast package agents + +@jooservices/react-toast — imperative `toast` API + `` viewport. + +## Paths + +- Source: `components/toast/src` +- Entry: `components/toast/src/index.ts` +- Build output: `components/toast/dist` (committed) + +## Commands + +```bash +cd components/toast +npm install # first time +npm run typecheck +npm test +npm run build +``` + +After user-visible changes: update `apps/demo` (`/toast`), mount `` in the demo shell, and run `npm run demo:typecheck`. + +## Peers + +`react`, `react-dom`, `lucide-react` + +## Notes + +- Module store (subscribe listeners) so mutations can toast outside React render. +- Mount a single `` near the app root; import `styles.css` once. +- Keep scope to transient mutation feedback — not a notification center / inbox. +- UI: Tailwind Plus–style Simple / actions-below (white card, colored icon, optional footer). No avatar layout. +- App-specific flash bridges (e.g. Inertia `useFlashToast`) stay in the consumer. + +## Docs + +- User guide: `docs/02-user-guide/11-react-toast.md` (consumer API — do not send humans to `src/`) +- Package README: `components/toast/README.md` +- Root policy: `AGENTS.md` diff --git a/components/toast/CHANGELOG.md b/components/toast/CHANGELOG.md new file mode 100644 index 0000000..3aa0347 --- /dev/null +++ b/components/toast/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +## [Unreleased] + +### Changed + +- Toast UI aligned with Tailwind Plus Simple / With actions below: white card, colored icon only, title + muted description, footer actions (`action` + `secondaryAction`) + +### Added + +- Initial `@jooservices/react-toast`: `toast` API (`success` / `error` / `info` / `warning` / `loading` / `promise` / `dismiss` / `dismissAll`), `` with position + maxVisible, variant icons, progress bar, hover/focus pause, optional title + action, replace-by-id diff --git a/components/toast/LICENSE b/components/toast/LICENSE new file mode 100644 index 0000000..e630730 --- /dev/null +++ b/components/toast/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 JOOservices + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/components/toast/README.md b/components/toast/README.md new file mode 100644 index 0000000..c5f1d6d --- /dev/null +++ b/components/toast/README.md @@ -0,0 +1,79 @@ +# @jooservices/react-toast + +Global **toast** stack: imperative `toast.*` API + `` viewport. + +UI follows Tailwind Plus–style **Simple** / **With actions below** notifications (white card, colored status icon, title + muted description, optional footer actions). Compatible with the XCrawlerII / XFlickr `toast.success/error/info` call shape. + +## Install + +```bash +pnpm add "github:jooservices/react#v1.0.0&path:components/toast" +``` + +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). + +## Usage + +```ts +import "@jooservices/react-toast/styles.css"; +import { Toaster, toast } from "@jooservices/react-toast"; + +// Mount once near the app root + + +toast.success("Saved."); +toast.error("Failed to save."); +toast.info("Import is already queued."); +toast.warning("Dispatch skipped — already running."); +toast.loading("Saving…"); // sticky until replaced / dismissed + +toast.success("Anyone with a link can now view this file.", { + title: "Successfully saved!", + action: { label: "Undo", onClick: () => undo() }, + secondaryAction: { label: "Dismiss", onClick: () => undefined }, +}); + +toast.success("Kept on screen", { durationMs: 0 }); // sticky +toast.dismiss(id); +toast.dismissAll(); + +await toast.promise(save(), { + loading: "Saving…", + success: "Saved.", + error: "Save failed.", +}); +``` + +### `toast` API + +| Method | Notes | +|--------|--------| +| `success` / `error` / `info` / `warning` / `loading` | `(message, durationMs?)` or `(message, options?)` | +| `promise` | loading → success/error, same `id` | +| `dismiss` / `dismissAll` | Remove one or all | + +### Options + +| Option | Role | +|--------|------| +| `id` | Stable id — replace an existing toast | +| `title` | Optional heading; message becomes muted description | +| `durationMs` | Auto-dismiss ms; `0` / `Infinity` = sticky | +| `action` | Primary footer action (dismisses after click) | +| `secondaryAction` | Secondary footer action (split “actions below”) | + +Defaults: success/info/warning **4500ms**, error **6000ms**, loading **sticky**. + +### `` + +| Prop | Role | +|------|------| +| `position?` | `top-right` (default) \| `top-center` \| `bottom-right` | +| `maxVisible?` | Cap (default `5`) | +| `className?` | Extra viewport class | + +Hover / focus pauses auto-dismiss and the progress bar. + +## Peers + +`react`, `react-dom`, `lucide-react` diff --git a/components/toast/dist/index.d.ts b/components/toast/dist/index.d.ts new file mode 100644 index 0000000..484ce88 --- /dev/null +++ b/components/toast/dist/index.d.ts @@ -0,0 +1,68 @@ +import * as react from 'react'; + +type ToastVariant = "success" | "error" | "info" | "warning" | "loading"; +type ToastPosition = "top-right" | "top-center" | "bottom-right"; +type ToastAction = { + label: string; + onClick: () => void; +}; +type ToastOptions = { + /** Replaces an existing toast with the same id (or sets a stable id). */ + id?: string; + /** Optional heading above the message (Tailwind Simple title). */ + title?: string; + /** + * Auto-dismiss delay in ms. + * Use `0` or `Infinity` for sticky toasts (no auto-dismiss). + */ + durationMs?: number; + /** Primary footer action (shows “actions below” layout). */ + action?: ToastAction; + /** Secondary footer action (split footer with `action`). */ + secondaryAction?: ToastAction; +}; +type ToastItem = { + id: string; + message: string; + variant: ToastVariant; + durationMs: number; + title?: string; + action?: ToastAction; + secondaryAction?: ToastAction; + createdAt: number; +}; +type ToasterProps = { + /** Viewport placement. Default `top-right`. */ + position?: ToastPosition; + /** Max visible toasts (oldest beyond the cap are dropped). Default `5`. */ + maxVisible?: number; + className?: string; +}; +type ToastPromiseMessages = { + loading: string; + success: string | ((data: T) => string); + error: string | ((error: unknown) => string); +}; + +declare function Toaster({ position, maxVisible, className, }: ToasterProps): react.JSX.Element | null; + +type ToastListener = (toasts: ToastItem[]) => void; +declare function dismissToast(id: string): void; +declare function dismissAllToasts(): void; +declare function subscribeToasts(listener: ToastListener): () => void; +declare const toast: { + success(message: string, optionsOrDuration?: number | ToastOptions): string; + error(message: string, optionsOrDuration?: number | ToastOptions): string; + info(message: string, optionsOrDuration?: number | ToastOptions): string; + warning(message: string, optionsOrDuration?: number | ToastOptions): string; + loading(message: string, optionsOrDuration?: number | ToastOptions): string; + dismiss: typeof dismissToast; + dismissAll: typeof dismissAllToasts; + promise(promise: Promise, messages: ToastPromiseMessages, options?: Omit & { + durationMs?: number; + }): Promise; +}; +/** Clears active toasts — for unit tests only. */ +declare function resetToastsForTests(): void; + +export { type ToastAction, type ToastItem, type ToastOptions, type ToastPosition, type ToastPromiseMessages, type ToastVariant, Toaster, type ToasterProps, dismissAllToasts, dismissToast, resetToastsForTests, subscribeToasts, toast }; diff --git a/components/toast/dist/index.js b/components/toast/dist/index.js new file mode 100644 index 0000000..04a794a --- /dev/null +++ b/components/toast/dist/index.js @@ -0,0 +1,331 @@ +import { X, LoaderCircle, AlertTriangle, Info, AlertCircle, CheckCircle2 } from 'lucide-react'; +import { useState, useEffect } from 'react'; +import { clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; +import { jsx, jsxs } from 'react/jsx-runtime'; + +// src/components/Toaster.tsx +function cn(...inputs) { + return twMerge(clsx(inputs)); +} + +// src/store.ts +var DEFAULT_DURATION_MS = 4500; +var DEFAULT_ERROR_DURATION_MS = 6e3; +var DEFAULT_MAX = 5; +var nextId = 0; +var maxVisible = DEFAULT_MAX; +var toasts = []; +var listeners = /* @__PURE__ */ new Set(); +var dismissTimers = /* @__PURE__ */ new Map(); +var remainingMs = /* @__PURE__ */ new Map(); +var timerStartedAt = /* @__PURE__ */ new Map(); +function emit() { + for (const listener of listeners) { + listener([...toasts]); + } +} +function isSticky(durationMs) { + return !Number.isFinite(durationMs) || durationMs <= 0; +} +function clearTimer(id) { + const timer = dismissTimers.get(id); + if (timer) { + clearTimeout(timer); + dismissTimers.delete(id); + } + timerStartedAt.delete(id); +} +function scheduleDismiss(id, durationMs) { + clearTimer(id); + if (isSticky(durationMs)) { + remainingMs.delete(id); + return; + } + remainingMs.set(id, durationMs); + timerStartedAt.set(id, Date.now()); + const timer = setTimeout(() => { + dismissTimers.delete(id); + timerStartedAt.delete(id); + remainingMs.delete(id); + dismissToast(id); + }, durationMs); + dismissTimers.set(id, timer); +} +function normalizeOptions(variant, optionsOrDuration) { + if (typeof optionsOrDuration === "number") { + return { durationMs: optionsOrDuration }; + } + return optionsOrDuration ?? {}; +} +function defaultDuration(variant, durationMs) { + if (durationMs !== void 0) { + return durationMs; + } + if (variant === "loading") { + return Number.POSITIVE_INFINITY; + } + if (variant === "error") { + return DEFAULT_ERROR_DURATION_MS; + } + return DEFAULT_DURATION_MS; +} +function pushToast(message, variant, optionsOrDuration) { + const options = normalizeOptions(variant, optionsOrDuration); + const id = options.id ?? `toast-${nextId++}`; + const durationMs = defaultDuration(variant, options.durationMs); + const item = { + id, + message, + variant, + durationMs, + title: options.title, + action: options.action, + secondaryAction: options.secondaryAction, + createdAt: Date.now() + }; + clearTimer(id); + remainingMs.delete(id); + const without = toasts.filter((toast2) => toast2.id !== id); + toasts = [item, ...without].slice(0, maxVisible); + emit(); + scheduleDismiss(id, durationMs); + return id; +} +function dismissToast(id) { + clearTimer(id); + remainingMs.delete(id); + const next = toasts.filter((toast2) => toast2.id !== id); + if (next.length === toasts.length) { + return; + } + toasts = next; + emit(); +} +function dismissAllToasts() { + for (const id of [...toasts.map((t) => t.id)]) { + clearTimer(id); + remainingMs.delete(id); + } + if (toasts.length === 0) { + return; + } + toasts = []; + emit(); +} +function subscribeToasts(listener) { + listeners.add(listener); + listener([...toasts]); + return () => { + listeners.delete(listener); + }; +} +function setToastMaxVisible(next) { + const capped = Math.max(1, Math.floor(next)); + if (capped === maxVisible) { + return; + } + maxVisible = capped; + if (toasts.length > maxVisible) { + const dropped = toasts.slice(maxVisible); + toasts = toasts.slice(0, maxVisible); + for (const item of dropped) { + clearTimer(item.id); + remainingMs.delete(item.id); + } + emit(); + } +} +function pauseToastTimer(id) { + const started = timerStartedAt.get(id); + const remaining = remainingMs.get(id); + if (started !== void 0 && remaining !== void 0) { + remainingMs.set(id, Math.max(0, remaining - (Date.now() - started))); + } + clearTimer(id); +} +function resumeToastTimer(id) { + const item = toasts.find((toast2) => toast2.id === id); + if (!item || isSticky(item.durationMs)) { + return; + } + const remaining = remainingMs.get(id) ?? item.durationMs; + if (remaining <= 0) { + dismissToast(id); + return; + } + scheduleDismiss(id, remaining); +} +var toast = { + success(message, optionsOrDuration) { + return pushToast(message, "success", optionsOrDuration); + }, + error(message, optionsOrDuration) { + return pushToast(message, "error", optionsOrDuration); + }, + info(message, optionsOrDuration) { + return pushToast(message, "info", optionsOrDuration); + }, + warning(message, optionsOrDuration) { + return pushToast(message, "warning", optionsOrDuration); + }, + loading(message, optionsOrDuration) { + return pushToast(message, "loading", optionsOrDuration); + }, + dismiss: dismissToast, + dismissAll: dismissAllToasts, + promise(promise, messages, options) { + const id = pushToast(messages.loading, "loading", { + ...options, + id: options?.id, + durationMs: Number.POSITIVE_INFINITY + }); + return promise.then((data) => { + const message = typeof messages.success === "function" ? messages.success(data) : messages.success; + pushToast(message, "success", { ...options, id }); + return data; + }).catch((error) => { + const message = typeof messages.error === "function" ? messages.error(error) : messages.error; + pushToast(message, "error", { ...options, id }); + throw error; + }); + } +}; +function resetToastsForTests() { + for (const timer of dismissTimers.values()) { + clearTimeout(timer); + } + dismissTimers.clear(); + remainingMs.clear(); + timerStartedAt.clear(); + toasts = []; + maxVisible = DEFAULT_MAX; + emit(); +} +var variantIcon = { + success: /* @__PURE__ */ jsx(CheckCircle2, { className: "joo-toast-icon", "aria-hidden": true }), + error: /* @__PURE__ */ jsx(AlertCircle, { className: "joo-toast-icon", "aria-hidden": true }), + info: /* @__PURE__ */ jsx(Info, { className: "joo-toast-icon", "aria-hidden": true }), + warning: /* @__PURE__ */ jsx(AlertTriangle, { className: "joo-toast-icon", "aria-hidden": true }), + loading: /* @__PURE__ */ jsx(LoaderCircle, { className: "joo-toast-icon joo-toast-icon--spin", "aria-hidden": true }) +}; +function isSticky2(durationMs) { + return !Number.isFinite(durationMs) || durationMs <= 0; +} +function runAction(itemId, action) { + action.onClick(); + dismissToast(itemId); +} +function ToastCard({ item }) { + const sticky = isSticky2(item.durationMs); + const role = item.variant === "error" || item.variant === "warning" ? "alert" : "status"; + const hasActions = Boolean(item.action || item.secondaryAction); + const hasTitle = Boolean(item.title); + return /* @__PURE__ */ jsxs( + "div", + { + role, + className: cn( + "joo-toast", + `joo-toast--${item.variant}`, + !hasTitle && "joo-toast--condensed", + hasActions && "joo-toast--with-actions" + ), + onMouseEnter: () => pauseToastTimer(item.id), + onMouseLeave: () => resumeToastTimer(item.id), + onFocus: () => pauseToastTimer(item.id), + onBlur: () => resumeToastTimer(item.id), + children: [ + /* @__PURE__ */ jsxs("div", { className: "joo-toast-main", children: [ + /* @__PURE__ */ jsx("div", { className: "joo-toast-icon-wrap", "data-variant": item.variant, children: variantIcon[item.variant] }), + /* @__PURE__ */ jsxs("div", { className: "joo-toast-body", children: [ + item.title ? /* @__PURE__ */ jsx("p", { className: "joo-toast-title", children: item.title }) : null, + /* @__PURE__ */ jsx("p", { className: item.title ? "joo-toast-description" : "joo-toast-title", children: item.message }) + ] }), + /* @__PURE__ */ jsx("div", { className: "joo-toast-dismiss-wrap", children: /* @__PURE__ */ jsxs( + "button", + { + type: "button", + className: "joo-toast-dismiss", + "aria-label": "Dismiss notification", + onClick: () => dismissToast(item.id), + children: [ + /* @__PURE__ */ jsx(X, { className: "joo-toast-dismiss-icon", "aria-hidden": true }), + /* @__PURE__ */ jsx("span", { className: "joo-toast-sr-only", children: "Close" }) + ] + } + ) }) + ] }), + hasActions ? /* @__PURE__ */ jsxs( + "div", + { + className: cn( + "joo-toast-actions", + item.action && item.secondaryAction && "joo-toast-actions--split" + ), + children: [ + item.action ? /* @__PURE__ */ jsx( + "button", + { + type: "button", + className: "joo-toast-action joo-toast-action--primary", + onClick: () => runAction(item.id, item.action), + children: item.action.label + } + ) : null, + item.secondaryAction ? /* @__PURE__ */ jsx( + "button", + { + type: "button", + className: "joo-toast-action joo-toast-action--secondary", + onClick: () => runAction(item.id, item.secondaryAction), + children: item.secondaryAction.label + } + ) : null + ] + } + ) : null, + !sticky ? /* @__PURE__ */ jsx( + "span", + { + className: "joo-toast-progress", + style: { animationDuration: `${item.durationMs}ms` }, + "aria-hidden": true + } + ) : null + ] + } + ); +} +var positionClass = { + "top-right": "joo-toaster--top-right", + "top-center": "joo-toaster--top-center", + "bottom-right": "joo-toaster--bottom-right" +}; +function Toaster({ + position = "top-right", + maxVisible: maxVisible2 = 5, + className +}) { + const [items, setItems] = useState([]); + useEffect(() => subscribeToasts(setItems), []); + useEffect(() => { + setToastMaxVisible(maxVisible2); + }, [maxVisible2]); + if (items.length === 0) { + return null; + } + return /* @__PURE__ */ jsx( + "div", + { + "aria-live": "polite", + "aria-relevant": "additions", + className: cn("joo-toaster", positionClass[position], className), + children: items.map((item) => /* @__PURE__ */ jsx(ToastCard, { item }, item.id)) + } + ); +} + +export { Toaster, dismissAllToasts, dismissToast, resetToastsForTests, subscribeToasts, toast }; +//# sourceMappingURL=index.js.map +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/components/toast/dist/index.js.map b/components/toast/dist/index.js.map new file mode 100644 index 0000000..1093606 --- /dev/null +++ b/components/toast/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/lib/cn.ts","../src/store.ts","../src/components/Toaster.tsx"],"names":["toast","isSticky","maxVisible"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { ToastItem, ToastOptions, ToastPromiseMessages, ToastVariant } from \"./types\";\n\ntype ToastListener = (toasts: ToastItem[]) => void;\n\nconst DEFAULT_DURATION_MS = 4_500;\nconst DEFAULT_ERROR_DURATION_MS = 6_000;\nconst DEFAULT_MAX = 5;\n\nlet nextId = 0;\nlet maxVisible = DEFAULT_MAX;\nlet toasts: ToastItem[] = [];\nconst listeners = new Set();\nconst dismissTimers = new Map>();\nconst remainingMs = new Map();\nconst timerStartedAt = new Map();\n\nfunction emit(): void {\n for (const listener of listeners) {\n listener([...toasts]);\n }\n}\n\nfunction isSticky(durationMs: number): boolean {\n return !Number.isFinite(durationMs) || durationMs <= 0;\n}\n\nfunction clearTimer(id: string): void {\n const timer = dismissTimers.get(id);\n if (timer) {\n clearTimeout(timer);\n dismissTimers.delete(id);\n }\n timerStartedAt.delete(id);\n}\n\nfunction scheduleDismiss(id: string, durationMs: number): void {\n clearTimer(id);\n if (isSticky(durationMs)) {\n remainingMs.delete(id);\n return;\n }\n\n remainingMs.set(id, durationMs);\n timerStartedAt.set(id, Date.now());\n\n const timer = setTimeout(() => {\n dismissTimers.delete(id);\n timerStartedAt.delete(id);\n remainingMs.delete(id);\n dismissToast(id);\n }, durationMs);\n\n dismissTimers.set(id, timer);\n}\n\nfunction normalizeOptions(\n variant: ToastVariant,\n optionsOrDuration?: number | ToastOptions,\n): ToastOptions {\n if (typeof optionsOrDuration === \"number\") {\n return { durationMs: optionsOrDuration };\n }\n return optionsOrDuration ?? {};\n}\n\nfunction defaultDuration(variant: ToastVariant, durationMs: number | undefined): number {\n if (durationMs !== undefined) {\n return durationMs;\n }\n if (variant === \"loading\") {\n return Number.POSITIVE_INFINITY;\n }\n if (variant === \"error\") {\n return DEFAULT_ERROR_DURATION_MS;\n }\n return DEFAULT_DURATION_MS;\n}\n\nfunction pushToast(\n message: string,\n variant: ToastVariant,\n optionsOrDuration?: number | ToastOptions,\n): string {\n const options = normalizeOptions(variant, optionsOrDuration);\n const id = options.id ?? `toast-${nextId++}`;\n const durationMs = defaultDuration(variant, options.durationMs);\n const item: ToastItem = {\n id,\n message,\n variant,\n durationMs,\n title: options.title,\n action: options.action,\n secondaryAction: options.secondaryAction,\n createdAt: Date.now(),\n };\n\n clearTimer(id);\n remainingMs.delete(id);\n\n const without = toasts.filter((toast) => toast.id !== id);\n toasts = [item, ...without].slice(0, maxVisible);\n emit();\n scheduleDismiss(id, durationMs);\n return id;\n}\n\nexport function dismissToast(id: string): void {\n clearTimer(id);\n remainingMs.delete(id);\n\n const next = toasts.filter((toast) => toast.id !== id);\n if (next.length === toasts.length) {\n return;\n }\n\n toasts = next;\n emit();\n}\n\nexport function dismissAllToasts(): void {\n for (const id of [...toasts.map((t) => t.id)]) {\n clearTimer(id);\n remainingMs.delete(id);\n }\n if (toasts.length === 0) {\n return;\n }\n toasts = [];\n emit();\n}\n\nexport function subscribeToasts(listener: ToastListener): () => void {\n listeners.add(listener);\n listener([...toasts]);\n\n return () => {\n listeners.delete(listener);\n };\n}\n\n/** Used by `` so the store and viewport share one cap. */\nexport function setToastMaxVisible(next: number): void {\n const capped = Math.max(1, Math.floor(next));\n if (capped === maxVisible) {\n return;\n }\n maxVisible = capped;\n if (toasts.length > maxVisible) {\n const dropped = toasts.slice(maxVisible);\n toasts = toasts.slice(0, maxVisible);\n for (const item of dropped) {\n clearTimer(item.id);\n remainingMs.delete(item.id);\n }\n emit();\n }\n}\n\nexport function pauseToastTimer(id: string): void {\n const started = timerStartedAt.get(id);\n const remaining = remainingMs.get(id);\n if (started !== undefined && remaining !== undefined) {\n remainingMs.set(id, Math.max(0, remaining - (Date.now() - started)));\n }\n clearTimer(id);\n}\n\nexport function resumeToastTimer(id: string): void {\n const item = toasts.find((toast) => toast.id === id);\n if (!item || isSticky(item.durationMs)) {\n return;\n }\n const remaining = remainingMs.get(id) ?? item.durationMs;\n if (remaining <= 0) {\n dismissToast(id);\n return;\n }\n scheduleDismiss(id, remaining);\n}\n\nexport const toast = {\n success(message: string, optionsOrDuration?: number | ToastOptions): string {\n return pushToast(message, \"success\", optionsOrDuration);\n },\n error(message: string, optionsOrDuration?: number | ToastOptions): string {\n return pushToast(message, \"error\", optionsOrDuration);\n },\n info(message: string, optionsOrDuration?: number | ToastOptions): string {\n return pushToast(message, \"info\", optionsOrDuration);\n },\n warning(message: string, optionsOrDuration?: number | ToastOptions): string {\n return pushToast(message, \"warning\", optionsOrDuration);\n },\n loading(message: string, optionsOrDuration?: number | ToastOptions): string {\n return pushToast(message, \"loading\", optionsOrDuration);\n },\n dismiss: dismissToast,\n dismissAll: dismissAllToasts,\n promise(\n promise: Promise,\n messages: ToastPromiseMessages,\n options?: Omit & { durationMs?: number },\n ): Promise {\n const id = pushToast(messages.loading, \"loading\", {\n ...options,\n id: options?.id,\n durationMs: Number.POSITIVE_INFINITY,\n });\n\n return promise\n .then((data) => {\n const message =\n typeof messages.success === \"function\" ? messages.success(data) : messages.success;\n pushToast(message, \"success\", { ...options, id });\n return data;\n })\n .catch((error: unknown) => {\n const message =\n typeof messages.error === \"function\" ? messages.error(error) : messages.error;\n pushToast(message, \"error\", { ...options, id });\n throw error;\n });\n },\n};\n\n/** Clears active toasts — for unit tests only. */\nexport function resetToastsForTests(): void {\n for (const timer of dismissTimers.values()) {\n clearTimeout(timer);\n }\n dismissTimers.clear();\n remainingMs.clear();\n timerStartedAt.clear();\n toasts = [];\n maxVisible = DEFAULT_MAX;\n emit();\n}\n","import { AlertCircle, AlertTriangle, CheckCircle2, Info, LoaderCircle, X } from \"lucide-react\";\nimport { useEffect, useState, type ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport {\n dismissToast,\n pauseToastTimer,\n resumeToastTimer,\n setToastMaxVisible,\n subscribeToasts,\n} from \"../store\";\nimport type {\n ToastAction,\n ToastItem,\n ToastPosition,\n ToastVariant,\n ToasterProps,\n} from \"../types\";\n\nconst variantIcon: Record = {\n success: ,\n error: ,\n info: ,\n warning: ,\n loading: ,\n};\n\nfunction isSticky(durationMs: number): boolean {\n return !Number.isFinite(durationMs) || durationMs <= 0;\n}\n\nfunction runAction(itemId: string, action: ToastAction): void {\n action.onClick();\n dismissToast(itemId);\n}\n\nfunction ToastCard({ item }: { item: ToastItem }) {\n const sticky = isSticky(item.durationMs);\n const role = item.variant === \"error\" || item.variant === \"warning\" ? \"alert\" : \"status\";\n const hasActions = Boolean(item.action || item.secondaryAction);\n const hasTitle = Boolean(item.title);\n\n return (\n pauseToastTimer(item.id)}\n onMouseLeave={() => resumeToastTimer(item.id)}\n onFocus={() => pauseToastTimer(item.id)}\n onBlur={() => resumeToastTimer(item.id)}\n >\n
\n
\n {variantIcon[item.variant]}\n
\n
\n {item.title ?

{item.title}

: null}\n

{item.message}

\n
\n
\n dismissToast(item.id)}\n >\n \n Close\n \n
\n
\n\n {hasActions ? (\n \n {item.action ? (\n runAction(item.id, item.action!)}\n >\n {item.action.label}\n \n ) : null}\n {item.secondaryAction ? (\n runAction(item.id, item.secondaryAction!)}\n >\n {item.secondaryAction.label}\n \n ) : null}\n \n ) : null}\n\n {!sticky ? (\n \n ) : null}\n \n );\n}\n\nconst positionClass: Record = {\n \"top-right\": \"joo-toaster--top-right\",\n \"top-center\": \"joo-toaster--top-center\",\n \"bottom-right\": \"joo-toaster--bottom-right\",\n};\n\nexport function Toaster({\n position = \"top-right\",\n maxVisible = 5,\n className,\n}: ToasterProps) {\n const [items, setItems] = useState([]);\n\n useEffect(() => subscribeToasts(setItems), []);\n\n useEffect(() => {\n setToastMaxVisible(maxVisible);\n }, [maxVisible]);\n\n if (items.length === 0) {\n return null;\n }\n\n return (\n \n {items.map((item) => (\n \n ))}\n \n );\n}\n"]} \ No newline at end of file diff --git a/components/toast/dist/styles.css b/components/toast/dist/styles.css new file mode 100644 index 0000000..3a7cb48 --- /dev/null +++ b/components/toast/dist/styles.css @@ -0,0 +1,309 @@ +:root { + --joo-toast-bg: 0 0% 100%; + --joo-toast-fg: 222.2 47.4% 11.2%; + --joo-toast-muted: 215.4 16.3% 46.9%; + --joo-toast-border: 214.3 31.8% 91.4%; + --joo-toast-ring: 214.3 31.8% 91.4%; + --joo-toast-radius: 0.5rem; + --joo-toast-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); + --joo-toast-z: 100; + --joo-toast-width: min(100vw - 2rem, 24rem); + --joo-toast-success: 142.1 70.6% 45.3%; + --joo-toast-error: 0 72.2% 50.6%; + --joo-toast-info: 217.2 91.2% 59.8%; + --joo-toast-warning: 37.7 92.1% 50.2%; + --joo-toast-loading: 192 70% 40%; + --joo-toast-action: 221.2 83.2% 53.3%; + --joo-toast-action-hover: 221.2 83.2% 45%; +} + +.joo-toaster { + pointer-events: none; + position: fixed; + z-index: var(--joo-toast-z); + display: flex; + width: var(--joo-toast-width); + flex-direction: column; + gap: 0.75rem; +} + +.joo-toaster--top-right { + top: 1rem; + right: 1rem; +} + +.joo-toaster--top-center { + top: 1rem; + left: 50%; + transform: translateX(-50%); +} + +.joo-toaster--bottom-right { + right: 1rem; + bottom: 1rem; +} + +.joo-toast { + pointer-events: auto; + position: relative; + display: flex; + width: 100%; + max-width: 24rem; + flex-direction: column; + overflow: hidden; + border: 1px solid hsl(var(--joo-toast-border)); + border-radius: var(--joo-toast-radius); + background: hsl(var(--joo-toast-bg)); + color: hsl(var(--joo-toast-fg)); + box-shadow: var(--joo-toast-shadow); + animation: joo-toast-in 180ms ease-out; +} + +.joo-toast-main { + display: flex; + align-items: flex-start; + gap: 0.75rem; + padding: 1rem; +} + +.joo-toast--condensed .joo-toast-main { + padding: 0.875rem 1rem; +} + +.joo-toast-icon-wrap { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + margin-top: 0.05rem; + color: hsl(var(--joo-toast-muted)); +} + +.joo-toast--success .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-success)); +} + +.joo-toast--error .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-error)); +} + +.joo-toast--info .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-info)); +} + +.joo-toast--warning .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-warning)); +} + +.joo-toast--loading .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-loading)); +} + +.joo-toast-icon { + width: 1.25rem; + height: 1.25rem; +} + +.joo-toast-icon--spin { + animation: joo-toast-spin 0.9s linear infinite; +} + +.joo-toast-body { + min-width: 0; + flex: 1; + display: flex; + flex-direction: column; + gap: 0.125rem; + padding-top: 0.05rem; +} + +.joo-toast-title { + margin: 0; + font-size: 0.875rem; + font-weight: 500; + line-height: 1.25rem; + color: hsl(var(--joo-toast-fg)); +} + +.joo-toast-description { + margin: 0; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.25rem; + color: hsl(var(--joo-toast-muted)); +} + +.joo-toast-dismiss-wrap { + margin: -0.25rem -0.25rem 0 0; +} + +.joo-toast-dismiss { + display: inline-flex; + align-items: center; + justify-content: center; + border: 0; + border-radius: 0.375rem; + background: transparent; + color: hsl(var(--joo-toast-muted)); + cursor: pointer; + padding: 0.375rem; +} + +.joo-toast-dismiss:hover { + color: hsl(var(--joo-toast-fg)); + background: hsl(var(--joo-toast-fg) / 0.05); +} + +.joo-toast-dismiss:focus-visible { + outline: 2px solid hsl(var(--joo-toast-action)); + outline-offset: 2px; +} + +.joo-toast-dismiss-icon { + width: 1.25rem; + height: 1.25rem; +} + +.joo-toast-sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +.joo-toast-actions { + display: flex; + border-top: 1px solid hsl(var(--joo-toast-border)); + background: hsl(var(--joo-toast-bg)); +} + +.joo-toast-actions--split > .joo-toast-action + .joo-toast-action { + border-left: 1px solid hsl(var(--joo-toast-border)); +} + +.joo-toast-action { + flex: 1; + display: inline-flex; + align-items: center; + justify-content: center; + border: 0; + background: transparent; + cursor: pointer; + font: inherit; + font-size: 0.875rem; + font-weight: 500; + line-height: 1.25rem; + padding: 0.75rem 1rem; + text-align: center; +} + +.joo-toast-action--primary { + color: hsl(var(--joo-toast-action)); +} + +.joo-toast-action--primary:hover { + background: hsl(var(--joo-toast-fg) / 0.03); + color: hsl(var(--joo-toast-action-hover)); +} + +.joo-toast-action--secondary { + color: hsl(var(--joo-toast-muted)); +} + +.joo-toast-action--secondary:hover { + background: hsl(var(--joo-toast-fg) / 0.03); + color: hsl(var(--joo-toast-fg)); +} + +.joo-toast-action:focus-visible { + outline: 2px solid hsl(var(--joo-toast-action)); + outline-offset: -2px; + z-index: 1; +} + +.joo-toast-progress { + position: absolute; + left: 0; + bottom: 0; + height: 2px; + width: 100%; + transform-origin: left; + background: currentColor; + opacity: 0.45; + animation-name: joo-toast-progress; + animation-timing-function: linear; + animation-fill-mode: forwards; +} + +.joo-toast--success .joo-toast-progress { + color: hsl(var(--joo-toast-success)); +} + +.joo-toast--error .joo-toast-progress { + color: hsl(var(--joo-toast-error)); +} + +.joo-toast--info .joo-toast-progress { + color: hsl(var(--joo-toast-info)); +} + +.joo-toast--warning .joo-toast-progress { + color: hsl(var(--joo-toast-warning)); +} + +.joo-toast--loading .joo-toast-progress { + color: hsl(var(--joo-toast-loading)); +} + +.joo-toast:hover .joo-toast-progress, +.joo-toast:focus-within .joo-toast-progress { + animation-play-state: paused; +} + +@keyframes joo-toast-in { + from { + opacity: 0; + transform: translateY(-0.5rem) scale(0.98); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +@keyframes joo-toast-progress { + from { + transform: scaleX(1); + } + to { + transform: scaleX(0); + } +} + +@keyframes joo-toast-spin { + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: reduce) { + .joo-toast { + animation: none; + } + + .joo-toast-icon--spin { + animation: none; + } + + .joo-toast-progress { + animation: none; + opacity: 0; + } +} diff --git a/components/toast/package-lock.json b/components/toast/package-lock.json new file mode 100644 index 0000000..8326b3d --- /dev/null +++ b/components/toast/package-lock.json @@ -0,0 +1,3656 @@ +{ + "name": "@jooservices/react-toast", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@jooservices/react-toast", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@adobe/css-tools": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz", + "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", + "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.0.0", + "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz", + "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.9.tgz", + "integrity": "sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.1.0", + "@csstools/css-calc": "^3.2.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz", + "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz", + "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^15.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/lucide-react": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.24.0.tgz", + "integrity": "sha512-YT6mBD8lGKkg4nM39enlm94/sfJIiW0YKUT60fBy4YK8tai31ylg1VhGNWxkpSKHo9UagfnZqwIff3HTDQwXeA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/postcss": { + "version": "8.5.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", + "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.8.tgz", + "integrity": "sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.8" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.8.tgz", + "integrity": "sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/tsup": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", + "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", + "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.16", + "rolldown": "~1.1.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/vitest/node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/components/toast/package.json b/components/toast/package.json new file mode 100644 index 0000000..4541c4d --- /dev/null +++ b/components/toast/package.json @@ -0,0 +1,68 @@ +{ + "name": "@jooservices/react-toast", + "version": "0.1.0", + "description": "Global toast stack for React \u2014 imperative toast API and Toaster viewport", + "type": "module", + "license": "MIT", + "author": "JOOservices", + "repository": { + "type": "git", + "url": "https://github.com/jooservices/react.git", + "directory": "components/toast" + }, + "keywords": [ + "react", + "toast", + "notification", + "snackbar" + ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./styles.css": "./dist/styles.css" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "sideEffects": [ + "**/*.css" + ], + "scripts": { + "build": "tsup && cp src/styles.css dist/styles.css", + "typecheck": "tsc --noEmit", + "test": "vitest run", + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" + }, + "dependencies": { + "clsx": "^2.1.1", + "tailwind-merge": "^3.6.0" + }, + "peerDependencies": { + "lucide-react": ">=0.400.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.0", + "@types/react": "^19.2.17", + "@types/react-dom": "^19.2.3", + "jsdom": "^27.0.1", + "lucide-react": "^1.21.0", + "react": "^19.2.7", + "react-dom": "^19.2.7", + "tsup": "^8.5.0", + "typescript": "^5.9.3", + "vitest": "^4.0.16" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/components/toast/src/components/Toaster.tsx b/components/toast/src/components/Toaster.tsx new file mode 100644 index 0000000..411e393 --- /dev/null +++ b/components/toast/src/components/Toaster.tsx @@ -0,0 +1,151 @@ +import { AlertCircle, AlertTriangle, CheckCircle2, Info, LoaderCircle, X } from "lucide-react"; +import { useEffect, useState, type ReactNode } from "react"; + +import { cn } from "../lib/cn"; +import { + dismissToast, + pauseToastTimer, + resumeToastTimer, + setToastMaxVisible, + subscribeToasts, +} from "../store"; +import type { + ToastAction, + ToastItem, + ToastPosition, + ToastVariant, + ToasterProps, +} from "../types"; + +const variantIcon: Record = { + success: , + error: , + info: , + warning: , + loading: , +}; + +function isSticky(durationMs: number): boolean { + return !Number.isFinite(durationMs) || durationMs <= 0; +} + +function runAction(itemId: string, action: ToastAction): void { + action.onClick(); + dismissToast(itemId); +} + +function ToastCard({ item }: { item: ToastItem }) { + const sticky = isSticky(item.durationMs); + const role = item.variant === "error" || item.variant === "warning" ? "alert" : "status"; + const hasActions = Boolean(item.action || item.secondaryAction); + const hasTitle = Boolean(item.title); + + return ( +
pauseToastTimer(item.id)} + onMouseLeave={() => resumeToastTimer(item.id)} + onFocus={() => pauseToastTimer(item.id)} + onBlur={() => resumeToastTimer(item.id)} + > +
+
+ {variantIcon[item.variant]} +
+
+ {item.title ?

{item.title}

: null} +

{item.message}

+
+
+ +
+
+ + {hasActions ? ( +
+ {item.action ? ( + + ) : null} + {item.secondaryAction ? ( + + ) : null} +
+ ) : null} + + {!sticky ? ( + + ) : null} +
+ ); +} + +const positionClass: Record = { + "top-right": "joo-toaster--top-right", + "top-center": "joo-toaster--top-center", + "bottom-right": "joo-toaster--bottom-right", +}; + +export function Toaster({ + position = "top-right", + maxVisible = 5, + className, +}: ToasterProps) { + const [items, setItems] = useState([]); + + useEffect(() => subscribeToasts(setItems), []); + + useEffect(() => { + setToastMaxVisible(maxVisible); + }, [maxVisible]); + + if (items.length === 0) { + return null; + } + + return ( +
+ {items.map((item) => ( + + ))} +
+ ); +} diff --git a/components/toast/src/index.ts b/components/toast/src/index.ts new file mode 100644 index 0000000..48b8cf6 --- /dev/null +++ b/components/toast/src/index.ts @@ -0,0 +1,18 @@ +export { Toaster } from "./components/Toaster"; +export { + dismissAllToasts, + dismissToast, + resetToastsForTests, + subscribeToasts, + toast, +} from "./store"; + +export type { + ToastAction, + ToastItem, + ToastOptions, + ToastPosition, + ToastPromiseMessages, + ToastVariant, + ToasterProps, +} from "./types"; diff --git a/components/toast/src/lib/cn.ts b/components/toast/src/lib/cn.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/components/toast/src/lib/cn.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/components/toast/src/store.ts b/components/toast/src/store.ts new file mode 100644 index 0000000..3f1d021 --- /dev/null +++ b/components/toast/src/store.ts @@ -0,0 +1,238 @@ +import type { ToastItem, ToastOptions, ToastPromiseMessages, ToastVariant } from "./types"; + +type ToastListener = (toasts: ToastItem[]) => void; + +const DEFAULT_DURATION_MS = 4_500; +const DEFAULT_ERROR_DURATION_MS = 6_000; +const DEFAULT_MAX = 5; + +let nextId = 0; +let maxVisible = DEFAULT_MAX; +let toasts: ToastItem[] = []; +const listeners = new Set(); +const dismissTimers = new Map>(); +const remainingMs = new Map(); +const timerStartedAt = new Map(); + +function emit(): void { + for (const listener of listeners) { + listener([...toasts]); + } +} + +function isSticky(durationMs: number): boolean { + return !Number.isFinite(durationMs) || durationMs <= 0; +} + +function clearTimer(id: string): void { + const timer = dismissTimers.get(id); + if (timer) { + clearTimeout(timer); + dismissTimers.delete(id); + } + timerStartedAt.delete(id); +} + +function scheduleDismiss(id: string, durationMs: number): void { + clearTimer(id); + if (isSticky(durationMs)) { + remainingMs.delete(id); + return; + } + + remainingMs.set(id, durationMs); + timerStartedAt.set(id, Date.now()); + + const timer = setTimeout(() => { + dismissTimers.delete(id); + timerStartedAt.delete(id); + remainingMs.delete(id); + dismissToast(id); + }, durationMs); + + dismissTimers.set(id, timer); +} + +function normalizeOptions( + variant: ToastVariant, + optionsOrDuration?: number | ToastOptions, +): ToastOptions { + if (typeof optionsOrDuration === "number") { + return { durationMs: optionsOrDuration }; + } + return optionsOrDuration ?? {}; +} + +function defaultDuration(variant: ToastVariant, durationMs: number | undefined): number { + if (durationMs !== undefined) { + return durationMs; + } + if (variant === "loading") { + return Number.POSITIVE_INFINITY; + } + if (variant === "error") { + return DEFAULT_ERROR_DURATION_MS; + } + return DEFAULT_DURATION_MS; +} + +function pushToast( + message: string, + variant: ToastVariant, + optionsOrDuration?: number | ToastOptions, +): string { + const options = normalizeOptions(variant, optionsOrDuration); + const id = options.id ?? `toast-${nextId++}`; + const durationMs = defaultDuration(variant, options.durationMs); + const item: ToastItem = { + id, + message, + variant, + durationMs, + title: options.title, + action: options.action, + secondaryAction: options.secondaryAction, + createdAt: Date.now(), + }; + + clearTimer(id); + remainingMs.delete(id); + + const without = toasts.filter((toast) => toast.id !== id); + toasts = [item, ...without].slice(0, maxVisible); + emit(); + scheduleDismiss(id, durationMs); + return id; +} + +export function dismissToast(id: string): void { + clearTimer(id); + remainingMs.delete(id); + + const next = toasts.filter((toast) => toast.id !== id); + if (next.length === toasts.length) { + return; + } + + toasts = next; + emit(); +} + +export function dismissAllToasts(): void { + for (const id of [...toasts.map((t) => t.id)]) { + clearTimer(id); + remainingMs.delete(id); + } + if (toasts.length === 0) { + return; + } + toasts = []; + emit(); +} + +export function subscribeToasts(listener: ToastListener): () => void { + listeners.add(listener); + listener([...toasts]); + + return () => { + listeners.delete(listener); + }; +} + +/** Used by `` so the store and viewport share one cap. */ +export function setToastMaxVisible(next: number): void { + const capped = Math.max(1, Math.floor(next)); + if (capped === maxVisible) { + return; + } + maxVisible = capped; + if (toasts.length > maxVisible) { + const dropped = toasts.slice(maxVisible); + toasts = toasts.slice(0, maxVisible); + for (const item of dropped) { + clearTimer(item.id); + remainingMs.delete(item.id); + } + emit(); + } +} + +export function pauseToastTimer(id: string): void { + const started = timerStartedAt.get(id); + const remaining = remainingMs.get(id); + if (started !== undefined && remaining !== undefined) { + remainingMs.set(id, Math.max(0, remaining - (Date.now() - started))); + } + clearTimer(id); +} + +export function resumeToastTimer(id: string): void { + const item = toasts.find((toast) => toast.id === id); + if (!item || isSticky(item.durationMs)) { + return; + } + const remaining = remainingMs.get(id) ?? item.durationMs; + if (remaining <= 0) { + dismissToast(id); + return; + } + scheduleDismiss(id, remaining); +} + +export const toast = { + success(message: string, optionsOrDuration?: number | ToastOptions): string { + return pushToast(message, "success", optionsOrDuration); + }, + error(message: string, optionsOrDuration?: number | ToastOptions): string { + return pushToast(message, "error", optionsOrDuration); + }, + info(message: string, optionsOrDuration?: number | ToastOptions): string { + return pushToast(message, "info", optionsOrDuration); + }, + warning(message: string, optionsOrDuration?: number | ToastOptions): string { + return pushToast(message, "warning", optionsOrDuration); + }, + loading(message: string, optionsOrDuration?: number | ToastOptions): string { + return pushToast(message, "loading", optionsOrDuration); + }, + dismiss: dismissToast, + dismissAll: dismissAllToasts, + promise( + promise: Promise, + messages: ToastPromiseMessages, + options?: Omit & { durationMs?: number }, + ): Promise { + const id = pushToast(messages.loading, "loading", { + ...options, + id: options?.id, + durationMs: Number.POSITIVE_INFINITY, + }); + + return promise + .then((data) => { + const message = + typeof messages.success === "function" ? messages.success(data) : messages.success; + pushToast(message, "success", { ...options, id }); + return data; + }) + .catch((error: unknown) => { + const message = + typeof messages.error === "function" ? messages.error(error) : messages.error; + pushToast(message, "error", { ...options, id }); + throw error; + }); + }, +}; + +/** Clears active toasts — for unit tests only. */ +export function resetToastsForTests(): void { + for (const timer of dismissTimers.values()) { + clearTimeout(timer); + } + dismissTimers.clear(); + remainingMs.clear(); + timerStartedAt.clear(); + toasts = []; + maxVisible = DEFAULT_MAX; + emit(); +} diff --git a/components/toast/src/styles.css b/components/toast/src/styles.css new file mode 100644 index 0000000..3a7cb48 --- /dev/null +++ b/components/toast/src/styles.css @@ -0,0 +1,309 @@ +:root { + --joo-toast-bg: 0 0% 100%; + --joo-toast-fg: 222.2 47.4% 11.2%; + --joo-toast-muted: 215.4 16.3% 46.9%; + --joo-toast-border: 214.3 31.8% 91.4%; + --joo-toast-ring: 214.3 31.8% 91.4%; + --joo-toast-radius: 0.5rem; + --joo-toast-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); + --joo-toast-z: 100; + --joo-toast-width: min(100vw - 2rem, 24rem); + --joo-toast-success: 142.1 70.6% 45.3%; + --joo-toast-error: 0 72.2% 50.6%; + --joo-toast-info: 217.2 91.2% 59.8%; + --joo-toast-warning: 37.7 92.1% 50.2%; + --joo-toast-loading: 192 70% 40%; + --joo-toast-action: 221.2 83.2% 53.3%; + --joo-toast-action-hover: 221.2 83.2% 45%; +} + +.joo-toaster { + pointer-events: none; + position: fixed; + z-index: var(--joo-toast-z); + display: flex; + width: var(--joo-toast-width); + flex-direction: column; + gap: 0.75rem; +} + +.joo-toaster--top-right { + top: 1rem; + right: 1rem; +} + +.joo-toaster--top-center { + top: 1rem; + left: 50%; + transform: translateX(-50%); +} + +.joo-toaster--bottom-right { + right: 1rem; + bottom: 1rem; +} + +.joo-toast { + pointer-events: auto; + position: relative; + display: flex; + width: 100%; + max-width: 24rem; + flex-direction: column; + overflow: hidden; + border: 1px solid hsl(var(--joo-toast-border)); + border-radius: var(--joo-toast-radius); + background: hsl(var(--joo-toast-bg)); + color: hsl(var(--joo-toast-fg)); + box-shadow: var(--joo-toast-shadow); + animation: joo-toast-in 180ms ease-out; +} + +.joo-toast-main { + display: flex; + align-items: flex-start; + gap: 0.75rem; + padding: 1rem; +} + +.joo-toast--condensed .joo-toast-main { + padding: 0.875rem 1rem; +} + +.joo-toast-icon-wrap { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + margin-top: 0.05rem; + color: hsl(var(--joo-toast-muted)); +} + +.joo-toast--success .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-success)); +} + +.joo-toast--error .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-error)); +} + +.joo-toast--info .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-info)); +} + +.joo-toast--warning .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-warning)); +} + +.joo-toast--loading .joo-toast-icon-wrap { + color: hsl(var(--joo-toast-loading)); +} + +.joo-toast-icon { + width: 1.25rem; + height: 1.25rem; +} + +.joo-toast-icon--spin { + animation: joo-toast-spin 0.9s linear infinite; +} + +.joo-toast-body { + min-width: 0; + flex: 1; + display: flex; + flex-direction: column; + gap: 0.125rem; + padding-top: 0.05rem; +} + +.joo-toast-title { + margin: 0; + font-size: 0.875rem; + font-weight: 500; + line-height: 1.25rem; + color: hsl(var(--joo-toast-fg)); +} + +.joo-toast-description { + margin: 0; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.25rem; + color: hsl(var(--joo-toast-muted)); +} + +.joo-toast-dismiss-wrap { + margin: -0.25rem -0.25rem 0 0; +} + +.joo-toast-dismiss { + display: inline-flex; + align-items: center; + justify-content: center; + border: 0; + border-radius: 0.375rem; + background: transparent; + color: hsl(var(--joo-toast-muted)); + cursor: pointer; + padding: 0.375rem; +} + +.joo-toast-dismiss:hover { + color: hsl(var(--joo-toast-fg)); + background: hsl(var(--joo-toast-fg) / 0.05); +} + +.joo-toast-dismiss:focus-visible { + outline: 2px solid hsl(var(--joo-toast-action)); + outline-offset: 2px; +} + +.joo-toast-dismiss-icon { + width: 1.25rem; + height: 1.25rem; +} + +.joo-toast-sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +.joo-toast-actions { + display: flex; + border-top: 1px solid hsl(var(--joo-toast-border)); + background: hsl(var(--joo-toast-bg)); +} + +.joo-toast-actions--split > .joo-toast-action + .joo-toast-action { + border-left: 1px solid hsl(var(--joo-toast-border)); +} + +.joo-toast-action { + flex: 1; + display: inline-flex; + align-items: center; + justify-content: center; + border: 0; + background: transparent; + cursor: pointer; + font: inherit; + font-size: 0.875rem; + font-weight: 500; + line-height: 1.25rem; + padding: 0.75rem 1rem; + text-align: center; +} + +.joo-toast-action--primary { + color: hsl(var(--joo-toast-action)); +} + +.joo-toast-action--primary:hover { + background: hsl(var(--joo-toast-fg) / 0.03); + color: hsl(var(--joo-toast-action-hover)); +} + +.joo-toast-action--secondary { + color: hsl(var(--joo-toast-muted)); +} + +.joo-toast-action--secondary:hover { + background: hsl(var(--joo-toast-fg) / 0.03); + color: hsl(var(--joo-toast-fg)); +} + +.joo-toast-action:focus-visible { + outline: 2px solid hsl(var(--joo-toast-action)); + outline-offset: -2px; + z-index: 1; +} + +.joo-toast-progress { + position: absolute; + left: 0; + bottom: 0; + height: 2px; + width: 100%; + transform-origin: left; + background: currentColor; + opacity: 0.45; + animation-name: joo-toast-progress; + animation-timing-function: linear; + animation-fill-mode: forwards; +} + +.joo-toast--success .joo-toast-progress { + color: hsl(var(--joo-toast-success)); +} + +.joo-toast--error .joo-toast-progress { + color: hsl(var(--joo-toast-error)); +} + +.joo-toast--info .joo-toast-progress { + color: hsl(var(--joo-toast-info)); +} + +.joo-toast--warning .joo-toast-progress { + color: hsl(var(--joo-toast-warning)); +} + +.joo-toast--loading .joo-toast-progress { + color: hsl(var(--joo-toast-loading)); +} + +.joo-toast:hover .joo-toast-progress, +.joo-toast:focus-within .joo-toast-progress { + animation-play-state: paused; +} + +@keyframes joo-toast-in { + from { + opacity: 0; + transform: translateY(-0.5rem) scale(0.98); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +@keyframes joo-toast-progress { + from { + transform: scaleX(1); + } + to { + transform: scaleX(0); + } +} + +@keyframes joo-toast-spin { + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: reduce) { + .joo-toast { + animation: none; + } + + .joo-toast-icon--spin { + animation: none; + } + + .joo-toast-progress { + animation: none; + opacity: 0; + } +} diff --git a/components/toast/src/toast.test.tsx b/components/toast/src/toast.test.tsx new file mode 100644 index 0000000..e70872b --- /dev/null +++ b/components/toast/src/toast.test.tsx @@ -0,0 +1,157 @@ +import { act, cleanup, fireEvent, render, screen } from "@testing-library/react"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { Toaster } from "./components/Toaster"; +import { resetToastsForTests, subscribeToasts, toast } from "./store"; + +beforeEach(() => { + vi.useFakeTimers(); + resetToastsForTests(); +}); + +afterEach(() => { + cleanup(); + resetToastsForTests(); + vi.useRealTimers(); +}); + +describe("toast store", () => { + it("pushes and dismisses success toasts", () => { + let items: { id: string; message: string }[] = []; + const unsubscribe = subscribeToasts((next) => { + items = next; + }); + + toast.success("Crawl started."); + expect(items).toHaveLength(1); + expect(items[0]?.message).toBe("Crawl started."); + + const id = toast.error("Something failed."); + expect(items).toHaveLength(2); + + toast.dismiss(id); + expect(items).toHaveLength(1); + expect(items[0]?.message).toBe("Crawl started."); + + unsubscribe(); + }); + + it("auto-dismisses after duration and keeps errors longer by default", () => { + let items: { message: string }[] = []; + subscribeToasts((next) => { + items = next; + }); + + toast.success("Saved."); + toast.error("Failed."); + + act(() => { + vi.advanceTimersByTime(4_500); + }); + expect(items.map((item) => item.message)).toEqual(["Failed."]); + + act(() => { + vi.advanceTimersByTime(1_500); + }); + expect(items).toHaveLength(0); + }); + + it("replaces toast by id and supports promise flow", async () => { + let items: { id: string; message: string; variant: string }[] = []; + subscribeToasts((next) => { + items = next; + }); + + toast.loading("Working…", { id: "job-1" }); + expect(items[0]?.variant).toBe("loading"); + + toast.success("Done.", { id: "job-1" }); + expect(items).toHaveLength(1); + expect(items[0]?.message).toBe("Done."); + expect(items[0]?.variant).toBe("success"); + + let resolve!: (value: string) => void; + const pending = new Promise((res) => { + resolve = res; + }); + + const resultPromise = toast.promise(pending, { + loading: "Queuing…", + success: (value) => `Queued ${value}`, + error: "Queue failed", + }); + + expect(items.some((item) => item.message === "Queuing…")).toBe(true); + + await act(async () => { + resolve("batch-9"); + await resultPromise; + }); + + expect(items.some((item) => item.message === "Queued batch-9")).toBe(true); + }); + + it("dismissAll clears the stack", () => { + let count = 0; + subscribeToasts((next) => { + count = next.length; + }); + + toast.info("One"); + toast.warning("Two"); + expect(count).toBe(2); + + toast.dismissAll(); + expect(count).toBe(0); + }); +}); + +describe("Toaster", () => { + it("renders Simple title/description and actions-below footer", () => { + const onAction = vi.fn(); + const onSecondary = vi.fn(); + render(); + + act(() => { + toast.success("Anyone with a link can now view this file.", { + title: "Successfully saved!", + action: { label: "Undo", onClick: onAction }, + secondaryAction: { label: "Dismiss", onClick: onSecondary }, + }); + }); + + expect(screen.getByText("Successfully saved!")).toBeTruthy(); + expect(screen.getByText("Anyone with a link can now view this file.")).toBeTruthy(); + + fireEvent.click(screen.getByRole("button", { name: "Undo" })); + expect(onAction).toHaveBeenCalledTimes(1); + expect(screen.queryByText("Successfully saved!")).toBeNull(); + }); + + it("renders secondary footer action", () => { + const onSecondary = vi.fn(); + render(); + + act(() => { + toast.info("Changes are ready to review.", { + title: "Draft saved", + action: { label: "Review", onClick: () => undefined }, + secondaryAction: { label: "Later", onClick: onSecondary }, + }); + }); + + fireEvent.click(screen.getByRole("button", { name: "Later" })); + expect(onSecondary).toHaveBeenCalledTimes(1); + }); + + it("dismiss button removes the toast", () => { + render(); + + act(() => { + toast.info("Hello"); + }); + + fireEvent.click(screen.getByRole("button", { name: "Dismiss notification" })); + expect(screen.queryByText("Hello")).toBeNull(); + }); +}); diff --git a/components/toast/src/types.ts b/components/toast/src/types.ts new file mode 100644 index 0000000..983f5be --- /dev/null +++ b/components/toast/src/types.ts @@ -0,0 +1,49 @@ +export type ToastVariant = "success" | "error" | "info" | "warning" | "loading"; + +export type ToastPosition = "top-right" | "top-center" | "bottom-right"; + +export type ToastAction = { + label: string; + onClick: () => void; +}; + +export type ToastOptions = { + /** Replaces an existing toast with the same id (or sets a stable id). */ + id?: string; + /** Optional heading above the message (Tailwind Simple title). */ + title?: string; + /** + * Auto-dismiss delay in ms. + * Use `0` or `Infinity` for sticky toasts (no auto-dismiss). + */ + durationMs?: number; + /** Primary footer action (shows “actions below” layout). */ + action?: ToastAction; + /** Secondary footer action (split footer with `action`). */ + secondaryAction?: ToastAction; +}; + +export type ToastItem = { + id: string; + message: string; + variant: ToastVariant; + durationMs: number; + title?: string; + action?: ToastAction; + secondaryAction?: ToastAction; + createdAt: number; +}; + +export type ToasterProps = { + /** Viewport placement. Default `top-right`. */ + position?: ToastPosition; + /** Max visible toasts (oldest beyond the cap are dropped). Default `5`. */ + maxVisible?: number; + className?: string; +}; + +export type ToastPromiseMessages = { + loading: string; + success: string | ((data: T) => string); + error: string | ((error: unknown) => string); +}; diff --git a/components/toast/tsconfig.json b/components/toast/tsconfig.json new file mode 100644 index 0000000..974dd00 --- /dev/null +++ b/components/toast/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "isolatedModules": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["src"] +} diff --git a/components/toast/tsup.config.ts b/components/toast/tsup.config.ts new file mode 100644 index 0000000..3f0c75c --- /dev/null +++ b/components/toast/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + dts: true, + sourcemap: true, + clean: true, + external: ["react", "react-dom", "lucide-react"], + treeshake: true, +}); diff --git a/components/toast/vitest.config.ts b/components/toast/vitest.config.ts new file mode 100644 index 0000000..e5d7e16 --- /dev/null +++ b/components/toast/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "jsdom", + setupFiles: [], + }, +}); From c4a5c8a5f4e8531042681189df859b03bd2d9e0f Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:24 -0600 Subject: [PATCH 05/14] feat(layout): add FooterBar and shared ShellBar chrome Share HeaderBar search/nav/actions chrome with FooterBar; extract SearchForm and ShellBar helpers. --- components/layout/AGENTS.md | 4 +- components/layout/CHANGELOG.md | 12 + components/layout/README.md | 28 +- components/layout/dist/index.d.ts | 18 +- components/layout/dist/index.js | 209 ++++++++++----- components/layout/dist/index.js.map | 2 +- components/layout/dist/styles.css | 89 ++++++- components/layout/package.json | 5 +- components/layout/src/AppShell.test.tsx | 66 ++++- components/layout/src/components/AppShell.tsx | 6 +- .../layout/src/components/FooterBar.tsx | 15 ++ .../layout/src/components/HeaderBar.tsx | 241 +---------------- components/layout/src/components/NavMenu.tsx | 43 ++- .../layout/src/components/SearchForm.tsx | 42 +++ components/layout/src/components/ShellBar.tsx | 249 ++++++++++++++++++ components/layout/src/index.ts | 2 + components/layout/src/styles.css | 89 ++++++- components/layout/src/types.ts | 8 + 18 files changed, 803 insertions(+), 325 deletions(-) create mode 100644 components/layout/CHANGELOG.md create mode 100644 components/layout/src/components/FooterBar.tsx create mode 100644 components/layout/src/components/SearchForm.tsx create mode 100644 components/layout/src/components/ShellBar.tsx diff --git a/components/layout/AGENTS.md b/components/layout/AGENTS.md index a94b287..7ccc257 100644 --- a/components/layout/AGENTS.md +++ b/components/layout/AGENTS.md @@ -11,6 +11,7 @@ ## Header API - **Primary:** `AppShell.HeaderBar` — fixed roles (brand / nav+dropdowns / search / actions+user). +- **Primary:** `AppShell.FooterBar` — shared ShellBar chrome; optional brand; menus open upward. - Low-level slots remain for escape hatches. - **No** light/dark theme toggle in this package. @@ -32,5 +33,6 @@ After user-visible changes: update `apps/demo` and run `npm run demo:typecheck`. ## Docs -- User guide: `docs/02-user-guide/03-react-layout.md` +- User guide: `docs/02-user-guide/03-react-layout.md` (consumer API — do not send humans to `src/`) +- Package README: `components/layout/README.md` - Root policy: `AGENTS.md` diff --git a/components/layout/CHANGELOG.md b/components/layout/CHANGELOG.md new file mode 100644 index 0000000..0c6a73b --- /dev/null +++ b/components/layout/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +## [Unreleased] + +### Added + +- `AppShell.FooterBar` — shared `ShellBar` chrome with `HeaderBar` (nav / search / actions / user); optional `brand`; menus open upward +- Sidebar footer rail always rendered at `--joo-layout-bottom-rail-height` (optional `footer` children) + +## 0.1.0 + +- Initial AppShell release with HeaderBar, Banner, Sidebar, Main / MainFrame. diff --git a/components/layout/README.md b/components/layout/README.md index 5417587..e629086 100644 --- a/components/layout/README.md +++ b/components/layout/README.md @@ -7,9 +7,11 @@ Master app shell for React — XFlickr-style grid with aligned brand column and ## Install ```bash -npm install @jooservices/react-layout lucide-react +pnpm add "github:jooservices/react#v1.0.0&path:components/layout" ``` +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). + ## Setup ```tsx @@ -20,7 +22,7 @@ import "@jooservices/react-layout/styles.css"; ```tsx import { AppShell, type AppShellLinkComponent } from "@jooservices/react-layout"; -import { Home, Settings2, Users } from "lucide-react"; +import { Boxes, Home, Settings2, Users } from "lucide-react"; import { Link } from "react-router-dom"; const RouterLink: AppShellLinkComponent = ({ href, className, children, onClick }) => ( @@ -64,6 +66,18 @@ const RouterLink: AppShellLinkComponent = ({ href, className, children, onClick footer}>{/* nav links */} {/* page content / Outlet */} + ; @@ -71,6 +85,12 @@ const RouterLink: AppShellLinkComponent = ({ href, className, children, onClick Nav / action / user menu items accept optional `icon?: ReactNode` (typically a Lucide element). -Low-level slots (`Brand`, `HeaderNav`, `HeaderCenter`, …) remain for rare custom composition; prefer `HeaderBar` for JOO apps. +## FooterBar + +`AppShell.FooterBar` shares `ShellBar` chrome with `HeaderBar` (nav / search / actions / user). Dropdowns open **up**. `brand` is optional — omit it when the footer sits under `Main` (no logo column). + +Sidebar always renders a matching bottom rail (`footer` children optional). + +Low-level slots (`Brand`, `HeaderNav`, `HeaderCenter`, …) remain for rare custom composition; prefer `HeaderBar` / `FooterBar` for JOO apps. -Pair with [`@jooservices/react-content`](https://www.npmjs.com/package/@jooservices/react-content) inside `MainFrame`. +Pair with [`@jooservices/react-content`](`@jooservices/react-content` (git install)) inside `MainFrame`. diff --git a/components/layout/dist/index.d.ts b/components/layout/dist/index.d.ts index 79a32c0..02285d2 100644 --- a/components/layout/dist/index.d.ts +++ b/components/layout/dist/index.d.ts @@ -52,6 +52,13 @@ type AppShellHeaderBarProps = { linkComponent?: AppShellLinkComponent; className?: string; }; +/** + * Same chrome as HeaderBar (nav / search / actions / user), menus open up. + * `brand` is optional — omit it when the footer sits under Main (no logo column). + */ +type AppShellFooterBarProps = Omit & { + brand?: AppShellHeaderBarBrand; +}; type AppShellProps = { children: ReactNode; /** CSS length for brand column and sidebar (default 16rem / w-64) */ @@ -114,7 +121,13 @@ type AppShellMainFrameProps = { declare function useAppShell(): AppShellContextValue; -declare function AppShellHeaderBar({ brand, nav, search, actions, user, guest, linkComponent: LinkComponent, className, }: AppShellHeaderBarProps): react.JSX.Element; +declare function AppShellHeaderBar(props: AppShellHeaderBarProps): react.JSX.Element; + +/** + * Exact HeaderBar chrome at the bottom of Main (brand | nav | search | actions + user). + * Dropdowns open upward. + */ +declare function AppShellFooterBar({ className, ...props }: AppShellFooterBarProps): react.JSX.Element; declare function AppShellRoot({ children, sidebarWidth, className }: AppShellProps): react.JSX.Element; declare function AppShellBanner({ children, className }: AppShellBannerProps): react.JSX.Element; @@ -145,7 +158,8 @@ type AppShellCompound = typeof AppShellRoot & { Sidebar: typeof AppShellSidebar; Main: typeof AppShellMain; MainFrame: typeof AppShellMainFrame; + FooterBar: typeof AppShellFooterBar; }; declare const AppShell: AppShellCompound; -export { AppShell, AppShellBanner, type AppShellBannerProps, AppShellBody, type AppShellBodyProps, AppShellBrand, type AppShellBrandProps, type AppShellContextValue, AppShellHeader, AppShellHeaderActions, type AppShellHeaderActionsProps, AppShellHeaderBar, type AppShellHeaderBarBrand, type AppShellHeaderBarProps, type AppShellHeaderBarSearch, type AppShellHeaderBarUser, AppShellHeaderCenter, type AppShellHeaderCenterProps, AppShellHeaderMain, type AppShellHeaderMainProps, AppShellHeaderMobile, type AppShellHeaderMobileProps, AppShellHeaderNav, type AppShellHeaderNavProps, type AppShellHeaderProps, AppShellHeaderRow, type AppShellHeaderRowProps, type AppShellLinkComponent, AppShellMain, AppShellMainFrame, type AppShellMainFrameProps, type AppShellMainProps, type AppShellNavItem, type AppShellProps, AppShellSidebar, type AppShellSidebarProps, useAppShell }; +export { AppShell, AppShellBanner, type AppShellBannerProps, AppShellBody, type AppShellBodyProps, AppShellBrand, type AppShellBrandProps, type AppShellContextValue, AppShellFooterBar, type AppShellFooterBarProps, AppShellHeader, AppShellHeaderActions, type AppShellHeaderActionsProps, AppShellHeaderBar, type AppShellHeaderBarBrand, type AppShellHeaderBarProps, type AppShellHeaderBarSearch, type AppShellHeaderBarUser, AppShellHeaderCenter, type AppShellHeaderCenterProps, AppShellHeaderMain, type AppShellHeaderMainProps, AppShellHeaderMobile, type AppShellHeaderMobileProps, AppShellHeaderNav, type AppShellHeaderNavProps, type AppShellHeaderProps, AppShellHeaderRow, type AppShellHeaderRowProps, type AppShellLinkComponent, AppShellMain, AppShellMainFrame, type AppShellMainFrameProps, type AppShellMainProps, type AppShellNavItem, type AppShellProps, AppShellSidebar, type AppShellSidebarProps, useAppShell }; diff --git a/components/layout/dist/index.js b/components/layout/dist/index.js index da68945..ab58aee 100644 --- a/components/layout/dist/index.js +++ b/components/layout/dist/index.js @@ -28,12 +28,18 @@ function itemKey(item, index) { return item.id ?? `${item.label}-${item.href ?? index}`; } function NavItemLabel({ label, icon }) { - return /* @__PURE__ */ jsxs(Fragment, { children: [ + return /* @__PURE__ */ jsxs("span", { className: "joo-layout-nav-label", children: [ icon ? /* @__PURE__ */ jsx("span", { className: "joo-layout-nav-icon-wrap", children: icon }) : null, - /* @__PURE__ */ jsx("span", { children: label }) + /* @__PURE__ */ jsx("span", { className: "joo-layout-nav-label-text", children: label }) ] }); } -function NavItemControl({ item, LinkComponent, variant = "nav" }) { +function NavItemControl({ + item, + LinkComponent, + variant = "nav", + menuPlacement = "down", + menuAlign = "start" +}) { const hasChildren = Boolean(item.children?.length); const [open, setOpen] = useState(false); const rootRef = useRef(null); @@ -77,19 +83,41 @@ function NavItemControl({ item, LinkComponent, variant = "nav" }) { onClick: () => setOpen((current) => !current), children: [ /* @__PURE__ */ jsx(NavItemLabel, { label: item.label, icon: item.icon }), - /* @__PURE__ */ jsx(ChevronDown, { className: cn("joo-layout-nav-chevron", open && "joo-layout-nav-chevron--open") }) + /* @__PURE__ */ jsx( + ChevronDown, + { + "aria-hidden": true, + className: cn( + "joo-layout-nav-chevron", + menuPlacement === "up" && "joo-layout-nav-chevron--up", + open && "joo-layout-nav-chevron--open" + ) + } + ) ] } ), - open ? /* @__PURE__ */ jsx("div", { id: menuId, role: "menu", className: "joo-layout-nav-menu", children: item.children.map((child, index) => /* @__PURE__ */ jsx( - NavMenuRow, + open ? /* @__PURE__ */ jsx( + "div", { - item: child, - LinkComponent, - onNavigate: () => setOpen(false) - }, - itemKey(child, index) - )) }) : null + id: menuId, + role: "menu", + className: cn( + "joo-layout-nav-menu", + menuPlacement === "up" && "joo-layout-nav-menu--up", + menuAlign === "end" && "joo-layout-nav-menu--end" + ), + children: item.children.map((child, index) => /* @__PURE__ */ jsx( + NavMenuRow, + { + item: child, + LinkComponent, + onNavigate: () => setOpen(false) + }, + itemKey(child, index) + )) + } + ) : null ] }); } if (item.href) { @@ -142,6 +170,8 @@ function NavItemList({ items, LinkComponent = DefaultLink, variant = "nav", + menuPlacement = "down", + menuAlign = "start", className }) { return /* @__PURE__ */ jsx("div", { className: cn("joo-layout-nav-list", className), children: items.map((item, index) => /* @__PURE__ */ jsx( @@ -149,7 +179,9 @@ function NavItemList({ { item, LinkComponent, - variant + variant, + menuPlacement, + menuAlign }, itemKey(item, index) )) }); @@ -182,11 +214,12 @@ function SearchForm({ ) ] }); } -function UserMenu({ +function ShellBarUserMenu({ name, avatarUrl, items, - LinkComponent + LinkComponent, + menuPlacement = "down" }) { const [open, setOpen] = useState(false); const rootRef = useRef(null); @@ -226,50 +259,72 @@ function UserMenu({ children: [ avatarUrl ? /* @__PURE__ */ jsx("img", { src: avatarUrl, alt: "", className: "joo-layout-user-avatar" }) : /* @__PURE__ */ jsx("span", { className: "joo-layout-user-avatar joo-layout-user-avatar--fallback", children: /* @__PURE__ */ jsx(User, { className: "joo-layout-user-avatar-icon", "aria-hidden": true }) }), /* @__PURE__ */ jsx("span", { className: "joo-layout-user-name", children: name }), - /* @__PURE__ */ jsx(ChevronDown, { className: cn("joo-layout-nav-chevron", open && "joo-layout-nav-chevron--open") }) + /* @__PURE__ */ jsx( + ChevronDown, + { + "aria-hidden": true, + className: cn( + "joo-layout-nav-chevron", + menuPlacement === "up" && "joo-layout-nav-chevron--up", + open && "joo-layout-nav-chevron--open" + ) + } + ) ] } ), - open ? /* @__PURE__ */ jsx("div", { id: menuId, role: "menu", className: "joo-layout-nav-menu joo-layout-nav-menu--end", children: items.map((item, index) => { - const key = item.id ?? `${item.label}-${index}`; - const className = cn( - "joo-layout-nav-menu-item", - item.active && "joo-layout-nav-menu-item--active" - ); - const content = /* @__PURE__ */ jsx(NavItemLabel, { label: item.label, icon: item.icon }); - if (item.href) { - return /* @__PURE__ */ jsx( - LinkComponent, - { - href: item.href, - className, - onClick: () => { - item.onClick?.(); - setOpen(false); + open ? /* @__PURE__ */ jsx( + "div", + { + id: menuId, + role: "menu", + className: cn( + "joo-layout-nav-menu", + "joo-layout-nav-menu--end", + menuPlacement === "up" && "joo-layout-nav-menu--up" + ), + children: items.map((item, index) => { + const key = item.id ?? `${item.label}-${index}`; + const className = cn( + "joo-layout-nav-menu-item", + item.active && "joo-layout-nav-menu-item--active" + ); + const content = /* @__PURE__ */ jsx(NavItemLabel, { label: item.label, icon: item.icon }); + if (item.href) { + return /* @__PURE__ */ jsx( + LinkComponent, + { + href: item.href, + className, + onClick: () => { + item.onClick?.(); + setOpen(false); + }, + children: content + }, + key + ); + } + return /* @__PURE__ */ jsx( + "button", + { + type: "button", + role: "menuitem", + className, + onClick: () => { + item.onClick?.(); + setOpen(false); + }, + children: content }, - children: content - }, - key - ); + key + ); + }) } - return /* @__PURE__ */ jsx( - "button", - { - type: "button", - role: "menuitem", - className, - onClick: () => { - item.onClick?.(); - setOpen(false); - }, - children: content - }, - key - ); - }) }) : null + ) : null ] }); } -function AppShellHeaderBar({ +function ShellBar({ brand, nav, search, @@ -277,19 +332,28 @@ function AppShellHeaderBar({ user, guest, linkComponent: LinkComponent = DefaultLink, - className + className, + menuPlacement = "down" }) { const searchId = useId(); const mobileSearchId = useId(); - const brandContent = /* @__PURE__ */ jsxs("span", { className: "joo-layout-brand-link-inner", children: [ + const brandContent = brand ? /* @__PURE__ */ jsxs("span", { className: "joo-layout-brand-link-inner", children: [ brand.logo, brand.title ? /* @__PURE__ */ jsx("span", { className: "joo-layout-brand-title", children: brand.title }) : null - ] }); - return /* @__PURE__ */ jsxs(AppShellHeader, { className, children: [ + ] }) : null; + return /* @__PURE__ */ jsxs("div", { className, children: [ /* @__PURE__ */ jsxs(AppShellHeaderRow, { children: [ - /* @__PURE__ */ jsx(AppShellBrand, { children: brand.href ? /* @__PURE__ */ jsx(LinkComponent, { href: brand.href, className: "joo-layout-brand-link", children: brandContent }) : brandContent }), + brand && brandContent ? /* @__PURE__ */ jsx(AppShellBrand, { children: brand.href ? /* @__PURE__ */ jsx(LinkComponent, { href: brand.href, className: "joo-layout-brand-link", children: brandContent }) : brandContent }) : null, /* @__PURE__ */ jsxs(AppShellHeaderMain, { children: [ - /* @__PURE__ */ jsx(AppShellHeaderNav, { children: /* @__PURE__ */ jsx(NavItemList, { items: nav, LinkComponent, variant: "nav" }) }), + /* @__PURE__ */ jsx(AppShellHeaderNav, { children: /* @__PURE__ */ jsx( + NavItemList, + { + items: nav, + LinkComponent, + variant: "nav", + menuPlacement + } + ) }), /* @__PURE__ */ jsx(AppShellHeaderCenter, { children: /* @__PURE__ */ jsx( SearchForm, { @@ -301,14 +365,24 @@ function AppShellHeaderBar({ } ) }), /* @__PURE__ */ jsxs(AppShellHeaderActions, { children: [ - actions?.length ? /* @__PURE__ */ jsx(NavItemList, { items: actions, LinkComponent, variant: "action" }) : null, + actions?.length ? /* @__PURE__ */ jsx( + NavItemList, + { + items: actions, + LinkComponent, + variant: "action", + menuPlacement, + menuAlign: "end" + } + ) : null, user ? /* @__PURE__ */ jsx( - UserMenu, + ShellBarUserMenu, { name: user.name, avatarUrl: user.avatarUrl, items: user.items, - LinkComponent + LinkComponent, + menuPlacement } ) : guest ] }) @@ -326,6 +400,12 @@ function AppShellHeaderBar({ ) }) ] }); } +function AppShellHeaderBar(props) { + return /* @__PURE__ */ jsx(AppShellHeader, { className: props.className, children: /* @__PURE__ */ jsx(ShellBar, { ...props, menuPlacement: "down", className: void 0 }) }); +} +function AppShellFooterBar({ className, ...props }) { + return /* @__PURE__ */ jsx("footer", { className: cn("joo-layout-footer-bar", className), "aria-label": "Application status", children: /* @__PURE__ */ jsx(ShellBar, { ...props, menuPlacement: "up" }) }); +} function shellStyle(sidebarWidth) { return { ["--joo-layout-sidebar-width"]: sidebarWidth @@ -383,7 +463,7 @@ function AppShellSidebar({ children, className, footer }) { const { mobileOpen, setMobileOpen } = useAppShell(); const sidebarInner = /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("div", { className: "joo-layout-sidebar-scroll", children }), - footer ? /* @__PURE__ */ jsx("div", { className: "joo-layout-sidebar-footer", children: footer }) : null + /* @__PURE__ */ jsx("div", { className: "joo-layout-sidebar-footer", children: footer }) ] }); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("aside", { className: cn("joo-layout-sidebar", className), children: sidebarInner }), @@ -433,9 +513,10 @@ var AppShell = Object.assign(AppShellRoot, { Body: AppShellBody, Sidebar: AppShellSidebar, Main: AppShellMain, - MainFrame: AppShellMainFrame + MainFrame: AppShellMainFrame, + FooterBar: AppShellFooterBar }); -export { AppShell, AppShellBanner, AppShellBody, AppShellBrand, AppShellHeader, AppShellHeaderActions, AppShellHeaderBar, AppShellHeaderCenter, AppShellHeaderMain, AppShellHeaderMobile, AppShellHeaderNav, AppShellHeaderRow, AppShellMain, AppShellMainFrame, AppShellSidebar, useAppShell }; +export { AppShell, AppShellBanner, AppShellBody, AppShellBrand, AppShellFooterBar, AppShellHeader, AppShellHeaderActions, AppShellHeaderBar, AppShellHeaderCenter, AppShellHeaderMain, AppShellHeaderMobile, AppShellHeaderNav, AppShellHeaderRow, AppShellMain, AppShellMainFrame, AppShellSidebar, useAppShell }; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/components/layout/dist/index.js.map b/components/layout/dist/index.js.map index 8deb5e1..93fa9f7 100644 --- a/components/layout/dist/index.js.map +++ b/components/layout/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/lib/cn.ts","../src/context.tsx","../src/components/NavMenu.tsx","../src/components/HeaderBar.tsx","../src/components/AppShell.tsx"],"names":["jsxs","jsx","useState","useRef","useId","useEffect","ChevronDown","Fragment"],"mappings":";;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACDO,IAAM,eAAA,GAAkB,cAA2C,IAAI,CAAA;AAEvE,SAAS,WAAA,GAAc;AAC5B,EAAA,MAAM,OAAA,GAAU,WAAW,eAAe,CAAA;AAC1C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,EACzE;AACA,EAAA,OAAO,OAAA;AACT;ACNA,SAAS,WAAA,CAAY;AAAA,EACnB,IAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,uBACE,GAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAY,SAAA,EAAsB,SAClC,QAAA,EACH,CAAA;AAEJ;AAEA,SAAS,OAAA,CAAQ,MAAuB,KAAA,EAAuB;AAC7D,EAAA,OAAO,IAAA,CAAK,MAAM,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,QAAQ,KAAK,CAAA,CAAA;AACvD;AAEO,SAAS,YAAA,CAAa,EAAE,KAAA,EAAO,IAAA,EAAK,EAAwC;AACjF,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,IAAA,mBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA4B,gBAAK,CAAA,GAAU,IAAA;AAAA,oBACnE,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM;AAAA,GAAA,EACf,CAAA;AAEJ;AAQO,SAAS,eAAe,EAAE,IAAA,EAAM,aAAA,EAAe,OAAA,GAAU,OAAM,EAAwB;AAC5F,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,IAAA,CAAK,QAAA,EAAU,MAAM,CAAA;AACjD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,SAAS,KAAA,EAAM;AAErB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA;AAAA,IACF;AAEA,IAAA,SAAS,cAAc,KAAA,EAAmB;AACxC,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAC,OAAA,CAAQ,QAAQ,QAAA,CAAS,KAAA,CAAM,MAAc,CAAA,EAAG;AACtE,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF;AAEA,IAAA,SAAS,UAAU,KAAA,EAAsB;AACvC,MAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC1B,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,aAAa,CAAA;AACpD,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC9C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,aAAa,CAAA;AACvD,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAAA,IACnD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,YAAA,GAAe,EAAA;AAAA,IACnB,qBAAA;AAAA,IACA,YAAY,QAAA,IAAY,6BAAA;AAAA,IACxB,KAAK,MAAA,IAAU;AAAA,GACjB;AAEA,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EAA0B,KAAK,OAAA,EAC5C,QAAA,EAAA;AAAA,sBAAA,IAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAW,YAAA;AAAA,UACX,eAAA,EAAe,IAAA;AAAA,UACf,eAAA,EAAc,MAAA;AAAA,UACd,eAAA,EAAe,MAAA;AAAA,UACf,SAAS,MAAM,OAAA,CAAQ,CAAC,OAAA,KAAY,CAAC,OAAO,CAAA;AAAA,UAE5C,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,gBAAa,KAAA,EAAO,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,KAAK,IAAA,EAAM,CAAA;AAAA,gCACjD,WAAA,EAAA,EAAY,SAAA,EAAW,GAAG,wBAAA,EAA0B,IAAA,IAAQ,8BAA8B,CAAA,EAAG;AAAA;AAAA;AAAA,OAChG;AAAA,MACC,IAAA,mBACC,GAAA,CAAC,KAAA,EAAA,EAAI,EAAA,EAAI,QAAQ,IAAA,EAAK,MAAA,EAAO,SAAA,EAAU,qBAAA,EACpC,QAAA,EAAA,IAAA,CAAK,QAAA,CAAU,GAAA,CAAI,CAAC,OAAO,KAAA,qBAC1B,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UAEC,IAAA,EAAM,KAAA;AAAA,UACN,aAAA;AAAA,UACA,UAAA,EAAY,MAAM,OAAA,CAAQ,KAAK;AAAA,SAAA;AAAA,QAH1B,OAAA,CAAQ,OAAO,KAAK;AAAA,OAK5B,GACH,CAAA,GACE;AAAA,KAAA,EACN,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,KAAK,IAAA,EAAM;AACb,IAAA,uBACE,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,SAAA,EAAW,YAAA;AAAA,QACX,SAAS,MAAM;AACb,UAAA,IAAA,CAAK,OAAA,IAAU;AAAA,QACjB,CAAA;AAAA,QAEA,8BAAC,YAAA,EAAA,EAAa,KAAA,EAAO,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,IAAA,EAAM;AAAA;AAAA,KACpD;AAAA,EAEJ;AAEA,EAAA,2BACG,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,SAAA,EAAW,cAAc,OAAA,EAAS,IAAA,CAAK,OAAA,EAC3D,QAAA,kBAAA,GAAA,CAAC,gBAAa,KAAA,EAAO,IAAA,CAAK,OAAO,IAAA,EAAM,IAAA,CAAK,MAAM,CAAA,EACpD,CAAA;AAEJ;AAQA,SAAS,UAAA,CAAW,EAAE,IAAA,EAAM,aAAA,EAAe,YAAW,EAAoB;AACxE,EAAA,MAAM,SAAA,GAAY,EAAA,CAAG,0BAAA,EAA4B,IAAA,CAAK,UAAU,kCAAkC,CAAA;AAClG,EAAA,MAAM,OAAA,uBAAW,YAAA,EAAA,EAAa,KAAA,EAAO,KAAK,KAAA,EAAO,IAAA,EAAM,KAAK,IAAA,EAAM,CAAA;AAElE,EAAA,IAAI,KAAK,IAAA,EAAM;AACb,IAAA,uBACE,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,SAAA;AAAA,QACA,SAAS,MAAM;AACb,UAAA,IAAA,CAAK,OAAA,IAAU;AACf,UAAA,UAAA,EAAW;AAAA,QACb,CAAA;AAAA,QAEC,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,IAAA,EAAK,UAAA;AAAA,MACL,SAAA;AAAA,MACA,SAAS,MAAM;AACb,QAAA,IAAA,CAAK,OAAA,IAAU;AACf,QAAA,UAAA,EAAW;AAAA,MACb,CAAA;AAAA,MAEC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ;AASO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EACA,aAAA,GAAgB,WAAA;AAAA,EAChB,OAAA,GAAU,KAAA;AAAA,EACV;AACF,CAAA,EAAqB;AACnB,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EAChD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,qBAChB,GAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MAEC,IAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KAAA;AAAA,IAHK,OAAA,CAAQ,MAAM,KAAK;AAAA,GAK3B,CAAA,EACH,CAAA;AAEJ;ACnLA,SAAS,UAAA,CAAW;AAAA,EAClB,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA,GAAc,cAAA;AAAA,EACd,SAAA;AAAA,EACA;AACF,CAAA,EAOG;AACD,EAAA,SAAS,aAAa,KAAA,EAAmC;AACvD,IAAA,KAAA,CAAM,cAAA,EAAe;AACrB,IAAA,QAAA,GAAW,KAAK,CAAA;AAAA,EAClB;AAEA,EAAA,uBACEA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,mBAAA,EAAqB,SAAS,CAAA,EAAG,QAAA,EAAU,YAAA,EAAc,IAAA,EAAK,QAAA,EAChF,QAAA,EAAA;AAAA,oBAAAC,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,wBAAA,EAAyB,eAAW,IAAA,EAAC,CAAA;AAAA,oBACvDA,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,KAAA;AAAA,QACA,UAAU,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,QAChD,WAAA;AAAA,QACA,SAAA,EAAU,yBAAA;AAAA,QACV,YAAA,EAAY;AAAA;AAAA;AACd,GAAA,EACF,CAAA;AAEJ;AAEA,SAAS,QAAA,CAAS;AAAA,EAChB,IAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIC,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,OAAA,GAAUC,OAAuB,IAAI,CAAA;AAC3C,EAAA,MAAM,SAASC,KAAAA,EAAM;AAErB,EAAAC,UAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA;AAAA,IACF;AAEA,IAAA,SAAS,cAAc,KAAA,EAAmB;AACxC,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAC,OAAA,CAAQ,QAAQ,QAAA,CAAS,KAAA,CAAM,MAAc,CAAA,EAAG;AACtE,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF;AAEA,IAAA,SAAS,UAAU,KAAA,EAAsB;AACvC,MAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC1B,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,aAAa,CAAA;AACpD,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC9C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,aAAa,CAAA;AACvD,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAAA,IACnD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,uBACEL,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EAAkB,KAAK,OAAA,EACpC,QAAA,EAAA;AAAA,oBAAAA,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,yBAAA;AAAA,QACV,eAAA,EAAe,IAAA;AAAA,QACf,eAAA,EAAc,MAAA;AAAA,QACd,eAAA,EAAe,MAAA;AAAA,QACf,YAAA,EAAY,GAAG,IAAI,CAAA,aAAA,CAAA;AAAA,QACnB,SAAS,MAAM,OAAA,CAAQ,CAAC,OAAA,KAAY,CAAC,OAAO,CAAA;AAAA,QAE3C,QAAA,EAAA;AAAA,UAAA,SAAA,mBACCC,IAAC,KAAA,EAAA,EAAI,GAAA,EAAK,WAAW,GAAA,EAAI,EAAA,EAAG,SAAA,EAAU,wBAAA,EAAyB,CAAA,mBAE/DA,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2DACd,QAAA,kBAAAA,GAAAA,CAAC,QAAK,SAAA,EAAU,6BAAA,EAA8B,aAAA,EAAW,IAAA,EAAC,CAAA,EAC5D,CAAA;AAAA,0BAEFA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAwB,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,0BAC7CA,IAACK,WAAAA,EAAA,EAAY,WAAW,EAAA,CAAG,wBAAA,EAA0B,IAAA,IAAQ,8BAA8B,CAAA,EAAG;AAAA;AAAA;AAAA,KAChG;AAAA,IACC,IAAA,mBACCL,GAAAA,CAAC,KAAA,EAAA,EAAI,IAAI,MAAA,EAAQ,IAAA,EAAK,MAAA,EAAO,SAAA,EAAU,8CAAA,EACpC,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AAC1B,MAAA,MAAM,MAAM,IAAA,CAAK,EAAA,IAAM,GAAG,IAAA,CAAK,KAAK,IAAI,KAAK,CAAA,CAAA;AAC7C,MAAA,MAAM,SAAA,GAAY,EAAA;AAAA,QAChB,0BAAA;AAAA,QACA,KAAK,MAAA,IAAU;AAAA,OACjB;AAEA,MAAA,MAAM,OAAA,mBAAUA,GAAAA,CAAC,YAAA,EAAA,EAAa,OAAO,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,CAAA;AAElE,MAAA,IAAI,KAAK,IAAA,EAAM;AACb,QAAA,uBACEA,GAAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YAEC,MAAM,IAAA,CAAK,IAAA;AAAA,YACX,SAAA;AAAA,YACA,SAAS,MAAM;AACb,cAAA,IAAA,CAAK,OAAA,IAAU;AACf,cAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,YACf,CAAA;AAAA,YAEC,QAAA,EAAA;AAAA,WAAA;AAAA,UARI;AAAA,SASP;AAAA,MAEJ;AAEA,MAAA,uBACEA,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UAEC,IAAA,EAAK,QAAA;AAAA,UACL,IAAA,EAAK,UAAA;AAAA,UACL,SAAA;AAAA,UACA,SAAS,MAAM;AACb,YAAA,IAAA,CAAK,OAAA,IAAU;AACf,YAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,UACf,CAAA;AAAA,UAEC,QAAA,EAAA;AAAA,SAAA;AAAA,QATI;AAAA,OAUP;AAAA,IAEJ,CAAC,GACH,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAEO,SAAS,iBAAA,CAAkB;AAAA,EAChC,KAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,eAAe,aAAA,GAAgB,WAAA;AAAA,EAC/B;AACF,CAAA,EAA2B;AACzB,EAAA,MAAM,WAAWG,KAAAA,EAAM;AACvB,EAAA,MAAM,iBAAiBA,KAAAA,EAAM;AAE7B,EAAA,MAAM,YAAA,mBACJJ,IAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,6BAAA,EACb,QAAA,EAAA;AAAA,IAAA,KAAA,CAAM,IAAA;AAAA,IACN,KAAA,CAAM,wBAAQC,GAAAA,CAAC,UAAK,SAAA,EAAU,wBAAA,EAA0B,QAAA,EAAA,KAAA,CAAM,KAAA,EAAM,CAAA,GAAU;AAAA,GAAA,EACjF,CAAA;AAGF,EAAA,uBACED,IAAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EACd,QAAA,EAAA;AAAA,oBAAAA,KAAC,iBAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAC,GAAAA,CAAC,aAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,IAAA,mBACLA,GAAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAM,KAAA,CAAM,IAAA,EAAM,SAAA,EAAU,uBAAA,EACxC,QAAA,EAAA,YAAA,EACH,IAEA,YAAA,EAEJ,CAAA;AAAA,sBAEAD,KAAC,kBAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAAC,GAAAA,CAAC,iBAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,WAAA,EAAA,EAAY,OAAO,GAAA,EAAK,aAAA,EAA8B,OAAA,EAAQ,KAAA,EAAM,CAAA,EACvE,CAAA;AAAA,wBAEAA,GAAAA,CAAC,oBAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,EAAA,EAAI,QAAA;AAAA,YACJ,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,UAAU,MAAA,CAAO,QAAA;AAAA,YACjB,UAAU,MAAA,CAAO,QAAA;AAAA,YACjB,aAAa,MAAA,CAAO;AAAA;AAAA,SACtB,EACF,CAAA;AAAA,wBAEAD,KAAC,qBAAA,EAAA,EACE,QAAA,EAAA;AAAA,UAAA,OAAA,EAAS,MAAA,mBACRC,GAAAA,CAAC,WAAA,EAAA,EAAY,OAAO,OAAA,EAAS,aAAA,EAA8B,OAAA,EAAQ,QAAA,EAAS,CAAA,GAC1E,IAAA;AAAA,UACH,uBACCA,GAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,MAAM,IAAA,CAAK,IAAA;AAAA,cACX,WAAW,IAAA,CAAK,SAAA;AAAA,cAChB,OAAO,IAAA,CAAK,KAAA;AAAA,cACZ;AAAA;AAAA,WACF,GAEA;AAAA,SAAA,EAEJ;AAAA,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,oBAEAA,GAAAA,CAAC,oBAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,EAAA,EAAI,cAAA;AAAA,QACJ,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,UAAU,MAAA,CAAO,QAAA;AAAA,QACjB,aAAa,MAAA,CAAO;AAAA;AAAA,KACtB,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;ACrNA,SAAS,WAAW,YAAA,EAAqC;AACvD,EAAA,OAAO;AAAA,IACL,CAAC,4BAAsC,GAAG;AAAA,GAC5C;AACF;AAEO,SAAS,aAAa,EAAE,QAAA,EAAU,YAAA,GAAe,OAAA,EAAS,WAAU,EAAkB;AAC3F,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIC,SAAS,KAAK,CAAA;AAElD,EAAA,uBACED,GAAAA,CAAC,eAAA,CAAgB,QAAA,EAAhB,EAAyB,OAAO,EAAE,UAAA,EAAY,aAAA,EAAe,YAAA,EAAa,EACzE,QAAA,kBAAAA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,SAAS,CAAA,EAAG,OAAO,UAAA,CAAW,YAAY,CAAA,EAC7E,QAAA,EACH,CAAA,EACF,CAAA;AAEJ;AAEO,SAAS,cAAA,CAAe,EAAE,QAAA,EAAU,SAAA,EAAU,EAAwB;AAC3E,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,mBAAA,EAAqB,SAAS,GAAI,QAAA,EAAS,CAAA;AACvE;AAEO,SAAS,cAAA,CAAe,EAAE,QAAA,EAAU,SAAA,EAAU,EAAwB;AAC3E,EAAA,uBACEA,GAAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,WAAW,EAAA,CAAG,mBAAA,EAAqB,SAAS,CAAA,EAC/D,QAAA,EACH,CAAA;AAEJ;AAEO,SAAS,iBAAA,CAAkB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA2B;AACjF,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,uBAAA,EAAyB,SAAS,GAAI,QAAA,EAAS,CAAA;AAC3E;AAEO,SAAS,aAAA,CAAc,EAAE,QAAA,EAAU,SAAA,EAAU,EAAuB;AACzE,EAAA,MAAM,EAAE,UAAA,EAAY,aAAA,EAAc,GAAI,WAAA,EAAY;AAElD,EAAA,uBACED,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,kBAAA,EAAoB,SAAS,CAAA,EAC9C,QAAA,EAAA;AAAA,oBAAAC,GAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,0BAAA;AAAA,QACV,OAAA,EAAS,MAAM,aAAA,CAAc,CAAC,UAAU,CAAA;AAAA,QACxC,eAAA,EAAe,UAAA;AAAA,QACf,YAAA,EAAY,aAAa,kBAAA,GAAqB,iBAAA;AAAA,QAE7C,QAAA,EAAA,UAAA,mBAAaA,GAAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,iBAAA,EAAkB,CAAA,mBAAKA,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,iBAAA,EAAkB;AAAA;AAAA,KACtF;AAAA,oBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAA4B,QAAA,EAAS;AAAA,GAAA,EACtD,CAAA;AAEJ;AAEO,SAAS,kBAAA,CAAmB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA4B;AACnF,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,wBAAA,EAA0B,SAAS,GAAI,QAAA,EAAS,CAAA;AAC5E;AAEO,SAAS,iBAAA,CAAkB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA2B;AACjF,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,uBAAA,EAAyB,SAAS,GAAI,QAAA,EAAS,CAAA;AAC3E;AAEO,SAAS,oBAAA,CAAqB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA8B;AACvF,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,0BAAA,EAA4B,SAAS,GAAI,QAAA,EAAS,CAAA;AAC9E;AAEO,SAAS,qBAAA,CAAsB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA+B;AACzF,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,2BAAA,EAA6B,SAAS,GAAI,QAAA,EAAS,CAAA;AAC/E;AAEO,SAAS,oBAAA,CAAqB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA8B;AACvF,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,0BAAA,EAA4B,SAAS,GAAI,QAAA,EAAS,CAAA;AAC9E;AAEO,SAAS,YAAA,CAAa,EAAE,QAAA,EAAU,SAAA,EAAU,EAAsB;AACvE,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,iBAAA,EAAmB,SAAS,GAAI,QAAA,EAAS,CAAA;AACrE;AAEO,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAU,SAAA,EAAW,QAAO,EAAyB;AACrF,EAAA,MAAM,EAAE,UAAA,EAAY,aAAA,EAAc,GAAI,WAAA,EAAY;AAElD,EAAA,MAAM,YAAA,mBACJD,IAAAA,CAAAO,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAN,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EAA6B,QAAA,EAAS,CAAA;AAAA,IACpD,yBAASA,GAAAA,CAAC,SAAI,SAAA,EAAU,2BAAA,EAA6B,kBAAO,CAAA,GAAS;AAAA,GAAA,EACxE,CAAA;AAGF,EAAA,uBACED,IAAAA,CAAAO,QAAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAN,IAAC,OAAA,EAAA,EAAM,SAAA,EAAW,GAAG,oBAAA,EAAsB,SAAS,GAAI,QAAA,EAAA,YAAA,EAAa,CAAA;AAAA,IAEpE,UAAA,mBACCD,IAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mBAAA,EAAoB,IAAA,EAAK,QAAA,EAAS,YAAA,EAAW,MAAA,EAC1D,QAAA,EAAA;AAAA,sBAAAC,GAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAU,4BAAA;AAAA,UACV,OAAA,EAAS,MAAM,aAAA,CAAc,KAAK,CAAA;AAAA,UAClC,YAAA,EAAW;AAAA;AAAA,OACb;AAAA,sBACAD,IAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,yBAAA,EACf,QAAA,EAAA;AAAA,wBAAAC,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,yBAAA;AAAA,YACV,OAAA,EAAS,MAAM,aAAA,CAAc,KAAK,CAAA;AAAA,YAClC,YAAA,EAAW,kBAAA;AAAA,YAEX,QAAA,kBAAAA,GAAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,iBAAA,EAAkB;AAAA;AAAA,SACjC;AAAA,QACC;AAAA,OAAA,EACH;AAAA,KAAA,EACF,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAEO,SAAS,YAAA,CAAa,EAAE,QAAA,EAAU,SAAA,EAAU,EAAsB;AACvE,EAAA,uBAAOA,IAAC,MAAA,EAAA,EAAK,SAAA,EAAW,GAAG,iBAAA,EAAmB,SAAS,GAAI,QAAA,EAAS,CAAA;AACtE;AAEO,SAAS,iBAAA,CAAkB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA2B;AACjF,EAAA,uBAAOA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,uBAAA,EAAyB,SAAS,GAAI,QAAA,EAAS,CAAA;AAC3E;AAmBO,IAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,YAAA,EAAc;AAAA,EAClD,MAAA,EAAQ,cAAA;AAAA,EACR,MAAA,EAAQ,cAAA;AAAA,EACR,SAAA,EAAW,iBAAA;AAAA,EACX,SAAA,EAAW,iBAAA;AAAA,EACX,KAAA,EAAO,aAAA;AAAA,EACP,UAAA,EAAY,kBAAA;AAAA,EACZ,SAAA,EAAW,iBAAA;AAAA,EACX,YAAA,EAAc,oBAAA;AAAA,EACd,aAAA,EAAe,qBAAA;AAAA,EACf,YAAA,EAAc,oBAAA;AAAA,EACd,IAAA,EAAM,YAAA;AAAA,EACN,OAAA,EAAS,eAAA;AAAA,EACT,IAAA,EAAM,YAAA;AAAA,EACN,SAAA,EAAW;AACb,CAAC","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { createContext, useContext } from \"react\";\n\nimport type { AppShellContextValue } from \"./types\";\n\nexport const AppShellContext = createContext(null);\n\nexport function useAppShell() {\n const context = useContext(AppShellContext);\n if (!context) {\n throw new Error(\"AppShell subcomponents must be used within \");\n }\n return context;\n}\n","import { ChevronDown } from \"lucide-react\";\nimport { useEffect, useId, useRef, useState, type ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport type { AppShellLinkComponent, AppShellNavItem } from \"../types\";\n\nfunction DefaultLink({\n href,\n className,\n children,\n onClick,\n}: {\n href: string;\n className?: string;\n children: React.ReactNode;\n onClick?: () => void;\n}) {\n return (\n \n {children}\n \n );\n}\n\nfunction itemKey(item: AppShellNavItem, index: number): string {\n return item.id ?? `${item.label}-${item.href ?? index}`;\n}\n\nexport function NavItemLabel({ label, icon }: { label: string; icon?: ReactNode }) {\n return (\n <>\n {icon ? {icon} : null}\n {label}\n \n );\n}\n\ntype NavItemControlProps = {\n item: AppShellNavItem;\n LinkComponent: AppShellLinkComponent;\n variant?: \"nav\" | \"menu\" | \"action\";\n};\n\nexport function NavItemControl({ item, LinkComponent, variant = \"nav\" }: NavItemControlProps) {\n const hasChildren = Boolean(item.children?.length);\n const [open, setOpen] = useState(false);\n const rootRef = useRef(null);\n const menuId = useId();\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function onPointerDown(event: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n setOpen(false);\n }\n }\n\n document.addEventListener(\"mousedown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open]);\n\n const triggerClass = cn(\n \"joo-layout-nav-item\",\n variant === \"action\" && \"joo-layout-nav-item--action\",\n item.active && \"joo-layout-nav-item--active\",\n );\n\n if (hasChildren) {\n return (\n
\n setOpen((current) => !current)}\n >\n \n \n \n {open ? (\n
\n {item.children!.map((child, index) => (\n setOpen(false)}\n />\n ))}\n
\n ) : null}\n
\n );\n }\n\n if (item.href) {\n return (\n {\n item.onClick?.();\n }}\n >\n \n \n );\n }\n\n return (\n \n );\n}\n\ntype NavMenuRowProps = {\n item: AppShellNavItem;\n LinkComponent: AppShellLinkComponent;\n onNavigate: () => void;\n};\n\nfunction NavMenuRow({ item, LinkComponent, onNavigate }: NavMenuRowProps) {\n const className = cn(\"joo-layout-nav-menu-item\", item.active && \"joo-layout-nav-menu-item--active\");\n const content = ;\n\n if (item.href) {\n return (\n {\n item.onClick?.();\n onNavigate();\n }}\n >\n {content}\n \n );\n }\n\n return (\n {\n item.onClick?.();\n onNavigate();\n }}\n >\n {content}\n \n );\n}\n\ntype NavItemListProps = {\n items: AppShellNavItem[];\n LinkComponent?: AppShellLinkComponent;\n variant?: \"nav\" | \"action\";\n className?: string;\n};\n\nexport function NavItemList({\n items,\n LinkComponent = DefaultLink,\n variant = \"nav\",\n className,\n}: NavItemListProps) {\n return (\n
\n {items.map((item, index) => (\n \n ))}\n
\n );\n}\n\nexport { DefaultLink };\n","import { ChevronDown, Search, User } from \"lucide-react\";\nimport { useEffect, useId, useRef, useState, type FormEvent } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport type { AppShellHeaderBarProps, AppShellLinkComponent, AppShellNavItem } from \"../types\";\nimport {\n AppShellBrand,\n AppShellHeader,\n AppShellHeaderActions,\n AppShellHeaderCenter,\n AppShellHeaderMain,\n AppShellHeaderMobile,\n AppShellHeaderNav,\n AppShellHeaderRow,\n} from \"./AppShell\";\nimport { DefaultLink, NavItemLabel, NavItemList } from \"./NavMenu\";\n\nfunction SearchForm({\n value,\n onChange,\n onSubmit,\n placeholder = \"Search…\",\n className,\n id,\n}: {\n value: string;\n onChange: (value: string) => void;\n onSubmit?: (value: string) => void;\n placeholder?: string;\n className?: string;\n id?: string;\n}) {\n function handleSubmit(event: FormEvent) {\n event.preventDefault();\n onSubmit?.(value);\n }\n\n return (\n
\n \n onChange(event.target.value)}\n placeholder={placeholder}\n className=\"joo-layout-search-input\"\n aria-label={placeholder}\n />\n \n );\n}\n\nfunction UserMenu({\n name,\n avatarUrl,\n items,\n LinkComponent,\n}: {\n name: string;\n avatarUrl?: string;\n items: AppShellNavItem[];\n LinkComponent: AppShellLinkComponent;\n}) {\n const [open, setOpen] = useState(false);\n const rootRef = useRef(null);\n const menuId = useId();\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function onPointerDown(event: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n setOpen(false);\n }\n }\n\n document.addEventListener(\"mousedown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open]);\n\n return (\n
\n setOpen((current) => !current)}\n >\n {avatarUrl ? (\n \"\"\n ) : (\n \n \n \n )}\n {name}\n \n \n {open ? (\n
\n {items.map((item, index) => {\n const key = item.id ?? `${item.label}-${index}`;\n const className = cn(\n \"joo-layout-nav-menu-item\",\n item.active && \"joo-layout-nav-menu-item--active\",\n );\n\n const content = ;\n\n if (item.href) {\n return (\n {\n item.onClick?.();\n setOpen(false);\n }}\n >\n {content}\n \n );\n }\n\n return (\n {\n item.onClick?.();\n setOpen(false);\n }}\n >\n {content}\n \n );\n })}\n
\n ) : null}\n
\n );\n}\n\nexport function AppShellHeaderBar({\n brand,\n nav,\n search,\n actions,\n user,\n guest,\n linkComponent: LinkComponent = DefaultLink,\n className,\n}: AppShellHeaderBarProps) {\n const searchId = useId();\n const mobileSearchId = useId();\n\n const brandContent = (\n \n {brand.logo}\n {brand.title ? {brand.title} : null}\n \n );\n\n return (\n \n \n \n {brand.href ? (\n \n {brandContent}\n \n ) : (\n brandContent\n )}\n \n\n \n \n \n \n\n \n \n \n\n \n {actions?.length ? (\n \n ) : null}\n {user ? (\n \n ) : (\n guest\n )}\n \n \n \n\n \n \n \n \n );\n}\n","import { Menu, X } from \"lucide-react\";\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport { AppShellContext, useAppShell } from \"../context\";\nimport type {\n AppShellBannerProps,\n AppShellBodyProps,\n AppShellBrandProps,\n AppShellHeaderActionsProps,\n AppShellHeaderCenterProps,\n AppShellHeaderMainProps,\n AppShellHeaderMobileProps,\n AppShellHeaderNavProps,\n AppShellHeaderProps,\n AppShellHeaderRowProps,\n AppShellMainFrameProps,\n AppShellMainProps,\n AppShellProps,\n AppShellSidebarProps,\n} from \"../types\";\nimport { AppShellHeaderBar } from \"./HeaderBar\";\n\nexport { AppShellContext, useAppShell };\nexport { AppShellHeaderBar };\n\nfunction shellStyle(sidebarWidth: string): CSSProperties {\n return {\n [\"--joo-layout-sidebar-width\" as string]: sidebarWidth,\n };\n}\n\nexport function AppShellRoot({ children, sidebarWidth = \"16rem\", className }: AppShellProps) {\n const [mobileOpen, setMobileOpen] = useState(false);\n\n return (\n \n
\n {children}\n
\n
\n );\n}\n\nexport function AppShellBanner({ children, className }: AppShellBannerProps) {\n return
{children}
;\n}\n\nexport function AppShellHeader({ children, className }: AppShellHeaderProps) {\n return (\n
\n {children}\n
\n );\n}\n\nexport function AppShellHeaderRow({ children, className }: AppShellHeaderRowProps) {\n return
{children}
;\n}\n\nexport function AppShellBrand({ children, className }: AppShellBrandProps) {\n const { mobileOpen, setMobileOpen } = useAppShell();\n\n return (\n
\n setMobileOpen(!mobileOpen)}\n aria-expanded={mobileOpen}\n aria-label={mobileOpen ? \"Close navigation\" : \"Open navigation\"}\n >\n {mobileOpen ? : }\n \n
{children}
\n
\n );\n}\n\nexport function AppShellHeaderMain({ children, className }: AppShellHeaderMainProps) {\n return
{children}
;\n}\n\nexport function AppShellHeaderNav({ children, className }: AppShellHeaderNavProps) {\n return ;\n}\n\nexport function AppShellHeaderCenter({ children, className }: AppShellHeaderCenterProps) {\n return
{children}
;\n}\n\nexport function AppShellHeaderActions({ children, className }: AppShellHeaderActionsProps) {\n return
{children}
;\n}\n\nexport function AppShellHeaderMobile({ children, className }: AppShellHeaderMobileProps) {\n return
{children}
;\n}\n\nexport function AppShellBody({ children, className }: AppShellBodyProps) {\n return
{children}
;\n}\n\nexport function AppShellSidebar({ children, className, footer }: AppShellSidebarProps) {\n const { mobileOpen, setMobileOpen } = useAppShell();\n\n const sidebarInner = (\n <>\n
{children}
\n {footer ?
{footer}
: null}\n \n );\n\n return (\n <>\n \n\n {mobileOpen ? (\n
\n setMobileOpen(false)}\n aria-label=\"Close navigation backdrop\"\n />\n \n
\n ) : null}\n \n );\n}\n\nexport function AppShellMain({ children, className }: AppShellMainProps) {\n return
{children}
;\n}\n\nexport function AppShellMainFrame({ children, className }: AppShellMainFrameProps) {\n return
{children}
;\n}\n\ntype AppShellCompound = typeof AppShellRoot & {\n Banner: typeof AppShellBanner;\n Header: typeof AppShellHeader;\n HeaderBar: typeof AppShellHeaderBar;\n HeaderRow: typeof AppShellHeaderRow;\n Brand: typeof AppShellBrand;\n HeaderMain: typeof AppShellHeaderMain;\n HeaderNav: typeof AppShellHeaderNav;\n HeaderCenter: typeof AppShellHeaderCenter;\n HeaderActions: typeof AppShellHeaderActions;\n HeaderMobile: typeof AppShellHeaderMobile;\n Body: typeof AppShellBody;\n Sidebar: typeof AppShellSidebar;\n Main: typeof AppShellMain;\n MainFrame: typeof AppShellMainFrame;\n};\n\nexport const AppShell = Object.assign(AppShellRoot, {\n Banner: AppShellBanner,\n Header: AppShellHeader,\n HeaderBar: AppShellHeaderBar,\n HeaderRow: AppShellHeaderRow,\n Brand: AppShellBrand,\n HeaderMain: AppShellHeaderMain,\n HeaderNav: AppShellHeaderNav,\n HeaderCenter: AppShellHeaderCenter,\n HeaderActions: AppShellHeaderActions,\n HeaderMobile: AppShellHeaderMobile,\n Body: AppShellBody,\n Sidebar: AppShellSidebar,\n Main: AppShellMain,\n MainFrame: AppShellMainFrame,\n}) as AppShellCompound;\n"]} \ No newline at end of file +{"version":3,"sources":["../src/lib/cn.ts","../src/context.tsx","../src/components/NavMenu.tsx","../src/components/SearchForm.tsx","../src/components/ShellBar.tsx","../src/components/HeaderBar.tsx","../src/components/FooterBar.tsx","../src/components/AppShell.tsx"],"names":["jsxs","jsx","useState","useRef","useId","useEffect","ChevronDown"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { createContext, useContext } from \"react\";\n\nimport type { AppShellContextValue } from \"./types\";\n\nexport const AppShellContext = createContext(null);\n\nexport function useAppShell() {\n const context = useContext(AppShellContext);\n if (!context) {\n throw new Error(\"AppShell subcomponents must be used within \");\n }\n return context;\n}\n","import { ChevronDown } from \"lucide-react\";\nimport { useEffect, useId, useRef, useState, type ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport type { AppShellLinkComponent, AppShellNavItem } from \"../types\";\n\nfunction DefaultLink({\n href,\n className,\n children,\n onClick,\n}: {\n href: string;\n className?: string;\n children: React.ReactNode;\n onClick?: () => void;\n}) {\n return (\n \n {children}\n \n );\n}\n\nfunction itemKey(item: AppShellNavItem, index: number): string {\n return item.id ?? `${item.label}-${item.href ?? index}`;\n}\n\nexport function NavItemLabel({ label, icon }: { label: string; icon?: ReactNode }) {\n return (\n \n {icon ? {icon} : null}\n {label}\n \n );\n}\n\ntype NavItemControlProps = {\n item: AppShellNavItem;\n LinkComponent: AppShellLinkComponent;\n variant?: \"nav\" | \"menu\" | \"action\";\n /** Footer menus open upward so they stay on-screen. */\n menuPlacement?: \"down\" | \"up\";\n /** Align popup to the end edge (right) — useful for footer/header actions. */\n menuAlign?: \"start\" | \"end\";\n};\n\nexport function NavItemControl({\n item,\n LinkComponent,\n variant = \"nav\",\n menuPlacement = \"down\",\n menuAlign = \"start\",\n}: NavItemControlProps) {\n const hasChildren = Boolean(item.children?.length);\n const [open, setOpen] = useState(false);\n const rootRef = useRef(null);\n const menuId = useId();\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function onPointerDown(event: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n setOpen(false);\n }\n }\n\n document.addEventListener(\"mousedown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open]);\n\n const triggerClass = cn(\n \"joo-layout-nav-item\",\n variant === \"action\" && \"joo-layout-nav-item--action\",\n item.active && \"joo-layout-nav-item--active\",\n );\n\n if (hasChildren) {\n return (\n
\n setOpen((current) => !current)}\n >\n \n \n \n {open ? (\n \n {item.children!.map((child, index) => (\n setOpen(false)}\n />\n ))}\n
\n ) : null}\n \n );\n }\n\n if (item.href) {\n return (\n {\n item.onClick?.();\n }}\n >\n \n \n );\n }\n\n return (\n \n );\n}\n\ntype NavMenuRowProps = {\n item: AppShellNavItem;\n LinkComponent: AppShellLinkComponent;\n onNavigate: () => void;\n};\n\nfunction NavMenuRow({ item, LinkComponent, onNavigate }: NavMenuRowProps) {\n const className = cn(\"joo-layout-nav-menu-item\", item.active && \"joo-layout-nav-menu-item--active\");\n const content = ;\n\n if (item.href) {\n return (\n {\n item.onClick?.();\n onNavigate();\n }}\n >\n {content}\n \n );\n }\n\n return (\n {\n item.onClick?.();\n onNavigate();\n }}\n >\n {content}\n \n );\n}\n\ntype NavItemListProps = {\n items: AppShellNavItem[];\n LinkComponent?: AppShellLinkComponent;\n variant?: \"nav\" | \"action\";\n menuPlacement?: \"down\" | \"up\";\n menuAlign?: \"start\" | \"end\";\n className?: string;\n};\n\nexport function NavItemList({\n items,\n LinkComponent = DefaultLink,\n variant = \"nav\",\n menuPlacement = \"down\",\n menuAlign = \"start\",\n className,\n}: NavItemListProps) {\n return (\n
\n {items.map((item, index) => (\n \n ))}\n
\n );\n}\n\nexport { DefaultLink };\n","import { Search } from \"lucide-react\";\nimport type { FormEvent } from \"react\";\n\nimport { cn } from \"../lib/cn\";\n\nexport type SearchFormProps = {\n value: string;\n onChange: (value: string) => void;\n onSubmit?: (value: string) => void;\n placeholder?: string;\n className?: string;\n id?: string;\n};\n\nexport function SearchForm({\n value,\n onChange,\n onSubmit,\n placeholder = \"Search…\",\n className,\n id,\n}: SearchFormProps) {\n function handleSubmit(event: FormEvent) {\n event.preventDefault();\n onSubmit?.(value);\n }\n\n return (\n
\n \n onChange(event.target.value)}\n placeholder={placeholder}\n className=\"joo-layout-search-input\"\n aria-label={placeholder}\n />\n \n );\n}\n","import { ChevronDown, User } from \"lucide-react\";\nimport { useEffect, useId, useRef, useState } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport type {\n AppShellHeaderBarProps,\n AppShellLinkComponent,\n AppShellNavItem,\n} from \"../types\";\nimport {\n AppShellBrand,\n AppShellHeaderActions,\n AppShellHeaderCenter,\n AppShellHeaderMain,\n AppShellHeaderMobile,\n AppShellHeaderNav,\n AppShellHeaderRow,\n} from \"./AppShell\";\nimport { DefaultLink, NavItemLabel, NavItemList } from \"./NavMenu\";\nimport { SearchForm } from \"./SearchForm\";\n\nexport type ShellBarUserMenuProps = {\n name: string;\n avatarUrl?: string;\n items: AppShellNavItem[];\n LinkComponent: AppShellLinkComponent;\n menuPlacement?: \"down\" | \"up\";\n};\n\nexport function ShellBarUserMenu({\n name,\n avatarUrl,\n items,\n LinkComponent,\n menuPlacement = \"down\",\n}: ShellBarUserMenuProps) {\n const [open, setOpen] = useState(false);\n const rootRef = useRef(null);\n const menuId = useId();\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function onPointerDown(event: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n setOpen(false);\n }\n }\n\n document.addEventListener(\"mousedown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open]);\n\n return (\n
\n setOpen((current) => !current)}\n >\n {avatarUrl ? (\n \"\"\n ) : (\n \n \n \n )}\n {name}\n \n \n {open ? (\n \n {items.map((item, index) => {\n const key = item.id ?? `${item.label}-${index}`;\n const className = cn(\n \"joo-layout-nav-menu-item\",\n item.active && \"joo-layout-nav-menu-item--active\",\n );\n\n const content = ;\n\n if (item.href) {\n return (\n {\n item.onClick?.();\n setOpen(false);\n }}\n >\n {content}\n \n );\n }\n\n return (\n {\n item.onClick?.();\n setOpen(false);\n }}\n >\n {content}\n \n );\n })}\n
\n ) : null}\n \n );\n}\n\nexport type ShellBarProps = Omit & {\n brand?: AppShellHeaderBarProps[\"brand\"];\n /** Opening direction for nav / action / user dropdowns. */\n menuPlacement?: \"down\" | \"up\";\n};\n\n/** Shared HeaderBar / FooterBar chrome (optional brand | nav | search | actions + user). */\nexport function ShellBar({\n brand,\n nav,\n search,\n actions,\n user,\n guest,\n linkComponent: LinkComponent = DefaultLink,\n className,\n menuPlacement = \"down\",\n}: ShellBarProps) {\n const searchId = useId();\n const mobileSearchId = useId();\n\n const brandContent = brand ? (\n \n {brand.logo}\n {brand.title ? {brand.title} : null}\n \n ) : null;\n\n return (\n
\n \n {brand && brandContent ? (\n \n {brand.href ? (\n \n {brandContent}\n \n ) : (\n brandContent\n )}\n \n ) : null}\n\n \n \n \n \n\n \n \n \n\n \n {actions?.length ? (\n \n ) : null}\n {user ? (\n \n ) : (\n guest\n )}\n \n \n \n\n \n \n \n
\n );\n}\n","import type { AppShellHeaderBarProps } from \"../types\";\nimport { AppShellHeader } from \"./AppShell\";\nimport { ShellBar } from \"./ShellBar\";\n\nexport function AppShellHeaderBar(props: AppShellHeaderBarProps) {\n return (\n \n \n \n );\n}\n","import { cn } from \"../lib/cn\";\nimport type { AppShellFooterBarProps } from \"../types\";\nimport { ShellBar } from \"./ShellBar\";\n\n/**\n * Exact HeaderBar chrome at the bottom of Main (brand | nav | search | actions + user).\n * Dropdowns open upward.\n */\nexport function AppShellFooterBar({ className, ...props }: AppShellFooterBarProps) {\n return (\n
\n \n
\n );\n}\n","import { Menu, X } from \"lucide-react\";\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport { AppShellContext, useAppShell } from \"../context\";\nimport type {\n AppShellBannerProps,\n AppShellBodyProps,\n AppShellBrandProps,\n AppShellHeaderActionsProps,\n AppShellHeaderCenterProps,\n AppShellHeaderMainProps,\n AppShellHeaderMobileProps,\n AppShellHeaderNavProps,\n AppShellHeaderProps,\n AppShellHeaderRowProps,\n AppShellMainFrameProps,\n AppShellMainProps,\n AppShellProps,\n AppShellSidebarProps,\n} from \"../types\";\nimport { AppShellHeaderBar } from \"./HeaderBar\";\nimport { AppShellFooterBar } from \"./FooterBar\";\n\nexport { AppShellContext, useAppShell };\nexport { AppShellHeaderBar };\nexport { AppShellFooterBar };\n\nfunction shellStyle(sidebarWidth: string): CSSProperties {\n return {\n [\"--joo-layout-sidebar-width\" as string]: sidebarWidth,\n };\n}\n\nexport function AppShellRoot({ children, sidebarWidth = \"16rem\", className }: AppShellProps) {\n const [mobileOpen, setMobileOpen] = useState(false);\n\n return (\n \n
\n {children}\n
\n
\n );\n}\n\nexport function AppShellBanner({ children, className }: AppShellBannerProps) {\n return
{children}
;\n}\n\nexport function AppShellHeader({ children, className }: AppShellHeaderProps) {\n return (\n
\n {children}\n
\n );\n}\n\nexport function AppShellHeaderRow({ children, className }: AppShellHeaderRowProps) {\n return
{children}
;\n}\n\nexport function AppShellBrand({ children, className }: AppShellBrandProps) {\n const { mobileOpen, setMobileOpen } = useAppShell();\n\n return (\n
\n setMobileOpen(!mobileOpen)}\n aria-expanded={mobileOpen}\n aria-label={mobileOpen ? \"Close navigation\" : \"Open navigation\"}\n >\n {mobileOpen ? : }\n \n
{children}
\n
\n );\n}\n\nexport function AppShellHeaderMain({ children, className }: AppShellHeaderMainProps) {\n return
{children}
;\n}\n\nexport function AppShellHeaderNav({ children, className }: AppShellHeaderNavProps) {\n return ;\n}\n\nexport function AppShellHeaderCenter({ children, className }: AppShellHeaderCenterProps) {\n return
{children}
;\n}\n\nexport function AppShellHeaderActions({ children, className }: AppShellHeaderActionsProps) {\n return
{children}
;\n}\n\nexport function AppShellHeaderMobile({ children, className }: AppShellHeaderMobileProps) {\n return
{children}
;\n}\n\nexport function AppShellBody({ children, className }: AppShellBodyProps) {\n return
{children}
;\n}\n\nexport function AppShellSidebar({ children, className, footer }: AppShellSidebarProps) {\n const { mobileOpen, setMobileOpen } = useAppShell();\n\n const sidebarInner = (\n <>\n
{children}
\n
{footer}
\n \n );\n\n return (\n <>\n \n\n {mobileOpen ? (\n
\n setMobileOpen(false)}\n aria-label=\"Close navigation backdrop\"\n />\n \n
\n ) : null}\n \n );\n}\n\nexport function AppShellMain({ children, className }: AppShellMainProps) {\n return
{children}
;\n}\n\nexport function AppShellMainFrame({ children, className }: AppShellMainFrameProps) {\n return
{children}
;\n}\n\ntype AppShellCompound = typeof AppShellRoot & {\n Banner: typeof AppShellBanner;\n Header: typeof AppShellHeader;\n HeaderBar: typeof AppShellHeaderBar;\n HeaderRow: typeof AppShellHeaderRow;\n Brand: typeof AppShellBrand;\n HeaderMain: typeof AppShellHeaderMain;\n HeaderNav: typeof AppShellHeaderNav;\n HeaderCenter: typeof AppShellHeaderCenter;\n HeaderActions: typeof AppShellHeaderActions;\n HeaderMobile: typeof AppShellHeaderMobile;\n Body: typeof AppShellBody;\n Sidebar: typeof AppShellSidebar;\n Main: typeof AppShellMain;\n MainFrame: typeof AppShellMainFrame;\n FooterBar: typeof AppShellFooterBar;\n};\n\nexport const AppShell = Object.assign(AppShellRoot, {\n Banner: AppShellBanner,\n Header: AppShellHeader,\n HeaderBar: AppShellHeaderBar,\n HeaderRow: AppShellHeaderRow,\n Brand: AppShellBrand,\n HeaderMain: AppShellHeaderMain,\n HeaderNav: AppShellHeaderNav,\n HeaderCenter: AppShellHeaderCenter,\n HeaderActions: AppShellHeaderActions,\n HeaderMobile: AppShellHeaderMobile,\n Body: AppShellBody,\n Sidebar: AppShellSidebar,\n Main: AppShellMain,\n MainFrame: AppShellMainFrame,\n FooterBar: AppShellFooterBar,\n}) as AppShellCompound;\n"]} \ No newline at end of file diff --git a/components/layout/dist/styles.css b/components/layout/dist/styles.css index 609f6c2..6fd1cd9 100644 --- a/components/layout/dist/styles.css +++ b/components/layout/dist/styles.css @@ -1,6 +1,8 @@ :root { --joo-layout-sidebar-width: 16rem; --joo-layout-topbar-height: 3.5rem; + /* Match top bar so footer nav chrome has the same vertical room as HeaderBar. */ + --joo-layout-bottom-rail-height: var(--joo-layout-topbar-height); --joo-background: 0 0% 100%; --joo-foreground: 222.2 84% 4.9%; --joo-border: 214.3 31.8% 91.4%; @@ -196,11 +198,18 @@ } .joo-layout-sidebar-footer { + box-sizing: border-box; + display: flex; + height: var(--joo-layout-bottom-rail-height); flex-shrink: 0; + align-items: center; + overflow: hidden; border-top: 1px solid hsl(var(--joo-border)); - padding: 1rem 1.25rem; + background-color: hsl(var(--joo-card) / 0.95); + padding: 0 1.25rem; font-size: 0.75rem; color: hsl(var(--joo-muted-foreground)); + backdrop-filter: blur(8px); } .joo-layout-main { @@ -227,6 +236,44 @@ } } +.joo-layout-footer-bar { + box-sizing: border-box; + z-index: 20; + flex-shrink: 0; + overflow: visible; + border-top: 1px solid hsl(var(--joo-border)); + background-color: hsl(var(--joo-card) / 0.95); + backdrop-filter: blur(8px); +} + +.joo-layout-footer-bar > .joo-layout-header-row { + min-height: var(--joo-layout-bottom-rail-height); +} + +/* Hide mobile nav toggle in the footer brand column (desktop chrome only). */ +.joo-layout-footer-bar .joo-layout-mobile-toggle { + display: none; +} + +/* Keep HeaderBar chrome visible in the footer on all breakpoints. */ +.joo-layout-footer-bar .joo-layout-header-nav, +.joo-layout-footer-bar .joo-layout-header-center { + display: flex; +} + +.joo-layout-footer-bar .joo-layout-header-actions { + display: flex; + flex-shrink: 0; + align-items: center; + gap: 0.5rem; +} + +@media (min-width: 1024px) { + .joo-layout-footer-bar > .joo-layout-header-row > .joo-layout-brand { + border-right: 1px solid hsl(var(--joo-border)); + } +} + .joo-layout-drawer { position: fixed; inset: 0; @@ -313,6 +360,13 @@ gap: 0.25rem; } +.joo-layout-nav-label { + display: inline-flex; + align-items: center; + gap: 0.375rem; + min-width: 0; +} + .joo-layout-nav-icon-wrap { display: inline-flex; flex-shrink: 0; @@ -326,30 +380,40 @@ .joo-layout-nav-icon { width: 1rem; height: 1rem; + flex-shrink: 0; } -.joo-layout-nav-item { +.joo-layout-nav-item, +a.joo-layout-nav-item, +button.joo-layout-nav-item { display: inline-flex; + flex-shrink: 0; align-items: center; gap: 0.375rem; border: none; border-radius: 0.375rem; background: transparent; padding: 0.375rem 0.75rem; + font-family: inherit; font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; color: hsl(var(--joo-muted-foreground)); text-decoration: none; + white-space: nowrap; cursor: pointer; } -.joo-layout-nav-item:hover { +.joo-layout-nav-item:hover, +a.joo-layout-nav-item:hover, +button.joo-layout-nav-item:hover { background-color: hsl(var(--joo-accent)); color: hsl(var(--joo-foreground)); } -.joo-layout-nav-item--active { +.joo-layout-nav-item--active, +a.joo-layout-nav-item--active, +button.joo-layout-nav-item--active { background-color: hsl(199 89% 48% / 0.12); color: hsl(199 89% 30%); } @@ -361,18 +425,29 @@ .joo-layout-nav-dropdown, .joo-layout-user { position: relative; + flex-shrink: 0; } .joo-layout-nav-chevron { width: 0.875rem; height: 0.875rem; + flex-shrink: 0; + color: currentColor; transition: transform 0.15s ease; } +.joo-layout-nav-chevron--up { + transform: rotate(180deg); +} + .joo-layout-nav-chevron--open { transform: rotate(180deg); } +.joo-layout-nav-chevron--up.joo-layout-nav-chevron--open { + transform: rotate(0deg); +} + .joo-layout-nav-menu { position: absolute; top: calc(100% + 0.25rem); @@ -386,6 +461,12 @@ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1); } +.joo-layout-nav-menu--up { + top: auto; + bottom: calc(100% + 0.25rem); + box-shadow: 0 -10px 15px -3px rgb(0 0 0 / 0.1); +} + .joo-layout-nav-menu--end { left: auto; right: 0; diff --git a/components/layout/package.json b/components/layout/package.json index 28d583e..b4b7e5e 100644 --- a/components/layout/package.json +++ b/components/layout/package.json @@ -1,7 +1,7 @@ { "name": "@jooservices/react-layout", "version": "0.1.0", - "description": "Master app shell for React — aligned top bar, sidebar, and main content (XFlickr-style grid)", + "description": "Master app shell for React \u2014 aligned top bar, sidebar, and main content (XFlickr-style grid)", "type": "module", "license": "MIT", "author": "JOOservices", @@ -39,7 +39,8 @@ "build": "tsup && cp src/styles.css dist/styles.css", "typecheck": "tsc --noEmit", "test": "vitest run", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" }, "dependencies": { "clsx": "^2.1.1", diff --git a/components/layout/src/AppShell.test.tsx b/components/layout/src/AppShell.test.tsx index b443306..ec17344 100644 --- a/components/layout/src/AppShell.test.tsx +++ b/components/layout/src/AppShell.test.tsx @@ -1,6 +1,6 @@ import "./styles.css"; -import { render, screen } from "@testing-library/react"; +import { render, screen, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { Boxes, LayoutTemplate, LogOut, Table2, UserCircle } from "lucide-react"; import { describe, expect, it, vi } from "vitest"; @@ -122,3 +122,67 @@ describe("AppShell.HeaderBar", () => { expect(screen.getByRole("link", { name: "Sign in" })).toBeInTheDocument(); }); }); + +describe("AppShell.FooterBar", () => { + it("matches HeaderBar chrome without brand (nav, search, actions, user) with upward menus", async () => { + const user = userEvent.setup(); + const onSearch = vi.fn(); + const onProfile = vi.fn(); + + render( + + + rail}>nav + + Content + }, + { + label: "Explore", + icon: , + children: [ + { label: "Layout", href: "/layout", icon: }, + { label: "Table", href: "/table", icon: }, + ], + }, + ]} + search={{ + value: "movies", + onChange: () => undefined, + onSubmit: onSearch, + placeholder: "Search movies…", + }} + actions={[{ label: "Help", href: "/help" }]} + user={{ + name: "Account", + items: [ + { label: "My profile", onClick: onProfile, icon: }, + { label: "Log out", onClick: () => undefined, icon: }, + ], + }} + /> + + + , + ); + + const footer = screen.getByRole("contentinfo", { name: "Application status" }); + expect(within(footer).queryByText("Demo")).not.toBeInTheDocument(); + expect(within(footer).getByText("Home")).toBeInTheDocument(); + expect(within(footer).getByText("Help")).toBeInTheDocument(); + + await user.click(within(footer).getByRole("button", { name: "Explore" })); + expect(within(footer).getByRole("menu")).toHaveClass("joo-layout-nav-menu--up"); + expect(within(footer).getByRole("link", { name: "Layout" })).toBeInTheDocument(); + + const searchInputs = within(footer).getAllByRole("searchbox"); + expect(searchInputs.length).toBeGreaterThanOrEqual(1); + await user.type(searchInputs[0]!, "{Enter}"); + expect(onSearch).toHaveBeenCalledWith("movies"); + + await user.click(within(footer).getByRole("button", { name: "Account account menu" })); + await user.click(within(footer).getByRole("menuitem", { name: "My profile" })); + expect(onProfile).toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/components/layout/src/components/AppShell.tsx b/components/layout/src/components/AppShell.tsx index 5557ebf..ee4dc02 100644 --- a/components/layout/src/components/AppShell.tsx +++ b/components/layout/src/components/AppShell.tsx @@ -20,9 +20,11 @@ import type { AppShellSidebarProps, } from "../types"; import { AppShellHeaderBar } from "./HeaderBar"; +import { AppShellFooterBar } from "./FooterBar"; export { AppShellContext, useAppShell }; export { AppShellHeaderBar }; +export { AppShellFooterBar }; function shellStyle(sidebarWidth: string): CSSProperties { return { @@ -107,7 +109,7 @@ export function AppShellSidebar({ children, className, footer }: AppShellSidebar const sidebarInner = ( <>
{children}
- {footer ?
{footer}
: null} +
{footer}
); @@ -163,6 +165,7 @@ type AppShellCompound = typeof AppShellRoot & { Sidebar: typeof AppShellSidebar; Main: typeof AppShellMain; MainFrame: typeof AppShellMainFrame; + FooterBar: typeof AppShellFooterBar; }; export const AppShell = Object.assign(AppShellRoot, { @@ -180,4 +183,5 @@ export const AppShell = Object.assign(AppShellRoot, { Sidebar: AppShellSidebar, Main: AppShellMain, MainFrame: AppShellMainFrame, + FooterBar: AppShellFooterBar, }) as AppShellCompound; diff --git a/components/layout/src/components/FooterBar.tsx b/components/layout/src/components/FooterBar.tsx new file mode 100644 index 0000000..d456930 --- /dev/null +++ b/components/layout/src/components/FooterBar.tsx @@ -0,0 +1,15 @@ +import { cn } from "../lib/cn"; +import type { AppShellFooterBarProps } from "../types"; +import { ShellBar } from "./ShellBar"; + +/** + * Exact HeaderBar chrome at the bottom of Main (brand | nav | search | actions + user). + * Dropdowns open upward. + */ +export function AppShellFooterBar({ className, ...props }: AppShellFooterBarProps) { + return ( +
+ +
+ ); +} diff --git a/components/layout/src/components/HeaderBar.tsx b/components/layout/src/components/HeaderBar.tsx index 460b0a3..45ff4c0 100644 --- a/components/layout/src/components/HeaderBar.tsx +++ b/components/layout/src/components/HeaderBar.tsx @@ -1,240 +1,11 @@ -import { ChevronDown, Search, User } from "lucide-react"; -import { useEffect, useId, useRef, useState, type FormEvent } from "react"; - -import { cn } from "../lib/cn"; -import type { AppShellHeaderBarProps, AppShellLinkComponent, AppShellNavItem } from "../types"; -import { - AppShellBrand, - AppShellHeader, - AppShellHeaderActions, - AppShellHeaderCenter, - AppShellHeaderMain, - AppShellHeaderMobile, - AppShellHeaderNav, - AppShellHeaderRow, -} from "./AppShell"; -import { DefaultLink, NavItemLabel, NavItemList } from "./NavMenu"; - -function SearchForm({ - value, - onChange, - onSubmit, - placeholder = "Search…", - className, - id, -}: { - value: string; - onChange: (value: string) => void; - onSubmit?: (value: string) => void; - placeholder?: string; - className?: string; - id?: string; -}) { - function handleSubmit(event: FormEvent) { - event.preventDefault(); - onSubmit?.(value); - } +import type { AppShellHeaderBarProps } from "../types"; +import { AppShellHeader } from "./AppShell"; +import { ShellBar } from "./ShellBar"; +export function AppShellHeaderBar(props: AppShellHeaderBarProps) { return ( -
- - onChange(event.target.value)} - placeholder={placeholder} - className="joo-layout-search-input" - aria-label={placeholder} - /> - - ); -} - -function UserMenu({ - name, - avatarUrl, - items, - LinkComponent, -}: { - name: string; - avatarUrl?: string; - items: AppShellNavItem[]; - LinkComponent: AppShellLinkComponent; -}) { - const [open, setOpen] = useState(false); - const rootRef = useRef(null); - const menuId = useId(); - - useEffect(() => { - if (!open) { - return; - } - - function onPointerDown(event: MouseEvent) { - if (rootRef.current && !rootRef.current.contains(event.target as Node)) { - setOpen(false); - } - } - - function onKeyDown(event: KeyboardEvent) { - if (event.key === "Escape") { - setOpen(false); - } - } - - document.addEventListener("mousedown", onPointerDown); - document.addEventListener("keydown", onKeyDown); - return () => { - document.removeEventListener("mousedown", onPointerDown); - document.removeEventListener("keydown", onKeyDown); - }; - }, [open]); - - return ( -
- - {open ? ( - - ) : null} -
- ); -} - -export function AppShellHeaderBar({ - brand, - nav, - search, - actions, - user, - guest, - linkComponent: LinkComponent = DefaultLink, - className, -}: AppShellHeaderBarProps) { - const searchId = useId(); - const mobileSearchId = useId(); - - const brandContent = ( - - {brand.logo} - {brand.title ? {brand.title} : null} - - ); - - return ( - - - - {brand.href ? ( - - {brandContent} - - ) : ( - brandContent - )} - - - - - - - - - - - - - {actions?.length ? ( - - ) : null} - {user ? ( - - ) : ( - guest - )} - - - - - - - + + ); } diff --git a/components/layout/src/components/NavMenu.tsx b/components/layout/src/components/NavMenu.tsx index 416aae4..219209b 100644 --- a/components/layout/src/components/NavMenu.tsx +++ b/components/layout/src/components/NavMenu.tsx @@ -28,10 +28,10 @@ function itemKey(item: AppShellNavItem, index: number): string { export function NavItemLabel({ label, icon }: { label: string; icon?: ReactNode }) { return ( - <> + {icon ? {icon} : null} - {label} - + {label} + ); } @@ -39,9 +39,19 @@ type NavItemControlProps = { item: AppShellNavItem; LinkComponent: AppShellLinkComponent; variant?: "nav" | "menu" | "action"; + /** Footer menus open upward so they stay on-screen. */ + menuPlacement?: "down" | "up"; + /** Align popup to the end edge (right) — useful for footer/header actions. */ + menuAlign?: "start" | "end"; }; -export function NavItemControl({ item, LinkComponent, variant = "nav" }: NavItemControlProps) { +export function NavItemControl({ + item, + LinkComponent, + variant = "nav", + menuPlacement = "down", + menuAlign = "start", +}: NavItemControlProps) { const hasChildren = Boolean(item.children?.length); const [open, setOpen] = useState(false); const rootRef = useRef(null); @@ -90,10 +100,25 @@ export function NavItemControl({ item, LinkComponent, variant = "nav" }: NavItem onClick={() => setOpen((current) => !current)} > - + {open ? ( - \n );\n}\n\n/** Alias for PageShellCanvas */\nexport const PageContent = PageShellCanvas;\n\nexport function PageShellFooter({ children, className }: PageShellFooterProps) {\n return
{children}
;\n}\n\n/** Aliases aligned with XFlickr-style naming */\nexport const PageIdentity = PageShellIdentity;\nexport const PageToolbar = PageShellToolbar;\nexport const PageAdvanced = PageShellAdvanced;\nexport const PageFooter = PageShellFooter;\n"]} \ No newline at end of file +{"version":3,"sources":["../src/lib/cn.ts","../src/components/PageShell.tsx"],"names":[],"mappings":";;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACWO,SAAS,SAAA,CAAU,EAAE,QAAA,EAAU,SAAA,EAAU,EAAmB;AACjE,EAAA,2BAAQ,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,mBAAA,EAAqB,SAAS,GAAI,QAAA,EAAS,CAAA;AACvE;AAGO,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAU,SAAA,EAAU,EAAyB;AAC7E,EAAA,2BAAQ,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,oBAAA,EAAsB,SAAS,GAAI,QAAA,EAAS,CAAA;AACxE;AAEO,SAAS,iBAAA,CAAkB;AAAA,EAChC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA,EAA2B;AACzB,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,sBAAA,EAAwB,SAAS,CAAA,EAClD,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,2BAAA,EACZ,QAAA,EAAA;AAAA,MAAA,WAAA,EAAa,MAAA,mBACZ,GAAA,CAAC,KAAA,EAAA,EAAI,YAAA,EAAW,YAAA,EAAa,SAAA,EAAU,yBAAA,EACpC,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,KAAU;AAChC,QAAA,MAAM,wBACJ,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,IAAA,uBACH,MAAA,EAAA,EAAK,SAAA,EAAU,+BAA8B,aAAA,EAAW,IAAA,EACtD,QAAA,EAAA,IAAA,CAAK,IAAA,EACR,CAAA,GACE,IAAA;AAAA,0BACJ,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,IAAA,CAAK,KAAA,EAAM;AAAA,SAAA,EACpB,CAAA;AAGF,QAAA,uBACE,IAAA,CAAC,MAAA,EAAA,EAAoC,SAAA,EAAU,6BAAA,EAC5C,QAAA,EAAA;AAAA,UAAA,KAAA,GAAQ,oBAAI,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA6B,eAAC,CAAA,GAAU,IAAA;AAAA,UACpE,IAAA,CAAK,IAAA,mBACJ,GAAA,CAAC,GAAA,EAAA,EAAE,MAAM,IAAA,CAAK,IAAA,EAAM,SAAA,EAAU,6BAAA,EAC3B,iBACH,CAAA,mBAEA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAkC,QAAA,EAAA,KAAA,EAAM;AAAA,SAAA,EAAA,EAPjD,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CASjC,CAAA;AAAA,MAEJ,CAAC,GACH,CAAA,GACE,IAAA;AAAA,sBACJ,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,mBAAA,EAAqB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MACxC,2BAAW,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sBAAA,EAAwB,oBAAS,CAAA,GAAO;AAAA,KAAA,EACnE,CAAA;AAAA,IACC,0BAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EAAgC,mBAAQ,CAAA,GAAS;AAAA,GAAA,EAC7E,CAAA;AAEJ;AAEO,SAAS,oBAAoB,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,WAAU,EAA6B;AACnG,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EAChD,QAAA,EAAA;AAAA,IAAA,IAAA,mBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EAAoB,gBAAK,CAAA,GAAS,IAAA;AAAA,IACxD,OAAA,IAAW,0BACV,IAAA,CAAC,KAAA,EAAA,EAAI,WAAW,EAAA,CAAG,yBAAA,EAA2B,OAAA,IAAW,kCAAkC,CAAA,EACxF,QAAA,EAAA;AAAA,MAAA,OAAA,mBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EAA+B,mBAAQ,CAAA,GAAS,IAAA;AAAA,MACzE,0BAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EAA+B,mBAAQ,CAAA,GAAS;AAAA,KAAA,EAC5E,CAAA,GACE;AAAA,GAAA,EACN,CAAA;AAEJ;AAEO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,WAAA,GAAc,QAAA;AAAA,EACd,UAAA,GAAa,OAAA;AAAA,EACb;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,0BACJ,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,IAAA,OAAA,mBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EAA+B,mBAAQ,CAAA,GAAS,IAAA;AAAA,oBAC1E,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACZ,QAAA,EAAA;AAAA,MAAA,QAAA,uBACE,QAAA,EAAA,EAAO,IAAA,EAAK,UAAS,SAAA,EAAU,0CAAA,EAC7B,uBACH,CAAA,GACE,IAAA;AAAA,MACH,OAAA,mBACC,GAAA,CAAC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,WAAU,4CAAA,EAA6C,OAAA,EAAS,OAAA,EACnF,QAAA,EAAA,UAAA,EACH,CAAA,GACE,IAAA;AAAA,MACH;AAAA,KAAA,EACH;AAAA,GAAA,EACF,CAAA;AAGF,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,MAAM,YAAA,GAAe,CAAC,KAAA,KAAsC;AAC1D,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,QAAA,EAAS;AAAA,IACX,CAAA;AAEA,IAAA,uBACE,GAAA,CAAC,UAAK,SAAA,EAAW,EAAA,CAAG,uBAAuB,SAAS,CAAA,EAAG,QAAA,EAAU,YAAA,EAC9D,QAAA,EAAA,OAAA,EACH,CAAA;AAAA,EAEJ;AAEA,EAAA,2BAAQ,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,qBAAA,EAAuB,SAAS,GAAI,QAAA,EAAA,OAAA,EAAQ,CAAA;AACxE;AAEO,SAAS,iBAAA,CAAkB;AAAA,EAChC,QAAA;AAAA,EACA,KAAA,GAAQ,kBAAA;AAAA,EACR,WAAA,GAAc,KAAA;AAAA,EACd;AACF,CAAA,EAA2B;AACzB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,WAAW,CAAA;AAE5C,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,sBAAA,EAAwB,SAAS,CAAA,EAClD,QAAA,EAAA;AAAA,oBAAA,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,6BAAA;AAAA,QACV,eAAA,EAAe,IAAA;AAAA,QACf,SAAS,MAAM,OAAA,CAAQ,CAAC,OAAA,KAAY,CAAC,OAAO,CAAA;AAAA,QAE5C,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,8BACZ,WAAA,EAAA,EAAY,SAAA,EAAW,GAAG,8BAAA,EAAgC,IAAA,IAAQ,oCAAoC,CAAA,EAAG;AAAA;AAAA;AAAA,KAC5G;AAAA,IACC,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EAA6B,UAAS,CAAA,GAAS;AAAA,GAAA,EACxE,CAAA;AAEJ;AAEO,SAAS,mBAAA,CAAoB,EAAE,QAAA,EAAU,SAAA,EAAU,EAA6B;AACrF,EAAA,2BAAQ,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,qBAAA,EAAuB,SAAS,GAAI,QAAA,EAAS,CAAA;AACzE;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC9B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA,GAAU,OAAA;AAAA,EACV,OAAA,GAAU,KAAA;AAAA,EACV,YAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA,GAAQ,KAAA;AAAA,EACR;AACF,CAAA,EAAyB;AACvB,EAAA,IAAI,IAAA,GAAkB,QAAA;AAEtB,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,IAAA,GAAO,YAAA,oBAAgB,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,qBAAoB,QAAA,EAAA,eAAA,EAAQ,CAAA;AAAA,EAClE,WAAW,KAAA,EAAO;AAChB,IAAA,IAAA,GAAO,KAAA;AAAA,EACT,CAAA,MAAA,IAAW,SAAS,UAAA,EAAY;AAC9B,IAAA,IAAA,GAAO,UAAA;AAAA,EACT;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,kBAAA;AAAA,QACA,YAAY,MAAA,IAAU,wBAAA;AAAA,QACtB,YAAY,OAAA,IAAW,yBAAA;AAAA,QACvB;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ;AAGO,IAAM,WAAA,GAAc;AAEpB,SAAS,eAAA,CAAgB,EAAE,QAAA,EAAU,SAAA,EAAU,EAAyB;AAC7E,EAAA,2BAAQ,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,oBAAA,EAAsB,SAAS,GAAI,QAAA,EAAS,CAAA;AACxE;AAGO,IAAM,UAAA,GAAa;AACnB,IAAM,YAAA,GAAe;AACrB,IAAM,WAAA,GAAc;AACpB,IAAM,YAAA,GAAe;AACrB,IAAM,UAAA,GAAa","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { useState, type FormEvent, type ReactNode } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\n\nimport { cn } from \"../lib/cn\";\nimport type {\n PageShellAdvancedProps,\n PageShellBannerProps,\n PageShellCanvasProps,\n PageShellContextBarProps,\n PageShellControlBarProps,\n PageShellFooterProps,\n PageShellIdentityProps,\n PageShellProps,\n PageShellToolbarProps,\n} from \"../types\";\n\nexport function PageShell({ children, className }: PageShellProps) {\n return
{children}
;\n}\n\n/** Page-scoped flash / notice — place first under PageShell (below app HeaderBar). */\nexport function PageShellBanner({ children, className }: PageShellBannerProps) {\n return
{children}
;\n}\n\nexport function PageShellIdentity({\n title,\n subtitle,\n actions,\n breadcrumbs,\n className,\n}: PageShellIdentityProps) {\n return (\n
\n
\n {breadcrumbs?.length ? (\n \n ) : null}\n

{title}

\n {subtitle ?

{subtitle}

: null}\n
\n {actions ?
{actions}
: null}\n
\n );\n}\n\nexport function PageShellControlBar({ tabs, filters, actions, className }: PageShellControlBarProps) {\n return (\n
\n {tabs ?
{tabs}
: null}\n {filters || actions ? (\n
\n {filters ?
{filters}
: null}\n {actions ?
{actions}
: null}\n
\n ) : null}\n
\n );\n}\n\nexport function PageShellToolbar({\n leading,\n trailing,\n onSubmit,\n onClear,\n submitLabel = \"Filter\",\n clearLabel = \"Clear\",\n className,\n}: PageShellToolbarProps) {\n const content = (\n <>\n {leading ?
{leading}
: null}\n
\n {onSubmit ? (\n \n ) : null}\n {onClear ? (\n \n ) : null}\n {trailing}\n
\n \n );\n\n if (onSubmit) {\n const handleSubmit = (event: FormEvent) => {\n event.preventDefault();\n onSubmit();\n };\n\n return (\n
\n {content}\n
\n );\n }\n\n return
{content}
;\n}\n\nexport function PageShellAdvanced({\n children,\n label = \"Advanced filters\",\n defaultOpen = false,\n className,\n}: PageShellAdvancedProps) {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n
\n setOpen((current) => !current)}\n >\n {label}\n \n \n {open ?
{children}
: null}\n
\n );\n}\n\nexport function PageShellContextBar({ children, className }: PageShellContextBarProps) {\n return
{children}
;\n}\n\nexport function PageShellCanvas({\n children,\n className,\n variant = \"plain\",\n loading = false,\n loadingState,\n error,\n empty = false,\n emptyState,\n}: PageShellCanvasProps) {\n let body: ReactNode = children;\n\n if (loading) {\n body = loadingState ??

Loading…

;\n } else if (error) {\n body = error;\n } else if (empty && emptyState) {\n body = emptyState;\n }\n\n return (\n \n {body}\n \n );\n}\n\n/** Alias for PageShellCanvas */\nexport const PageContent = PageShellCanvas;\n\nexport function PageShellFooter({ children, className }: PageShellFooterProps) {\n return
{children}
;\n}\n\n/** Aliases aligned with XFlickr-style naming */\nexport const PageBanner = PageShellBanner;\nexport const PageIdentity = PageShellIdentity;\nexport const PageToolbar = PageShellToolbar;\nexport const PageAdvanced = PageShellAdvanced;\nexport const PageFooter = PageShellFooter;\n"]} \ No newline at end of file diff --git a/components/content/dist/styles.css b/components/content/dist/styles.css index f734684..5c9d433 100644 --- a/components/content/dist/styles.css +++ b/components/content/dist/styles.css @@ -42,6 +42,10 @@ gap: 1.5rem; } +.joo-content-banner { + min-width: 0; +} + .joo-content-identity { display: flex; flex-direction: column; @@ -82,6 +86,13 @@ color: hsl(var(--joo-muted-foreground)); } +.joo-content-breadcrumb-link, +.joo-content-breadcrumb-current { + display: inline-flex; + align-items: center; + gap: 0.25rem; +} + .joo-content-breadcrumb-link { font-weight: 500; color: hsl(187 85% 35%); @@ -92,6 +103,20 @@ color: hsl(187 85% 25%); } +.joo-content-breadcrumb-icon { + display: inline-flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 0.875rem; + height: 0.875rem; +} + +.joo-content-breadcrumb-icon > svg { + width: 0.875rem; + height: 0.875rem; +} + .joo-content-title { font-size: 1.5rem; font-weight: 600; diff --git a/components/content/package.json b/components/content/package.json index bb3eacf..adc8f89 100644 --- a/components/content/package.json +++ b/components/content/package.json @@ -39,7 +39,8 @@ "build": "tsup && cp src/styles.css dist/styles.css", "typecheck": "tsc --noEmit", "test": "vitest run", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" }, "dependencies": { "class-variance-authority": "^0.7.1", diff --git a/components/content/src/PageShell.test.tsx b/components/content/src/PageShell.test.tsx index e8179d4..7c0798b 100644 --- a/components/content/src/PageShell.test.tsx +++ b/components/content/src/PageShell.test.tsx @@ -3,7 +3,12 @@ import "./styles.css"; import { render, screen } from "@testing-library/react"; import { describe, expect, it } from "vitest"; -import { PageShell, PageShellCanvas, PageShellIdentity } from "./components/PageShell"; +import { + PageShell, + PageShellBanner, + PageShellCanvas, + PageShellIdentity, +} from "./components/PageShell"; import "@testing-library/jest-dom/vitest"; @@ -22,4 +27,44 @@ describe("PageShell", () => { expect(screen.getByText("Browse catalog titles.")).toBeInTheDocument(); expect(screen.getByText("Main body")).toBeInTheDocument(); }); + + it("renders breadcrumb icons alongside labels", () => { + render( + + H, + }, + { + label: "Movies", + icon: M, + }, + ]} + /> + , + ); + + expect(screen.getByRole("navigation", { name: "Breadcrumb" })).toBeInTheDocument(); + expect(screen.getByTestId("crumb-home-icon")).toBeInTheDocument(); + expect(screen.getByTestId("crumb-page-icon")).toBeInTheDocument(); + expect(screen.getByRole("link", { name: /Demo/ })).toHaveAttribute("href", "/"); + }); + + it("renders banner/flash above identity", () => { + render( + + +

Saved successfully

+
+ +
, + ); + + expect(screen.getByText("Saved successfully")).toBeInTheDocument(); + expect(screen.getByRole("heading", { name: "Catalog" })).toBeInTheDocument(); + }); }); diff --git a/components/content/src/components/PageShell.tsx b/components/content/src/components/PageShell.tsx index fa04fcb..4787bae 100644 --- a/components/content/src/components/PageShell.tsx +++ b/components/content/src/components/PageShell.tsx @@ -4,6 +4,7 @@ import { ChevronDown } from "lucide-react"; import { cn } from "../lib/cn"; import type { PageShellAdvancedProps, + PageShellBannerProps, PageShellCanvasProps, PageShellContextBarProps, PageShellControlBarProps, @@ -17,6 +18,11 @@ export function PageShell({ children, className }: PageShellProps) { return
{children}
; } +/** Page-scoped flash / notice — place first under PageShell (below app HeaderBar). */ +export function PageShellBanner({ children, className }: PageShellBannerProps) { + return
{children}
; +} + export function PageShellIdentity({ title, subtitle, @@ -29,18 +35,31 @@ export function PageShellIdentity({
{breadcrumbs?.length ? ( ) : null}

{title}

@@ -179,6 +198,7 @@ export function PageShellFooter({ children, className }: PageShellFooterProps) { } /** Aliases aligned with XFlickr-style naming */ +export const PageBanner = PageShellBanner; export const PageIdentity = PageShellIdentity; export const PageToolbar = PageShellToolbar; export const PageAdvanced = PageShellAdvanced; diff --git a/components/content/src/index.ts b/components/content/src/index.ts index f67aed1..a9b0f21 100644 --- a/components/content/src/index.ts +++ b/components/content/src/index.ts @@ -1,5 +1,6 @@ export { PageShell, + PageShellBanner, PageShellIdentity, PageShellControlBar, PageShellToolbar, @@ -8,6 +9,7 @@ export { PageShellCanvas, PageContent, PageShellFooter, + PageBanner, PageIdentity, PageToolbar, PageAdvanced, @@ -16,7 +18,9 @@ export { export type { PageContentVariant, + PageShellBreadcrumbItem, PageShellProps, + PageShellBannerProps, PageShellIdentityProps, PageShellControlBarProps, PageShellToolbarProps, diff --git a/components/content/src/styles.css b/components/content/src/styles.css index f734684..5c9d433 100644 --- a/components/content/src/styles.css +++ b/components/content/src/styles.css @@ -42,6 +42,10 @@ gap: 1.5rem; } +.joo-content-banner { + min-width: 0; +} + .joo-content-identity { display: flex; flex-direction: column; @@ -82,6 +86,13 @@ color: hsl(var(--joo-muted-foreground)); } +.joo-content-breadcrumb-link, +.joo-content-breadcrumb-current { + display: inline-flex; + align-items: center; + gap: 0.25rem; +} + .joo-content-breadcrumb-link { font-weight: 500; color: hsl(187 85% 35%); @@ -92,6 +103,20 @@ color: hsl(187 85% 25%); } +.joo-content-breadcrumb-icon { + display: inline-flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 0.875rem; + height: 0.875rem; +} + +.joo-content-breadcrumb-icon > svg { + width: 0.875rem; + height: 0.875rem; +} + .joo-content-title { font-size: 1.5rem; font-weight: 600; diff --git a/components/content/src/types.ts b/components/content/src/types.ts index c1d53c0..70fe4cb 100644 --- a/components/content/src/types.ts +++ b/components/content/src/types.ts @@ -1,17 +1,30 @@ -import type { FormEvent, ReactNode } from "react"; +import type { ReactNode } from "react"; export type PageContentVariant = "plain" | "card" | "flush"; +export type PageShellBreadcrumbItem = { + label: string; + href?: string; + /** Optional leading icon (typically a Lucide element). */ + icon?: ReactNode; +}; + export type PageShellProps = { children: ReactNode; className?: string; }; +/** Page-scoped flash / notice slot (place as first child of PageShell, under app header). */ +export type PageShellBannerProps = { + children: ReactNode; + className?: string; +}; + export type PageShellIdentityProps = { title: string; subtitle?: string; actions?: ReactNode; - breadcrumbs?: Array<{ label: string; href?: string }>; + breadcrumbs?: PageShellBreadcrumbItem[]; className?: string; }; From 9c61a8d7a94c70b9effb848ba8df5228ceeb5f24 Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:24 -0600 Subject: [PATCH 07/14] feat(config): move Create CTAs to PageShell Identity Expose ConfigPanelHandle.openCreate and remove built-in panel Create buttons. --- components/config/AGENTS.md | 14 ++- components/config/CHANGELOG.md | 9 ++ components/config/README.md | 56 +++++++++- components/config/dist/index.d.ts | 17 +-- components/config/dist/index.js | 25 ++--- components/config/dist/index.js.map | 2 +- components/config/package.json | 3 +- .../config/src/components/ConfigPanel.tsx | 102 +++++++++--------- .../src/components/ConfigTreeBrowser.tsx | 7 +- components/config/src/index.ts | 1 + components/config/src/types.ts | 10 +- 11 files changed, 157 insertions(+), 89 deletions(-) create mode 100644 components/config/CHANGELOG.md diff --git a/components/config/AGENTS.md b/components/config/AGENTS.md index bf49f06..7ec72e0 100644 --- a/components/config/AGENTS.md +++ b/components/config/AGENTS.md @@ -22,7 +22,19 @@ npm run build `react`, `react-dom`, `lucide-react` +## Primary actions (PageShell — required) + +When `ConfigPanel` sits on a PageShell page: + +1. **Create / New / Publish / Export / view-level Delete** → **only** `PageShellIdentity` → `actions` via `@jooservices/react-action-buttons`. **No exceptions.** +2. Wire create with `ref` → `ConfigPanelHandle.openCreate()` from the Identity button. +3. **Do not** render Create / New / other page CTAs inside `ConfigPanel` (no built-in New button, no empty-state Create CTA). +4. **Allowed local only:** search, tab chrome, expert/technical toggles, per-row edit/delete, `headerActions` for non-primary local chrome. + +See `components/content/AGENTS.md` and `docs/02-user-guide/02-react-config.md`. + ## Docs -- User guide: `docs/02-user-guide/` (matching package page) +- User guide: `docs/02-user-guide/02-react-config.md` (consumer API — do not send humans to `src/`) +- Package README: `components/config/README.md` - Root policy: `AGENTS.md` diff --git a/components/config/CHANGELOG.md b/components/config/CHANGELOG.md new file mode 100644 index 0000000..f35c879 --- /dev/null +++ b/components/config/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## [Unreleased] + +### Changed + +- Removed built-in panel / empty-state **Create** / **New** buttons — view-level create belongs in `PageShellIdentity` → `actions` +- `ConfigPanel` is `forwardRef` exposing `ConfigPanelHandle.openCreate()` for Identity wiring +- `features.create` removed; `headerActions` is `ReactNode` only (local chrome, not primary CTAs) diff --git a/components/config/README.md b/components/config/README.md index 047d1ef..d8a22e7 100644 --- a/components/config/README.md +++ b/components/config/README.md @@ -5,18 +5,63 @@ Schema-driven configuration panel for React — declarative tabs, grouped browse ## Install ```bash -npm install @jooservices/react-config lucide-react +pnpm add "github:jooservices/react#v1.0.0&path:components/config" ``` +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). + ## Setup ```tsx import "@jooservices/react-config/styles.css"; ``` -Pair with [`@jooservices/react-content`](https://www.npmjs.com/package/@jooservices/react-content) for page shell layout. +Pair with [`@jooservices/react-content`](`@jooservices/react-content` (git install)) `PageShell` and [`@jooservices/react-action-buttons`](`@jooservices/react-action-buttons` (git install)) for page primary actions. + +## Primary actions (required) + +**Create / New / Publish / Export / other view-level CTAs** must live in `PageShellIdentity` → `actions` — **not** inside `ConfigPanel`. + +```tsx +import { useRef } from "react"; +import { ActionBar, Button } from "@jooservices/react-action-buttons"; +import { ConfigPanel, type ConfigPanelHandle } from "@jooservices/react-config"; +import { PageShell, PageShellIdentity, PageShellCanvas } from "@jooservices/react-content"; +import { Plus } from "lucide-react"; + +const panelRef = useRef(null); + + + + + + } + /> + + { + /* PATCH or POST */ + }} + onDelete={async (path) => { + /* per-row delete handler; view-level bulk delete stays in Identity */ + }} + /> + + +``` + +`ConfigPanel` does **not** render its own New / Create primary button. Row edit/delete remain local. -## Usage +## Usage (panel only) ```tsx import { ConfigPanel, type ConfigEntry, type ConfigTabDef } from "@jooservices/react-config"; @@ -37,7 +82,7 @@ const tabs: ConfigTabDef[] = [ // PATCH or POST via your API client }} onDelete={async (path) => { - // DELETE via your API client + // DELETE via your API client (row-level) }} /> ``` @@ -52,7 +97,8 @@ const tabs: ConfigTabDef[] = [ | Export | Purpose | |--------|---------| -| `ConfigPanel` | Full UI: tabs, search, toggles, browser, dialog | +| `ConfigPanel` | Full UI: tabs, search, toggles, browser, dialog (`ref` → `openCreate`) | +| `ConfigPanelHandle` | Imperative `{ openCreate() }` for Identity primary Create | | `ConfigTreeBrowser` | Lower-level grouped rows (custom layouts) | | `ConfigRecordForm` | Modal form only | | `resolveEntryTabId`, `partitionEntriesByTab` | Tab routing helpers | diff --git a/components/config/dist/index.d.ts b/components/config/dist/index.d.ts index bffa65c..1890dc3 100644 --- a/components/config/dist/index.d.ts +++ b/components/config/dist/index.d.ts @@ -61,7 +61,10 @@ type ConfigPanelFeatures = { search?: boolean; expertToggle?: boolean; technicalKeysToggle?: boolean; - create?: boolean; +}; +/** Imperative helpers for PageShell Identity primary actions (create / open editor). */ +type ConfigPanelHandle = { + openCreate: () => void; }; type ConfigGeneralTabDef = { id?: string; @@ -82,9 +85,8 @@ type ConfigPanelProps = { valueTypes?: ConfigValueType[]; features?: ConfigPanelFeatures; contextBar?: ReactNode | ((activeTab: string) => ReactNode); - headerActions?: ReactNode | ((helpers: { - openCreate: () => void; - }) => ReactNode); + /** Local / non-primary chrome only — do not put Create / view CTAs here; use PageShellIdentity + `ConfigPanelHandle`. */ + headerActions?: ReactNode; siteOverridePanel?: SiteOverridePanelProps | null; showSiteOverridePanel?: boolean; tab?: string; @@ -147,14 +149,13 @@ type ConfigTreeBrowserProps = { onNavigateEntry: (entry: ConfigEntry, tabId: string) => void; onNavigateSite: (siteSlug: string) => void; onClearSearch: () => void; - onOpenCreate: () => void; onToggleGroup: (group: string) => void; isGroupCollapsed: (group: string, tier: ConfigTier) => boolean; }; -declare function ConfigPanel({ tabs, generalTab, entries, rawEntries, valueTypes, features, contextBar, headerActions, siteOverridePanel, showSiteOverridePanel, tab: controlledTab, defaultTab, onTabChange, query: controlledQuery, defaultQuery, onQueryChange, showExpert: controlledShowExpert, defaultShowExpert, onShowExpertChange, showTechnicalKeys: controlledShowTechnicalKeys, defaultShowTechnicalKeys, onShowTechnicalKeysChange, onSave, onDelete, onNavigateSite, processing, errors, searchPlaceholder, className, }: ConfigPanelProps): react.JSX.Element; +declare const ConfigPanel: react.ForwardRefExoticComponent>; -declare function ConfigTreeBrowser({ entries, searchEntries, rawEntries, sites, activeTab, rawTabIds, showExpert, showTechnicalKeys, normalizedQuery, isSearching, siteOverridePanel, showSiteOverridePanel, tabLabel, resolveTabId, onEdit, onRemove, onNavigateEntry, onNavigateSite, onClearSearch, onOpenCreate, onToggleGroup, isGroupCollapsed, }: ConfigTreeBrowserProps): react.JSX.Element; +declare function ConfigTreeBrowser({ entries, searchEntries, rawEntries, sites, activeTab, rawTabIds, showExpert, showTechnicalKeys, normalizedQuery, isSearching, siteOverridePanel, showSiteOverridePanel, tabLabel, resolveTabId, onEdit, onRemove, onNavigateEntry, onNavigateSite, onClearSearch, onToggleGroup, isGroupCollapsed, }: ConfigTreeBrowserProps): react.JSX.Element; declare function ConfigRecordForm({ editing, types, path, type, value, errors, processing, onPathChange, onTypeChange, onValueChange, onSubmit, onCancel, }: ConfigRecordFormProps): react.JSX.Element; @@ -173,4 +174,4 @@ declare function entryBreadcrumb(entry: ConfigEntry, tabLabel: string, sites: { name: string; }[]): string; -export { type ConfigEntry, type ConfigFormData, type ConfigGeneralTabDef, ConfigPanel, type ConfigPanelFeatures, type ConfigPanelProps, type ConfigRecord, ConfigRecordForm, type ConfigRecordFormProps, type ConfigSiteContext, type ConfigSiteOverride, type ConfigTabDef, type ConfigTier, ConfigTreeBrowser, type ConfigTreeBrowserProps, type ConfigValueType, type SiteOverridePanelProps, displayValue, entryBreadcrumb, formatConfigDate, generalTabId, isConfigEntry, parseValue, partitionEntriesByTab, resolveEntryTabId, valueToText }; +export { type ConfigEntry, type ConfigFormData, type ConfigGeneralTabDef, ConfigPanel, type ConfigPanelFeatures, type ConfigPanelHandle, type ConfigPanelProps, type ConfigRecord, ConfigRecordForm, type ConfigRecordFormProps, type ConfigSiteContext, type ConfigSiteOverride, type ConfigTabDef, type ConfigTier, ConfigTreeBrowser, type ConfigTreeBrowserProps, type ConfigValueType, type SiteOverridePanelProps, displayValue, entryBreadcrumb, formatConfigDate, generalTabId, isConfigEntry, parseValue, partitionEntriesByTab, resolveEntryTabId, valueToText }; diff --git a/components/config/dist/index.js b/components/config/dist/index.js index a89a200..8045129 100644 --- a/components/config/dist/index.js +++ b/components/config/dist/index.js @@ -1,5 +1,5 @@ -import { Copy, Pencil, Trash2, Search, X, ChevronRight, ChevronDown } from 'lucide-react'; -import { useMemo, useState, useId, useRef, useEffect } from 'react'; +import { Search, X, Pencil, Trash2, Copy, ChevronRight, ChevronDown } from 'lucide-react'; +import { forwardRef, useMemo, useState, useCallback, useImperativeHandle, useId, useRef, useEffect } from 'react'; import { clsx } from 'clsx'; import { jsxs, jsx } from 'react/jsx-runtime'; @@ -430,7 +430,6 @@ function ConfigTreeBrowser({ onNavigateEntry, onNavigateSite, onClearSearch, - onOpenCreate, onToggleGroup, isGroupCollapsed }) { @@ -612,7 +611,7 @@ function ConfigTreeBrowser({ EmptyState, { title: "No configs found", - action: /* @__PURE__ */ jsx(Button, { type: "button", onClick: onOpenCreate, children: "Create config" }) + message: "Use the page primary action to create a config." } ); } @@ -726,7 +725,7 @@ function useControllable(controlled, defaultValue, onChange) { }; return [value, setValue]; } -function ConfigPanel({ +var ConfigPanel = forwardRef(function ConfigPanel2({ tabs, generalTab = true, entries, @@ -756,7 +755,7 @@ function ConfigPanel({ errors = {}, searchPlaceholder = "Search settings by name, description, site, or key", className -}) { +}, ref) { const generalId = generalTabId(generalTab); const generalEnabled = generalTab !== false; const generalLabel = generalTab && typeof generalTab === "object" && generalTab.label ? generalTab.label : "General"; @@ -794,11 +793,12 @@ function ConfigPanel({ const isSearching = features?.search !== false && normalizedQuery !== ""; const activeEntries = rawTabIds.includes(activeTab) ? [] : partition.get(activeTab) ?? []; const tabLabel = (tabId) => visibleTabs.find((tab) => tab.id === tabId)?.label ?? tabId; - const openCreate = () => { + const openCreate = useCallback(() => { setEditing(null); setForm({ path: "", type: "string", value: "" }); setModalOpen(true); - }; + }, []); + useImperativeHandle(ref, () => ({ openCreate }), [openCreate]); const openEdit = (config) => { setEditing(config); const rawValue = "effective_value" in config ? config.effective_value : config.value; @@ -857,12 +857,8 @@ function ConfigPanel({ ] }); const resolvedContextBar = typeof contextBar === "function" ? contextBar(activeTab) : contextBar; const modalTitle = editing ? "effective_value" in editing ? editing.label : `Edit ${editing.path}` : "New config"; - const resolvedHeaderActions = typeof headerActions === "function" ? headerActions({ openCreate }) : headerActions; return /* @__PURE__ */ jsxs("div", { className: cn("joo-config-panel", className), children: [ - /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexWrap: "wrap", justifyContent: "space-between", gap: "0.75rem" }, children: [ - resolvedHeaderActions ? /* @__PURE__ */ jsx("div", { children: resolvedHeaderActions }) : /* @__PURE__ */ jsx("span", {}), - features?.create !== false ? /* @__PURE__ */ jsx(Button, { type: "button", onClick: openCreate, children: "New" }) : null - ] }), + headerActions ? /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", justifyContent: "flex-end", gap: "0.75rem" }, children: headerActions }) : null, /* @__PURE__ */ jsx("div", { className: "joo-config-tabs", children: visibleTabs.map((tab) => { const Icon = tab.icon; return /* @__PURE__ */ jsxs( @@ -927,7 +923,6 @@ function ConfigPanel({ onNavigateSite?.(siteSlug); }, onClearSearch: () => setQuery(""), - onOpenCreate: openCreate, onToggleGroup: toggleGroup, isGroupCollapsed } @@ -952,7 +947,7 @@ function ConfigPanel({ } ) }) ] }); -} +}); export { ConfigPanel, ConfigRecordForm, ConfigTreeBrowser, displayValue, entryBreadcrumb, formatConfigDate, generalTabId, isConfigEntry, parseValue, partitionEntriesByTab, resolveEntryTabId, valueToText }; //# sourceMappingURL=index.js.map diff --git a/components/config/dist/index.js.map b/components/config/dist/index.js.map index ea6d939..92a8c72 100644 --- a/components/config/dist/index.js.map +++ b/components/config/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/lib/config-utils.ts","../src/lib/cn.ts","../src/components/ui/Button.tsx","../src/components/ui/Input.tsx","../src/components/ConfigRecordForm.tsx","../src/components/ui/Badge.tsx","../src/components/ui/EmptyState.tsx","../src/components/ConfigTreeBrowser.tsx","../src/components/ui/Dialog.tsx","../src/components/ConfigPanel.tsx"],"names":["jsx","jsxs","useMemo","Search"],"mappings":"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","file":"index.js","sourcesContent":["import type { ConfigEntry, ConfigRecord, ConfigTabDef, ConfigValueType } from \"../types\";\n\nexport type { ConfigFormData } from \"../types\";\n\nexport function isConfigEntry(\n config: ConfigEntry | ConfigRecord | null,\n): config is ConfigEntry {\n return config !== null && \"effective_value\" in config;\n}\n\nexport function valueToText(value: unknown, type?: ConfigValueType): string {\n if (type === \"null\" || value === null || value === undefined) {\n return \"\";\n }\n\n if (type === \"bool\") {\n return value ? \"true\" : \"false\";\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value, null, 2);\n }\n\n return String(value);\n}\n\nexport function parseValue(raw: string, type: ConfigValueType): unknown {\n if (type === \"null\") {\n return null;\n }\n\n if (type === \"bool\") {\n return raw === \"true\" || raw === \"1\";\n }\n\n if (type === \"int\") {\n return Number.parseInt(raw, 10);\n }\n\n if (type === \"float\") {\n return Number.parseFloat(raw);\n }\n\n if (type === \"array\" || type === \"json\") {\n return JSON.parse(raw);\n }\n\n return raw;\n}\n\nexport function displayValue(\n value: unknown,\n type?: ConfigValueType,\n sensitive = false,\n): string {\n if (sensitive && value !== null && value !== undefined && value !== \"\") {\n return \"••••••••\";\n }\n\n if (type === \"null\" || value === null || value === undefined) {\n return \"null\";\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n\n return String(value);\n}\n\nexport function formatConfigDate(iso: string | null | undefined): string {\n if (!iso) {\n return \"-\";\n }\n\n try {\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(new Date(iso));\n } catch {\n return iso;\n }\n}\n\nconst DEFAULT_GENERAL_TAB_ID = \"general\";\n\nexport function generalTabId(generalTab?: boolean | { id?: string }): string {\n if (generalTab && typeof generalTab === \"object\" && generalTab.id) {\n return generalTab.id;\n }\n\n return DEFAULT_GENERAL_TAB_ID;\n}\n\nexport function curatedTabs(tabs: ConfigTabDef[]): ConfigTabDef[] {\n return tabs.filter((tab) => tab.mode !== \"raw\");\n}\n\nexport function rawTabs(tabs: ConfigTabDef[]): ConfigTabDef[] {\n return tabs.filter((tab) => tab.mode === \"raw\");\n}\n\nexport function resolveEntryTabId(entry: ConfigEntry, tabs: ConfigTabDef[]): string | null {\n for (const tab of curatedTabs(tabs)) {\n if (tab.filter?.(entry)) {\n return tab.id;\n }\n\n if (tab.groups?.includes(entry.group_label)) {\n return tab.id;\n }\n }\n\n return null;\n}\n\nexport function partitionEntriesByTab(\n entries: ConfigEntry[],\n tabs: ConfigTabDef[],\n generalTabIdValue: string,\n): Map {\n const curated = curatedTabs(tabs);\n const buckets = new Map();\n\n for (const tab of curated) {\n buckets.set(tab.id, []);\n }\n\n buckets.set(generalTabIdValue, []);\n\n for (const entry of entries) {\n const tabId = resolveEntryTabId(entry, curated) ?? generalTabIdValue;\n const bucket = buckets.get(tabId) ?? buckets.get(generalTabIdValue) ?? [];\n bucket.push(entry);\n buckets.set(tabId, bucket);\n }\n\n return buckets;\n}\n\nexport function entryBreadcrumb(\n entry: ConfigEntry,\n tabLabel: string,\n sites: { slug: string; name: string }[],\n): string {\n const siteSlug = typeof entry.meta?.site_slug === \"string\" ? entry.meta.site_slug : undefined;\n if (siteSlug) {\n const site = sites.find((item) => item.slug === siteSlug);\n return `${tabLabel} › ${site?.name ?? siteSlug} › ${entry.group_label}`;\n }\n\n return `${tabLabel} › ${entry.group_label}`;\n}\n","import { clsx, type ClassValue } from \"clsx\";\n\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs);\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\ntype Variant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\";\n\nexport function Button({\n className,\n variant = \"primary\",\n iconOnly = false,\n children,\n type = \"button\",\n ...props\n}: ButtonHTMLAttributes & {\n variant?: Variant;\n iconOnly?: boolean;\n children?: ReactNode;\n}) {\n return (\n \n {children}\n \n );\n}\n","import type { InputHTMLAttributes } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport function Input({ className, ...props }: InputHTMLAttributes) {\n return ;\n}\n","import { Copy } from \"lucide-react\";\n\nimport { isConfigEntry } from \"../lib/config-utils\";\nimport type { ConfigEntry, ConfigRecordFormProps, ConfigValueType } from \"../types\";\nimport { Button } from \"./ui/Button\";\nimport { Input } from \"./ui/Input\";\n\nasync function copyText(text: string): Promise {\n await navigator.clipboard.writeText(text);\n}\n\nfunction resolveSelectChoices(\n options?: string[],\n optionLabels?: Record,\n): Array<{ value: string; label: string }> {\n if (!options?.length) {\n return [];\n }\n\n return options.map((option) => ({\n value: option,\n label: optionLabels?.[option] ?? option,\n }));\n}\n\nfunction typeInput(\n type: ConfigValueType,\n value: string,\n setValue: (value: string) => void,\n options?: string[],\n optionLabels?: Record,\n) {\n if (type === \"bool\") {\n return (\n setValue(event.target.value)}\n >\n \n \n \n );\n }\n\n const choices = resolveSelectChoices(options, optionLabels);\n if (type === \"string\" && choices.length > 0) {\n return (\n setValue(event.target.value)}\n >\n {choices.map((choice) => (\n \n ))}\n \n );\n }\n\n if (type === \"array\" || type === \"json\") {\n return (\n setValue(event.target.value)}\n rows={7}\n />\n );\n }\n\n if (type === \"null\") {\n return ;\n }\n\n return (\n setValue(event.target.value)}\n />\n );\n}\n\nexport function ConfigRecordForm({\n editing,\n types,\n path,\n type,\n value,\n errors,\n processing,\n onPathChange,\n onTypeChange,\n onValueChange,\n onSubmit,\n onCancel,\n}: ConfigRecordFormProps) {\n const curatedEntry =\n editing !== null && \"effective_value\" in editing ? (editing as ConfigEntry) : null;\n\n return (\n
\n {curatedEntry ? (\n
\n

{curatedEntry.description}

\n
\n Technical key\n {curatedEntry.path}\n \n Type\n {curatedEntry.type}\n \n Source\n {curatedEntry.source}\n \n
\n
\n ) : null}\n {editing && !curatedEntry ? (\n
\n
\n \n \n {errors.path ?

{errors.path}

: null}\n
\n
\n \n onTypeChange(event.target.value as ConfigValueType)}\n >\n {types.map((option) => (\n \n ))}\n \n {errors.type ?

{errors.type}

: null}\n
\n
\n ) : !editing ? (\n
\n
\n \n onPathChange(event.target.value)} placeholder=\"group.key\" />\n {errors.path ?

{errors.path}

: null}\n
\n
\n \n onTypeChange(event.target.value as ConfigValueType)}\n >\n {types.map((option) => (\n \n ))}\n \n {errors.type ?

{errors.type}

: null}\n
\n
\n ) : null}\n
\n \n {typeInput(\n type,\n value,\n onValueChange,\n curatedEntry?.meta?.options as string[] | undefined,\n curatedEntry?.meta?.option_labels as Record | undefined,\n )}\n {errors.value ?

{errors.value}

: null}\n
\n
\n \n \n
\n
\n );\n}\n","import type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport function Badge({\n children,\n tone = \"slate\",\n className,\n}: {\n children: ReactNode;\n tone?: \"slate\" | \"cyan\" | \"amber\";\n className?: string;\n}) {\n return (\n \n {children}\n \n );\n}\n","import type { ReactNode } from \"react\";\n\nexport function EmptyState({\n title,\n message,\n action,\n}: {\n title: string;\n message?: string;\n action?: ReactNode;\n}) {\n return (\n
\n

{title}

\n {message ?

{message}

: null}\n {action ?
{action}
: null}\n
\n );\n}\n","import {\n ChevronDown,\n ChevronRight,\n DatabaseZap,\n Pencil,\n Search,\n Settings,\n Trash2,\n} from \"lucide-react\";\nimport { useMemo } from \"react\";\n\nimport { displayValue, entryBreadcrumb, formatConfigDate } from \"../lib/config-utils\";\nimport { cn } from \"../lib/cn\";\nimport type {\n ConfigEntry,\n ConfigRecord,\n ConfigSiteContext,\n ConfigTreeBrowserProps,\n} from \"../types\";\nimport { Badge } from \"./ui/Badge\";\nimport { Button } from \"./ui/Button\";\nimport { EmptyState } from \"./ui/EmptyState\";\n\ntype SearchHit =\n | { kind: \"entry\"; breadcrumb: string; item: ConfigEntry; tabId: string }\n | {\n kind: \"override\";\n breadcrumb: string;\n siteSlug: string;\n row: ConfigSiteContext[\"overrides\"][number];\n }\n | { kind: \"raw\"; breadcrumb: string; config: ConfigRecord };\n\nfunction sourceTone(source: string): \"cyan\" | \"slate\" | \"amber\" {\n if (source === \"config-store\" || source === \"runtime-global\") {\n return \"cyan\";\n }\n\n if (source === \"site-record\") {\n return \"amber\";\n }\n\n return \"slate\";\n}\n\nfunction searchableText(parts: Array): string {\n return parts\n .filter((part) => typeof part === \"string\" && part !== \"\")\n .join(\" \")\n .toLowerCase();\n}\n\nfunction matchesQuery(query: string, parts: Array): boolean {\n const normalized = query.trim().toLowerCase();\n if (!normalized) {\n return true;\n }\n return searchableText(parts).includes(normalized);\n}\n\nfunction searchScore(query: string, parts: Array): number {\n const normalized = query.trim().toLowerCase();\n const label = (parts[0] ?? \"\").toLowerCase();\n if (!normalized) {\n return 0;\n }\n if (label.startsWith(normalized)) {\n return 0;\n }\n if (label.includes(normalized)) {\n return 1;\n }\n if (searchableText(parts.slice(1)).includes(normalized)) {\n return 2;\n }\n return 3;\n}\n\nfunction ConfigRow({\n item,\n onEdit,\n onRemove,\n showTechnicalKeys,\n breadcrumb,\n onNavigate,\n}: {\n item: ConfigEntry;\n onEdit: (item: ConfigEntry) => void;\n onRemove: (path: string) => void;\n showTechnicalKeys: boolean;\n breadcrumb?: string;\n onNavigate?: (item: ConfigEntry) => void;\n}) {\n const subtitle = showTechnicalKeys ? item.path : item.description;\n\n return (\n
\n
\n {breadcrumb ? (\n
\n {breadcrumb}\n {item.tier === \"expert\" ? expert : null}\n {onNavigate ? (\n \n ) : null}\n
\n ) : null}\n
{item.label}
\n
\n {subtitle}\n
\n
\n
\n {displayValue(item.effective_value, item.type, item.sensitive)}\n {item.source}\n
\n
\n \n {item.stored ? (\n \n ) : null}\n
\n
\n );\n}\n\nfunction ConfigGroupSection({\n group,\n items,\n collapsed,\n onToggle,\n onEdit,\n onRemove,\n showTechnicalKeys,\n}: {\n group: string;\n items: ConfigEntry[];\n collapsed: boolean;\n onToggle: (group: string) => void;\n onEdit: (item: ConfigEntry) => void;\n onRemove: (path: string) => void;\n showTechnicalKeys: boolean;\n}) {\n return (\n
\n \n {!collapsed ? (\n
\n {items.map((item) => (\n \n ))}\n
\n ) : null}\n
\n );\n}\n\nexport function ConfigTreeBrowser({\n entries,\n searchEntries,\n rawEntries,\n sites,\n activeTab,\n rawTabIds,\n showExpert,\n showTechnicalKeys,\n normalizedQuery,\n isSearching,\n siteOverridePanel,\n showSiteOverridePanel = false,\n tabLabel,\n resolveTabId,\n onEdit,\n onRemove,\n onNavigateEntry,\n onNavigateSite,\n onClearSearch,\n onOpenCreate,\n onToggleGroup,\n isGroupCollapsed,\n}: ConfigTreeBrowserProps) {\n const isRawTab = rawTabIds.includes(activeTab);\n const searchableEntries = searchEntries ?? entries;\n\n const visibleEntries = useMemo(() => {\n const tierFilter = (item: ConfigEntry) => showExpert || item.tier !== \"expert\";\n return entries.filter(tierFilter);\n }, [entries, showExpert]);\n\n const groupedEntries = useMemo(() => {\n return visibleEntries.reduce>((groups, item) => {\n const group = groups[item.group_label] ?? [];\n group.push(item);\n groups[item.group_label] = group;\n return groups;\n }, {});\n }, [visibleEntries]);\n\n const sortedGroups = Object.entries(groupedEntries).sort(([, leftItems], [, rightItems]) => {\n const leftSort = leftItems[0]?.sort ?? 0;\n const rightSort = rightItems[0]?.sort ?? 0;\n return leftSort - rightSort || (leftItems[0]?.group_label ?? \"\").localeCompare(rightItems[0]?.group_label ?? \"\");\n });\n\n const entryPaths = useMemo(() => new Set(searchableEntries.map((entry) => entry.path)), [searchableEntries]);\n\n const searchHits = useMemo((): SearchHit[] => {\n if (!isSearching) {\n return [];\n }\n\n const hits: Array = [];\n\n searchableEntries.forEach((item) => {\n if (\n !matchesQuery(normalizedQuery, [\n item.label,\n item.description,\n item.path,\n item.group_label,\n displayValue(item.effective_value, item.type),\n ])\n ) {\n return;\n }\n\n hits.push({\n kind: \"entry\",\n breadcrumb: entryBreadcrumb(item, tabLabel(resolveTabId?.(item) ?? activeTab), sites),\n item,\n tabId: resolveTabId?.(item) ?? activeTab,\n score: searchScore(normalizedQuery, [item.label, item.description, item.path, item.group_label]),\n });\n });\n\n sites.forEach((site) => {\n site.overrides.forEach((row) => {\n if (\n !matchesQuery(normalizedQuery, [\n row.label,\n row.description,\n row.key,\n site.name,\n site.slug,\n displayValue(row.effective_value, row.type),\n ])\n ) {\n return;\n }\n\n hits.push({\n kind: \"override\",\n breadcrumb: `Site › ${site.name}`,\n siteSlug: site.slug,\n row,\n score: searchScore(normalizedQuery, [row.label, row.description, row.key]),\n });\n });\n });\n\n rawEntries.forEach((config) => {\n if (entryPaths.has(config.path)) {\n return;\n }\n\n if (!matchesQuery(normalizedQuery, [config.path, config.type, displayValue(config.value, config.type)])) {\n return;\n }\n\n hits.push({\n kind: \"raw\",\n breadcrumb: \"Raw store\",\n config,\n score: searchScore(normalizedQuery, [config.path, config.type, displayValue(config.value, config.type)]),\n });\n });\n\n return hits.sort((left, right) => left.score - right.score || left.breadcrumb.localeCompare(right.breadcrumb));\n }, [searchableEntries, entryPaths, isSearching, normalizedQuery, rawEntries, sites, activeTab, tabLabel, resolveTabId]);\n\n const filteredRaw = useMemo(() => {\n if (!isSearching) {\n return rawEntries;\n }\n\n return rawEntries.filter((config) =>\n matchesQuery(normalizedQuery, [config.path, config.type, displayValue(config.value, config.type)]),\n );\n }, [isSearching, normalizedQuery, rawEntries]);\n\n const selectedSite =\n siteOverridePanel?.sites.find((site) => site.slug === siteOverridePanel.selectedSiteSlug) ?? null;\n\n const siteOverrideRows =\n selectedSite?.overrides.filter((row) => row.has_site_value || row.runtime_stored) ?? [];\n\n if (isSearching) {\n return (\n
\n
\n

\n Search results for "{normalizedQuery}" · {searchHits.length}{\" \"}\n {searchHits.length === 1 ? \"match\" : \"matches\"}\n

\n \n
\n {searchHits.length ? (\n
\n {searchHits.map((hit) => {\n if (hit.kind === \"entry\") {\n return (\n onNavigateEntry(hit.item, hit.tabId)}\n onEdit={onEdit}\n onRemove={onRemove}\n showTechnicalKeys={showTechnicalKeys}\n />\n );\n }\n\n if (hit.kind === \"override\") {\n return (\n
\n
\n
\n {hit.breadcrumb}\n \n
\n
{hit.row.label}
\n
\n {showTechnicalKeys ? hit.row.key : hit.row.description}\n
\n
\n
\n {displayValue(hit.row.effective_value, hit.row.type)}\n {hit.row.effective_source}\n
\n
\n );\n }\n\n return (\n
\n
\n
{hit.breadcrumb}
\n
\n {hit.config.path}\n
\n
\n
\n {displayValue(hit.config.value, hit.config.type)}\n {hit.config.type}\n
\n
\n \n \n
\n
\n );\n })}\n
\n ) : (\n \n )}\n
\n );\n }\n\n if (isRawTab) {\n return filteredRaw.length ? (\n
\n \n \n \n \n \n \n \n \n \n \n \n {filteredRaw.map((config) => (\n \n \n \n \n \n \n \n ))}\n \n
PathTypeValueUpdatedActions
{config.path}\n {config.type}\n {displayValue(config.value, config.type)}{formatConfigDate(config.updated_at)}\n
\n \n \n
\n
\n
\n ) : (\n \n Create config\n \n }\n />\n );\n }\n\n return (\n
\n {showSiteOverridePanel && siteOverridePanel ? (\n
\n
\n Site record overrides\n {selectedSite ? siteOverridePanel.renderEditLink(selectedSite) : (\n No site record for this slug.\n )}\n
\n
\n {siteOverrideRows.length ? (\n siteOverrideRows.map((row) => (\n
\n
\n
{row.label}
\n
\n {showTechnicalKeys ? row.key : row.description}\n
\n
\n
\n {displayValue(row.effective_value, row.type)}\n {row.effective_source}\n
\n
\n ))\n ) : (\n
No site-record overrides for this context.
\n )}\n
\n
\n ) : null}\n\n {sortedGroups.length ? (\n sortedGroups.map(([group, items]) => (\n \n ))\n ) : siteOverrideRows.length === 0 ? (\n \n ) : null}\n
\n );\n}\n","import { useEffect, useId, useRef, type ReactNode } from \"react\";\n\nexport function Dialog({\n open,\n title,\n children,\n onClose,\n}: {\n open: boolean;\n title: string;\n children?: ReactNode;\n onClose: () => void;\n}) {\n const titleId = useId();\n const panelRef = useRef(null);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n panelRef.current?.focus();\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [open, onClose]);\n\n if (!open) {\n return null;\n }\n\n return (\n {\n if (event.target === event.currentTarget) {\n onClose();\n }\n }}\n >\n \n

\n {title}\n

\n {children ?
{children}
: null}\n
\n \n );\n}\n","import { Search, X } from \"lucide-react\";\nimport { type FormEvent, useMemo, useState } from \"react\";\n\nimport {\n generalTabId,\n isConfigEntry,\n partitionEntriesByTab,\n parseValue,\n rawTabs,\n resolveEntryTabId,\n valueToText,\n} from \"../lib/config-utils\";\nimport { cn } from \"../lib/cn\";\nimport type {\n ConfigEntry,\n ConfigFormData,\n ConfigPanelProps,\n ConfigRecord,\n ConfigTier,\n ConfigValueType,\n} from \"../types\";\nimport { ConfigRecordForm } from \"./ConfigRecordForm\";\nimport { ConfigTreeBrowser } from \"./ConfigTreeBrowser\";\nimport { Button } from \"./ui/Button\";\nimport { Dialog } from \"./ui/Dialog\";\nimport { Input } from \"./ui/Input\";\n\nconst DEFAULT_VALUE_TYPES: ConfigValueType[] = [\n \"string\",\n \"int\",\n \"float\",\n \"bool\",\n \"array\",\n \"json\",\n \"null\",\n];\n\nfunction useControllable(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void,\n): [T, (value: T) => void] {\n const [internal, setInternal] = useState(defaultValue);\n const value = controlled ?? internal;\n const setValue = (next: T) => {\n if (controlled === undefined) {\n setInternal(next);\n }\n onChange?.(next);\n };\n return [value, setValue];\n}\n\nexport function ConfigPanel({\n tabs,\n generalTab = true,\n entries,\n rawEntries = [],\n valueTypes = DEFAULT_VALUE_TYPES,\n features,\n contextBar,\n headerActions,\n siteOverridePanel,\n showSiteOverridePanel = false,\n tab: controlledTab,\n defaultTab,\n onTabChange,\n query: controlledQuery,\n defaultQuery = \"\",\n onQueryChange,\n showExpert: controlledShowExpert,\n defaultShowExpert = false,\n onShowExpertChange,\n showTechnicalKeys: controlledShowTechnicalKeys,\n defaultShowTechnicalKeys = false,\n onShowTechnicalKeysChange,\n onSave,\n onDelete,\n onNavigateSite,\n processing = false,\n errors = {},\n searchPlaceholder = \"Search settings by name, description, site, or key\",\n className,\n}: ConfigPanelProps) {\n const generalId = generalTabId(generalTab);\n const generalEnabled = generalTab !== false;\n const generalLabel =\n generalTab && typeof generalTab === \"object\" && generalTab.label ? generalTab.label : \"General\";\n const hideGeneralWhenEmpty =\n generalTab === false\n ? true\n : generalTab && typeof generalTab === \"object\"\n ? generalTab.hideWhenEmpty !== false\n : true;\n\n const rawTabIds = useMemo(() => rawTabs(tabs).map((tab) => tab.id), [tabs]);\n const curatedTabDefs = useMemo(() => tabs.filter((tab) => tab.mode !== \"raw\"), [tabs]);\n\n const partition = useMemo(\n () => partitionEntriesByTab(entries, tabs, generalId),\n [entries, generalId, tabs],\n );\n\n const generalCount = partition.get(generalId)?.length ?? 0;\n const showGeneralTab = generalEnabled && (!hideGeneralWhenEmpty || generalCount > 0);\n\n const visibleTabs = useMemo(() => {\n const list = [...curatedTabDefs];\n if (showGeneralTab) {\n list.push({ id: generalId, label: generalLabel });\n }\n list.push(...rawTabs(tabs));\n return list;\n }, [curatedTabDefs, generalId, generalLabel, showGeneralTab, tabs]);\n\n const firstTab = defaultTab ?? visibleTabs[0]?.id ?? generalId;\n const [activeTab, setActiveTab] = useControllable(controlledTab, firstTab, onTabChange);\n const [query, setQuery] = useControllable(controlledQuery, defaultQuery, onQueryChange);\n const [showExpert, setShowExpert] = useControllable(controlledShowExpert, defaultShowExpert, onShowExpertChange);\n const [showTechnicalKeys, setShowTechnicalKeys] = useControllable(\n controlledShowTechnicalKeys,\n defaultShowTechnicalKeys,\n onShowTechnicalKeysChange,\n );\n\n const [collapsedGroups, setCollapsedGroups] = useState>({});\n const [editing, setEditing] = useState(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [form, setForm] = useState({ path: \"\", type: \"string\", value: \"\" });\n\n const normalizedQuery = query.trim();\n const isSearching = features?.search !== false && normalizedQuery !== \"\";\n const activeEntries = rawTabIds.includes(activeTab)\n ? []\n : (partition.get(activeTab) ?? []);\n\n const tabLabel = (tabId: string) => visibleTabs.find((tab) => tab.id === tabId)?.label ?? tabId;\n\n const openCreate = () => {\n setEditing(null);\n setForm({ path: \"\", type: \"string\", value: \"\" });\n setModalOpen(true);\n };\n\n const openEdit = (config: ConfigEntry | ConfigRecord) => {\n setEditing(config);\n const rawValue = \"effective_value\" in config ? config.effective_value : config.value;\n setForm({\n path: config.path,\n type: config.type,\n value: valueToText(rawValue, config.type),\n });\n setModalOpen(true);\n };\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n try {\n await onSave({\n path: form.path,\n type: form.type,\n value: parseValue(form.value, form.type),\n editing,\n });\n setModalOpen(false);\n } catch {\n // Keep dialog open; caller surfaces errors via `errors` prop.\n }\n };\n\n const toggleGroup = (group: string) => {\n setCollapsedGroups((current) => ({ ...current, [group]: !current[group] }));\n };\n\n const isGroupCollapsed = (group: string, tier: ConfigTier): boolean => {\n if (collapsedGroups[group] !== undefined) {\n return collapsedGroups[group];\n }\n return tier === \"expert\";\n };\n\n const viewToggles = (\n
\n {features?.technicalKeysToggle !== false ? (\n \n ) : null}\n {features?.expertToggle !== false ? (\n \n ) : null}\n
\n );\n\n const resolvedContextBar =\n typeof contextBar === \"function\" ? contextBar(activeTab) : contextBar;\n\n const modalTitle = editing\n ? \"effective_value\" in editing\n ? editing.label\n : `Edit ${editing.path}`\n : \"New config\";\n\n const resolvedHeaderActions =\n typeof headerActions === \"function\" ? headerActions({ openCreate }) : headerActions;\n\n return (\n
\n
\n {resolvedHeaderActions ?
{resolvedHeaderActions}
: }\n {features?.create !== false ? (\n \n ) : null}\n
\n\n
\n {visibleTabs.map((tab) => {\n const Icon = tab.icon;\n return (\n setActiveTab(tab.id)}\n >\n {Icon ? : null}\n {tab.label}\n \n );\n })}\n
\n\n {features?.search !== false ? (\n
\n \n setQuery(event.target.value)}\n placeholder={searchPlaceholder}\n />\n {isSearching ? (\n \n ) : null}\n
\n ) : null}\n\n {resolvedContextBar ?
{resolvedContextBar}
: viewToggles}\n\n resolveEntryTabId(entry, tabs) ?? generalId}\n onEdit={openEdit}\n onRemove={(path) => {\n void onDelete?.(path);\n }}\n onNavigateEntry={(entry, tabId) => {\n setQuery(\"\");\n setActiveTab(tabId);\n if (entry.tier === \"expert\") {\n setShowExpert(true);\n }\n }}\n onNavigateSite={(siteSlug) => {\n setQuery(\"\");\n onNavigateSite?.(siteSlug);\n }}\n onClearSearch={() => setQuery(\"\")}\n onOpenCreate={openCreate}\n onToggleGroup={toggleGroup}\n isGroupCollapsed={isGroupCollapsed}\n />\n\n setModalOpen(false)}>\n setForm((current) => ({ ...current, path }))}\n onTypeChange={(type) => setForm((current) => ({ ...current, type }))}\n onValueChange={(value) => setForm((current) => ({ ...current, value }))}\n onSubmit={(event) => {\n void submit(event);\n }}\n onCancel={() => setModalOpen(false)}\n />\n \n
\n );\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../src/lib/config-utils.ts","../src/lib/cn.ts","../src/components/ui/Button.tsx","../src/components/ui/Input.tsx","../src/components/ConfigRecordForm.tsx","../src/components/ui/Badge.tsx","../src/components/ui/EmptyState.tsx","../src/components/ConfigTreeBrowser.tsx","../src/components/ui/Dialog.tsx","../src/components/ConfigPanel.tsx"],"names":["jsx","jsxs","ConfigPanel","useMemo","Search"],"mappings":"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","file":"index.js","sourcesContent":["import type { ConfigEntry, ConfigRecord, ConfigTabDef, ConfigValueType } from \"../types\";\n\nexport type { ConfigFormData } from \"../types\";\n\nexport function isConfigEntry(\n config: ConfigEntry | ConfigRecord | null,\n): config is ConfigEntry {\n return config !== null && \"effective_value\" in config;\n}\n\nexport function valueToText(value: unknown, type?: ConfigValueType): string {\n if (type === \"null\" || value === null || value === undefined) {\n return \"\";\n }\n\n if (type === \"bool\") {\n return value ? \"true\" : \"false\";\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value, null, 2);\n }\n\n return String(value);\n}\n\nexport function parseValue(raw: string, type: ConfigValueType): unknown {\n if (type === \"null\") {\n return null;\n }\n\n if (type === \"bool\") {\n return raw === \"true\" || raw === \"1\";\n }\n\n if (type === \"int\") {\n return Number.parseInt(raw, 10);\n }\n\n if (type === \"float\") {\n return Number.parseFloat(raw);\n }\n\n if (type === \"array\" || type === \"json\") {\n return JSON.parse(raw);\n }\n\n return raw;\n}\n\nexport function displayValue(\n value: unknown,\n type?: ConfigValueType,\n sensitive = false,\n): string {\n if (sensitive && value !== null && value !== undefined && value !== \"\") {\n return \"••••••••\";\n }\n\n if (type === \"null\" || value === null || value === undefined) {\n return \"null\";\n }\n\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n\n return String(value);\n}\n\nexport function formatConfigDate(iso: string | null | undefined): string {\n if (!iso) {\n return \"-\";\n }\n\n try {\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(new Date(iso));\n } catch {\n return iso;\n }\n}\n\nconst DEFAULT_GENERAL_TAB_ID = \"general\";\n\nexport function generalTabId(generalTab?: boolean | { id?: string }): string {\n if (generalTab && typeof generalTab === \"object\" && generalTab.id) {\n return generalTab.id;\n }\n\n return DEFAULT_GENERAL_TAB_ID;\n}\n\nexport function curatedTabs(tabs: ConfigTabDef[]): ConfigTabDef[] {\n return tabs.filter((tab) => tab.mode !== \"raw\");\n}\n\nexport function rawTabs(tabs: ConfigTabDef[]): ConfigTabDef[] {\n return tabs.filter((tab) => tab.mode === \"raw\");\n}\n\nexport function resolveEntryTabId(entry: ConfigEntry, tabs: ConfigTabDef[]): string | null {\n for (const tab of curatedTabs(tabs)) {\n if (tab.filter?.(entry)) {\n return tab.id;\n }\n\n if (tab.groups?.includes(entry.group_label)) {\n return tab.id;\n }\n }\n\n return null;\n}\n\nexport function partitionEntriesByTab(\n entries: ConfigEntry[],\n tabs: ConfigTabDef[],\n generalTabIdValue: string,\n): Map {\n const curated = curatedTabs(tabs);\n const buckets = new Map();\n\n for (const tab of curated) {\n buckets.set(tab.id, []);\n }\n\n buckets.set(generalTabIdValue, []);\n\n for (const entry of entries) {\n const tabId = resolveEntryTabId(entry, curated) ?? generalTabIdValue;\n const bucket = buckets.get(tabId) ?? buckets.get(generalTabIdValue) ?? [];\n bucket.push(entry);\n buckets.set(tabId, bucket);\n }\n\n return buckets;\n}\n\nexport function entryBreadcrumb(\n entry: ConfigEntry,\n tabLabel: string,\n sites: { slug: string; name: string }[],\n): string {\n const siteSlug = typeof entry.meta?.site_slug === \"string\" ? entry.meta.site_slug : undefined;\n if (siteSlug) {\n const site = sites.find((item) => item.slug === siteSlug);\n return `${tabLabel} › ${site?.name ?? siteSlug} › ${entry.group_label}`;\n }\n\n return `${tabLabel} › ${entry.group_label}`;\n}\n","import { clsx, type ClassValue } from \"clsx\";\n\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs);\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\ntype Variant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\";\n\nexport function Button({\n className,\n variant = \"primary\",\n iconOnly = false,\n children,\n type = \"button\",\n ...props\n}: ButtonHTMLAttributes & {\n variant?: Variant;\n iconOnly?: boolean;\n children?: ReactNode;\n}) {\n return (\n \n {children}\n \n );\n}\n","import type { InputHTMLAttributes } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport function Input({ className, ...props }: InputHTMLAttributes) {\n return ;\n}\n","import { Copy } from \"lucide-react\";\n\nimport { isConfigEntry } from \"../lib/config-utils\";\nimport type { ConfigEntry, ConfigRecordFormProps, ConfigValueType } from \"../types\";\nimport { Button } from \"./ui/Button\";\nimport { Input } from \"./ui/Input\";\n\nasync function copyText(text: string): Promise {\n await navigator.clipboard.writeText(text);\n}\n\nfunction resolveSelectChoices(\n options?: string[],\n optionLabels?: Record,\n): Array<{ value: string; label: string }> {\n if (!options?.length) {\n return [];\n }\n\n return options.map((option) => ({\n value: option,\n label: optionLabels?.[option] ?? option,\n }));\n}\n\nfunction typeInput(\n type: ConfigValueType,\n value: string,\n setValue: (value: string) => void,\n options?: string[],\n optionLabels?: Record,\n) {\n if (type === \"bool\") {\n return (\n setValue(event.target.value)}\n >\n \n \n \n );\n }\n\n const choices = resolveSelectChoices(options, optionLabels);\n if (type === \"string\" && choices.length > 0) {\n return (\n setValue(event.target.value)}\n >\n {choices.map((choice) => (\n \n ))}\n \n );\n }\n\n if (type === \"array\" || type === \"json\") {\n return (\n setValue(event.target.value)}\n rows={7}\n />\n );\n }\n\n if (type === \"null\") {\n return ;\n }\n\n return (\n setValue(event.target.value)}\n />\n );\n}\n\nexport function ConfigRecordForm({\n editing,\n types,\n path,\n type,\n value,\n errors,\n processing,\n onPathChange,\n onTypeChange,\n onValueChange,\n onSubmit,\n onCancel,\n}: ConfigRecordFormProps) {\n const curatedEntry =\n editing !== null && \"effective_value\" in editing ? (editing as ConfigEntry) : null;\n\n return (\n
\n {curatedEntry ? (\n
\n

{curatedEntry.description}

\n
\n Technical key\n {curatedEntry.path}\n \n Type\n {curatedEntry.type}\n \n Source\n {curatedEntry.source}\n \n
\n
\n ) : null}\n {editing && !curatedEntry ? (\n
\n
\n \n \n {errors.path ?

{errors.path}

: null}\n
\n
\n \n onTypeChange(event.target.value as ConfigValueType)}\n >\n {types.map((option) => (\n \n ))}\n \n {errors.type ?

{errors.type}

: null}\n
\n
\n ) : !editing ? (\n
\n
\n \n onPathChange(event.target.value)} placeholder=\"group.key\" />\n {errors.path ?

{errors.path}

: null}\n
\n
\n \n onTypeChange(event.target.value as ConfigValueType)}\n >\n {types.map((option) => (\n \n ))}\n \n {errors.type ?

{errors.type}

: null}\n
\n
\n ) : null}\n
\n \n {typeInput(\n type,\n value,\n onValueChange,\n curatedEntry?.meta?.options as string[] | undefined,\n curatedEntry?.meta?.option_labels as Record | undefined,\n )}\n {errors.value ?

{errors.value}

: null}\n
\n
\n \n \n
\n
\n );\n}\n","import type { ReactNode } from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport function Badge({\n children,\n tone = \"slate\",\n className,\n}: {\n children: ReactNode;\n tone?: \"slate\" | \"cyan\" | \"amber\";\n className?: string;\n}) {\n return (\n \n {children}\n \n );\n}\n","import type { ReactNode } from \"react\";\n\nexport function EmptyState({\n title,\n message,\n action,\n}: {\n title: string;\n message?: string;\n action?: ReactNode;\n}) {\n return (\n
\n

{title}

\n {message ?

{message}

: null}\n {action ?
{action}
: null}\n
\n );\n}\n","import {\n ChevronDown,\n ChevronRight,\n DatabaseZap,\n Pencil,\n Search,\n Settings,\n Trash2,\n} from \"lucide-react\";\nimport { useMemo } from \"react\";\n\nimport { displayValue, entryBreadcrumb, formatConfigDate } from \"../lib/config-utils\";\nimport { cn } from \"../lib/cn\";\nimport type {\n ConfigEntry,\n ConfigRecord,\n ConfigSiteContext,\n ConfigTreeBrowserProps,\n} from \"../types\";\nimport { Badge } from \"./ui/Badge\";\nimport { Button } from \"./ui/Button\";\nimport { EmptyState } from \"./ui/EmptyState\";\n\ntype SearchHit =\n | { kind: \"entry\"; breadcrumb: string; item: ConfigEntry; tabId: string }\n | {\n kind: \"override\";\n breadcrumb: string;\n siteSlug: string;\n row: ConfigSiteContext[\"overrides\"][number];\n }\n | { kind: \"raw\"; breadcrumb: string; config: ConfigRecord };\n\nfunction sourceTone(source: string): \"cyan\" | \"slate\" | \"amber\" {\n if (source === \"config-store\" || source === \"runtime-global\") {\n return \"cyan\";\n }\n\n if (source === \"site-record\") {\n return \"amber\";\n }\n\n return \"slate\";\n}\n\nfunction searchableText(parts: Array): string {\n return parts\n .filter((part) => typeof part === \"string\" && part !== \"\")\n .join(\" \")\n .toLowerCase();\n}\n\nfunction matchesQuery(query: string, parts: Array): boolean {\n const normalized = query.trim().toLowerCase();\n if (!normalized) {\n return true;\n }\n return searchableText(parts).includes(normalized);\n}\n\nfunction searchScore(query: string, parts: Array): number {\n const normalized = query.trim().toLowerCase();\n const label = (parts[0] ?? \"\").toLowerCase();\n if (!normalized) {\n return 0;\n }\n if (label.startsWith(normalized)) {\n return 0;\n }\n if (label.includes(normalized)) {\n return 1;\n }\n if (searchableText(parts.slice(1)).includes(normalized)) {\n return 2;\n }\n return 3;\n}\n\nfunction ConfigRow({\n item,\n onEdit,\n onRemove,\n showTechnicalKeys,\n breadcrumb,\n onNavigate,\n}: {\n item: ConfigEntry;\n onEdit: (item: ConfigEntry) => void;\n onRemove: (path: string) => void;\n showTechnicalKeys: boolean;\n breadcrumb?: string;\n onNavigate?: (item: ConfigEntry) => void;\n}) {\n const subtitle = showTechnicalKeys ? item.path : item.description;\n\n return (\n
\n
\n {breadcrumb ? (\n
\n {breadcrumb}\n {item.tier === \"expert\" ? expert : null}\n {onNavigate ? (\n \n ) : null}\n
\n ) : null}\n
{item.label}
\n
\n {subtitle}\n
\n
\n
\n {displayValue(item.effective_value, item.type, item.sensitive)}\n {item.source}\n
\n
\n \n {item.stored ? (\n \n ) : null}\n
\n
\n );\n}\n\nfunction ConfigGroupSection({\n group,\n items,\n collapsed,\n onToggle,\n onEdit,\n onRemove,\n showTechnicalKeys,\n}: {\n group: string;\n items: ConfigEntry[];\n collapsed: boolean;\n onToggle: (group: string) => void;\n onEdit: (item: ConfigEntry) => void;\n onRemove: (path: string) => void;\n showTechnicalKeys: boolean;\n}) {\n return (\n
\n \n {!collapsed ? (\n
\n {items.map((item) => (\n \n ))}\n
\n ) : null}\n
\n );\n}\n\nexport function ConfigTreeBrowser({\n entries,\n searchEntries,\n rawEntries,\n sites,\n activeTab,\n rawTabIds,\n showExpert,\n showTechnicalKeys,\n normalizedQuery,\n isSearching,\n siteOverridePanel,\n showSiteOverridePanel = false,\n tabLabel,\n resolveTabId,\n onEdit,\n onRemove,\n onNavigateEntry,\n onNavigateSite,\n onClearSearch,\n onToggleGroup,\n isGroupCollapsed,\n}: ConfigTreeBrowserProps) {\n const isRawTab = rawTabIds.includes(activeTab);\n const searchableEntries = searchEntries ?? entries;\n\n const visibleEntries = useMemo(() => {\n const tierFilter = (item: ConfigEntry) => showExpert || item.tier !== \"expert\";\n return entries.filter(tierFilter);\n }, [entries, showExpert]);\n\n const groupedEntries = useMemo(() => {\n return visibleEntries.reduce>((groups, item) => {\n const group = groups[item.group_label] ?? [];\n group.push(item);\n groups[item.group_label] = group;\n return groups;\n }, {});\n }, [visibleEntries]);\n\n const sortedGroups = Object.entries(groupedEntries).sort(([, leftItems], [, rightItems]) => {\n const leftSort = leftItems[0]?.sort ?? 0;\n const rightSort = rightItems[0]?.sort ?? 0;\n return leftSort - rightSort || (leftItems[0]?.group_label ?? \"\").localeCompare(rightItems[0]?.group_label ?? \"\");\n });\n\n const entryPaths = useMemo(() => new Set(searchableEntries.map((entry) => entry.path)), [searchableEntries]);\n\n const searchHits = useMemo((): SearchHit[] => {\n if (!isSearching) {\n return [];\n }\n\n const hits: Array = [];\n\n searchableEntries.forEach((item) => {\n if (\n !matchesQuery(normalizedQuery, [\n item.label,\n item.description,\n item.path,\n item.group_label,\n displayValue(item.effective_value, item.type),\n ])\n ) {\n return;\n }\n\n hits.push({\n kind: \"entry\",\n breadcrumb: entryBreadcrumb(item, tabLabel(resolveTabId?.(item) ?? activeTab), sites),\n item,\n tabId: resolveTabId?.(item) ?? activeTab,\n score: searchScore(normalizedQuery, [item.label, item.description, item.path, item.group_label]),\n });\n });\n\n sites.forEach((site) => {\n site.overrides.forEach((row) => {\n if (\n !matchesQuery(normalizedQuery, [\n row.label,\n row.description,\n row.key,\n site.name,\n site.slug,\n displayValue(row.effective_value, row.type),\n ])\n ) {\n return;\n }\n\n hits.push({\n kind: \"override\",\n breadcrumb: `Site › ${site.name}`,\n siteSlug: site.slug,\n row,\n score: searchScore(normalizedQuery, [row.label, row.description, row.key]),\n });\n });\n });\n\n rawEntries.forEach((config) => {\n if (entryPaths.has(config.path)) {\n return;\n }\n\n if (!matchesQuery(normalizedQuery, [config.path, config.type, displayValue(config.value, config.type)])) {\n return;\n }\n\n hits.push({\n kind: \"raw\",\n breadcrumb: \"Raw store\",\n config,\n score: searchScore(normalizedQuery, [config.path, config.type, displayValue(config.value, config.type)]),\n });\n });\n\n return hits.sort((left, right) => left.score - right.score || left.breadcrumb.localeCompare(right.breadcrumb));\n }, [searchableEntries, entryPaths, isSearching, normalizedQuery, rawEntries, sites, activeTab, tabLabel, resolveTabId]);\n\n const filteredRaw = useMemo(() => {\n if (!isSearching) {\n return rawEntries;\n }\n\n return rawEntries.filter((config) =>\n matchesQuery(normalizedQuery, [config.path, config.type, displayValue(config.value, config.type)]),\n );\n }, [isSearching, normalizedQuery, rawEntries]);\n\n const selectedSite =\n siteOverridePanel?.sites.find((site) => site.slug === siteOverridePanel.selectedSiteSlug) ?? null;\n\n const siteOverrideRows =\n selectedSite?.overrides.filter((row) => row.has_site_value || row.runtime_stored) ?? [];\n\n if (isSearching) {\n return (\n
\n
\n

\n Search results for "{normalizedQuery}" · {searchHits.length}{\" \"}\n {searchHits.length === 1 ? \"match\" : \"matches\"}\n

\n \n
\n {searchHits.length ? (\n
\n {searchHits.map((hit) => {\n if (hit.kind === \"entry\") {\n return (\n onNavigateEntry(hit.item, hit.tabId)}\n onEdit={onEdit}\n onRemove={onRemove}\n showTechnicalKeys={showTechnicalKeys}\n />\n );\n }\n\n if (hit.kind === \"override\") {\n return (\n
\n
\n
\n {hit.breadcrumb}\n \n
\n
{hit.row.label}
\n
\n {showTechnicalKeys ? hit.row.key : hit.row.description}\n
\n
\n
\n {displayValue(hit.row.effective_value, hit.row.type)}\n {hit.row.effective_source}\n
\n
\n );\n }\n\n return (\n
\n
\n
{hit.breadcrumb}
\n
\n {hit.config.path}\n
\n
\n
\n {displayValue(hit.config.value, hit.config.type)}\n {hit.config.type}\n
\n
\n \n \n
\n
\n );\n })}\n
\n ) : (\n \n )}\n
\n );\n }\n\n if (isRawTab) {\n return filteredRaw.length ? (\n
\n \n \n \n \n \n \n \n \n \n \n \n {filteredRaw.map((config) => (\n \n \n \n \n \n \n \n ))}\n \n
PathTypeValueUpdatedActions
{config.path}\n {config.type}\n {displayValue(config.value, config.type)}{formatConfigDate(config.updated_at)}\n
\n \n \n
\n
\n
\n ) : (\n \n );\n }\n\n return (\n
\n {showSiteOverridePanel && siteOverridePanel ? (\n
\n
\n Site record overrides\n {selectedSite ? siteOverridePanel.renderEditLink(selectedSite) : (\n No site record for this slug.\n )}\n
\n
\n {siteOverrideRows.length ? (\n siteOverrideRows.map((row) => (\n
\n
\n
{row.label}
\n
\n {showTechnicalKeys ? row.key : row.description}\n
\n
\n
\n {displayValue(row.effective_value, row.type)}\n {row.effective_source}\n
\n
\n ))\n ) : (\n
No site-record overrides for this context.
\n )}\n
\n
\n ) : null}\n\n {sortedGroups.length ? (\n sortedGroups.map(([group, items]) => (\n \n ))\n ) : siteOverrideRows.length === 0 ? (\n \n ) : null}\n
\n );\n}\n","import { useEffect, useId, useRef, type ReactNode } from \"react\";\n\nexport function Dialog({\n open,\n title,\n children,\n onClose,\n}: {\n open: boolean;\n title: string;\n children?: ReactNode;\n onClose: () => void;\n}) {\n const titleId = useId();\n const panelRef = useRef(null);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n panelRef.current?.focus();\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [open, onClose]);\n\n if (!open) {\n return null;\n }\n\n return (\n {\n if (event.target === event.currentTarget) {\n onClose();\n }\n }}\n >\n \n

\n {title}\n

\n {children ?
{children}
: null}\n \n \n );\n}\n","import { Search, X } from \"lucide-react\";\nimport {\n forwardRef,\n useCallback,\n useImperativeHandle,\n type FormEvent,\n useMemo,\n useState,\n} from \"react\";\n\nimport {\n generalTabId,\n partitionEntriesByTab,\n parseValue,\n rawTabs,\n resolveEntryTabId,\n valueToText,\n} from \"../lib/config-utils\";\nimport { cn } from \"../lib/cn\";\nimport type {\n ConfigEntry,\n ConfigFormData,\n ConfigPanelHandle,\n ConfigPanelProps,\n ConfigRecord,\n ConfigTier,\n ConfigValueType,\n} from \"../types\";\nimport { ConfigRecordForm } from \"./ConfigRecordForm\";\nimport { ConfigTreeBrowser } from \"./ConfigTreeBrowser\";\nimport { Dialog } from \"./ui/Dialog\";\nimport { Input } from \"./ui/Input\";\n\nconst DEFAULT_VALUE_TYPES: ConfigValueType[] = [\n \"string\",\n \"int\",\n \"float\",\n \"bool\",\n \"array\",\n \"json\",\n \"null\",\n];\n\nfunction useControllable(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void,\n): [T, (value: T) => void] {\n const [internal, setInternal] = useState(defaultValue);\n const value = controlled ?? internal;\n const setValue = (next: T) => {\n if (controlled === undefined) {\n setInternal(next);\n }\n onChange?.(next);\n };\n return [value, setValue];\n}\n\nexport const ConfigPanel = forwardRef(function ConfigPanel(\n {\n tabs,\n generalTab = true,\n entries,\n rawEntries = [],\n valueTypes = DEFAULT_VALUE_TYPES,\n features,\n contextBar,\n headerActions,\n siteOverridePanel,\n showSiteOverridePanel = false,\n tab: controlledTab,\n defaultTab,\n onTabChange,\n query: controlledQuery,\n defaultQuery = \"\",\n onQueryChange,\n showExpert: controlledShowExpert,\n defaultShowExpert = false,\n onShowExpertChange,\n showTechnicalKeys: controlledShowTechnicalKeys,\n defaultShowTechnicalKeys = false,\n onShowTechnicalKeysChange,\n onSave,\n onDelete,\n onNavigateSite,\n processing = false,\n errors = {},\n searchPlaceholder = \"Search settings by name, description, site, or key\",\n className,\n },\n ref,\n) {\n const generalId = generalTabId(generalTab);\n const generalEnabled = generalTab !== false;\n const generalLabel =\n generalTab && typeof generalTab === \"object\" && generalTab.label ? generalTab.label : \"General\";\n const hideGeneralWhenEmpty =\n generalTab === false\n ? true\n : generalTab && typeof generalTab === \"object\"\n ? generalTab.hideWhenEmpty !== false\n : true;\n\n const rawTabIds = useMemo(() => rawTabs(tabs).map((tab) => tab.id), [tabs]);\n const curatedTabDefs = useMemo(() => tabs.filter((tab) => tab.mode !== \"raw\"), [tabs]);\n\n const partition = useMemo(\n () => partitionEntriesByTab(entries, tabs, generalId),\n [entries, generalId, tabs],\n );\n\n const generalCount = partition.get(generalId)?.length ?? 0;\n const showGeneralTab = generalEnabled && (!hideGeneralWhenEmpty || generalCount > 0);\n\n const visibleTabs = useMemo(() => {\n const list = [...curatedTabDefs];\n if (showGeneralTab) {\n list.push({ id: generalId, label: generalLabel });\n }\n list.push(...rawTabs(tabs));\n return list;\n }, [curatedTabDefs, generalId, generalLabel, showGeneralTab, tabs]);\n\n const firstTab = defaultTab ?? visibleTabs[0]?.id ?? generalId;\n const [activeTab, setActiveTab] = useControllable(controlledTab, firstTab, onTabChange);\n const [query, setQuery] = useControllable(controlledQuery, defaultQuery, onQueryChange);\n const [showExpert, setShowExpert] = useControllable(controlledShowExpert, defaultShowExpert, onShowExpertChange);\n const [showTechnicalKeys, setShowTechnicalKeys] = useControllable(\n controlledShowTechnicalKeys,\n defaultShowTechnicalKeys,\n onShowTechnicalKeysChange,\n );\n\n const [collapsedGroups, setCollapsedGroups] = useState>({});\n const [editing, setEditing] = useState(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [form, setForm] = useState({ path: \"\", type: \"string\", value: \"\" });\n\n const normalizedQuery = query.trim();\n const isSearching = features?.search !== false && normalizedQuery !== \"\";\n const activeEntries = rawTabIds.includes(activeTab)\n ? []\n : (partition.get(activeTab) ?? []);\n\n const tabLabel = (tabId: string) => visibleTabs.find((tab) => tab.id === tabId)?.label ?? tabId;\n\n const openCreate = useCallback(() => {\n setEditing(null);\n setForm({ path: \"\", type: \"string\", value: \"\" });\n setModalOpen(true);\n }, []);\n\n useImperativeHandle(ref, () => ({ openCreate }), [openCreate]);\n\n const openEdit = (config: ConfigEntry | ConfigRecord) => {\n setEditing(config);\n const rawValue = \"effective_value\" in config ? config.effective_value : config.value;\n setForm({\n path: config.path,\n type: config.type,\n value: valueToText(rawValue, config.type),\n });\n setModalOpen(true);\n };\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n try {\n await onSave({\n path: form.path,\n type: form.type,\n value: parseValue(form.value, form.type),\n editing,\n });\n setModalOpen(false);\n } catch {\n // Keep dialog open; caller surfaces errors via `errors` prop.\n }\n };\n\n const toggleGroup = (group: string) => {\n setCollapsedGroups((current) => ({ ...current, [group]: !current[group] }));\n };\n\n const isGroupCollapsed = (group: string, tier: ConfigTier): boolean => {\n if (collapsedGroups[group] !== undefined) {\n return collapsedGroups[group];\n }\n return tier === \"expert\";\n };\n\n const viewToggles = (\n
\n {features?.technicalKeysToggle !== false ? (\n \n ) : null}\n {features?.expertToggle !== false ? (\n \n ) : null}\n
\n );\n\n const resolvedContextBar =\n typeof contextBar === \"function\" ? contextBar(activeTab) : contextBar;\n\n const modalTitle = editing\n ? \"effective_value\" in editing\n ? editing.label\n : `Edit ${editing.path}`\n : \"New config\";\n\n return (\n
\n {headerActions ? (\n
\n {headerActions}\n
\n ) : null}\n\n
\n {visibleTabs.map((tab) => {\n const Icon = tab.icon;\n return (\n setActiveTab(tab.id)}\n >\n {Icon ? : null}\n {tab.label}\n \n );\n })}\n
\n\n {features?.search !== false ? (\n
\n \n setQuery(event.target.value)}\n placeholder={searchPlaceholder}\n />\n {isSearching ? (\n \n ) : null}\n
\n ) : null}\n\n {resolvedContextBar ?
{resolvedContextBar}
: viewToggles}\n\n resolveEntryTabId(entry, tabs) ?? generalId}\n onEdit={openEdit}\n onRemove={(path) => {\n void onDelete?.(path);\n }}\n onNavigateEntry={(entry, tabId) => {\n setQuery(\"\");\n setActiveTab(tabId);\n if (entry.tier === \"expert\") {\n setShowExpert(true);\n }\n }}\n onNavigateSite={(siteSlug) => {\n setQuery(\"\");\n onNavigateSite?.(siteSlug);\n }}\n onClearSearch={() => setQuery(\"\")}\n onToggleGroup={toggleGroup}\n isGroupCollapsed={isGroupCollapsed}\n />\n\n setModalOpen(false)}>\n setForm((current) => ({ ...current, path }))}\n onTypeChange={(type) => setForm((current) => ({ ...current, type }))}\n onValueChange={(value) => setForm((current) => ({ ...current, value }))}\n onSubmit={(event) => {\n void submit(event);\n }}\n onCancel={() => setModalOpen(false)}\n />\n \n
\n );\n});\n"]} \ No newline at end of file diff --git a/components/config/package.json b/components/config/package.json index 50ccf80..39f949e 100644 --- a/components/config/package.json +++ b/components/config/package.json @@ -39,7 +39,8 @@ "build": "tsup && cp src/styles.css dist/styles.css", "typecheck": "tsc --noEmit", "test": "vitest run", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" }, "dependencies": { "clsx": "^2.1.1" diff --git a/components/config/src/components/ConfigPanel.tsx b/components/config/src/components/ConfigPanel.tsx index 2ccdcbe..8a67201 100644 --- a/components/config/src/components/ConfigPanel.tsx +++ b/components/config/src/components/ConfigPanel.tsx @@ -1,9 +1,15 @@ import { Search, X } from "lucide-react"; -import { type FormEvent, useMemo, useState } from "react"; +import { + forwardRef, + useCallback, + useImperativeHandle, + type FormEvent, + useMemo, + useState, +} from "react"; import { generalTabId, - isConfigEntry, partitionEntriesByTab, parseValue, rawTabs, @@ -14,6 +20,7 @@ import { cn } from "../lib/cn"; import type { ConfigEntry, ConfigFormData, + ConfigPanelHandle, ConfigPanelProps, ConfigRecord, ConfigTier, @@ -21,7 +28,6 @@ import type { } from "../types"; import { ConfigRecordForm } from "./ConfigRecordForm"; import { ConfigTreeBrowser } from "./ConfigTreeBrowser"; -import { Button } from "./ui/Button"; import { Dialog } from "./ui/Dialog"; import { Input } from "./ui/Input"; @@ -51,37 +57,40 @@ function useControllable( return [value, setValue]; } -export function ConfigPanel({ - tabs, - generalTab = true, - entries, - rawEntries = [], - valueTypes = DEFAULT_VALUE_TYPES, - features, - contextBar, - headerActions, - siteOverridePanel, - showSiteOverridePanel = false, - tab: controlledTab, - defaultTab, - onTabChange, - query: controlledQuery, - defaultQuery = "", - onQueryChange, - showExpert: controlledShowExpert, - defaultShowExpert = false, - onShowExpertChange, - showTechnicalKeys: controlledShowTechnicalKeys, - defaultShowTechnicalKeys = false, - onShowTechnicalKeysChange, - onSave, - onDelete, - onNavigateSite, - processing = false, - errors = {}, - searchPlaceholder = "Search settings by name, description, site, or key", - className, -}: ConfigPanelProps) { +export const ConfigPanel = forwardRef(function ConfigPanel( + { + tabs, + generalTab = true, + entries, + rawEntries = [], + valueTypes = DEFAULT_VALUE_TYPES, + features, + contextBar, + headerActions, + siteOverridePanel, + showSiteOverridePanel = false, + tab: controlledTab, + defaultTab, + onTabChange, + query: controlledQuery, + defaultQuery = "", + onQueryChange, + showExpert: controlledShowExpert, + defaultShowExpert = false, + onShowExpertChange, + showTechnicalKeys: controlledShowTechnicalKeys, + defaultShowTechnicalKeys = false, + onShowTechnicalKeysChange, + onSave, + onDelete, + onNavigateSite, + processing = false, + errors = {}, + searchPlaceholder = "Search settings by name, description, site, or key", + className, + }, + ref, +) { const generalId = generalTabId(generalTab); const generalEnabled = generalTab !== false; const generalLabel = @@ -136,11 +145,13 @@ export function ConfigPanel({ const tabLabel = (tabId: string) => visibleTabs.find((tab) => tab.id === tabId)?.label ?? tabId; - const openCreate = () => { + const openCreate = useCallback(() => { setEditing(null); setForm({ path: "", type: "string", value: "" }); setModalOpen(true); - }; + }, []); + + useImperativeHandle(ref, () => ({ openCreate }), [openCreate]); const openEdit = (config: ConfigEntry | ConfigRecord) => { setEditing(config); @@ -213,19 +224,13 @@ export function ConfigPanel({ : `Edit ${editing.path}` : "New config"; - const resolvedHeaderActions = - typeof headerActions === "function" ? headerActions({ openCreate }) : headerActions; - return (
-
- {resolvedHeaderActions ?
{resolvedHeaderActions}
: } - {features?.create !== false ? ( - - ) : null} -
+ {headerActions ? ( +
+ {headerActions} +
+ ) : null}
{visibleTabs.map((tab) => { @@ -295,7 +300,6 @@ export function ConfigPanel({ onNavigateSite?.(siteSlug); }} onClearSearch={() => setQuery("")} - onOpenCreate={openCreate} onToggleGroup={toggleGroup} isGroupCollapsed={isGroupCollapsed} /> @@ -320,4 +324,4 @@ export function ConfigPanel({
); -} +}); diff --git a/components/config/src/components/ConfigTreeBrowser.tsx b/components/config/src/components/ConfigTreeBrowser.tsx index 39d7009..69fe487 100644 --- a/components/config/src/components/ConfigTreeBrowser.tsx +++ b/components/config/src/components/ConfigTreeBrowser.tsx @@ -187,7 +187,6 @@ export function ConfigTreeBrowser({ onNavigateEntry, onNavigateSite, onClearSearch, - onOpenCreate, onToggleGroup, isGroupCollapsed, }: ConfigTreeBrowserProps) { @@ -429,11 +428,7 @@ export function ConfigTreeBrowser({ ) : ( - Create config - - } + message="Use the page primary action to create a config." /> ); } diff --git a/components/config/src/index.ts b/components/config/src/index.ts index 1a6bd77..b602c3f 100644 --- a/components/config/src/index.ts +++ b/components/config/src/index.ts @@ -7,6 +7,7 @@ export type { ConfigFormData, ConfigGeneralTabDef, ConfigPanelFeatures, + ConfigPanelHandle, ConfigPanelProps, ConfigRecord, ConfigRecordFormProps, diff --git a/components/config/src/types.ts b/components/config/src/types.ts index 14bd7c7..9f31e25 100644 --- a/components/config/src/types.ts +++ b/components/config/src/types.ts @@ -68,7 +68,11 @@ export type ConfigPanelFeatures = { search?: boolean; expertToggle?: boolean; technicalKeysToggle?: boolean; - create?: boolean; +}; + +/** Imperative helpers for PageShell Identity primary actions (create / open editor). */ +export type ConfigPanelHandle = { + openCreate: () => void; }; export type ConfigGeneralTabDef = { @@ -92,7 +96,8 @@ export type ConfigPanelProps = { valueTypes?: ConfigValueType[]; features?: ConfigPanelFeatures; contextBar?: ReactNode | ((activeTab: string) => ReactNode); - headerActions?: ReactNode | ((helpers: { openCreate: () => void }) => ReactNode); + /** Local / non-primary chrome only — do not put Create / view CTAs here; use PageShellIdentity + `ConfigPanelHandle`. */ + headerActions?: ReactNode; siteOverridePanel?: SiteOverridePanelProps | null; showSiteOverridePanel?: boolean; tab?: string; @@ -157,7 +162,6 @@ export type ConfigTreeBrowserProps = { onNavigateEntry: (entry: ConfigEntry, tabId: string) => void; onNavigateSite: (siteSlug: string) => void; onClearSearch: () => void; - onOpenCreate: () => void; onToggleGroup: (group: string) => void; isGroupCollapsed: (group: string, tier: ConfigTier) => boolean; }; From f773748005dee344ba9f18a25d7f17bd06637226 Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:25 -0600 Subject: [PATCH 08/14] feat(table): accept ReactNode header and row actions Compose DataTable actions with react-action-buttons; allow custom footer beside selection/pagination. --- components/table/AGENTS.md | 7 +- components/table/CHANGELOG.md | 7 + components/table/README.md | 84 +++-- components/table/dist/index.d.ts | 12 +- components/table/dist/index.js | 337 +++++++++--------- components/table/dist/index.js.map | 2 +- components/table/dist/styles.css | 4 + components/table/package.json | 3 +- components/table/src/DataTable.test.tsx | 36 +- components/table/src/components/DataTable.tsx | 24 +- components/table/src/styles.css | 4 + components/table/src/types.ts | 12 +- 12 files changed, 309 insertions(+), 223 deletions(-) diff --git a/components/table/AGENTS.md b/components/table/AGENTS.md index d5fc61c..c53ccd9 100644 --- a/components/table/AGENTS.md +++ b/components/table/AGENTS.md @@ -22,7 +22,12 @@ npm run build `react`, `react-dom`, `lucide-react` +## Actions + +Compose `headerActions` and `rowActions` with `@jooservices/react-action-buttons`. Prefer that package over inventing new button chrome. PageShell primary CTAs stay in `PageShellIdentity` → `actions` only. + ## Docs -- User guide: `docs/02-user-guide/` (matching package page) +- User guide: `docs/02-user-guide/04-react-table.md` (consumer API — do not send humans to `src/`) +- Package README: `components/table/README.md` - Root policy: `AGENTS.md` diff --git a/components/table/CHANGELOG.md b/components/table/CHANGELOG.md index 9588125..19f6572 100644 --- a/components/table/CHANGELOG.md +++ b/components/table/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [Unreleased] + +### Changed + +- `headerActions` and `rowActions` are now `ReactNode` slots — compose with `@jooservices/react-action-buttons` (preferred) or existing `TableActions` / `TableHeaderIconAction` helpers +- Custom `footer` renders alongside selection / totals (no longer mutually exclusive with pagination) + ## [0.1.0] - 2026-06-25 ### Added diff --git a/components/table/README.md b/components/table/README.md index e9de7d3..d583641 100644 --- a/components/table/README.md +++ b/components/table/README.md @@ -5,12 +5,12 @@ Ready-to-use `DataTable` for React apps — shadcn-compatible theme (CSS variabl ## Install ```bash -npm install @jooservices/react-table lucide-react -# or -pnpm add @jooservices/react-table lucide-react +pnpm add "github:jooservices/react#v1.0.0&path:components/table" ``` -Peer dependencies: `react`, `react-dom`, `lucide-react`. +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). + +Prefer `@jooservices/react-action-buttons` for header and row action UI. ## Setup (any React + Vite/CRA/Next app) @@ -18,6 +18,7 @@ Import theme once in your app entry: ```ts import "@jooservices/react-table/styles.css"; +import "@jooservices/react-action-buttons/styles.css"; ``` No Tailwind config required — styles ship with the package (`joo-*` CSS + theme variables). Works standalone in any React 18+ project. @@ -25,7 +26,8 @@ No Tailwind config required — styles ship with the package (`joo-*` CSS + them ## Usage ```tsx -import { DataTable, type DataTableColumn, type TableAction } from "@jooservices/react-table"; +import { ActionBar, ActionMenu, Button } from "@jooservices/react-action-buttons"; +import { DataTable, type DataTableColumn } from "@jooservices/react-table"; import { MoreHorizontal, Pencil, Plus, Trash2 } from "lucide-react"; type User = { id: number; name: string; email: string }; @@ -35,34 +37,52 @@ const columns: DataTableColumn[] = [ { key: "email", label: "Email", render: (row) => row.email }, ]; -const headerActions: TableAction[] = [ - { type: "single", label: "Add user", icon: , onClick: () => openCreate() }, - { - type: "multi", - label: "More", - icon: , - items: [{ label: "Export CSV", onClick: () => exportCsv() }], - }, -]; - + \n );\n }\n\n const iconOnly = action.icon !== undefined && action.label.length > 0;\n\n return (\n \n \n \n {action.icon ?? (\n <>\n {action.label}\n \n \n )}\n {action.icon ? {action.label} : null}\n \n \n \n {action.label}\n \n {action.items.map((item) => (\n {\n event.preventDefault();\n item.onClick();\n }}\n >\n {item.icon}\n {item.label}\n \n ))}\n \n \n );\n}\n\nexport function TableHeaderIconAction({ action }: { action: TableAction }) {\n if (action.type === \"single\") {\n return (\n \n {action.icon}\n \n );\n }\n\n return (\n \n \n \n \n \n {action.label}\n \n {action.items.map((item) => (\n {\n event.preventDefault();\n item.onClick();\n }}\n >\n {item.icon}\n {item.label}\n \n ))}\n \n \n );\n}\n","import * as React from \"react\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { Check, Minus } from \"lucide-react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport type CheckboxProps = React.ComponentPropsWithoutRef;\n\nexport function Checkbox({ className, ...props }: CheckboxProps) {\n return (\n \n \n {props.checked === \"indeterminate\" ? : }\n \n \n );\n}\n","import * as React from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport function Table({ className, ...props }: React.HTMLAttributes) {\n return (\n
\n \n \n );\n}\n\nexport function TableHeader({ className, ...props }: React.HTMLAttributes) {\n return ;\n}\n\nexport function TableBody({ className, ...props }: React.HTMLAttributes) {\n return ;\n}\n\nexport function TableRow({ className, ...props }: React.HTMLAttributes) {\n return ;\n}\n\nexport function TableHead({ className, ...props }: React.ThHTMLAttributes) {\n return
;\n}\n\nexport function TableCell({ className, ...props }: React.TdHTMLAttributes) {\n return ;\n}\n","import {\n flexRender,\n getCoreRowModel,\n useReactTable,\n type ColumnDef,\n type RowSelectionState,\n type SortingState,\n} from \"@tanstack/react-table\";\nimport { ArrowDown, ArrowUp, ArrowUpDown } from \"lucide-react\";\nimport { useMemo, type ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport type { DataTableProps, SortDirection } from \"../types\";\nimport { TableActions, TableHeaderIconAction } from \"./TableActionButton\";\nimport { Button } from \"./ui/button\";\nimport { Checkbox } from \"./ui/checkbox\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"./ui/table\";\n\nfunction nextDirection(currentKey: string, columnKey: string, currentDirection: SortDirection): SortDirection {\n if (currentKey === columnKey) {\n return currentDirection === \"asc\" ? \"desc\" : \"asc\";\n }\n\n return \"asc\";\n}\n\nfunction alignClass(align: \"left\" | \"right\" | \"center\" | undefined, prefix: \"joo-table-head-cell\" | \"joo-table-cell\") {\n if (align === \"right\") {\n return `${prefix}--right`;\n }\n\n if (align === \"center\") {\n return `${prefix}--center`;\n }\n\n return undefined;\n}\n\nfunction selectionStateToRowSelection(selectedKeys: Set): RowSelectionState {\n const state: RowSelectionState = {};\n for (const key of selectedKeys) {\n state[key] = true;\n }\n return state;\n}\n\nfunction rowSelectionToKeys(selection: RowSelectionState): Set {\n return new Set(Object.keys(selection).filter((key) => selection[key]));\n}\n\nexport function DataTable({\n title,\n subtitle,\n headerActions,\n toolbar,\n columns,\n data,\n rowKey,\n rowActions,\n actionsLabel = \"Actions\",\n selection,\n sort,\n pagination,\n emptyMessage = \"No data.\",\n loading = false,\n className,\n footer,\n}: DataTableProps) {\n const hasSelection = selection !== undefined;\n const hasRowActions = rowActions !== undefined;\n const sortingState: SortingState = sort ? [{ id: sort.key, desc: sort.direction === \"desc\" }] : [];\n\n const tableColumns = useMemo[]>(() => {\n const defs: ColumnDef[] = [];\n\n if (hasSelection) {\n defs.push({\n id: \"__select\",\n enableSorting: false,\n header: ({ table }) => {\n const rows = table.getRowModel().rows.filter((row) =>\n selection?.isRowSelectable ? selection.isRowSelectable(row.original) : true,\n );\n const selectedCount = rows.filter((row) => row.getIsSelected()).length;\n const checked =\n rows.length > 0 && selectedCount === rows.length\n ? true\n : selectedCount > 0\n ? \"indeterminate\"\n : false;\n\n return (\n {\n const next = new Set(selection?.selectedKeys ?? []);\n if (value) {\n for (const row of rows) {\n next.add(rowKey(row.original));\n }\n } else {\n for (const row of rows) {\n next.delete(rowKey(row.original));\n }\n }\n selection?.onChange(next);\n }}\n aria-label=\"Select all on this page\"\n disabled={rows.length === 0}\n />\n );\n },\n cell: ({ row }) => {\n const selectable = selection?.isRowSelectable ? selection.isRowSelectable(row.original) : true;\n const key = rowKey(row.original);\n const label = selection?.rowLabel?.(row.original) ?? key;\n\n return (\n {\n const next = new Set(selection?.selectedKeys ?? []);\n if (value) {\n next.add(key);\n } else {\n next.delete(key);\n }\n selection?.onChange(next);\n }}\n aria-label={`Select ${label}`}\n />\n );\n },\n });\n }\n\n for (const column of columns) {\n defs.push({\n id: column.key,\n accessorKey: column.key,\n enableSorting: Boolean(column.sortable && sort),\n header: () => {\n if (column.sortable && sort) {\n const isActive = sort.key === column.key;\n const Icon = !isActive ? ArrowUpDown : sort.direction === \"asc\" ? ArrowUp : ArrowDown;\n\n return (\n sort.onChange(column.key, nextDirection(sort.key, column.key, sort.direction))}\n >\n {column.label}\n \n \n );\n }\n\n return {column.label};\n },\n cell: ({ row }) => column.render(row.original),\n });\n }\n\n if (hasRowActions) {\n defs.push({\n id: \"__actions\",\n enableSorting: false,\n header: () => {actionsLabel},\n cell: ({ row }) => ,\n });\n }\n\n return defs;\n }, [actionsLabel, columns, hasRowActions, hasSelection, rowActions, rowKey, selection, sort]);\n\n const table = useReactTable({\n data,\n columns: tableColumns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: Boolean(sort),\n enableRowSelection: hasSelection,\n getRowId: (row) => rowKey(row),\n onRowSelectionChange: (updater) => {\n if (!selection) {\n return;\n }\n\n const current = selectionStateToRowSelection(selection.selectedKeys);\n const next = typeof updater === \"function\" ? updater(current) : updater;\n selection.onChange(rowSelectionToKeys(next));\n },\n onSortingChange: (updater) => {\n if (!sort) {\n return;\n }\n\n const next = typeof updater === \"function\" ? updater(sortingState) : updater;\n const first = next[0];\n if (!first) {\n return;\n }\n\n sort.onChange(first.id, first.desc ? \"desc\" : \"asc\");\n },\n state: {\n sorting: sortingState,\n rowSelection: hasSelection ? selectionStateToRowSelection(selection.selectedKeys) : {},\n },\n });\n\n const colSpan = tableColumns.length;\n const selectedCount = selection?.selectedKeys.size ?? 0;\n const showHeader = title || subtitle || (headerActions && headerActions.length > 0);\n\n return (\n
\n {showHeader ? (\n
\n
\n {title ?
{title}
: null}\n {subtitle ?
{subtitle}
: null}\n
\n {headerActions && headerActions.length > 0 ? (\n
\n {headerActions.map((action, index) => (\n \n ))}\n
\n ) : null}\n
\n ) : null}\n\n {toolbar ?
{toolbar}
: null}\n\n \n \n {table.getHeaderGroups().map((headerGroup) => (\n \n {headerGroup.headers.map((header) => {\n const column = columns.find((item) => item.key === header.column.id);\n const align =\n header.column.id === \"__actions\"\n ? \"joo-table-head-cell--right\"\n : alignClass(column?.align, \"joo-table-head-cell\");\n\n return (\n \n {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n \n );\n })}\n \n ))}\n \n \n {loading ? (\n \n \n \n ) : table.getRowModel().rows.length === 0 ? (\n \n \n \n ) : (\n table.getRowModel().rows.map((row) => {\n const key = rowKey(row.original);\n const selected = selection?.selectedKeys.has(key) ?? false;\n\n return (\n \n {row.getVisibleCells().map((cell) => {\n const column = columns.find((item) => item.key === cell.column.id);\n const align =\n cell.column.id === \"__actions\"\n ? \"joo-table-cell--right\"\n : alignClass(column?.align, \"joo-table-cell\");\n\n return (\n \n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n \n );\n })}\n \n );\n })\n )}\n \n
\n Loading…\n \n {emptyMessage}\n
\n\n {pagination || footer || hasSelection ? (\n
\n
\n {hasSelection ? (\n \n {selectedCount} selected\n {pagination?.total !== undefined ? ` · ${pagination.total.toLocaleString()} total` : null}\n \n ) : pagination?.total !== undefined ? (\n {pagination.total.toLocaleString()} items\n ) : (\n footer ?? null\n )}\n
\n {pagination ? (\n
\n pagination.onPageChange(pagination.page - 1)}\n >\n Previous\n \n \n Page {pagination.page} of {pagination.lastPage}\n \n = pagination.lastPage}\n onClick={() => pagination.onPageChange(pagination.page + 1)}\n >\n Next\n \n
\n ) : (\n (footer as ReactNode) ?? null\n )}\n
\n ) : null}\n
\n );\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../src/lib/cn.ts","../src/components/ui/button.tsx","../src/components/ui/checkbox.tsx","../src/components/ui/table.tsx","../src/components/DataTable.tsx","../src/components/ActionBar.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/TableActionButton.tsx"],"names":["jsx","table","selectedCount","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/cn\";\n\nconst buttonVariants = cva(\"joo-btn\", {\n variants: {\n variant: {\n default: \"joo-btn--default\",\n secondary: \"joo-btn--secondary\",\n ghost: \"joo-btn--ghost\",\n destructive: \"joo-btn--destructive\",\n },\n size: {\n sm: \"joo-btn--sm\",\n icon: \"joo-btn--icon\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"sm\",\n },\n});\n\nexport type ButtonProps = React.ButtonHTMLAttributes &\n VariantProps & {\n asChild?: boolean;\n };\n\nexport function Button({\n className,\n variant,\n size,\n asChild = false,\n type = \"button\",\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot : \"button\";\n return ;\n}\n\nexport { buttonVariants };\n","import * as React from \"react\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { Check, Minus } from \"lucide-react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport type CheckboxProps = React.ComponentPropsWithoutRef;\n\nexport function Checkbox({ className, ...props }: CheckboxProps) {\n return (\n \n \n {props.checked === \"indeterminate\" ? : }\n \n \n );\n}\n","import * as React from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport function Table({ className, ...props }: React.HTMLAttributes) {\n return (\n
\n \n \n );\n}\n\nexport function TableHeader({ className, ...props }: React.HTMLAttributes) {\n return ;\n}\n\nexport function TableBody({ className, ...props }: React.HTMLAttributes) {\n return ;\n}\n\nexport function TableRow({ className, ...props }: React.HTMLAttributes) {\n return ;\n}\n\nexport function TableHead({ className, ...props }: React.ThHTMLAttributes) {\n return
;\n}\n\nexport function TableCell({ className, ...props }: React.TdHTMLAttributes) {\n return ;\n}\n","import {\n flexRender,\n getCoreRowModel,\n useReactTable,\n type ColumnDef,\n type RowSelectionState,\n type SortingState,\n} from \"@tanstack/react-table\";\nimport { ArrowDown, ArrowUp, ArrowUpDown } from \"lucide-react\";\nimport { useMemo } from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport type { DataTableProps, SortDirection } from \"../types\";\nimport { Button } from \"./ui/button\";\nimport { Checkbox } from \"./ui/checkbox\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"./ui/table\";\n\nfunction nextDirection(currentKey: string, columnKey: string, currentDirection: SortDirection): SortDirection {\n if (currentKey === columnKey) {\n return currentDirection === \"asc\" ? \"desc\" : \"asc\";\n }\n\n return \"asc\";\n}\n\nfunction alignClass(align: \"left\" | \"right\" | \"center\" | undefined, prefix: \"joo-table-head-cell\" | \"joo-table-cell\") {\n if (align === \"right\") {\n return `${prefix}--right`;\n }\n\n if (align === \"center\") {\n return `${prefix}--center`;\n }\n\n return undefined;\n}\n\nfunction selectionStateToRowSelection(selectedKeys: Set): RowSelectionState {\n const state: RowSelectionState = {};\n for (const key of selectedKeys) {\n state[key] = true;\n }\n return state;\n}\n\nfunction rowSelectionToKeys(selection: RowSelectionState): Set {\n return new Set(Object.keys(selection).filter((key) => selection[key]));\n}\n\nexport function DataTable({\n title,\n subtitle,\n headerActions,\n toolbar,\n columns,\n data,\n rowKey,\n rowActions,\n actionsLabel = \"Actions\",\n selection,\n sort,\n pagination,\n emptyMessage = \"No data.\",\n loading = false,\n className,\n footer,\n}: DataTableProps) {\n const hasSelection = selection !== undefined;\n const hasRowActions = rowActions !== undefined;\n const sortingState: SortingState = sort ? [{ id: sort.key, desc: sort.direction === \"desc\" }] : [];\n\n const tableColumns = useMemo[]>(() => {\n const defs: ColumnDef[] = [];\n\n if (hasSelection) {\n defs.push({\n id: \"__select\",\n enableSorting: false,\n header: ({ table }) => {\n const rows = table.getRowModel().rows.filter((row) =>\n selection?.isRowSelectable ? selection.isRowSelectable(row.original) : true,\n );\n const selectedCount = rows.filter((row) => row.getIsSelected()).length;\n const checked =\n rows.length > 0 && selectedCount === rows.length\n ? true\n : selectedCount > 0\n ? \"indeterminate\"\n : false;\n\n return (\n {\n const next = new Set(selection?.selectedKeys ?? []);\n if (value) {\n for (const row of rows) {\n next.add(rowKey(row.original));\n }\n } else {\n for (const row of rows) {\n next.delete(rowKey(row.original));\n }\n }\n selection?.onChange(next);\n }}\n aria-label=\"Select all on this page\"\n disabled={rows.length === 0}\n />\n );\n },\n cell: ({ row }) => {\n const selectable = selection?.isRowSelectable ? selection.isRowSelectable(row.original) : true;\n const key = rowKey(row.original);\n const label = selection?.rowLabel?.(row.original) ?? key;\n\n return (\n {\n const next = new Set(selection?.selectedKeys ?? []);\n if (value) {\n next.add(key);\n } else {\n next.delete(key);\n }\n selection?.onChange(next);\n }}\n aria-label={`Select ${label}`}\n />\n );\n },\n });\n }\n\n for (const column of columns) {\n defs.push({\n id: column.key,\n accessorKey: column.key,\n enableSorting: Boolean(column.sortable && sort),\n header: () => {\n if (column.sortable && sort) {\n const isActive = sort.key === column.key;\n const Icon = !isActive ? ArrowUpDown : sort.direction === \"asc\" ? ArrowUp : ArrowDown;\n\n return (\n sort.onChange(column.key, nextDirection(sort.key, column.key, sort.direction))}\n >\n {column.label}\n \n \n );\n }\n\n return {column.label};\n },\n cell: ({ row }) => column.render(row.original),\n });\n }\n\n if (hasRowActions) {\n defs.push({\n id: \"__actions\",\n enableSorting: false,\n header: () => {actionsLabel},\n cell: ({ row }) => rowActions(row.original),\n });\n }\n\n return defs;\n }, [actionsLabel, columns, hasRowActions, hasSelection, rowActions, rowKey, selection, sort]);\n\n const table = useReactTable({\n data,\n columns: tableColumns,\n getCoreRowModel: getCoreRowModel(),\n manualSorting: Boolean(sort),\n enableRowSelection: hasSelection,\n getRowId: (row) => rowKey(row),\n onRowSelectionChange: (updater) => {\n if (!selection) {\n return;\n }\n\n const current = selectionStateToRowSelection(selection.selectedKeys);\n const next = typeof updater === \"function\" ? updater(current) : updater;\n selection.onChange(rowSelectionToKeys(next));\n },\n onSortingChange: (updater) => {\n if (!sort) {\n return;\n }\n\n const next = typeof updater === \"function\" ? updater(sortingState) : updater;\n const first = next[0];\n if (!first) {\n return;\n }\n\n sort.onChange(first.id, first.desc ? \"desc\" : \"asc\");\n },\n state: {\n sorting: sortingState,\n rowSelection: hasSelection ? selectionStateToRowSelection(selection.selectedKeys) : {},\n },\n });\n\n const colSpan = tableColumns.length;\n const selectedCount = selection?.selectedKeys.size ?? 0;\n const showHeader = Boolean(title || subtitle || headerActions);\n\n return (\n
\n {showHeader ? (\n
\n
\n {title ?
{title}
: null}\n {subtitle ?
{subtitle}
: null}\n
\n {headerActions ?
{headerActions}
: null}\n
\n ) : null}\n\n {toolbar ?
{toolbar}
: null}\n\n \n \n {table.getHeaderGroups().map((headerGroup) => (\n \n {headerGroup.headers.map((header) => {\n const column = columns.find((item) => item.key === header.column.id);\n const align =\n header.column.id === \"__actions\"\n ? \"joo-table-head-cell--right\"\n : alignClass(column?.align, \"joo-table-head-cell\");\n\n return (\n \n {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n \n );\n })}\n \n ))}\n \n \n {loading ? (\n \n \n \n ) : table.getRowModel().rows.length === 0 ? (\n \n \n \n ) : (\n table.getRowModel().rows.map((row) => {\n const key = rowKey(row.original);\n const selected = selection?.selectedKeys.has(key) ?? false;\n\n return (\n \n {row.getVisibleCells().map((cell) => {\n const column = columns.find((item) => item.key === cell.column.id);\n const align =\n cell.column.id === \"__actions\"\n ? \"joo-table-cell--right\"\n : alignClass(column?.align, \"joo-table-cell\");\n\n return (\n \n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n \n );\n })}\n \n );\n })\n )}\n \n
\n Loading…\n \n {emptyMessage}\n
\n\n {pagination || footer || hasSelection ? (\n
\n
\n {hasSelection ? (\n \n {selectedCount} selected\n {pagination?.total !== undefined ? ` · ${pagination.total.toLocaleString()} total` : null}\n \n ) : pagination?.total !== undefined ? (\n {pagination.total.toLocaleString()} items\n ) : null}\n {footer ? {footer} : null}\n
\n {pagination ? (\n
\n pagination.onPageChange(pagination.page - 1)}\n >\n Previous\n \n \n Page {pagination.page} of {pagination.lastPage}\n \n = pagination.lastPage}\n onClick={() => pagination.onPageChange(pagination.page + 1)}\n >\n Next\n \n
\n ) : null}\n
\n ) : null}\n
\n );\n}\n","import type { ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn\";\n\nexport function ActionBar({ children, className }: { children: ReactNode; className?: string }) {\n return
{children}
;\n}\n","import * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\n\nimport { cn } from \"../../lib/cn\";\n\nexport const DropdownMenu = DropdownMenuPrimitive.Root;\nexport const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;\nexport const DropdownMenuGroup = DropdownMenuPrimitive.Group;\nexport const DropdownMenuPortal = DropdownMenuPrimitive.Portal;\n\nexport function DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentPropsWithoutRef) {\n return (\n \n \n \n );\n}\n\nexport function DropdownMenuLabel({\n className,\n ...props\n}: React.ComponentPropsWithoutRef) {\n return ;\n}\n\nexport function DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentPropsWithoutRef) {\n return ;\n}\n\nexport function DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentPropsWithoutRef & {\n inset?: boolean;\n variant?: \"default\" | \"danger\";\n}) {\n return (\n \n );\n}\n","import { ChevronDown, MoreHorizontal } from \"lucide-react\";\n\nimport { ActionBar } from \"./ActionBar\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"./ui/dropdown-menu\";\nimport { Button } from \"./ui/button\";\nimport type { TableAction } from \"../types\";\n\nexport function TableActions({ actions }: { actions: TableAction[] }) {\n if (actions.length === 0) {\n return null;\n }\n\n return (\n \n {actions.map((action, index) => (\n \n ))}\n \n );\n}\n\nexport function TableActionButton({ action }: { action: TableAction }) {\n if (action.type === \"single\") {\n return (\n \n {action.icon ?? action.label}\n \n );\n }\n\n const iconOnly = action.icon !== undefined && action.label.length > 0;\n\n return (\n \n \n \n {action.icon ?? (\n <>\n {action.label}\n \n \n )}\n {action.icon ? {action.label} : null}\n \n \n \n {action.label}\n \n {action.items.map((item) => (\n {\n event.preventDefault();\n item.onClick();\n }}\n >\n {item.icon}\n {item.label}\n \n ))}\n \n \n );\n}\n\nexport function TableHeaderIconAction({ action }: { action: TableAction }) {\n if (action.type === \"single\") {\n return (\n \n {action.icon}\n \n );\n }\n\n return (\n \n \n \n \n \n {action.label}\n \n {action.items.map((item) => (\n {\n event.preventDefault();\n item.onClick();\n }}\n >\n {item.icon}\n {item.label}\n \n ))}\n \n \n );\n}\n"]} \ No newline at end of file diff --git a/components/table/dist/styles.css b/components/table/dist/styles.css index e366601..a133dec 100644 --- a/components/table/dist/styles.css +++ b/components/table/dist/styles.css @@ -188,6 +188,10 @@ } .joo-table-footer-meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem 0.75rem; color: hsl(var(--joo-muted-foreground)); } diff --git a/components/table/package.json b/components/table/package.json index a5a6bbf..11b2128 100644 --- a/components/table/package.json +++ b/components/table/package.json @@ -39,7 +39,8 @@ "build": "tsup && cp src/styles.css dist/styles.css", "typecheck": "tsc --noEmit", "test": "vitest run", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" }, "dependencies": { "@radix-ui/react-checkbox": "^1.3.3", diff --git a/components/table/src/DataTable.test.tsx b/components/table/src/DataTable.test.tsx index ba1a0e2..9598282 100644 --- a/components/table/src/DataTable.test.tsx +++ b/components/table/src/DataTable.test.tsx @@ -15,20 +15,52 @@ const columns: DataTableColumn[] = [ ]; describe("DataTable", () => { - it("renders title, rows, and actions column", () => { + it("renders title, rows, header actions, and actions column", () => { + const onEdit = vi.fn(); + render( + Refresh + + } columns={columns} data={[{ id: 1, name: "Jable" }]} rowKey={(row) => String(row.id)} - rowActions={() => [{ type: "single", label: "Edit", onClick: vi.fn() }]} + rowActions={() => ( + + )} />, ); expect(screen.getByText("Sites")).toBeInTheDocument(); expect(screen.getByText("Jable")).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Refresh" })).toBeInTheDocument(); expect(screen.getByRole("columnheader", { name: "Actions" })).toBeInTheDocument(); expect(screen.getByRole("button", { name: "Edit" })).toBeInTheDocument(); }); + + it("renders toolbar, loading, and custom footer with pagination", () => { + render( + Filters} + columns={columns} + data={[{ id: 1, name: "Jable" }]} + rowKey={(row) => String(row.id)} + loading + footer={Server-side demo} + pagination={{ page: 1, lastPage: 3, total: 12, onPageChange: vi.fn() }} + />, + ); + + expect(screen.getByText("Filters")).toBeInTheDocument(); + expect(screen.getByText("Loading…")).toBeInTheDocument(); + expect(screen.getByText("Server-side demo")).toBeInTheDocument(); + expect(screen.getByText("Page 1 of 3")).toBeInTheDocument(); + }); }); diff --git a/components/table/src/components/DataTable.tsx b/components/table/src/components/DataTable.tsx index 8bb2ad5..85502bc 100644 --- a/components/table/src/components/DataTable.tsx +++ b/components/table/src/components/DataTable.tsx @@ -7,11 +7,10 @@ import { type SortingState, } from "@tanstack/react-table"; import { ArrowDown, ArrowUp, ArrowUpDown } from "lucide-react"; -import { useMemo, type ReactNode } from "react"; +import { useMemo } from "react"; import { cn } from "../lib/cn"; import type { DataTableProps, SortDirection } from "../types"; -import { TableActions, TableHeaderIconAction } from "./TableActionButton"; import { Button } from "./ui/button"; import { Checkbox } from "./ui/checkbox"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./ui/table"; @@ -168,7 +167,7 @@ export function DataTable({ id: "__actions", enableSorting: false, header: () => {actionsLabel}, - cell: ({ row }) => , + cell: ({ row }) => rowActions(row.original), }); } @@ -212,7 +211,7 @@ export function DataTable({ const colSpan = tableColumns.length; const selectedCount = selection?.selectedKeys.size ?? 0; - const showHeader = title || subtitle || (headerActions && headerActions.length > 0); + const showHeader = Boolean(title || subtitle || headerActions); return (
@@ -222,13 +221,7 @@ export function DataTable({ {title ?
{title}
: null} {subtitle ?
{subtitle}
: null}
- {headerActions && headerActions.length > 0 ? ( -
- {headerActions.map((action, index) => ( - - ))} -
- ) : null} + {headerActions ?
{headerActions}
: null} ) : null} @@ -304,9 +297,8 @@ export function DataTable({ ) : pagination?.total !== undefined ? ( {pagination.total.toLocaleString()} items - ) : ( - footer ?? null - )} + ) : null} + {footer ? {footer} : null} {pagination ? (
@@ -330,9 +322,7 @@ export function DataTable({ Next
- ) : ( - (footer as ReactNode) ?? null - )} + ) : null} ) : null} diff --git a/components/table/src/styles.css b/components/table/src/styles.css index e366601..a133dec 100644 --- a/components/table/src/styles.css +++ b/components/table/src/styles.css @@ -188,6 +188,10 @@ } .joo-table-footer-meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem 0.75rem; color: hsl(var(--joo-muted-foreground)); } diff --git a/components/table/src/types.ts b/components/table/src/types.ts index c7259b5..4bfa6bd 100644 --- a/components/table/src/types.ts +++ b/components/table/src/types.ts @@ -60,12 +60,20 @@ export type DataTableSelection = { export type DataTableProps = { title?: string; subtitle?: ReactNode; - headerActions?: TableAction[]; + /** + * Header trailing slot — compose with `@jooservices/react-action-buttons` + * (`ActionBar` / `Button` / `ActionMenu`) or table `TableHeaderIconAction`. + */ + headerActions?: ReactNode; toolbar?: ReactNode; columns: DataTableColumn[]; data: T[]; rowKey: (row: T) => string; - rowActions?: (row: T) => TableAction[]; + /** + * Last column cell — return action-buttons (`ActionBar` + `Button` / `ActionMenu`) + * or table `TableActions` helpers. + */ + rowActions?: (row: T) => ReactNode; actionsLabel?: string; selection?: DataTableSelection; sort?: DataTableSort; From 082112da9a152980a13a169c1d2f8ce5d3ebbf8c Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:25 -0600 Subject: [PATCH 09/14] chore(ui): document lint script and consumer install path --- components/ui/AGENTS.md | 3 ++- components/ui/README.md | 8 +++++--- components/ui/package.json | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/components/ui/AGENTS.md b/components/ui/AGENTS.md index b51a50e..f643fab 100644 --- a/components/ui/AGENTS.md +++ b/components/ui/AGENTS.md @@ -24,5 +24,6 @@ npm run build ## Docs -- User guide: `docs/02-user-guide/` (matching package page) +- User guide: `docs/02-user-guide/01-react-ui.md` (consumer API — do not send humans to `src/`) +- Package README: `components/ui/README.md` - Root policy: `AGENTS.md` diff --git a/components/ui/README.md b/components/ui/README.md index bf0d996..1e8243a 100644 --- a/components/ui/README.md +++ b/components/ui/README.md @@ -5,10 +5,10 @@ Shared UI primitives for React apps — colored status controls with Lucide icon ## Install ```bash -npm install @jooservices/react-ui lucide-react +pnpm add "github:jooservices/react#v1.0.0&path:components/ui" ``` -Peer dependencies: `react`, `react-dom`, `lucide-react`. +Peer dependencies: `react`, `react-dom` (>=18), `lucide-react` (>=0.400). ## Setup @@ -37,6 +37,8 @@ import { StatusToggle } from "@jooservices/react-ui"; | Export | Description | |--------|-------------| -| `StatusToggle` | Interactive button for `active` ↔ `disabled` | +| `StatusToggle` | Interactive button for `active` ↔ `disabled` (`pending`, `size` `sm`\|`md`, `showLabel`) | | `StatusIndicator` | Read-only pill for any `StatusValue` | | `StatusValue` | `"active" \| "disabled" \| "pending_review" \| "failed"` | + +Full prop tables: `docs/02-user-guide/01-react-ui.md`. diff --git a/components/ui/package.json b/components/ui/package.json index c01d417..b9adc75 100644 --- a/components/ui/package.json +++ b/components/ui/package.json @@ -39,7 +39,8 @@ "build": "tsup && cp src/styles.css dist/styles.css", "typecheck": "tsc --noEmit", "test": "vitest run", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "lint": "tsc --noEmit" }, "dependencies": { "class-variance-authority": "^0.7.1", From f3c0ecfcf86f5f89213103a501439535c962715a Mon Sep 17 00:00:00 2001 From: Viet Vu Date: Tue, 14 Jul 2026 14:37:25 -0600 Subject: [PATCH 10/14] feat(demo): rebuild showcase around Dashboard and package guides Add Buttons/Card/Modal/Toast/Docs pages, identity action-buttons, and in-app docs content. --- apps/demo/AGENTS.md | 11 +- apps/demo/package-lock.json | 132 +++++ apps/demo/package.json | 4 + apps/demo/src/app/App.tsx | 15 +- .../src/components/demo/CoverageChart.tsx | 45 ++ .../src/components/demo/PackageGuideIntro.tsx | 48 ++ apps/demo/src/components/layout/Sidebar.tsx | 69 ++- apps/demo/src/components/layout/nav-config.ts | 198 +++++++- .../demo/src/components/layout/page-shell.tsx | 4 + .../components/table/RowAnnotationActions.tsx | 132 +++++ .../src/components/table/RowStatusToggle.tsx | 52 ++ apps/demo/src/data/demo-data.ts | 51 ++ apps/demo/src/data/docs-content.ts | 209 ++++++++ apps/demo/src/layout/AppLayout.tsx | 266 ++++++---- apps/demo/src/main.tsx | 4 + apps/demo/src/pages/ButtonsPage.tsx | 324 ++++++++++++ apps/demo/src/pages/CardPage.tsx | 117 +++++ apps/demo/src/pages/ConfigPage.tsx | 76 ++- apps/demo/src/pages/ContentPage.tsx | 76 ++- apps/demo/src/pages/DashboardPage.tsx | 476 ++++++++++++++++++ apps/demo/src/pages/DocsPage.tsx | 137 +++++ apps/demo/src/pages/LayoutPage.tsx | 60 ++- apps/demo/src/pages/ModalPage.tsx | 166 ++++++ apps/demo/src/pages/OverviewPage.tsx | 198 -------- apps/demo/src/pages/TablePage.tsx | 411 +++++++++++++-- apps/demo/src/pages/ToastPage.tsx | 219 ++++++++ apps/demo/src/pages/UiPage.tsx | 62 ++- apps/demo/vite.config.ts | 4 + 28 files changed, 3146 insertions(+), 420 deletions(-) create mode 100644 apps/demo/src/components/demo/CoverageChart.tsx create mode 100644 apps/demo/src/components/demo/PackageGuideIntro.tsx create mode 100644 apps/demo/src/components/table/RowAnnotationActions.tsx create mode 100644 apps/demo/src/components/table/RowStatusToggle.tsx create mode 100644 apps/demo/src/data/docs-content.ts create mode 100644 apps/demo/src/pages/ButtonsPage.tsx create mode 100644 apps/demo/src/pages/CardPage.tsx create mode 100644 apps/demo/src/pages/DashboardPage.tsx create mode 100644 apps/demo/src/pages/DocsPage.tsx create mode 100644 apps/demo/src/pages/ModalPage.tsx delete mode 100644 apps/demo/src/pages/OverviewPage.tsx create mode 100644 apps/demo/src/pages/ToastPage.tsx diff --git a/apps/demo/AGENTS.md b/apps/demo/AGENTS.md index a9ddcd4..8d82cf6 100644 --- a/apps/demo/AGENTS.md +++ b/apps/demo/AGENTS.md @@ -5,9 +5,18 @@ ## Rules - Light-only chrome — no theme toggle / dark mode switcher. -- Prefer package public APIs (`AppShell.HeaderBar`, `PageShell`, `DataTable`, …). +- Prefer package public APIs (`AppShell.HeaderBar`, `PageShell`, `DataTable`, `ActionBar` / `Button`, …). - When any `components/*` public API or user-visible styles change, update this demo in the same change and run `npm run demo:typecheck` (and `demo:build` when layout/styles change). +### Primary action placement (no exceptions) + +On every PageShell demo page, **view-level CTAs** must use `@jooservices/react-action-buttons` in **`PageShellIdentity` → `actions`** only. + +- Do not invent custom primary `