From 2a3bb0ef7ea95a711d70903636e22eb0c50990f5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 7 Jan 2026 19:11:42 +0000 Subject: [PATCH 1/3] refactor: rebuild SCL with pure Radix primitives and vanilla CSS Remove shadcn/ui patterns and Tailwind CSS in favor of vanilla CSS with CSS custom properties. All components now use Radix primitives directly with component-specific CSS files using BEM-like naming (scl-*). Changes: - Replace Tailwind utility classes with vanilla CSS - Replace class-variance-authority (CVA) with simple CSS modifiers - Replace cn() (clsx + tailwind-merge) with cx() utility - Create component-specific CSS files (e.g., button.css, dialog.css) - Use CSS custom properties for design tokens (--scl-*) - Remove tailwind.config.ts and postcss.config.js - Update vite.config.ts to build CSS properly Removed components (depended on removed libraries): - alert-dialog, combobox, command (used cmdk) - form (used react-hook-form) - sheet, dropdown-menu (used lucide-react) - dithered-image, statusline, terminal-textarea Updated tests to use new CSS class naming conventions. BREAKING CHANGE: API changes to variant props and CSS class names --- bun.lock | 391 +------------- package.json | 51 +- postcss.config.js | 6 - src/components/ui/accordion/accordion.css | 58 ++ src/components/ui/accordion/accordion.tsx | 36 +- .../ui/alert-dialog/alert-dialog.stories.tsx | 41 -- .../ui/alert-dialog/alert-dialog.test.tsx | 46 -- .../ui/alert-dialog/alert-dialog.tsx | 109 ---- src/components/ui/alert-dialog/index.ts | 13 - src/components/ui/alert/alert.css | 71 +++ src/components/ui/alert/alert.test.tsx | 4 +- src/components/ui/alert/alert.tsx | 51 +- src/components/ui/alert/index.ts | 2 +- src/components/ui/avatar/avatar.css | 32 ++ src/components/ui/avatar/avatar.tsx | 15 +- src/components/ui/badge/badge.css | 56 ++ src/components/ui/badge/badge.test.tsx | 8 +- src/components/ui/badge/badge.tsx | 45 +- src/components/ui/badge/index.ts | 2 +- src/components/ui/button/button.css | 185 +++++++ src/components/ui/button/button.stories.tsx | 63 +-- src/components/ui/button/button.test.tsx | 4 +- src/components/ui/button/button.tsx | 70 +-- src/components/ui/button/index.ts | 2 +- src/components/ui/card/card.css | 41 ++ src/components/ui/card/card.tsx | 32 +- src/components/ui/checkbox/checkbox.css | 40 ++ src/components/ui/checkbox/checkbox.tsx | 27 +- src/components/ui/collapsible/collapsible.css | 11 + src/components/ui/collapsible/collapsible.tsx | 1 + .../ui/combobox/combobox.stories.tsx | 188 ------- src/components/ui/combobox/combobox.test.tsx | 186 ------- src/components/ui/combobox/combobox.tsx | 190 ------- src/components/ui/combobox/index.ts | 2 - src/components/ui/command/command.stories.tsx | 241 --------- src/components/ui/command/command.test.tsx | 190 ------- src/components/ui/command/command.tsx | 144 ----- src/components/ui/command/index.ts | 11 - src/components/ui/dialog/dialog.css | 108 ++++ src/components/ui/dialog/dialog.tsx | 45 +- .../dithered-image/dithered-image.stories.tsx | 176 ------ .../ui/dithered-image/dithered-image.tsx | 452 ---------------- src/components/ui/dithered-image/index.ts | 2 - .../dropdown-menu/dropdown-menu.stories.tsx | 66 --- .../ui/dropdown-menu/dropdown-menu.test.tsx | 58 -- .../ui/dropdown-menu/dropdown-menu.tsx | 185 ------- src/components/ui/dropdown-menu/index.ts | 17 - src/components/ui/form/form.stories.tsx | 342 ------------ src/components/ui/form/form.test.tsx | 180 ------- src/components/ui/form/form.tsx | 166 ------ src/components/ui/form/index.ts | 10 - src/components/ui/input/input.css | 79 +++ src/components/ui/input/input.tsx | 8 +- src/components/ui/label/label.css | 14 + src/components/ui/label/label.tsx | 16 +- src/components/ui/popover/popover.css | 11 + src/components/ui/popover/popover.tsx | 10 +- src/components/ui/progress/progress.css | 33 ++ src/components/ui/progress/progress.tsx | 17 +- src/components/ui/radio-group/radio-group.css | 43 ++ src/components/ui/radio-group/radio-group.tsx | 21 +- src/components/ui/scroll-area/scroll-area.css | 37 ++ src/components/ui/scroll-area/scroll-area.tsx | 17 +- src/components/ui/select/select.css | 137 +++++ src/components/ui/select/select.tsx | 87 +-- src/components/ui/separator/separator.css | 16 + .../ui/separator/separator.test.tsx | 8 +- src/components/ui/separator/separator.tsx | 9 +- src/components/ui/sheet/index.ts | 12 - src/components/ui/sheet/sheet.stories.tsx | 50 -- src/components/ui/sheet/sheet.test.tsx | 36 -- src/components/ui/sheet/sheet.tsx | 107 ---- src/components/ui/skeleton/skeleton.css | 10 + src/components/ui/skeleton/skeleton.test.tsx | 7 +- src/components/ui/skeleton/skeleton.tsx | 6 +- src/components/ui/slider/slider.css | 48 ++ src/components/ui/slider/slider.tsx | 14 +- src/components/ui/statusline/index.ts | 1 - .../ui/statusline/statusline.stories.tsx | 159 ------ .../ui/statusline/statusline.test.tsx | 90 ---- src/components/ui/statusline/statusline.tsx | 216 -------- src/components/ui/switch/switch.css | 40 ++ src/components/ui/switch/switch.tsx | 14 +- src/components/ui/table/table.css | 65 +++ src/components/ui/table/table.tsx | 43 +- src/components/ui/tabs/tabs.css | 55 ++ src/components/ui/tabs/tabs.tsx | 18 +- src/components/ui/terminal-textarea/index.ts | 1 - .../terminal-textarea.stories.tsx | 120 ----- .../terminal-textarea.test.tsx | 82 --- .../terminal-textarea/terminal-textarea.tsx | 119 ---- src/components/ui/textarea/textarea.css | 35 ++ src/components/ui/textarea/textarea.tsx | 8 +- src/components/ui/toggle/index.ts | 2 +- src/components/ui/toggle/toggle.css | 65 +++ src/components/ui/toggle/toggle.stories.tsx | 14 +- src/components/ui/toggle/toggle.test.tsx | 9 - src/components/ui/toggle/toggle.tsx | 38 +- src/components/ui/tooltip/tooltip.css | 11 + src/components/ui/tooltip/tooltip.tsx | 9 +- src/index.ts | 13 +- src/lib/utils.ts | 24 +- src/styles/globals.css | 509 ++++++++---------- tailwind.config.ts | 145 ----- vite.config.ts | 4 + 105 files changed, 1872 insertions(+), 5362 deletions(-) delete mode 100644 postcss.config.js create mode 100644 src/components/ui/accordion/accordion.css delete mode 100644 src/components/ui/alert-dialog/alert-dialog.stories.tsx delete mode 100644 src/components/ui/alert-dialog/alert-dialog.test.tsx delete mode 100644 src/components/ui/alert-dialog/alert-dialog.tsx delete mode 100644 src/components/ui/alert-dialog/index.ts create mode 100644 src/components/ui/alert/alert.css create mode 100644 src/components/ui/avatar/avatar.css create mode 100644 src/components/ui/badge/badge.css create mode 100644 src/components/ui/button/button.css create mode 100644 src/components/ui/card/card.css create mode 100644 src/components/ui/checkbox/checkbox.css create mode 100644 src/components/ui/collapsible/collapsible.css delete mode 100644 src/components/ui/combobox/combobox.stories.tsx delete mode 100644 src/components/ui/combobox/combobox.test.tsx delete mode 100644 src/components/ui/combobox/combobox.tsx delete mode 100644 src/components/ui/combobox/index.ts delete mode 100644 src/components/ui/command/command.stories.tsx delete mode 100644 src/components/ui/command/command.test.tsx delete mode 100644 src/components/ui/command/command.tsx delete mode 100644 src/components/ui/command/index.ts create mode 100644 src/components/ui/dialog/dialog.css delete mode 100644 src/components/ui/dithered-image/dithered-image.stories.tsx delete mode 100644 src/components/ui/dithered-image/dithered-image.tsx delete mode 100644 src/components/ui/dithered-image/index.ts delete mode 100644 src/components/ui/dropdown-menu/dropdown-menu.stories.tsx delete mode 100644 src/components/ui/dropdown-menu/dropdown-menu.test.tsx delete mode 100644 src/components/ui/dropdown-menu/dropdown-menu.tsx delete mode 100644 src/components/ui/dropdown-menu/index.ts delete mode 100644 src/components/ui/form/form.stories.tsx delete mode 100644 src/components/ui/form/form.test.tsx delete mode 100644 src/components/ui/form/form.tsx delete mode 100644 src/components/ui/form/index.ts create mode 100644 src/components/ui/input/input.css create mode 100644 src/components/ui/label/label.css create mode 100644 src/components/ui/popover/popover.css create mode 100644 src/components/ui/progress/progress.css create mode 100644 src/components/ui/radio-group/radio-group.css create mode 100644 src/components/ui/scroll-area/scroll-area.css create mode 100644 src/components/ui/select/select.css create mode 100644 src/components/ui/separator/separator.css delete mode 100644 src/components/ui/sheet/index.ts delete mode 100644 src/components/ui/sheet/sheet.stories.tsx delete mode 100644 src/components/ui/sheet/sheet.test.tsx delete mode 100644 src/components/ui/sheet/sheet.tsx create mode 100644 src/components/ui/skeleton/skeleton.css create mode 100644 src/components/ui/slider/slider.css delete mode 100644 src/components/ui/statusline/index.ts delete mode 100644 src/components/ui/statusline/statusline.stories.tsx delete mode 100644 src/components/ui/statusline/statusline.test.tsx delete mode 100644 src/components/ui/statusline/statusline.tsx create mode 100644 src/components/ui/switch/switch.css create mode 100644 src/components/ui/table/table.css create mode 100644 src/components/ui/tabs/tabs.css delete mode 100644 src/components/ui/terminal-textarea/index.ts delete mode 100644 src/components/ui/terminal-textarea/terminal-textarea.stories.tsx delete mode 100644 src/components/ui/terminal-textarea/terminal-textarea.test.tsx delete mode 100644 src/components/ui/terminal-textarea/terminal-textarea.tsx create mode 100644 src/components/ui/textarea/textarea.css create mode 100644 src/components/ui/toggle/toggle.css create mode 100644 src/components/ui/tooltip/tooltip.css delete mode 100644 tailwind.config.ts diff --git a/bun.lock b/bun.lock index 22dd51c..e3efba5 100644 --- a/bun.lock +++ b/bun.lock @@ -5,36 +5,18 @@ "": { "name": "@drjoshcsimmons/scl", "dependencies": { - "@codemirror/basic-setup": "^0.20.0", - "@codemirror/commands": "^6.10.1", - "@codemirror/lang-css": "^6.3.1", - "@codemirror/lang-html": "^6.4.11", - "@codemirror/lang-javascript": "^6.2.4", - "@codemirror/lang-json": "^6.0.2", - "@codemirror/lang-markdown": "^6.5.0", - "@codemirror/language": "^6.11.3", - "@codemirror/state": "^6.5.2", - "@codemirror/view": "^6.39.4", - "@lezer/highlight": "^1.2.3", - "@replit/codemirror-vim": "^6.3.0", "@vercel/analytics": "^1.6.1", }, "devDependencies": { "@biomejs/biome": "2.3.10", - "@hookform/resolvers": "^3.9.0", "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-alert-dialog": "^1.1.0", - "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-avatar": "^1.1.0", "@radix-ui/react-checkbox": "^1.1.0", "@radix-ui/react-collapsible": "^1.1.0", - "@radix-ui/react-context-menu": "^2.2.0", "@radix-ui/react-dialog": "^1.1.0", "@radix-ui/react-dropdown-menu": "^2.1.0", - "@radix-ui/react-hover-card": "^1.1.0", "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-menubar": "^1.1.0", - "@radix-ui/react-navigation-menu": "^1.2.0", "@radix-ui/react-popover": "^1.1.0", "@radix-ui/react-progress": "^1.1.0", "@radix-ui/react-radio-group": "^1.2.0", @@ -45,9 +27,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", - "@radix-ui/react-toast": "^1.2.0", "@radix-ui/react-toggle": "^1.1.0", - "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.0", "@storybook/addon-a11y": "8.6.15", "@storybook/addon-essentials": "8.6.15", @@ -65,33 +45,14 @@ "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.0", "@vitest/coverage-v8": "^2.1.0", - "autoprefixer": "^10.4.0", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.0", - "cmdk": "^1.0.0", - "date-fns": "^3.6.0", - "embla-carousel-react": "^8.3.0", - "input-otp": "^1.4.0", "jsdom": "^25.0.0", - "lucide-react": "^0.460.0", - "postcss": "^8.4.0", "react": "^18.3.0", - "react-day-picker": "^9.3.0", "react-dom": "^18.3.0", - "react-hook-form": "^7.54.0", - "react-resizable-panels": "^2.1.0", - "recharts": "^2.13.0", - "sonner": "^1.7.0", "storybook": "8.6.15", - "tailwind-merge": "^2.5.0", - "tailwindcss": "^3.4.0", - "tailwindcss-animate": "^1.0.0", "typescript": "^5.6.0", - "vaul": "^1.1.0", "vite": "^5.4.0", "vite-plugin-dts": "^4.3.0", "vitest": "^2.1.0", - "zod": "^3.24.0", }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -102,8 +63,6 @@ "packages": { "@adobe/css-tools": ["@adobe/css-tools@4.4.4", "", {}, "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg=="], - "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], - "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], "@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.2.0", "", { "dependencies": { "@csstools/css-calc": "^2.1.3", "@csstools/css-color-parser": "^3.0.9", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw=="], @@ -168,32 +127,6 @@ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.10", "", { "os": "win32", "cpu": "x64" }, "sha512-pHEFgq7dUEsKnqG9mx9bXihxGI49X+ar+UBrEIj3Wqj3UCZp1rNgV+OoyjFgcXsjCWpuEAF4VJdkZr3TrWdCbQ=="], - "@codemirror/autocomplete": ["@codemirror/autocomplete@0.20.3", "", { "dependencies": { "@codemirror/language": "^0.20.0", "@codemirror/state": "^0.20.0", "@codemirror/view": "^0.20.0", "@lezer/common": "^0.16.0" } }, "sha512-lYB+NPGP+LEzAudkWhLfMxhTrxtLILGl938w+RcFrGdrIc54A+UgmCoz+McE3IYRFp4xyQcL4uFJwo+93YdgHw=="], - - "@codemirror/basic-setup": ["@codemirror/basic-setup@0.20.0", "", { "dependencies": { "@codemirror/autocomplete": "^0.20.0", "@codemirror/commands": "^0.20.0", "@codemirror/language": "^0.20.0", "@codemirror/lint": "^0.20.0", "@codemirror/search": "^0.20.0", "@codemirror/state": "^0.20.0", "@codemirror/view": "^0.20.0" } }, "sha512-W/ERKMLErWkrVLyP5I8Yh8PXl4r+WFNkdYVSzkXYPQv2RMPSkWpr2BgggiSJ8AHF/q3GuApncDD8I4BZz65fyg=="], - - "@codemirror/commands": ["@codemirror/commands@6.10.1", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } }, "sha512-uWDWFypNdQmz2y1LaNJzK7fL7TYKLeUAU0npEC685OKTF3KcQ2Vu3klIM78D7I6wGhktme0lh3CuQLv0ZCrD9Q=="], - - "@codemirror/lang-css": ["@codemirror/lang-css@6.3.1", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@lezer/common": "^1.0.2", "@lezer/css": "^1.1.7" } }, "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg=="], - - "@codemirror/lang-html": ["@codemirror/lang-html@6.4.11", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/lang-css": "^6.0.0", "@codemirror/lang-javascript": "^6.0.0", "@codemirror/language": "^6.4.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0", "@lezer/css": "^1.1.0", "@lezer/html": "^1.3.12" } }, "sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw=="], - - "@codemirror/lang-javascript": ["@codemirror/lang-javascript@6.2.4", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.6.0", "@codemirror/lint": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0", "@lezer/javascript": "^1.0.0" } }, "sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA=="], - - "@codemirror/lang-json": ["@codemirror/lang-json@6.0.2", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@lezer/json": "^1.0.0" } }, "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ=="], - - "@codemirror/lang-markdown": ["@codemirror/lang-markdown@6.5.0", "", { "dependencies": { "@codemirror/autocomplete": "^6.7.1", "@codemirror/lang-html": "^6.0.0", "@codemirror/language": "^6.3.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "@lezer/common": "^1.2.1", "@lezer/markdown": "^1.0.0" } }, "sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw=="], - - "@codemirror/language": ["@codemirror/language@6.11.3", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", "@lezer/common": "^1.1.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0", "style-mod": "^4.0.0" } }, "sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA=="], - - "@codemirror/lint": ["@codemirror/lint@0.20.3", "", { "dependencies": { "@codemirror/state": "^0.20.0", "@codemirror/view": "^0.20.2", "crelt": "^1.0.5" } }, "sha512-06xUScbbspZ8mKoODQCEx6hz1bjaq9m8W8DxdycWARMiiX1wMtfCh/MoHpaL7ws/KUMwlsFFfp2qhm32oaCvVA=="], - - "@codemirror/search": ["@codemirror/search@0.20.1", "", { "dependencies": { "@codemirror/state": "^0.20.0", "@codemirror/view": "^0.20.0", "crelt": "^1.0.5" } }, "sha512-ROe6gRboQU5E4z6GAkNa2kxhXqsGNbeLEisbvzbOeB7nuDYXUZ70vGIgmqPu0tB+1M3F9yWk6W8k2vrFpJaD4Q=="], - - "@codemirror/state": ["@codemirror/state@6.5.2", "", { "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } }, "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA=="], - - "@codemirror/view": ["@codemirror/view@6.39.4", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-xMF6OfEAUVY5Waega4juo1QGACfNkNF+aJLqpd8oUJz96ms2zbfQ9Gh35/tI3y8akEV31FruKfj7hBnIU/nkqA=="], - "@csstools/color-helpers": ["@csstools/color-helpers@5.1.0", "", {}, "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA=="], "@csstools/css-calc": ["@csstools/css-calc@2.1.4", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4" } }, "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ=="], @@ -204,8 +137,6 @@ "@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="], - "@date-fns/tz": ["@date-fns/tz@1.4.1", "", {}, "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], @@ -266,8 +197,6 @@ "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], - "@hookform/resolvers": ["@hookform/resolvers@3.10.0", "", { "peerDependencies": { "react-hook-form": "^7.0.0" } }, "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag=="], - "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="], @@ -288,24 +217,6 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - "@lezer/common": ["@lezer/common@1.4.0", "", {}, "sha512-DVeMRoGrgn/k45oQNu189BoW4SZwgZFzJ1+1TV5j2NJ/KFC83oa/enRqZSGshyeMk5cPWMhsKs9nx+8o0unwGg=="], - - "@lezer/css": ["@lezer/css@1.3.0", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.3.0" } }, "sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw=="], - - "@lezer/highlight": ["@lezer/highlight@1.2.3", "", { "dependencies": { "@lezer/common": "^1.3.0" } }, "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g=="], - - "@lezer/html": ["@lezer/html@1.3.12", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-RJ7eRWdaJe3bsiiLLHjCFT1JMk8m1YP9kaUbvu2rMLEoOnke9mcTVDyfOslsln0LtujdWespjJ39w6zo+RsQYw=="], - - "@lezer/javascript": ["@lezer/javascript@1.5.4", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.1.3", "@lezer/lr": "^1.3.0" } }, "sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA=="], - - "@lezer/json": ["@lezer/json@1.0.3", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ=="], - - "@lezer/lr": ["@lezer/lr@1.4.5", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-/YTRKP5yPPSo1xImYQk7AZZMAgap0kegzqCSYHjAL9x1AZ0ZQW+IpcEzMKagCsbTsLnVeWkxYrCNeXG8xEPrjg=="], - - "@lezer/markdown": ["@lezer/markdown@1.6.1", "", { "dependencies": { "@lezer/common": "^1.0.0", "@lezer/highlight": "^1.0.0" } }, "sha512-72ah+Sml7lD8Wn7lnz9vwYmZBo9aQT+I2gjK/0epI+gjdwUbWw3MJ/ZBGEqG1UfrIauRqH37/c5mVHXeCTGXtA=="], - - "@marijn/find-cluster-break": ["@marijn/find-cluster-break@1.0.2", "", {}, "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="], - "@mdx-js/react": ["@mdx-js/react@3.1.1", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw=="], "@microsoft/api-extractor": ["@microsoft/api-extractor@7.55.2", "", { "dependencies": { "@microsoft/api-extractor-model": "7.32.2", "@microsoft/tsdoc": "~0.16.0", "@microsoft/tsdoc-config": "~0.18.0", "@rushstack/node-core-library": "5.19.1", "@rushstack/rig-package": "0.6.0", "@rushstack/terminal": "0.19.5", "@rushstack/ts-command-line": "5.1.5", "diff": "~8.0.2", "lodash": "~4.17.15", "minimatch": "10.0.3", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", "typescript": "5.8.2" }, "bin": { "api-extractor": "bin/api-extractor" } }, "sha512-1jlWO4qmgqYoVUcyh+oXYRztZde/pAi7cSVzBz/rc+S7CoVzDasy8QE13dx6sLG4VRo8SfkkLbFORR6tBw4uGQ=="], @@ -316,12 +227,6 @@ "@microsoft/tsdoc-config": ["@microsoft/tsdoc-config@0.18.0", "", { "dependencies": { "@microsoft/tsdoc": "0.16.0", "ajv": "~8.12.0", "jju": "~1.4.0", "resolve": "~1.22.2" } }, "sha512-8N/vClYyfOH+l4fLkkr9+myAoR6M7akc8ntBJ4DJdWH2b09uVfr71+LTMpNyG19fNqWDg8KEDZhx5wxuqHyGjw=="], - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], - - "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], - - "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], - "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], @@ -334,8 +239,6 @@ "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.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" } }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], - "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "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" } }, "sha512-5nZrJTF7gH+e0nZS7/QxFz6tJV4VimhQb1avEgtsJxvvIp5JilL+c58HICsKzPxghdwaDt48hEfPM1au4zGy+w=="], - "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.11", "", { "dependencies": { "@radix-ui/react-context": "1.1.3", "@radix-ui/react-primitive": "2.1.4", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "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" } }, "sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q=="], "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "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" } }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="], @@ -348,8 +251,6 @@ "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.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" } }, "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww=="], - "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.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" } }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], @@ -362,18 +263,12 @@ "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "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" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], - "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.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" } }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="], - "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], "@radix-ui/react-label": ["@radix-ui/react-label@2.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "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" } }, "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A=="], "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.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" } }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="], - "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.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" } }, "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA=="], - - "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "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" } }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="], - "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.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" } }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="], "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "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" } }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="], @@ -404,12 +299,8 @@ "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.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" } }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], - "@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-visually-hidden": "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" } }, "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g=="], - "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.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" } }, "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ=="], - "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.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" } }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="], - "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "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" } }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="], "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], @@ -434,8 +325,6 @@ "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], - "@replit/codemirror-vim": ["@replit/codemirror-vim@6.3.0", "", { "peerDependencies": { "@codemirror/commands": "6.x.x", "@codemirror/language": "6.x.x", "@codemirror/search": "6.x.x", "@codemirror/state": "6.x.x", "@codemirror/view": "6.x.x" } }, "sha512-aTx931ULAMuJx6xLf7KQDOL7CxD+Sa05FktTDrtLaSy53uj01ll3Zf17JdKsriER248oS55GBzg0CfCTjEneAQ=="], - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" } }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="], @@ -572,24 +461,6 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="], - - "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="], - - "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="], - - "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="], - - "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="], - - "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="], - - "@types/d3-shape": ["@types/d3-shape@3.1.7", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg=="], - - "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="], - - "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="], - "@types/doctrine": ["@types/doctrine@0.0.9", "", {}, "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], @@ -658,12 +529,6 @@ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], - - "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], - - "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], - "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], @@ -676,8 +541,6 @@ "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], - "autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": "bin/autoprefixer" }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], - "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], "axe-core": ["axe-core@4.11.0", "", {}, "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ=="], @@ -688,12 +551,8 @@ "better-opn": ["better-opn@3.0.2", "", { "dependencies": { "open": "^8.0.4" } }, "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ=="], - "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], - "brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], - "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - "browser-assert": ["browser-assert@1.2.1", "", {}, "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ=="], "browserslist": ["browserslist@4.26.2", "", { "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", "electron-to-chromium": "^1.5.218", "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": "cli.js" }, "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A=="], @@ -706,8 +565,6 @@ "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], - "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001745", "", {}, "sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ=="], "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], @@ -716,76 +573,34 @@ "check-error": ["check-error@2.1.1", "", {}, "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw=="], - "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], - - "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], - - "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], - - "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="], - "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], - "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], - "compare-versions": ["compare-versions@6.1.1", "", {}, "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg=="], "confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "crelt": ["crelt@1.0.6", "", {}, "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="], - "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="], - "cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], - "cssstyle": ["cssstyle@4.6.0", "", { "dependencies": { "@asamuzakjp/css-color": "^3.2.0", "rrweb-cssom": "^0.8.0" } }, "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg=="], "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="], - - "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="], - - "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="], - - "d3-format": ["d3-format@3.1.0", "", {}, "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="], - - "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="], - - "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="], - - "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="], - - "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="], - - "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="], - - "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="], - - "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="], - "data-urls": ["data-urls@5.0.0", "", { "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" } }, "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg=="], - "date-fns": ["date-fns@3.6.0", "", {}, "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww=="], - - "date-fns-jalali": ["date-fns-jalali@4.1.0-0", "", {}, "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg=="], - "de-indent": ["de-indent@1.0.2", "", {}, "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], "decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="], - "decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="], - "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], @@ -798,30 +613,18 @@ "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], - "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], - "diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], - "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], - "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="], "dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="], - "dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="], - "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], "electron-to-chromium": ["electron-to-chromium@1.5.227", "", {}, "sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA=="], - "embla-carousel": ["embla-carousel@8.6.0", "", {}, "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="], - - "embla-carousel-react": ["embla-carousel-react@8.6.0", "", { "dependencies": { "embla-carousel": "8.6.0", "embla-carousel-reactive-utils": "8.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA=="], - - "embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A=="], - "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], @@ -848,22 +651,12 @@ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], - "eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], - "expect-type": ["expect-type@1.2.2", "", {}, "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA=="], "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], - "fast-equals": ["fast-equals@5.4.0", "", {}, "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw=="], - - "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], - - "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], - - "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], @@ -872,8 +665,6 @@ "form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="], - "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], - "fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -892,8 +683,6 @@ "glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], - "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], @@ -926,30 +715,18 @@ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], - "input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="], - - "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], - "is-arguments": ["is-arguments@1.2.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA=="], - "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], - "is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="], "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], "is-docker": ["is-docker@2.2.1", "", { "bin": "cli.js" }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], - "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], "is-generator-function": ["is-generator-function@1.1.2", "", { "dependencies": { "call-bound": "^1.0.4", "generator-function": "^2.0.0", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA=="], - "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], - "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], "is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="], @@ -970,8 +747,6 @@ "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - "jiti": ["jiti@1.21.7", "", { "bin": "bin/jiti.js" }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - "jju": ["jju@1.4.0", "", {}, "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -990,10 +765,6 @@ "kolorist": ["kolorist@1.8.0", "", {}, "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="], - "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], - - "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], - "local-pkg": ["local-pkg@1.1.2", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", "quansync": "^0.2.11" } }, "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A=="], "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], @@ -1006,8 +777,6 @@ "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - "lucide-react": ["lucide-react@0.460.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } }, "sha512-BVtq/DykVeIvRTJvRAgCsOwaGL8Un3Bxh8MbDxMhEWlZay3T4IpEKDEpwt5KZ0KJMHzgm6jrltxlT5eXOWXDHg=="], - "lz-string": ["lz-string@1.5.0", "", { "bin": "bin/bin.js" }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="], @@ -1022,10 +791,6 @@ "memoizerific": ["memoizerific@1.11.3", "", { "dependencies": { "map-or-similar": "^1.5.0" } }, "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog=="], - "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - - "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], @@ -1044,22 +809,12 @@ "muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="], - "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], - "nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "node-releases": ["node-releases@2.0.21", "", {}, "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw=="], - "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - - "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], - "nwsapi": ["nwsapi@2.2.23", "", {}, "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ=="], - "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], - - "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], - "open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], @@ -1088,10 +843,6 @@ "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], - - "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], - "pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], "polished": ["polished@4.3.1", "", { "dependencies": { "@babel/runtime": "^7.17.8" } }, "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA=="], @@ -1100,45 +851,25 @@ "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], - "postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="], - - "postcss-js": ["postcss-js@4.1.0", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="], - - "postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="], - - "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], - - "postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - - "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], - "prettier": ["prettier@3.7.4", "", { "bin": "bin/prettier.cjs" }, "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA=="], "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="], - "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], - "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], - "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], - "react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="], - "react-day-picker": ["react-day-picker@9.13.0", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "date-fns": "^4.1.0", "date-fns-jalali": "^4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-euzj5Hlq+lOHqI53NiuNhCP8HWgsPf/bBAVijR50hNaY1XwjKjShAnIe8jm8RD2W9IJUvihDIZ+KrmqfFzNhFQ=="], - "react-docgen": ["react-docgen@7.1.1", "", { "dependencies": { "@babel/core": "^7.18.9", "@babel/traverse": "^7.18.9", "@babel/types": "^7.18.9", "@types/babel__core": "^7.18.0", "@types/babel__traverse": "^7.18.0", "@types/doctrine": "^0.0.9", "@types/resolve": "^1.20.2", "doctrine": "^3.0.0", "resolve": "^1.22.1", "strip-indent": "^4.0.0" } }, "sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg=="], "react-docgen-typescript": ["react-docgen-typescript@2.4.0", "", { "peerDependencies": { "typescript": ">= 4.3.x" } }, "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg=="], "react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], - "react-hook-form": ["react-hook-form@7.69.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-yt6ZGME9f4F6WHwevrvpAjh42HMvocuSnSIHUGycBqXIJdhqGSPQzTpGF+1NLREk/58IdPxEMfPcFCjlMhclGw=="], - - "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + "react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], "react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="], @@ -1146,38 +877,20 @@ "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], - "react-resizable-panels": ["react-resizable-panels@2.1.9", "", { "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-z77+X08YDIrgAes4jl8xhnUu1LNIRp4+E7cv4xHmLOxxUPO/ML7PSrE813b90vj7xvQ1lcf7g2uA9GeMZonjhQ=="], - - "react-smooth": ["react-smooth@4.0.4", "", { "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q=="], - "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], - "react-transition-group": ["react-transition-group@4.4.5", "", { "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" }, "peerDependencies": { "react": ">=16.6.0", "react-dom": ">=16.6.0" } }, "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="], - - "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], - - "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="], - "recharts": ["recharts@2.15.4", "", { "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", "lodash": "^4.17.21", "react-is": "^18.3.1", "react-smooth": "^4.0.4", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw=="], - - "recharts-scale": ["recharts-scale@0.4.5", "", { "dependencies": { "decimal.js-light": "^2.4.1" } }, "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w=="], - "redent": ["redent@3.0.0", "", { "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" } }, "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg=="], "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], - "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "rollup": ["rollup@4.52.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.3", "@rollup/rollup-android-arm64": "4.52.3", "@rollup/rollup-darwin-arm64": "4.52.3", "@rollup/rollup-darwin-x64": "4.52.3", "@rollup/rollup-freebsd-arm64": "4.52.3", "@rollup/rollup-freebsd-x64": "4.52.3", "@rollup/rollup-linux-arm-gnueabihf": "4.52.3", "@rollup/rollup-linux-arm-musleabihf": "4.52.3", "@rollup/rollup-linux-arm64-gnu": "4.52.3", "@rollup/rollup-linux-arm64-musl": "4.52.3", "@rollup/rollup-linux-loong64-gnu": "4.52.3", "@rollup/rollup-linux-ppc64-gnu": "4.52.3", "@rollup/rollup-linux-riscv64-gnu": "4.52.3", "@rollup/rollup-linux-riscv64-musl": "4.52.3", "@rollup/rollup-linux-s390x-gnu": "4.52.3", "@rollup/rollup-linux-x64-gnu": "4.52.3", "@rollup/rollup-linux-x64-musl": "4.52.3", "@rollup/rollup-openharmony-arm64": "4.52.3", "@rollup/rollup-win32-arm64-msvc": "4.52.3", "@rollup/rollup-win32-ia32-msvc": "4.52.3", "@rollup/rollup-win32-x64-gnu": "4.52.3", "@rollup/rollup-win32-x64-msvc": "4.52.3", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A=="], "rrweb-cssom": ["rrweb-cssom@0.7.1", "", {}, "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg=="], - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], - "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], @@ -1198,8 +911,6 @@ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - "sonner": ["sonner@1.7.4", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw=="], - "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -1228,28 +939,14 @@ "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], - "style-mod": ["style-mod@4.1.3", "", {}, "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ=="], - - "sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="], - "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], "symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="], - "tailwind-merge": ["tailwind-merge@2.6.0", "", {}, "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA=="], - - "tailwindcss": ["tailwindcss@3.4.17", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.6", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og=="], - - "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="], - "test-exclude": ["test-exclude@7.0.1", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^10.4.1", "minimatch": "^9.0.4" } }, "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg=="], - "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], - - "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], - "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], @@ -1266,16 +963,12 @@ "tldts-core": ["tldts-core@6.1.86", "", {}, "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA=="], - "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], - "tough-cookie": ["tough-cookie@5.1.2", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A=="], "tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], "ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="], - "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], - "tsconfig-paths": ["tsconfig-paths@4.2.0", "", { "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -1300,14 +993,8 @@ "util": ["util@0.12.5", "", { "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", "which-typed-array": "^1.1.2" } }, "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA=="], - "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "uuid": ["uuid@9.0.1", "", { "bin": "dist/bin/uuid" }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - "vaul": ["vaul@1.1.2", "", { "dependencies": { "@radix-ui/react-dialog": "^1.1.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA=="], - - "victory-vendor": ["victory-vendor@36.9.2", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ=="], - "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], "vite-node": ["vite-node@2.1.9", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.3.7", "es-module-lexer": "^1.5.4", "pathe": "^1.1.2", "vite": "^5.0.0" }, "bin": "vite-node.mjs" }, "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA=="], @@ -1318,8 +1005,6 @@ "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="], - "w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="], - "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], @@ -1350,48 +1035,10 @@ "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "yaml": ["yaml@2.8.1", "", { "bin": "bin.mjs" }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="], - "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], - "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@asamuzakjp/css-color/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "@codemirror/autocomplete/@codemirror/language": ["@codemirror/language@0.20.2", "", { "dependencies": { "@codemirror/state": "^0.20.0", "@codemirror/view": "^0.20.0", "@lezer/common": "^0.16.0", "@lezer/highlight": "^0.16.0", "@lezer/lr": "^0.16.0", "style-mod": "^4.0.0" } }, "sha512-WB3Bnuusw0xhVvhBocieYKwJm04SOk5bPoOEYksVHKHcGHFOaYaw+eZVxR4gIqMMcGzOIUil0FsCmFk8yrhHpw=="], - - "@codemirror/autocomplete/@codemirror/state": ["@codemirror/state@0.20.1", "", {}, "sha512-ms0tlV5A02OK0pFvTtSUGMLkoarzh1F8mr6jy1cD7ucSC2X/VLHtQCxfhdSEGqTYlQF2hoZtmLv+amqhdgbwjQ=="], - - "@codemirror/autocomplete/@codemirror/view": ["@codemirror/view@0.20.7", "", { "dependencies": { "@codemirror/state": "^0.20.0", "style-mod": "^4.0.0", "w3c-keyname": "^2.2.4" } }, "sha512-pqEPCb9QFTOtHgAH5XU/oVy9UR/Anj6r+tG5CRmkNVcqSKEPmBU05WtN/jxJCFZBXf6HumzWC9ydE4qstO3TxQ=="], - - "@codemirror/autocomplete/@lezer/common": ["@lezer/common@0.16.1", "", {}, "sha512-qPmG7YTZ6lATyTOAWf8vXE+iRrt1NJd4cm2nJHK+v7X9TsOF6+HtuU/ctaZy2RCrluxDb89hI6KWQ5LfQGQWuA=="], - - "@codemirror/basic-setup/@codemirror/commands": ["@codemirror/commands@0.20.0", "", { "dependencies": { "@codemirror/language": "^0.20.0", "@codemirror/state": "^0.20.0", "@codemirror/view": "^0.20.0", "@lezer/common": "^0.16.0" } }, "sha512-v9L5NNVA+A9R6zaFvaTbxs30kc69F6BkOoiEbeFw4m4I0exmDEKBILN6mK+GksJtvTzGBxvhAPlVFTdQW8GB7Q=="], - - "@codemirror/basic-setup/@codemirror/language": ["@codemirror/language@0.20.2", "", { "dependencies": { "@codemirror/state": "^0.20.0", "@codemirror/view": "^0.20.0", "@lezer/common": "^0.16.0", "@lezer/highlight": "^0.16.0", "@lezer/lr": "^0.16.0", "style-mod": "^4.0.0" } }, "sha512-WB3Bnuusw0xhVvhBocieYKwJm04SOk5bPoOEYksVHKHcGHFOaYaw+eZVxR4gIqMMcGzOIUil0FsCmFk8yrhHpw=="], - - "@codemirror/basic-setup/@codemirror/state": ["@codemirror/state@0.20.1", "", {}, "sha512-ms0tlV5A02OK0pFvTtSUGMLkoarzh1F8mr6jy1cD7ucSC2X/VLHtQCxfhdSEGqTYlQF2hoZtmLv+amqhdgbwjQ=="], - - "@codemirror/basic-setup/@codemirror/view": ["@codemirror/view@0.20.7", "", { "dependencies": { "@codemirror/state": "^0.20.0", "style-mod": "^4.0.0", "w3c-keyname": "^2.2.4" } }, "sha512-pqEPCb9QFTOtHgAH5XU/oVy9UR/Anj6r+tG5CRmkNVcqSKEPmBU05WtN/jxJCFZBXf6HumzWC9ydE4qstO3TxQ=="], - - "@codemirror/lang-css/@codemirror/autocomplete": ["@codemirror/autocomplete@6.20.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg=="], - - "@codemirror/lang-html/@codemirror/autocomplete": ["@codemirror/autocomplete@6.20.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg=="], - - "@codemirror/lang-javascript/@codemirror/autocomplete": ["@codemirror/autocomplete@6.20.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg=="], - - "@codemirror/lang-javascript/@codemirror/lint": ["@codemirror/lint@6.9.2", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.35.0", "crelt": "^1.0.5" } }, "sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ=="], - - "@codemirror/lang-markdown/@codemirror/autocomplete": ["@codemirror/autocomplete@6.20.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg=="], - - "@codemirror/lint/@codemirror/state": ["@codemirror/state@0.20.1", "", {}, "sha512-ms0tlV5A02OK0pFvTtSUGMLkoarzh1F8mr6jy1cD7ucSC2X/VLHtQCxfhdSEGqTYlQF2hoZtmLv+amqhdgbwjQ=="], - - "@codemirror/lint/@codemirror/view": ["@codemirror/view@0.20.7", "", { "dependencies": { "@codemirror/state": "^0.20.0", "style-mod": "^4.0.0", "w3c-keyname": "^2.2.4" } }, "sha512-pqEPCb9QFTOtHgAH5XU/oVy9UR/Anj6r+tG5CRmkNVcqSKEPmBU05WtN/jxJCFZBXf6HumzWC9ydE4qstO3TxQ=="], - - "@codemirror/search/@codemirror/state": ["@codemirror/state@0.20.1", "", {}, "sha512-ms0tlV5A02OK0pFvTtSUGMLkoarzh1F8mr6jy1cD7ucSC2X/VLHtQCxfhdSEGqTYlQF2hoZtmLv+amqhdgbwjQ=="], - - "@codemirror/search/@codemirror/view": ["@codemirror/view@0.20.7", "", { "dependencies": { "@codemirror/state": "^0.20.0", "style-mod": "^4.0.0", "w3c-keyname": "^2.2.4" } }, "sha512-pqEPCb9QFTOtHgAH5XU/oVy9UR/Anj6r+tG5CRmkNVcqSKEPmBU05WtN/jxJCFZBXf6HumzWC9ydE4qstO3TxQ=="], - "@joshwooding/vite-plugin-react-docgen-typescript/magic-string": ["magic-string@0.27.0", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" } }, "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA=="], "@microsoft/api-extractor/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], @@ -1402,8 +1049,6 @@ "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@radix-ui/react-aspect-ratio/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "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" } }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="], - "@radix-ui/react-avatar/@radix-ui/react-context": ["@radix-ui/react-context@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw=="], "@radix-ui/react-avatar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "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" } }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="], @@ -1430,8 +1075,6 @@ "@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - "@replit/codemirror-vim/@codemirror/search": ["@codemirror/search@6.5.11", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "crelt": "^1.0.5" } }, "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA=="], - "@rushstack/node-core-library/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], "@rushstack/node-core-library/semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": "bin/semver.js" }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="], @@ -1458,20 +1101,10 @@ "ajv-formats/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], - "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - - "chokidar/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - - "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - "cssstyle/rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], - "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - "make-dir/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], - "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "mlly/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], @@ -1482,14 +1115,6 @@ "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], - "pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], - - "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], - - "react-day-picker/date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="], - - "readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "redent/strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="], "rollup/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], @@ -1500,8 +1125,6 @@ "strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - "sucrase/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], - "vitest/@vitest/expect": ["@vitest/expect@2.1.9", "", { "dependencies": { "@vitest/spy": "2.1.9", "@vitest/utils": "2.1.9", "chai": "^5.1.2", "tinyrainbow": "^1.2.0" } }, "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw=="], "vitest/@vitest/spy": ["@vitest/spy@2.1.9", "", { "dependencies": { "tinyspy": "^3.0.2" } }, "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ=="], @@ -1512,18 +1135,6 @@ "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "@codemirror/autocomplete/@codemirror/language/@lezer/highlight": ["@lezer/highlight@0.16.0", "", { "dependencies": { "@lezer/common": "^0.16.0" } }, "sha512-iE5f4flHlJ1g1clOStvXNLbORJoiW4Kytso6ubfYzHnaNo/eo5SKhxs4wv/rtvwZQeZrK3we8S9SyA7OGOoRKQ=="], - - "@codemirror/autocomplete/@codemirror/language/@lezer/lr": ["@lezer/lr@0.16.3", "", { "dependencies": { "@lezer/common": "^0.16.0" } }, "sha512-pau7um4eAw94BEuuShUIeQDTf3k4Wt6oIUOYxMmkZgDHdqtIcxWND4LRxi8nI9KuT4I1bXQv67BCapkxt7Ywqw=="], - - "@codemirror/basic-setup/@codemirror/commands/@lezer/common": ["@lezer/common@0.16.1", "", {}, "sha512-qPmG7YTZ6lATyTOAWf8vXE+iRrt1NJd4cm2nJHK+v7X9TsOF6+HtuU/ctaZy2RCrluxDb89hI6KWQ5LfQGQWuA=="], - - "@codemirror/basic-setup/@codemirror/language/@lezer/common": ["@lezer/common@0.16.1", "", {}, "sha512-qPmG7YTZ6lATyTOAWf8vXE+iRrt1NJd4cm2nJHK+v7X9TsOF6+HtuU/ctaZy2RCrluxDb89hI6KWQ5LfQGQWuA=="], - - "@codemirror/basic-setup/@codemirror/language/@lezer/highlight": ["@lezer/highlight@0.16.0", "", { "dependencies": { "@lezer/common": "^0.16.0" } }, "sha512-iE5f4flHlJ1g1clOStvXNLbORJoiW4Kytso6ubfYzHnaNo/eo5SKhxs4wv/rtvwZQeZrK3we8S9SyA7OGOoRKQ=="], - - "@codemirror/basic-setup/@codemirror/language/@lezer/lr": ["@lezer/lr@0.16.3", "", { "dependencies": { "@lezer/common": "^0.16.0" } }, "sha512-pau7um4eAw94BEuuShUIeQDTf3k4Wt6oIUOYxMmkZgDHdqtIcxWND4LRxi8nI9KuT4I1bXQv67BCapkxt7Ywqw=="], - "@microsoft/api-extractor/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], "@rushstack/node-core-library/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], diff --git a/package.json b/package.json index eac99d4..cbc3af7 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,14 @@ { "name": "@drjoshcsimmons/scl", - "version": "0.2.8", - "description": "A retro terminal-themed React component library built on Radix and Tailwind", + "version": "0.3.0", + "description": "A retro terminal-themed React component library built on Radix primitives with vanilla CSS", "keywords": [ "react", "components", "ui", "terminal", "retro", - "radix", - "tailwind", - "shadcn" + "radix" ], "homepage": "https://jcpsimmons.github.io/scl/", "author": "Josh Simmons", @@ -48,7 +46,7 @@ "format": "biome format --write src", "check": "biome check --write src", "typecheck": "tsc --noEmit", - "prepublishOnly": "npm run build" + "prepublishOnly": "bun run build" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -56,20 +54,14 @@ }, "devDependencies": { "@biomejs/biome": "2.3.10", - "@hookform/resolvers": "^3.9.0", "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-alert-dialog": "^1.1.0", - "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-avatar": "^1.1.0", "@radix-ui/react-checkbox": "^1.1.0", "@radix-ui/react-collapsible": "^1.1.0", - "@radix-ui/react-context-menu": "^2.2.0", "@radix-ui/react-dialog": "^1.1.0", "@radix-ui/react-dropdown-menu": "^2.1.0", - "@radix-ui/react-hover-card": "^1.1.0", "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-menubar": "^1.1.0", - "@radix-ui/react-navigation-menu": "^1.2.0", "@radix-ui/react-popover": "^1.1.0", "@radix-ui/react-progress": "^1.1.0", "@radix-ui/react-radio-group": "^1.2.0", @@ -80,9 +72,7 @@ "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-tabs": "^1.1.0", - "@radix-ui/react-toast": "^1.2.0", "@radix-ui/react-toggle": "^1.1.0", - "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.0", "@storybook/addon-a11y": "8.6.15", "@storybook/addon-essentials": "8.6.15", @@ -100,47 +90,16 @@ "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.0", "@vitest/coverage-v8": "^2.1.0", - "autoprefixer": "^10.4.0", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.0", - "cmdk": "^1.0.0", - "date-fns": "^3.6.0", - "embla-carousel-react": "^8.3.0", - "input-otp": "^1.4.0", "jsdom": "^25.0.0", - "lucide-react": "^0.460.0", - "postcss": "^8.4.0", "react": "^18.3.0", - "react-day-picker": "^9.3.0", "react-dom": "^18.3.0", - "react-hook-form": "^7.54.0", - "react-resizable-panels": "^2.1.0", - "recharts": "^2.13.0", - "sonner": "^1.7.0", "storybook": "8.6.15", - "tailwind-merge": "^2.5.0", - "tailwindcss": "^3.4.0", - "tailwindcss-animate": "^1.0.0", "typescript": "^5.6.0", - "vaul": "^1.1.0", "vite": "^5.4.0", "vite-plugin-dts": "^4.3.0", - "vitest": "^2.1.0", - "zod": "^3.24.0" + "vitest": "^2.1.0" }, "dependencies": { - "@codemirror/basic-setup": "^0.20.0", - "@codemirror/commands": "^6.10.1", - "@codemirror/lang-css": "^6.3.1", - "@codemirror/lang-html": "^6.4.11", - "@codemirror/lang-javascript": "^6.2.4", - "@codemirror/lang-json": "^6.0.2", - "@codemirror/lang-markdown": "^6.5.0", - "@codemirror/language": "^6.11.3", - "@codemirror/state": "^6.5.2", - "@codemirror/view": "^6.39.4", - "@lezer/highlight": "^1.2.3", - "@replit/codemirror-vim": "^6.3.0", "@vercel/analytics": "^1.6.1" } } diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index 2e7af2b..0000000 --- a/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/src/components/ui/accordion/accordion.css b/src/components/ui/accordion/accordion.css new file mode 100644 index 0000000..c622674 --- /dev/null +++ b/src/components/ui/accordion/accordion.css @@ -0,0 +1,58 @@ +/* Accordion Component Styles */ + +.scl-accordion-item { + border-bottom: 2px solid var(--scl-primary); + width: 100%; +} + +.scl-accordion-header { + display: flex; +} + +.scl-accordion-trigger { + display: flex; + flex: 1; + align-items: center; + justify-content: space-between; + padding: var(--scl-space-4) 0; + font-size: var(--scl-text-sm); + font-weight: 500; + font-family: var(--scl-font-mono); + text-align: left; + background: none; + border: none; + color: var(--scl-primary); + cursor: pointer; +} + +.scl-accordion-trigger:hover { + text-decoration: underline; +} + +.scl-accordion-trigger__icon { + width: 1rem; + height: 1rem; + flex-shrink: 0; + color: var(--scl-muted-foreground); + transition: transform var(--scl-duration-normal); +} + +.scl-accordion-trigger[data-state="open"] .scl-accordion-trigger__icon { + transform: rotate(180deg); +} + +.scl-accordion-content { + overflow: hidden; + font-size: var(--scl-text-sm); + color: var(--scl-primary); +} + +.scl-accordion-content[data-state="closed"] { + height: 0; + visibility: hidden; +} + +.scl-accordion-content__inner { + padding-bottom: var(--scl-space-4); + padding-top: 0; +} diff --git a/src/components/ui/accordion/accordion.tsx b/src/components/ui/accordion/accordion.tsx index 7ee08a5..2107b9f 100644 --- a/src/components/ui/accordion/accordion.tsx +++ b/src/components/ui/accordion/accordion.tsx @@ -1,15 +1,32 @@ import * as AccordionPrimitive from '@radix-ui/react-accordion'; -import { ChevronDown } from 'lucide-react'; import * as React from 'react'; -import { cn } from '@/lib/utils'; +import { cx } from '@/lib/utils'; +import './accordion.css'; const Accordion = AccordionPrimitive.Root; +const ChevronIcon = () => ( + + + +); + const AccordionItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); AccordionItem.displayName = 'AccordionItem'; @@ -17,17 +34,14 @@ const AccordionTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - + svg]:rotate-180', - className - )} + className={cx('scl-accordion-trigger', className)} {...props} > {children} - + )); @@ -39,10 +53,10 @@ const AccordionContent = React.forwardRef< >(({ className, children, ...props }, ref) => ( -
{children}
+
{children}
)); AccordionContent.displayName = AccordionPrimitive.Content.displayName; diff --git a/src/components/ui/alert-dialog/alert-dialog.stories.tsx b/src/components/ui/alert-dialog/alert-dialog.stories.tsx deleted file mode 100644 index 074db55..0000000 --- a/src/components/ui/alert-dialog/alert-dialog.stories.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { Button } from '../button'; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger, -} from './alert-dialog'; - -const meta: Meta = { - title: 'Components/AlertDialog', - component: AlertDialog, - tags: ['autodocs'], -}; -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => ( - - - - - - - Are you absolutely sure? - This action cannot be undone. - - - Cancel - Continue - - - - ), -}; diff --git a/src/components/ui/alert-dialog/alert-dialog.test.tsx b/src/components/ui/alert-dialog/alert-dialog.test.tsx deleted file mode 100644 index 3d55047..0000000 --- a/src/components/ui/alert-dialog/alert-dialog.test.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { describe, expect, it } from 'vitest'; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger, -} from './alert-dialog'; - -describe('AlertDialog', () => { - it('renders trigger', () => { - render( - - Delete - - - Are you sure? - - - - ); - expect(screen.getByRole('button', { name: 'Delete' })).toBeInTheDocument(); - }); - - it('opens on trigger click', async () => { - const user = userEvent.setup(); - render( - - Delete - - - Confirm - - Continue - Cancel - - - ); - await user.click(screen.getByRole('button', { name: 'Delete' })); - expect(screen.getByRole('alertdialog')).toBeInTheDocument(); - }); -}); diff --git a/src/components/ui/alert-dialog/alert-dialog.tsx b/src/components/ui/alert-dialog/alert-dialog.tsx deleted file mode 100644 index 690befe..0000000 --- a/src/components/ui/alert-dialog/alert-dialog.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'; -import * as React from 'react'; -import { cn } from '@/lib/utils'; -import { buttonVariants } from '../button'; - -const AlertDialog = AlertDialogPrimitive.Root; -const AlertDialogTrigger = AlertDialogPrimitive.Trigger; -const AlertDialogPortal = AlertDialogPrimitive.Portal; - -const AlertDialogOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName; - -const AlertDialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - -)); -AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName; - -const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( -
-); -AlertDialogHeader.displayName = 'AlertDialogHeader'; - -const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( -
-); -AlertDialogFooter.displayName = 'AlertDialogFooter'; - -const AlertDialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName; - -const AlertDialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName; - -const AlertDialogAction = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName; - -const AlertDialogCancel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName; - -export { - AlertDialog, - AlertDialogPortal, - AlertDialogOverlay, - AlertDialogTrigger, - AlertDialogContent, - AlertDialogHeader, - AlertDialogFooter, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, -}; diff --git a/src/components/ui/alert-dialog/index.ts b/src/components/ui/alert-dialog/index.ts deleted file mode 100644 index afdb95f..0000000 --- a/src/components/ui/alert-dialog/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -export { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogOverlay, - AlertDialogPortal, - AlertDialogTitle, - AlertDialogTrigger, -} from './alert-dialog'; diff --git a/src/components/ui/alert/alert.css b/src/components/ui/alert/alert.css new file mode 100644 index 0000000..e913497 --- /dev/null +++ b/src/components/ui/alert/alert.css @@ -0,0 +1,71 @@ +/* Alert Component Styles */ + +.scl-alert { + position: relative; + width: 100%; + padding: var(--scl-space-3) var(--scl-space-4); + font-size: var(--scl-text-sm); + font-weight: 500; + font-family: var(--scl-font-mono); + border: 2px solid; +} + +.scl-alert svg { + position: absolute; + left: var(--scl-space-4); + top: var(--scl-space-4); +} + +.scl-alert svg + div { + transform: translateY(-3px); +} + +.scl-alert svg ~ * { + padding-left: var(--scl-space-7); +} + +/* Variants */ +.scl-alert--default { + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); + border-color: var(--scl-primary); +} + +.scl-alert--default svg { + color: var(--scl-primary-foreground); +} + +.scl-alert--secondary { + background-color: var(--scl-secondary); + color: var(--scl-secondary-foreground); + border-color: var(--scl-secondary); +} + +.scl-alert--secondary svg { + color: var(--scl-secondary-foreground); +} + +.scl-alert--destructive { + background-color: var(--scl-destructive); + color: var(--scl-destructive-foreground); + border-color: var(--scl-destructive); +} + +.scl-alert--destructive svg { + color: var(--scl-destructive-foreground); +} + +.scl-alert__title { + margin-bottom: var(--scl-space-1); + font-weight: 500; + line-height: 1; + letter-spacing: -0.025em; +} + +.scl-alert__description { + font-size: var(--scl-text-sm); +} + +.scl-alert__description p { + line-height: 1.625; +} diff --git a/src/components/ui/alert/alert.test.tsx b/src/components/ui/alert/alert.test.tsx index 2fe14b4..c6632b9 100644 --- a/src/components/ui/alert/alert.test.tsx +++ b/src/components/ui/alert/alert.test.tsx @@ -18,12 +18,12 @@ describe('Alert', () => { it('applies default variant', () => { render(Default Alert); - expect(screen.getByRole('alert')).toHaveClass('bg-primary'); + expect(screen.getByRole('alert')).toHaveClass('scl-alert--default'); }); it('applies destructive variant', () => { render(Error Alert); - expect(screen.getByRole('alert')).toHaveClass('bg-destructive'); + expect(screen.getByRole('alert')).toHaveClass('scl-alert--destructive'); }); it('forwards ref to Alert', () => { diff --git a/src/components/ui/alert/alert.tsx b/src/components/ui/alert/alert.tsx index 5b3d3df..b67e35f 100644 --- a/src/components/ui/alert/alert.tsx +++ b/src/components/ui/alert/alert.tsx @@ -1,50 +1,37 @@ -import { cva, type VariantProps } from 'class-variance-authority'; import * as React from 'react'; -import { cn } from '@/lib/utils'; +import { cx } from '@/lib/utils'; +import './alert.css'; -const alertVariants = cva( - 'relative w-full px-4 py-3 text-sm font-medium [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-7', - { - variants: { - variant: { - default: - 'bg-primary text-primary-foreground border-2 border-primary [&>svg]:text-primary-foreground', - secondary: - 'bg-secondary text-secondary-foreground border-2 border-secondary [&>svg]:text-secondary-foreground', - destructive: - 'bg-destructive text-destructive-foreground border-2 border-destructive [&>svg]:text-destructive-foreground', - }, - }, - defaultVariants: { - variant: 'default', - }, - } -); +export type AlertVariant = 'default' | 'secondary' | 'destructive'; -const Alert = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & VariantProps ->(({ className, variant, ...props }, ref) => ( -
-)); -Alert.displayName = 'Alert'; +export interface AlertProps extends React.HTMLAttributes { + variant?: AlertVariant; +} -const AlertTitle = React.forwardRef>( - ({ className, ...props }, ref) => ( -
( + ({ className, variant = 'default', ...props }, ref) => ( +
) ); +Alert.displayName = 'Alert'; + +const AlertTitle = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +); AlertTitle.displayName = 'AlertTitle'; const AlertDescription = React.forwardRef< HTMLParagraphElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( -
+
)); AlertDescription.displayName = 'AlertDescription'; diff --git a/src/components/ui/alert/index.ts b/src/components/ui/alert/index.ts index ddf39c8..9e353ac 100644 --- a/src/components/ui/alert/index.ts +++ b/src/components/ui/alert/index.ts @@ -1 +1 @@ -export { Alert, AlertDescription, AlertTitle } from './alert'; +export { Alert, AlertDescription, AlertTitle, type AlertProps, type AlertVariant } from './alert'; diff --git a/src/components/ui/avatar/avatar.css b/src/components/ui/avatar/avatar.css new file mode 100644 index 0000000..d38e208 --- /dev/null +++ b/src/components/ui/avatar/avatar.css @@ -0,0 +1,32 @@ +/* Avatar Component Styles */ + +.scl-avatar { + position: relative; + display: flex; + height: 2.5rem; + width: 2.5rem; + flex-shrink: 0; + overflow: hidden; + border: 1px solid var(--scl-primary); +} + +.scl-avatar__image { + aspect-ratio: 1; + height: 100%; + width: 100%; + object-fit: cover; +} + +.scl-avatar__fallback { + display: flex; + height: 100%; + width: 100%; + align-items: center; + justify-content: center; + background-color: var(--scl-background); + border: 1px solid var(--scl-primary); + color: var(--scl-primary); + font-family: var(--scl-font-mono); + font-size: var(--scl-text-sm); + font-weight: 500; +} diff --git a/src/components/ui/avatar/avatar.tsx b/src/components/ui/avatar/avatar.tsx index 54a7cd2..5986b83 100644 --- a/src/components/ui/avatar/avatar.tsx +++ b/src/components/ui/avatar/avatar.tsx @@ -1,6 +1,7 @@ import * as AvatarPrimitive from '@radix-ui/react-avatar'; import * as React from 'react'; -import { cn } from '@/lib/utils'; +import { cx } from '@/lib/utils'; +import './avatar.css'; const Avatar = React.forwardRef< React.ElementRef, @@ -8,10 +9,7 @@ const Avatar = React.forwardRef< >(({ className, ...props }, ref) => ( )); @@ -23,7 +21,7 @@ const AvatarImage = React.forwardRef< >(({ className, ...props }, ref) => ( )); @@ -35,10 +33,7 @@ const AvatarFallback = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/src/components/ui/badge/badge.css b/src/components/ui/badge/badge.css new file mode 100644 index 0000000..65d25c2 --- /dev/null +++ b/src/components/ui/badge/badge.css @@ -0,0 +1,56 @@ +/* Badge Component Styles */ + +.scl-badge { + display: inline-flex; + align-items: center; + border: 2px solid; + padding: var(--scl-space-0-5) var(--scl-space-2-5); + font-size: var(--scl-text-xs); + font-weight: 600; + font-family: var(--scl-font-mono); + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.scl-badge:focus { + outline: var(--scl-focus-ring-width) solid var(--scl-ring); + outline-offset: var(--scl-focus-ring-offset); +} + +/* Filled variants */ +.scl-badge--default { + border-color: var(--scl-primary); + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); +} + +.scl-badge--secondary { + border-color: var(--scl-secondary); + background-color: var(--scl-secondary); + color: var(--scl-secondary-foreground); +} + +.scl-badge--destructive { + border-color: var(--scl-destructive); + background-color: var(--scl-destructive); + color: var(--scl-destructive-foreground); +} + +/* Outline variants */ +.scl-badge--outline { + border-color: var(--scl-primary); + background-color: transparent; + color: var(--scl-primary); +} + +.scl-badge--secondary-outline { + border-color: var(--scl-secondary); + background-color: transparent; + color: var(--scl-secondary); +} + +.scl-badge--destructive-outline { + border-color: var(--scl-destructive); + background-color: transparent; + color: var(--scl-destructive); +} diff --git a/src/components/ui/badge/badge.test.tsx b/src/components/ui/badge/badge.test.tsx index 833e305..4bbd09f 100644 --- a/src/components/ui/badge/badge.test.tsx +++ b/src/components/ui/badge/badge.test.tsx @@ -10,22 +10,22 @@ describe('Badge', () => { it('applies default variant', () => { render(Default); - expect(screen.getByText('Default')).toHaveClass('bg-primary'); + expect(screen.getByText('Default')).toHaveClass('scl-badge--default'); }); it('applies destructive variant', () => { render(Error); - expect(screen.getByText('Error')).toHaveClass('bg-destructive'); + expect(screen.getByText('Error')).toHaveClass('scl-badge--destructive'); }); it('applies secondary variant', () => { render(Secondary); - expect(screen.getByText('Secondary')).toHaveClass('bg-secondary'); + expect(screen.getByText('Secondary')).toHaveClass('scl-badge--secondary'); }); it('applies outline variant', () => { render(Outline); - expect(screen.getByText('Outline')).toHaveClass('text-primary'); + expect(screen.getByText('Outline')).toHaveClass('scl-badge--outline'); }); it('merges custom className', () => { diff --git a/src/components/ui/badge/badge.tsx b/src/components/ui/badge/badge.tsx index 82ba743..3076c16 100644 --- a/src/components/ui/badge/badge.tsx +++ b/src/components/ui/badge/badge.tsx @@ -1,34 +1,21 @@ -import { cva, type VariantProps } from 'class-variance-authority'; -import type * as React from 'react'; -import { cn } from '@/lib/utils'; +import * as React from 'react'; +import { cx } from '@/lib/utils'; +import './badge.css'; -const badgeVariants = cva( - 'inline-flex items-center border-2 px-2.5 py-0.5 text-xs font-semibold uppercase tracking-wider focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', - { - variants: { - variant: { - // Filled variants (color bg, black text) - default: 'border-primary bg-primary text-primary-foreground', - secondary: 'border-secondary bg-secondary text-secondary-foreground', - destructive: 'border-destructive bg-destructive text-destructive-foreground', - // Outline variants (transparent bg, color text/border) - outline: 'border-primary bg-transparent text-primary', - 'secondary-outline': 'border-secondary bg-transparent text-secondary', - 'destructive-outline': 'border-destructive bg-transparent text-destructive', - }, - }, - defaultVariants: { - variant: 'default', - }, - } -); +export type BadgeVariant = + | 'default' + | 'secondary' + | 'destructive' + | 'outline' + | 'secondary-outline' + | 'destructive-outline'; -export interface BadgeProps - extends React.HTMLAttributes, - VariantProps {} +export interface BadgeProps extends React.HTMLAttributes { + variant?: BadgeVariant; +} -function Badge({ className, variant, ...props }: BadgeProps) { - return
; +function Badge({ className, variant = 'default', ...props }: BadgeProps) { + return
; } -export { Badge, badgeVariants }; +export { Badge }; diff --git a/src/components/ui/badge/index.ts b/src/components/ui/badge/index.ts index 846cd9a..3027ed9 100644 --- a/src/components/ui/badge/index.ts +++ b/src/components/ui/badge/index.ts @@ -1 +1 @@ -export { Badge, type BadgeProps, badgeVariants } from './badge'; +export { Badge, type BadgeProps, type BadgeVariant } from './badge'; diff --git a/src/components/ui/button/button.css b/src/components/ui/button/button.css new file mode 100644 index 0000000..4828ee4 --- /dev/null +++ b/src/components/ui/button/button.css @@ -0,0 +1,185 @@ +/* Button Component Styles */ + +.scl-button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--scl-space-2); + white-space: nowrap; + font-family: var(--scl-font-mono); + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + cursor: pointer; + border: 2px solid transparent; + background: transparent; + transition: all var(--scl-duration-fast); +} + +.scl-button:focus-visible { + outline: var(--scl-focus-ring-width) solid var(--scl-ring); + outline-offset: var(--scl-focus-ring-offset); +} + +.scl-button:disabled { + pointer-events: none; + opacity: 0.3; +} + +.scl-button svg { + pointer-events: none; + width: 1rem; + height: 1rem; + flex-shrink: 0; +} + +/* Sizes */ +.scl-button--default { + height: 2.75rem; + padding: var(--scl-space-3) var(--scl-space-6); + font-size: var(--scl-text-sm); +} + +.scl-button--sm { + height: 2.25rem; + padding: var(--scl-space-2) var(--scl-space-4); + font-size: var(--scl-text-xs); +} + +.scl-button--lg { + height: 3.5rem; + padding: var(--scl-space-4) var(--scl-space-10); + font-size: var(--scl-text-base); +} + +.scl-button--icon { + height: 2.75rem; + width: 2.75rem; + padding: 0; +} + +/* Variants */ +.scl-button--primary { + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); + border-color: var(--scl-primary); +} + +.scl-button--primary:hover { + background-color: transparent; + color: var(--scl-primary); +} + +.scl-button--primary:active { + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); +} + +.scl-button--secondary { + background-color: var(--scl-secondary); + color: var(--scl-secondary-foreground); + border-color: var(--scl-secondary); +} + +.scl-button--secondary:hover { + background-color: transparent; + color: var(--scl-secondary); +} + +.scl-button--secondary:active { + background-color: var(--scl-secondary); + color: var(--scl-secondary-foreground); +} + +.scl-button--outline { + background-color: transparent; + color: var(--scl-primary); + border-color: var(--scl-primary); +} + +.scl-button--outline:hover { + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); +} + +.scl-button--outline:active { + background-color: transparent; + color: var(--scl-primary); +} + +.scl-button--secondary-outline { + background-color: transparent; + color: var(--scl-secondary); + border-color: var(--scl-secondary); +} + +.scl-button--secondary-outline:hover { + background-color: var(--scl-secondary); + color: var(--scl-secondary-foreground); +} + +.scl-button--secondary-outline:active { + background-color: transparent; + color: var(--scl-secondary); +} + +.scl-button--ghost { + background-color: transparent; + color: var(--scl-primary); + border-color: transparent; +} + +.scl-button--ghost:hover { + border-color: var(--scl-primary); + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); +} + +.scl-button--ghost:active { + background-color: transparent; + color: var(--scl-primary); +} + +.scl-button--link { + background-color: transparent; + color: var(--scl-primary); + border: none; + text-decoration-line: underline; + text-underline-offset: 4px; +} + +.scl-button--link:hover { + text-decoration-line: none; +} + +.scl-button--destructive { + background-color: var(--scl-destructive); + color: var(--scl-destructive-foreground); + border-color: var(--scl-destructive); +} + +.scl-button--destructive:hover { + background-color: transparent; + color: var(--scl-destructive); +} + +.scl-button--destructive:active { + background-color: var(--scl-destructive); + color: var(--scl-destructive-foreground); +} + +.scl-button--destructive-outline { + background-color: transparent; + color: var(--scl-destructive); + border-color: var(--scl-destructive); +} + +.scl-button--destructive-outline:hover { + background-color: var(--scl-destructive); + color: var(--scl-destructive-foreground); +} + +.scl-button--destructive-outline:active { + background-color: transparent; + color: var(--scl-destructive); +} diff --git a/src/components/ui/button/button.stories.tsx b/src/components/ui/button/button.stories.tsx index f189ea2..b614c8e 100644 --- a/src/components/ui/button/button.stories.tsx +++ b/src/components/ui/button/button.stories.tsx @@ -9,7 +9,7 @@ const meta: Meta = { variant: { control: 'select', options: [ - 'default', + 'primary', 'destructive', 'outline', 'secondary', @@ -43,7 +43,7 @@ export const Default: Story = { export const Primary: Story = { args: { - variant: 'default', + variant: 'primary', children: '[Start Quiz]', }, }; @@ -57,8 +57,8 @@ export const Secondary: Story = { export const AllVariants: Story = { render: () => ( -
- +
+ @@ -72,7 +72,7 @@ export const AllVariants: Story = { export const AllSizes: Story = { render: () => ( -
+
@@ -92,7 +92,7 @@ export const Disabled: Story = { export const WithIcon: Story = { render: () => ( -
+
), }; - -export const InteractiveDemo: Story = { - render: () => ( -
-
-

14 questions • ~3 minutes

- -

- Press{' '} - {' '} - to start -

-
-
- - -
-
- ), -}; - -export const WithThemeColors: Story = { - render: () => ( -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- ), -}; diff --git a/src/components/ui/button/button.test.tsx b/src/components/ui/button/button.test.tsx index eeb4b95..d1af49a 100644 --- a/src/components/ui/button/button.test.tsx +++ b/src/components/ui/button/button.test.tsx @@ -12,13 +12,13 @@ describe('Button', () => { it('applies variant classes correctly', () => { render(); const button = screen.getByRole('button'); - expect(button).toHaveClass('bg-destructive'); + expect(button).toHaveClass('scl-button--destructive'); }); it('applies size classes correctly', () => { render(); const button = screen.getByRole('button'); - expect(button).toHaveClass('h-9'); + expect(button).toHaveClass('scl-button--sm'); }); it('forwards ref correctly', () => { diff --git a/src/components/ui/button/button.tsx b/src/components/ui/button/button.tsx index 743d82b..db63365 100644 --- a/src/components/ui/button/button.tsx +++ b/src/components/ui/button/button.tsx @@ -1,57 +1,43 @@ import { Slot } from '@radix-ui/react-slot'; -import { cva, type VariantProps } from 'class-variance-authority'; import * as React from 'react'; -import { cn } from '@/lib/utils'; +import { cx } from '@/lib/utils'; +import './button.css'; -const buttonVariants = cva( - 'inline-flex items-center justify-center gap-2 whitespace-nowrap font-mono font-bold uppercase tracking-wider cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-30 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', - { - variants: { - variant: { - default: - 'bg-primary text-primary-foreground border-2 border-primary hover:bg-transparent hover:text-primary active:bg-primary active:text-primary-foreground active:border-primary-foreground', - secondary: - 'bg-secondary text-secondary-foreground border-2 border-secondary hover:bg-transparent hover:text-secondary active:bg-secondary active:text-secondary-foreground active:border-secondary-foreground', - outline: - 'bg-transparent text-primary border-2 border-primary hover:bg-primary hover:text-primary-foreground active:bg-transparent active:text-primary active:border-primary-foreground', - 'secondary-outline': - 'bg-transparent text-secondary border-2 border-secondary hover:bg-secondary hover:text-secondary-foreground active:bg-transparent active:text-secondary active:border-secondary-foreground', - ghost: - 'bg-transparent text-primary border-2 border-transparent hover:border-primary hover:bg-primary hover:text-primary-foreground active:bg-transparent active:border-primary-foreground active:text-primary', - link: 'bg-transparent text-primary underline-offset-4 hover:underline border-none active:no-underline', - destructive: - 'bg-destructive text-destructive-foreground border-2 border-destructive hover:bg-transparent hover:text-destructive active:bg-destructive active:text-destructive-foreground active:border-destructive-foreground', - 'destructive-outline': - 'bg-transparent text-destructive border-2 border-destructive hover:bg-destructive hover:text-destructive-foreground active:bg-transparent active:text-destructive active:border-destructive-foreground', - }, - size: { - default: 'h-11 px-6 py-3 text-sm', - sm: 'h-9 px-4 py-2 text-xs', - lg: 'h-14 px-10 py-4 text-base', - icon: 'h-11 w-11', - }, - }, - defaultVariants: { - variant: 'default', - size: 'default', - }, - } -); +export type ButtonVariant = + | 'primary' + | 'secondary' + | 'outline' + | 'secondary-outline' + | 'ghost' + | 'link' + | 'destructive' + | 'destructive-outline'; + +export type ButtonSize = 'default' | 'sm' | 'lg' | 'icon'; -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { +export interface ButtonProps extends React.ButtonHTMLAttributes { + variant?: ButtonVariant; + size?: ButtonSize; asChild?: boolean; } const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { + ({ className, variant = 'primary', size = 'default', asChild = false, ...props }, ref) => { const Comp = asChild ? Slot : 'button'; return ( - + ); } ); Button.displayName = 'Button'; -export { Button, buttonVariants }; +export { Button }; diff --git a/src/components/ui/button/index.ts b/src/components/ui/button/index.ts index e4d4fef..016cc80 100644 --- a/src/components/ui/button/index.ts +++ b/src/components/ui/button/index.ts @@ -1 +1 @@ -export { Button, type ButtonProps, buttonVariants } from './button'; +export { Button, type ButtonProps, type ButtonVariant, type ButtonSize } from './button'; diff --git a/src/components/ui/card/card.css b/src/components/ui/card/card.css new file mode 100644 index 0000000..5abe13c --- /dev/null +++ b/src/components/ui/card/card.css @@ -0,0 +1,41 @@ +/* Card Component Styles */ + +.scl-card { + border: 2px solid var(--scl-primary); + background-color: var(--scl-card); + color: var(--scl-card-foreground); +} + +.scl-card__header { + display: flex; + flex-direction: column; + gap: var(--scl-space-1-5); +} + +.scl-card__title { + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); + padding: var(--scl-space-1) var(--scl-space-2); + font-size: var(--scl-text-sm); + font-weight: 600; + font-family: var(--scl-font-mono); + line-height: 1; + letter-spacing: -0.025em; + width: 100%; +} + +.scl-card__description { + padding: var(--scl-space-2) var(--scl-space-6) 0; + font-size: var(--scl-text-sm); + color: var(--scl-muted-foreground); +} + +.scl-card__content { + padding: var(--scl-space-6); +} + +.scl-card__footer { + display: flex; + align-items: center; + padding: 0 var(--scl-space-6) var(--scl-space-6); +} diff --git a/src/components/ui/card/card.tsx b/src/components/ui/card/card.tsx index ad23e44..ed81755 100644 --- a/src/components/ui/card/card.tsx +++ b/src/components/ui/card/card.tsx @@ -1,57 +1,45 @@ import * as React from 'react'; -import { cn } from '@/lib/utils'; +import { cx } from '@/lib/utils'; +import './card.css'; const Card = React.forwardRef>( ({ className, ...props }, ref) => ( -
+
) ); Card.displayName = 'Card'; const CardHeader = React.forwardRef>( ({ className, ...props }, ref) => ( -
+
) ); CardHeader.displayName = 'CardHeader'; const CardTitle = React.forwardRef>( ({ className, ...props }, ref) => ( -
+
) ); CardTitle.displayName = 'CardTitle'; const CardDescription = React.forwardRef>( ({ className, ...props }, ref) => ( -
+
) ); CardDescription.displayName = 'CardDescription'; const CardContent = React.forwardRef>( - ({ className, ...props }, ref) =>
+ ({ className, ...props }, ref) => ( +
+ ) ); CardContent.displayName = 'CardContent'; const CardFooter = React.forwardRef>( ({ className, ...props }, ref) => ( -
+
) ); CardFooter.displayName = 'CardFooter'; diff --git a/src/components/ui/checkbox/checkbox.css b/src/components/ui/checkbox/checkbox.css new file mode 100644 index 0000000..6d9281d --- /dev/null +++ b/src/components/ui/checkbox/checkbox.css @@ -0,0 +1,40 @@ +/* Checkbox Component Styles */ + +.scl-checkbox { + display: flex; + align-items: center; + justify-content: center; + height: 1.5rem; + width: 1.5rem; + flex-shrink: 0; + border: 2px solid var(--scl-primary); + background-color: var(--scl-background); + cursor: pointer; +} + +.scl-checkbox:focus-visible { + outline: none; + box-shadow: 0 0 0 1px var(--scl-ring) !important; +} + +.scl-checkbox:disabled { + cursor: not-allowed; + opacity: 0.5; +} + +.scl-checkbox[data-state="checked"] { + background-color: var(--scl-primary); + color: var(--scl-primary-foreground); +} + +.scl-checkbox__indicator { + display: flex; + align-items: center; + justify-content: center; + color: currentColor; +} + +.scl-checkbox__icon { + width: 1.25rem; + height: 1.25rem; +} diff --git a/src/components/ui/checkbox/checkbox.tsx b/src/components/ui/checkbox/checkbox.tsx index dca4892..db166a6 100644 --- a/src/components/ui/checkbox/checkbox.tsx +++ b/src/components/ui/checkbox/checkbox.tsx @@ -1,7 +1,21 @@ import * as CheckboxPrimitive from '@radix-ui/react-checkbox'; -import { Check } from 'lucide-react'; import * as React from 'react'; -import { cn } from '@/lib/utils'; +import { cx } from '@/lib/utils'; +import './checkbox.css'; + +const CheckIcon = () => ( + + + +); const Checkbox = React.forwardRef< React.ElementRef, @@ -9,14 +23,11 @@ const Checkbox = React.forwardRef< >(({ className, ...props }, ref) => ( - - + + )); diff --git a/src/components/ui/collapsible/collapsible.css b/src/components/ui/collapsible/collapsible.css new file mode 100644 index 0000000..ba06c01 --- /dev/null +++ b/src/components/ui/collapsible/collapsible.css @@ -0,0 +1,11 @@ +/* Collapsible Component Styles */ +/* Collapsible uses Radix primitives directly with minimal styling */ + +.scl-collapsible-content[data-state="closed"] { + height: 0; + overflow: hidden; +} + +.scl-collapsible-content[data-state="open"] { + animation: scl-collapsible-down var(--scl-duration-normal) ease-out; +} diff --git a/src/components/ui/collapsible/collapsible.tsx b/src/components/ui/collapsible/collapsible.tsx index c6a17d4..8c4b8d3 100644 --- a/src/components/ui/collapsible/collapsible.tsx +++ b/src/components/ui/collapsible/collapsible.tsx @@ -1,4 +1,5 @@ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'; +import './collapsible.css'; const Collapsible = CollapsiblePrimitive.Root; const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger; diff --git a/src/components/ui/combobox/combobox.stories.tsx b/src/components/ui/combobox/combobox.stories.tsx deleted file mode 100644 index 135b241..0000000 --- a/src/components/ui/combobox/combobox.stories.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import * as React from 'react'; -import { Combobox, ComboboxMulti } from './combobox'; - -const meta: Meta = { - title: 'Components/Combobox', - component: Combobox, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -const frameworks = [ - { value: 'next', label: 'Next.js' }, - { value: 'sveltekit', label: 'SvelteKit' }, - { value: 'nuxt', label: 'Nuxt.js' }, - { value: 'remix', label: 'Remix' }, - { value: 'astro', label: 'Astro' }, -]; - -const vimPlugins = [ - { value: 'telescope', label: 'Telescope' }, - { value: 'treesitter', label: 'Treesitter' }, - { value: 'lspconfig', label: 'LSP Config' }, - { value: 'cmp', label: 'nvim-cmp' }, - { value: 'mason', label: 'Mason' }, - { value: 'lazy', label: 'lazy.nvim' }, -]; - -const colorschemes = [ - { value: 'green', label: 'Terminal Green' }, - { value: 'cyan', label: 'Cyan' }, - { value: 'hotpink', label: 'Hot Pink' }, - { value: 'yellow', label: 'Yellow' }, - { value: 'amber', label: 'Amber' }, - { value: 'white', label: 'White' }, - { value: 'blue', label: 'Blue' }, -]; - -export const Default: Story = { - render: function ControlledExample() { - const [value, setValue] = React.useState(''); - return ( - - ); - }, -}; - -export const WithPreselection: Story = { - render: function PreselectedExample() { - const [value, setValue] = React.useState('next'); - return ( - - ); - }, -}; - -export const VimPluginSelector: Story = { - render: function VimExample() { - const [value, setValue] = React.useState(''); - return ( - - ); - }, -}; - -export const ColorschemeSelector: Story = { - render: function ColorschemeExample() { - const [value, setValue] = React.useState('green'); - return ( -
- -

- Selected: {value || 'none'} -

-
- ); - }, -}; - -export const Disabled: Story = { - args: { - options: frameworks, - placeholder: 'Select framework...', - disabled: true, - }, -}; - -export const WithDisabledOptions: Story = { - render: function DisabledOptionsExample() { - const [value, setValue] = React.useState(''); - const optionsWithDisabled = [ - { value: 'next', label: 'Next.js' }, - { value: 'sveltekit', label: 'SvelteKit', disabled: true }, - { value: 'nuxt', label: 'Nuxt.js' }, - { value: 'remix', label: 'Remix', disabled: true }, - { value: 'astro', label: 'Astro' }, - ]; - return ( - - ); - }, -}; - -// Multi-select stories -export const MultiSelect: Story = { - render: function MultiExample() { - const [value, setValue] = React.useState([]); - return ( - - ); - }, -}; - -export const MultiSelectWithPreselection: Story = { - render: function MultiPreselectedExample() { - const [value, setValue] = React.useState(['telescope', 'treesitter', 'lspconfig']); - return ( - - ); - }, -}; - -export const MultiSelectWithMax: Story = { - render: function MultiMaxExample() { - const [value, setValue] = React.useState([]); - return ( -
- -

Selected {value.length}/3 colors

-
- ); - }, -}; diff --git a/src/components/ui/combobox/combobox.test.tsx b/src/components/ui/combobox/combobox.test.tsx deleted file mode 100644 index c685a6d..0000000 --- a/src/components/ui/combobox/combobox.test.tsx +++ /dev/null @@ -1,186 +0,0 @@ -import { render, screen, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { describe, expect, it, vi } from 'vitest'; -import { Combobox, ComboboxMulti } from './combobox'; - -const testOptions = [ - { value: 'apple', label: 'Apple' }, - { value: 'banana', label: 'Banana' }, - { value: 'cherry', label: 'Cherry' }, -]; - -describe('Combobox', () => { - it('renders with placeholder', () => { - render(); - - expect(screen.getByRole('combobox')).toHaveTextContent('Select fruit...'); - }); - - it('renders selected value', () => { - render(); - - expect(screen.getByRole('combobox')).toHaveTextContent('Apple'); - }); - - it('opens popover on click', async () => { - const user = userEvent.setup(); - - render(); - - await user.click(screen.getByRole('combobox')); - - await waitFor(() => { - expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument(); - }); - }); - - it('shows all options when opened', async () => { - const user = userEvent.setup(); - - render(); - - await user.click(screen.getByRole('combobox')); - - await waitFor(() => { - expect(screen.getByText('Apple')).toBeInTheDocument(); - expect(screen.getByText('Banana')).toBeInTheDocument(); - expect(screen.getByText('Cherry')).toBeInTheDocument(); - }); - }); - - it('calls onValueChange when option is selected', async () => { - const user = userEvent.setup(); - const onValueChange = vi.fn(); - - render( - - ); - - await user.click(screen.getByRole('combobox')); - - await waitFor(() => { - expect(screen.getByText('Banana')).toBeInTheDocument(); - }); - - await user.click(screen.getByText('Banana')); - - expect(onValueChange).toHaveBeenCalledWith('banana'); - }); - - it('shows empty state when no matches', async () => { - const user = userEvent.setup(); - - render( - - ); - - await user.click(screen.getByRole('combobox')); - - const searchInput = await screen.findByPlaceholderText('Search...'); - await user.type(searchInput, 'xyz'); - - await waitFor(() => { - expect(screen.getByText('No fruits found.')).toBeInTheDocument(); - }); - }); - - it('respects disabled state', () => { - render(); - - expect(screen.getByRole('combobox')).toBeDisabled(); - }); -}); - -describe('ComboboxMulti', () => { - it('renders with placeholder', () => { - render(); - - expect(screen.getByRole('combobox')).toHaveTextContent('Select fruits...'); - }); - - it('renders selected values', () => { - render( - - ); - - expect(screen.getByRole('combobox')).toHaveTextContent('Apple, Banana'); - }); - - it('toggles selection', async () => { - const user = userEvent.setup(); - const onValueChange = vi.fn(); - - render( - - ); - - await user.click(screen.getByRole('combobox')); - - await waitFor(() => { - expect(screen.getByText('Banana')).toBeInTheDocument(); - }); - - await user.click(screen.getByText('Banana')); - - expect(onValueChange).toHaveBeenCalledWith(['apple', 'banana']); - }); - - it('removes selection when clicked again', async () => { - const user = userEvent.setup(); - const onValueChange = vi.fn(); - - render( - - ); - - await user.click(screen.getByRole('combobox')); - - await waitFor(() => { - expect(screen.getByText('Apple')).toBeInTheDocument(); - }); - - await user.click(screen.getByText('Apple')); - - expect(onValueChange).toHaveBeenCalledWith(['banana']); - }); - - it('respects maxSelected limit', async () => { - const user = userEvent.setup(); - const onValueChange = vi.fn(); - - render( - - ); - - await user.click(screen.getByRole('combobox')); - - await waitFor(() => { - expect(screen.getByText('Cherry')).toBeInTheDocument(); - }); - - await user.click(screen.getByText('Cherry')); - - // Should not add third item when at max - expect(onValueChange).toHaveBeenCalledWith(['apple', 'banana']); - }); -}); diff --git a/src/components/ui/combobox/combobox.tsx b/src/components/ui/combobox/combobox.tsx deleted file mode 100644 index 2c32993..0000000 --- a/src/components/ui/combobox/combobox.tsx +++ /dev/null @@ -1,190 +0,0 @@ -import { Check, ChevronsUpDown } from 'lucide-react'; -import * as React from 'react'; -import { Button } from '@/components/ui/button'; -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, -} from '@/components/ui/command'; -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; -import { cn } from '@/lib/utils'; - -export interface ComboboxOption { - value: string; - label: string; - disabled?: boolean; -} - -export interface ComboboxProps { - options: ComboboxOption[]; - value?: string; - onValueChange?: (value: string) => void; - placeholder?: string; - searchPlaceholder?: string; - emptyText?: string; - className?: string; - disabled?: boolean; -} - -const Combobox = React.forwardRef( - ( - { - options, - value, - onValueChange, - placeholder = 'Select option...', - searchPlaceholder = 'Search...', - emptyText = 'No option found.', - className, - disabled = false, - }, - ref - ) => { - const [open, setOpen] = React.useState(false); - - const selectedOption = options.find((option) => option.value === value); - - return ( - - - - - - - - - {emptyText} - - {options.map((option) => ( - { - onValueChange?.(currentValue === value ? '' : currentValue); - setOpen(false); - }} - disabled={option.disabled} - > - - {option.label} - - ))} - - - - - - ); - } -); -Combobox.displayName = 'Combobox'; - -export interface ComboboxMultiProps { - options: ComboboxOption[]; - value?: string[]; - onValueChange?: (value: string[]) => void; - placeholder?: string; - searchPlaceholder?: string; - emptyText?: string; - className?: string; - disabled?: boolean; - maxSelected?: number; -} - -const ComboboxMulti = React.forwardRef( - ( - { - options, - value = [], - onValueChange, - placeholder = 'Select options...', - searchPlaceholder = 'Search...', - emptyText = 'No option found.', - className, - disabled = false, - maxSelected, - }, - ref - ) => { - const [open, setOpen] = React.useState(false); - - const selectedLabels = value - .map((v) => options.find((option) => option.value === v)?.label) - .filter(Boolean) - .join(', '); - - const toggleOption = (optionValue: string) => { - const newValue = value.includes(optionValue) - ? value.filter((v) => v !== optionValue) - : maxSelected && value.length >= maxSelected - ? value - : [...value, optionValue]; - onValueChange?.(newValue); - }; - - return ( - - - - - - - - - {emptyText} - - {options.map((option) => ( - toggleOption(option.value)} - disabled={option.disabled} - > - - {option.label} - - ))} - - - - - - ); - } -); -ComboboxMulti.displayName = 'ComboboxMulti'; - -export { Combobox, ComboboxMulti }; diff --git a/src/components/ui/combobox/index.ts b/src/components/ui/combobox/index.ts deleted file mode 100644 index c0848ac..0000000 --- a/src/components/ui/combobox/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { ComboboxMultiProps, ComboboxOption, ComboboxProps } from './combobox'; -export { Combobox, ComboboxMulti } from './combobox'; diff --git a/src/components/ui/command/command.stories.tsx b/src/components/ui/command/command.stories.tsx deleted file mode 100644 index 6e68b85..0000000 --- a/src/components/ui/command/command.stories.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { - Calculator, - Calendar, - CreditCard, - File, - Moon, - Settings, - Smile, - Sun, - Terminal, - User, -} from 'lucide-react'; -import * as React from 'react'; -import { - Command, - CommandDialog, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - CommandSeparator, - CommandShortcut, -} from './command'; - -const meta: Meta = { - title: 'Components/Command', - component: Command, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => ( - - - - No results found. - - - - Calendar - - - - Search Emoji - - - - Calculator - - - - - - - Profile - :profile - - - - Billing - :billing - - - - Settings - :settings - - - - - ), -}; - -export const VimStyle: Story = { - render: () => ( - - - - No commands found. - - - - New file - :e [file] - - - 󰆓 - Save - :w - - - 󰈆 - Quit - :q - - - 󰈆 - Save and quit - :wq - - - - - - - Terminal - :term - - - 󰕭 - Split vertical - :vs - - - 󰕮 - Split horizontal - :sp - - - - - - - Set options - :set - - - - Colorscheme - :colorscheme - - - - - ), -}; - -export const WithDialog: Story = { - render: function DialogExample() { - const [open, setOpen] = React.useState(false); - - React.useEffect(() => { - const down = (e: KeyboardEvent) => { - if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { - e.preventDefault(); - setOpen((open) => !open); - } - }; - - document.addEventListener('keydown', down); - return () => document.removeEventListener('keydown', down); - }, []); - - return ( - <> -

- Press{' '} - - ⌘K - -

- - - - No results found. - - - - Calendar - - - - Search Emoji - - - - Calculator - - - - - - ); - }, -}; - -export const ThemeSwitcher: Story = { - render: () => ( - - - - No themes found. - - - - Green (Default) - - - - Cyan - - - - Hot Pink - - - - Yellow - - - - Amber - - - - White - - - - - ), -}; - -export const Empty: Story = { - render: () => ( - - - - No results found. - - - ), -}; diff --git a/src/components/ui/command/command.test.tsx b/src/components/ui/command/command.test.tsx deleted file mode 100644 index 6e8021a..0000000 --- a/src/components/ui/command/command.test.tsx +++ /dev/null @@ -1,190 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { describe, expect, it } from 'vitest'; -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - CommandSeparator, - CommandShortcut, -} from './command'; - -describe('Command', () => { - it('renders command component', () => { - render( - - - - No results. - - Item 1 - - - - ); - - expect(screen.getByTestId('command')).toBeInTheDocument(); - expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument(); - }); - - it('renders command items', () => { - render( - - - - Action 1 - Action 2 - Action 3 - - - - ); - - expect(screen.getByText('Action 1')).toBeInTheDocument(); - expect(screen.getByText('Action 2')).toBeInTheDocument(); - expect(screen.getByText('Action 3')).toBeInTheDocument(); - expect(screen.getByText('Actions')).toBeInTheDocument(); - }); - - it('renders command shortcut', () => { - render( - - - - - Save - :w - - - - - ); - - expect(screen.getByText('Save')).toBeInTheDocument(); - expect(screen.getByText(':w')).toBeInTheDocument(); - }); - - it('renders command separator', () => { - render( - - - - Item 1 - - - - Item 2 - - - - ); - - expect(screen.getByTestId('separator')).toBeInTheDocument(); - expect(screen.getByText('Group 1')).toBeInTheDocument(); - expect(screen.getByText('Group 2')).toBeInTheDocument(); - }); - - it('shows empty state when no results', async () => { - const user = userEvent.setup(); - - render( - - - - No results found. - - Apple - Banana - - - - ); - - const input = screen.getByPlaceholderText('Search...'); - await user.type(input, 'xyz'); - - expect(screen.getByText('No results found.')).toBeInTheDocument(); - }); - - it('filters items based on search', async () => { - const user = userEvent.setup(); - - render( - - - - No results found. - - Apple - Banana - Cherry - - - - ); - - const input = screen.getByPlaceholderText('Search...'); - await user.type(input, 'app'); - - expect(screen.getByText('Apple')).toBeInTheDocument(); - expect(screen.queryByText('Banana')).not.toBeInTheDocument(); - expect(screen.queryByText('Cherry')).not.toBeInTheDocument(); - }); - - it('supports keyboard navigation', async () => { - const user = userEvent.setup(); - - render( - - - - - Item 1 - Item 2 - Item 3 - - - - ); - - const input = screen.getByPlaceholderText('Search...'); - await user.click(input); - await user.keyboard('{ArrowDown}'); - await user.keyboard('{ArrowDown}'); - - // Check that navigation works (items should be selectable) - expect(screen.getByText('Item 1')).toBeInTheDocument(); - expect(screen.getByText('Item 2')).toBeInTheDocument(); - expect(screen.getByText('Item 3')).toBeInTheDocument(); - }); - - it('renders disabled items correctly', () => { - render( - - - - Disabled Item - - - - ); - - const item = screen.getByText('Disabled Item').closest('[cmdk-item]'); - expect(item).toHaveAttribute('data-disabled', 'true'); - }); - - it('applies custom className', () => { - render( - - - Test - - - ); - - expect(screen.getByTestId('command')).toHaveClass('custom-class'); - }); -}); diff --git a/src/components/ui/command/command.tsx b/src/components/ui/command/command.tsx deleted file mode 100644 index 3363dfe..0000000 --- a/src/components/ui/command/command.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { Command as CommandPrimitive } from 'cmdk'; -import { Search } from 'lucide-react'; -import * as React from 'react'; -import { Dialog, DialogContent } from '@/components/ui/dialog'; -import { cn } from '@/lib/utils'; - -const Command = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -Command.displayName = CommandPrimitive.displayName; - -interface CommandDialogProps { - children: React.ReactNode; - open?: boolean; - onOpenChange?: (open: boolean) => void; -} - -const CommandDialog = ({ children, ...props }: CommandDialogProps) => { - return ( - - - - {children} - - - - ); -}; - -const CommandInput = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( -
- - -
-)); -CommandInput.displayName = CommandPrimitive.Input.displayName; - -const CommandList = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CommandList.displayName = CommandPrimitive.List.displayName; - -const CommandEmpty = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->((props, ref) => ( - -)); -CommandEmpty.displayName = CommandPrimitive.Empty.displayName; - -const CommandGroup = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CommandGroup.displayName = CommandPrimitive.Group.displayName; - -const CommandSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CommandSeparator.displayName = CommandPrimitive.Separator.displayName; - -const CommandItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CommandItem.displayName = CommandPrimitive.Item.displayName; - -const CommandShortcut = ({ className, ...props }: React.HTMLAttributes) => { - return ( - - ); -}; -CommandShortcut.displayName = 'CommandShortcut'; - -export { - Command, - CommandDialog, - CommandInput, - CommandList, - CommandEmpty, - CommandGroup, - CommandItem, - CommandSeparator, - CommandShortcut, -}; diff --git a/src/components/ui/command/index.ts b/src/components/ui/command/index.ts deleted file mode 100644 index e2a383a..0000000 --- a/src/components/ui/command/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export { - Command, - CommandDialog, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, - CommandSeparator, - CommandShortcut, -} from './command'; diff --git a/src/components/ui/dialog/dialog.css b/src/components/ui/dialog/dialog.css new file mode 100644 index 0000000..2ac65eb --- /dev/null +++ b/src/components/ui/dialog/dialog.css @@ -0,0 +1,108 @@ +/* Dialog Component Styles */ + +.scl-dialog-overlay { + position: fixed; + inset: 0; + z-index: 50; + background-color: rgba(0, 0, 0, 0.8); +} + +.scl-dialog-overlay[data-state="closed"] { + display: none; +} + +.scl-dialog-content { + position: fixed; + left: 50%; + top: 50%; + z-index: 50; + display: grid; + width: 100%; + max-width: 32rem; + transform: translate(-50%, -50%); + gap: var(--scl-space-4); + border: 2px solid var(--scl-primary); + background-color: var(--scl-background); + padding: var(--scl-space-6); +} + +.scl-dialog-close { + position: absolute; + right: var(--scl-space-4); + top: var(--scl-space-4); + background: none; + border: none; + color: var(--scl-primary); + cursor: pointer; + padding: 0; +} + +.scl-dialog-close:hover { + opacity: 0.8; +} + +.scl-dialog-close:focus { + outline: var(--scl-focus-ring-width) solid var(--scl-ring); + outline-offset: var(--scl-focus-ring-offset); +} + +.scl-dialog-close:disabled { + pointer-events: none; +} + +.scl-dialog-close__icon { + width: 1rem; + height: 1rem; +} + +.scl-dialog-header { + display: flex; + flex-direction: column; + gap: var(--scl-space-1-5); + text-align: center; +} + +@media (min-width: 640px) { + .scl-dialog-header { + text-align: left; + } +} + +.scl-dialog-footer { + display: flex; + flex-direction: column-reverse; + gap: var(--scl-space-2); +} + +@media (min-width: 640px) { + .scl-dialog-footer { + flex-direction: row; + justify-content: flex-end; + } +} + +.scl-dialog-title { + font-size: var(--scl-text-lg); + font-weight: 600; + font-family: var(--scl-font-mono); + line-height: 1; + letter-spacing: -0.025em; + color: var(--scl-primary); +} + +.scl-dialog-description { + font-size: var(--scl-text-sm); + color: var(--scl-muted-foreground); +} + +.scl-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; +} diff --git a/src/components/ui/dialog/dialog.tsx b/src/components/ui/dialog/dialog.tsx index 417e16b..1045f2c 100644 --- a/src/components/ui/dialog/dialog.tsx +++ b/src/components/ui/dialog/dialog.tsx @@ -1,23 +1,34 @@ import * as DialogPrimitive from '@radix-ui/react-dialog'; -import { X } from 'lucide-react'; import * as React from 'react'; -import { cn } from '@/lib/utils'; +import { cx } from '@/lib/utils'; +import './dialog.css'; const Dialog = DialogPrimitive.Root; - const DialogTrigger = DialogPrimitive.Trigger; - const DialogPortal = DialogPrimitive.Portal; - const DialogClose = DialogPrimitive.Close; +const CloseIcon = () => ( + + + + +); + const DialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); @@ -31,16 +42,13 @@ const DialogContent = React.forwardRef< {children} - - - Close + + + Close @@ -48,15 +56,12 @@ const DialogContent = React.forwardRef< DialogContent.displayName = DialogPrimitive.Content.displayName; const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( -
+
); DialogHeader.displayName = 'DialogHeader'; const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( -
+
); DialogFooter.displayName = 'DialogFooter'; @@ -66,7 +71,7 @@ const DialogTitle = React.forwardRef< >(({ className, ...props }, ref) => ( )); @@ -78,7 +83,7 @@ const DialogDescription = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/src/components/ui/dithered-image/dithered-image.stories.tsx b/src/components/ui/dithered-image/dithered-image.stories.tsx deleted file mode 100644 index 2431832..0000000 --- a/src/components/ui/dithered-image/dithered-image.stories.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { DitheredImage } from './dithered-image'; - -const meta: Meta = { - title: 'Components/DitheredImage', - component: DitheredImage, - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], - argTypes: { - ditherSize: { - control: { type: 'range', min: 1, max: 8, step: 1 }, - }, - threshold: { - control: { type: 'range', min: 0, max: 255, step: 1 }, - }, - algorithm: { - control: { type: 'select' }, - options: ['atkinson', 'floyd-steinberg', 'bayer'], - }, - color: { - control: false, - }, - }, -}; - -export default meta; -type Story = StoryObj; - -// Using picsum for a consistent sample portrait -const SAMPLE_IMAGE = 'https://picsum.photos/seed/scl-demo/400/400'; - -// Default now uses Atkinson (classic Mac) -export const Default: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Atkinson dithered image (classic Mac)', - width: 400, - }, -}; - -// Classic Mac aesthetic - Atkinson with green -export const AtkinsonGreen: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Atkinson dithered - classic Mac green', - width: 400, - algorithm: 'atkinson', - color: [0, 255, 0], - }, -}; - -// Atkinson with amber (like old monochrome monitors) -export const AtkinsonAmber: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Atkinson dithered - amber monochrome', - width: 400, - algorithm: 'atkinson', - color: [255, 176, 0], - }, -}; - -// Floyd-Steinberg for comparison (smoother gradients) -export const FloydSteinberg: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Floyd-Steinberg dithered', - width: 400, - algorithm: 'floyd-steinberg', - color: [0, 255, 0], - }, -}; - -// Bayer ordered dithering (the original pattern) -export const BayerOrdered: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Bayer ordered dithering', - width: 400, - algorithm: 'bayer', - ditherSize: 1, - }, -}; - -// Large Bayer pattern -export const BayerLargePattern: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Large Bayer dither pattern', - width: 400, - algorithm: 'bayer', - ditherSize: 2, - }, -}; - -// Cyan terminal color -export const CyanColor: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Cyan dithered image', - width: 400, - algorithm: 'atkinson', - color: [0, 255, 255], - }, -}; - -// Hot pink -export const HotPinkColor: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Hot pink dithered image', - width: 400, - algorithm: 'atkinson', - color: [255, 0, 255], - }, -}; - -// White (high contrast) -export const WhiteColor: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'White dithered image', - width: 400, - algorithm: 'atkinson', - color: [255, 255, 255], - }, -}; - -// Custom threshold (darker) -export const DarkThreshold: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Dark threshold dithering', - width: 400, - algorithm: 'atkinson', - threshold: 100, - }, -}; - -// Custom threshold (lighter) -export const LightThreshold: Story = { - args: { - src: SAMPLE_IMAGE, - alt: 'Light threshold dithering', - width: 400, - algorithm: 'atkinson', - threshold: 180, - }, -}; - -// Comparison grid -export const AlgorithmComparison: Story = { - render: () => ( -
-
- -

Atkinson (Mac)

-
-
- -

Floyd-Steinberg

-
-
- -

Bayer (Ordered)

-
-
- ), -}; diff --git a/src/components/ui/dithered-image/dithered-image.tsx b/src/components/ui/dithered-image/dithered-image.tsx deleted file mode 100644 index 259bf12..0000000 --- a/src/components/ui/dithered-image/dithered-image.tsx +++ /dev/null @@ -1,452 +0,0 @@ -import * as React from 'react'; -import { cn } from '@/lib/utils'; - -// Simple colorization shader (used after CPU-based dithering) -const VERTEX_SHADER = ` - attribute vec2 a_position; - attribute vec2 a_texCoord; - varying vec2 v_texCoord; - - void main() { - gl_Position = vec4(a_position, 0.0, 1.0); - v_texCoord = a_texCoord; - } -`; - -const COLORIZE_SHADER = ` - precision mediump float; - - varying vec2 v_texCoord; - - uniform sampler2D u_image; - uniform vec3 u_color; - - void main() { - vec4 texColor = texture2D(u_image, v_texCoord); - // Dithered image is already black/white, just colorize the white pixels - vec3 finalColor = texColor.r * u_color; - gl_FragColor = vec4(finalColor, texColor.a); - } -`; - -// Bayer dithering shader (for ordered dithering mode) -const BAYER_SHADER = ` - precision mediump float; - - varying vec2 v_texCoord; - - uniform sampler2D u_image; - uniform sampler2D u_bayerTex; - uniform vec2 u_resolution; - uniform float u_ditherSize; - uniform vec3 u_color; - - void main() { - vec2 pixelPos = mod(floor(gl_FragCoord.xy / u_ditherSize), 8.0); - vec4 texColor = texture2D(u_image, v_texCoord); - - // Convert to grayscale using luminance - float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114)); - - // Look up threshold from Bayer texture - float threshold = texture2D(u_bayerTex, (pixelPos + 0.5) / 8.0).r; - float dithered = step(threshold, gray); - - // Output color or black - vec3 finalColor = dithered * u_color; - gl_FragColor = vec4(finalColor, texColor.a); - } -`; - -// 8x8 Bayer matrix values (0-63, will be normalized to 0-1) -const BAYER_MATRIX = [ - 0, 32, 8, 40, 2, 34, 10, 42, 48, 16, 56, 24, 50, 18, 58, 26, 12, 44, 4, 36, 14, 46, 6, 38, 60, 28, - 52, 20, 62, 30, 54, 22, 3, 35, 11, 43, 1, 33, 9, 41, 51, 19, 59, 27, 49, 17, 57, 25, 15, 47, 7, - 39, 13, 45, 5, 37, 63, 31, 55, 23, 61, 29, 53, 21, -]; - -export type DitherAlgorithm = 'atkinson' | 'bayer' | 'floyd-steinberg'; - -export interface DitheredImageProps extends Omit, 'color'> { - src: string; - alt?: string; - /** Width in pixels. If only width is set, height is calculated from aspect ratio */ - width?: number; - /** Height in pixels. If only height is set, width is calculated from aspect ratio */ - height?: number; - /** Size of dither pattern pixels (default: 1) */ - ditherSize?: number; - /** RGB color for lit pixels (default: terminal green [0, 255, 0]) */ - color?: [number, number, number]; - /** Dithering algorithm (default: 'atkinson' for classic Mac look) */ - algorithm?: DitherAlgorithm; - /** Threshold for black/white conversion (0-255, default: 128) */ - threshold?: number; -} - -/** - * Atkinson dithering algorithm (Bill Atkinson, Apple 1980s) - * Diffuses 6/8 (75%) of the error to create sharper contrast - * - * Error diffusion pattern: - * X 1/8 1/8 - * 1/8 1/8 1/8 - * 1/8 - */ -function atkinsonDither(imageData: ImageData, threshold: number = 128): ImageData { - const data = new Uint8ClampedArray(imageData.data); - const width = imageData.width; - const height = imageData.height; - - const getIndex = (x: number, y: number) => (y * width + x) * 4; - - const addError = (x: number, y: number, error: number) => { - if (x < 0 || x >= width || y < 0 || y >= height) return; - const idx = getIndex(x, y); - data[idx] = Math.max(0, Math.min(255, data[idx] + error)); - data[idx + 1] = Math.max(0, Math.min(255, data[idx + 1] + error)); - data[idx + 2] = Math.max(0, Math.min(255, data[idx + 2] + error)); - }; - - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - const idx = getIndex(x, y); - - // Get grayscale value using luminance - const gray = data[idx] * 0.299 + data[idx + 1] * 0.587 + data[idx + 2] * 0.114; - const newVal = gray < threshold ? 0 : 255; - - // Calculate error (only diffuse 6/8 = 75%) - const error = Math.floor((gray - newVal) / 8); - - // Set pixel to black or white - data[idx] = newVal; - data[idx + 1] = newVal; - data[idx + 2] = newVal; - - // Diffuse error to neighbors (Atkinson pattern) - addError(x + 1, y, error); // right - addError(x + 2, y, error); // right+1 - addError(x - 1, y + 1, error); // bottom-left - addError(x, y + 1, error); // bottom - addError(x + 1, y + 1, error); // bottom-right - addError(x, y + 2, error); // bottom+1 - } - } - - return new ImageData(data, width, height); -} - -/** - * Floyd-Steinberg dithering algorithm - * Diffuses 100% of error, creates smoother gradients - * - * Error diffusion pattern: - * X 7/16 - * 3/16 5/16 1/16 - */ -function floydSteinbergDither(imageData: ImageData, threshold: number = 128): ImageData { - const data = new Uint8ClampedArray(imageData.data); - const width = imageData.width; - const height = imageData.height; - - const getIndex = (x: number, y: number) => (y * width + x) * 4; - - const addError = (x: number, y: number, error: number, factor: number) => { - if (x < 0 || x >= width || y < 0 || y >= height) return; - const idx = getIndex(x, y); - const e = error * factor; - data[idx] = Math.max(0, Math.min(255, data[idx] + e)); - data[idx + 1] = Math.max(0, Math.min(255, data[idx + 1] + e)); - data[idx + 2] = Math.max(0, Math.min(255, data[idx + 2] + e)); - }; - - for (let y = 0; y < height; y++) { - for (let x = 0; x < width; x++) { - const idx = getIndex(x, y); - - const gray = data[idx] * 0.299 + data[idx + 1] * 0.587 + data[idx + 2] * 0.114; - const newVal = gray < threshold ? 0 : 255; - const error = gray - newVal; - - data[idx] = newVal; - data[idx + 1] = newVal; - data[idx + 2] = newVal; - - // Floyd-Steinberg error diffusion - addError(x + 1, y, error, 7 / 16); - addError(x - 1, y + 1, error, 3 / 16); - addError(x, y + 1, error, 5 / 16); - addError(x + 1, y + 1, error, 1 / 16); - } - } - - return new ImageData(data, width, height); -} - -function createShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader | null { - const shader = gl.createShader(type); - if (!shader) return null; - - gl.shaderSource(shader, source); - gl.compileShader(shader); - - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - console.error('Shader compile error:', gl.getShaderInfoLog(shader)); - gl.deleteShader(shader); - return null; - } - return shader; -} - -function createProgram( - gl: WebGLRenderingContext, - vertexShader: WebGLShader, - fragmentShader: WebGLShader -): WebGLProgram | null { - const program = gl.createProgram(); - if (!program) return null; - - gl.attachShader(program, vertexShader); - gl.attachShader(program, fragmentShader); - gl.linkProgram(program); - - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - console.error('Program link error:', gl.getProgramInfoLog(program)); - gl.deleteProgram(program); - return null; - } - return program; -} - -const DitheredImage = React.forwardRef( - ( - { - className, - src, - alt, - width, - height, - ditherSize = 1, - color = [0, 255, 0], - algorithm = 'atkinson', - threshold = 128, - ...props - }, - ref - ) => { - const canvasRef = React.useRef(null); - const glRef = React.useRef(null); - const programRef = React.useRef(null); - const bayerTexRef = React.useRef(null); - - React.useImperativeHandle(ref, () => canvasRef.current!); - - // Initialize WebGL - React.useEffect(() => { - const canvas = canvasRef.current; - if (!canvas) return; - - const gl = canvas.getContext('webgl', { preserveDrawingBuffer: true }); - if (!gl) { - console.error('WebGL not supported'); - return; - } - glRef.current = gl; - - // Choose shader based on algorithm - const fragmentShaderSource = algorithm === 'bayer' ? BAYER_SHADER : COLORIZE_SHADER; - - const vertexShader = createShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER); - const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource); - - if (!vertexShader || !fragmentShader) { - console.error('Failed to create shaders'); - return; - } - - const program = createProgram(gl, vertexShader, fragmentShader); - if (!program) { - console.error('Failed to create program'); - return; - } - - // biome-ignore lint/correctness/useHookAtTopLevel: This is WebGL's useProgram, not a React hook - gl.useProgram(program); - programRef.current = program; - - // Create Bayer texture (only needed for bayer algorithm) - if (algorithm === 'bayer') { - const bayerTex = gl.createTexture(); - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, bayerTex); - const bayerData = new Uint8Array(BAYER_MATRIX.map((v) => (v / 64) * 255)); - gl.texImage2D( - gl.TEXTURE_2D, - 0, - gl.LUMINANCE, - 8, - 8, - 0, - gl.LUMINANCE, - gl.UNSIGNED_BYTE, - bayerData - ); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - bayerTexRef.current = bayerTex; - } - - // Set up geometry (full-screen quad) - const positions = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]); - const texCoords = new Float32Array([0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0]); - - const positionBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); - gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW); - const positionLoc = gl.getAttribLocation(program, 'a_position'); - gl.enableVertexAttribArray(positionLoc); - gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0); - - const texCoordBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); - gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW); - const texCoordLoc = gl.getAttribLocation(program, 'a_texCoord'); - gl.enableVertexAttribArray(texCoordLoc); - gl.vertexAttribPointer(texCoordLoc, 2, gl.FLOAT, false, 0, 0); - - // Set texture units - gl.uniform1i(gl.getUniformLocation(program, 'u_image'), 0); - if (algorithm === 'bayer') { - gl.uniform1i(gl.getUniformLocation(program, 'u_bayerTex'), 1); - } - - return () => { - gl.deleteProgram(program); - gl.deleteShader(vertexShader); - gl.deleteShader(fragmentShader); - if (bayerTexRef.current) { - gl.deleteTexture(bayerTexRef.current); - } - }; - }, [algorithm]); - - // Process image when src or settings change - React.useEffect(() => { - const canvas = canvasRef.current; - const gl = glRef.current; - const program = programRef.current; - if (!canvas || !gl || !program) return; - - const image = new Image(); - image.crossOrigin = 'anonymous'; - image.onload = () => { - const aspectRatio = image.naturalWidth / image.naturalHeight; - let w: number; - let h: number; - - if (width && height) { - w = width; - h = height; - } else if (width) { - w = width; - h = Math.round(width / aspectRatio); - } else if (height) { - h = height; - w = Math.round(height * aspectRatio); - } else { - w = image.naturalWidth; - h = image.naturalHeight; - } - - canvas.width = w; - canvas.height = h; - gl.viewport(0, 0, w, h); - - // biome-ignore lint/correctness/useHookAtTopLevel: This is WebGL's useProgram, not a React hook - gl.useProgram(program); - - let textureData: ImageData | HTMLImageElement = image; - - // For error diffusion algorithms, process on CPU first - if (algorithm === 'atkinson' || algorithm === 'floyd-steinberg') { - // Draw image to temp canvas to get pixel data - const tempCanvas = document.createElement('canvas'); - tempCanvas.width = w; - tempCanvas.height = h; - const tempCtx = tempCanvas.getContext('2d'); - if (tempCtx) { - tempCtx.drawImage(image, 0, 0, w, h); - const imageData = tempCtx.getImageData(0, 0, w, h); - - // Apply dithering algorithm - const dithered = - algorithm === 'atkinson' - ? atkinsonDither(imageData, threshold) - : floydSteinbergDither(imageData, threshold); - - textureData = dithered; - } - } - - // Bind Bayer texture if needed - if (algorithm === 'bayer') { - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, bayerTexRef.current); - } - - // Create and bind image texture - gl.activeTexture(gl.TEXTURE0); - const texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - - if (textureData instanceof ImageData) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureData); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureData); - } - - // Set uniforms - if (algorithm === 'bayer') { - gl.uniform2f(gl.getUniformLocation(program, 'u_resolution'), w, h); - gl.uniform1f(gl.getUniformLocation(program, 'u_ditherSize'), ditherSize); - } - gl.uniform3f( - gl.getUniformLocation(program, 'u_color'), - color[0] / 255, - color[1] / 255, - color[2] / 255 - ); - - // Draw - gl.drawArrays(gl.TRIANGLES, 0, 6); - - // Clean up image texture - gl.deleteTexture(texture); - }; - image.onerror = () => { - console.error('Failed to load image:', src); - }; - image.src = src; - }, [src, width, height, ditherSize, color, algorithm, threshold]); - - return ( - - ); - } -); -DitheredImage.displayName = 'DitheredImage'; - -export { DitheredImage }; diff --git a/src/components/ui/dithered-image/index.ts b/src/components/ui/dithered-image/index.ts deleted file mode 100644 index 72991fc..0000000 --- a/src/components/ui/dithered-image/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { DitherAlgorithm, DitheredImageProps } from './dithered-image'; -export { DitheredImage } from './dithered-image'; diff --git a/src/components/ui/dropdown-menu/dropdown-menu.stories.tsx b/src/components/ui/dropdown-menu/dropdown-menu.stories.tsx deleted file mode 100644 index eb44525..0000000 --- a/src/components/ui/dropdown-menu/dropdown-menu.stories.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { Button } from '../button'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuTrigger, -} from './dropdown-menu'; - -const meta: Meta = { - title: 'Components/DropdownMenu', - component: DropdownMenu, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => ( - - - - - - My Account - - - Profile - ⇧⌘P - - - Billing - ⌘B - - - Settings - ⌘S - - - - Log out - ⇧⌘Q - - - - ), -}; - -export const Simple: Story = { - render: () => ( - - - - - - Edit - Duplicate - Delete - - - ), -}; diff --git a/src/components/ui/dropdown-menu/dropdown-menu.test.tsx b/src/components/ui/dropdown-menu/dropdown-menu.test.tsx deleted file mode 100644 index 84243cb..0000000 --- a/src/components/ui/dropdown-menu/dropdown-menu.test.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { describe, expect, it } from 'vitest'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from './dropdown-menu'; - -describe('DropdownMenu', () => { - it('renders dropdown trigger', () => { - render( - - Open - - Item 1 - - - ); - expect(screen.getByRole('button', { name: 'Open' })).toBeInTheDocument(); - }); - - it('opens dropdown on click', async () => { - const user = userEvent.setup(); - render( - - Open - - Item 1 - Item 2 - - - ); - await user.click(screen.getByRole('button', { name: 'Open' })); - expect(screen.getByRole('menuitem', { name: 'Item 1' })).toBeInTheDocument(); - expect(screen.getByRole('menuitem', { name: 'Item 2' })).toBeInTheDocument(); - }); - - it('renders label and separator', async () => { - const user = userEvent.setup(); - render( - - Open - - My Account - - Profile - - - ); - await user.click(screen.getByRole('button', { name: 'Open' })); - expect(screen.getByText('My Account')).toBeInTheDocument(); - expect(screen.getByRole('separator')).toBeInTheDocument(); - }); -}); diff --git a/src/components/ui/dropdown-menu/dropdown-menu.tsx b/src/components/ui/dropdown-menu/dropdown-menu.tsx deleted file mode 100644 index 8ac31a0..0000000 --- a/src/components/ui/dropdown-menu/dropdown-menu.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; -import { Check, ChevronRight, Circle } from 'lucide-react'; -import * as React from 'react'; -import { cn } from '@/lib/utils'; - -const DropdownMenu = DropdownMenuPrimitive.Root; -const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; -const DropdownMenuGroup = DropdownMenuPrimitive.Group; -const DropdownMenuPortal = DropdownMenuPrimitive.Portal; -const DropdownMenuSub = DropdownMenuPrimitive.Sub; -const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; - -const DropdownMenuSubTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, children, ...props }, ref) => ( - - {children} - - -)); -DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName; - -const DropdownMenuSubContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName; - -const DropdownMenuContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, sideOffset = 4, ...props }, ref) => ( - - - -)); -DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; - -const DropdownMenuItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, ...props }, ref) => ( - svg]:size-4 [&>svg]:shrink-0', - inset && 'pl-8', - className - )} - {...props} - /> -)); -DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; - -const DropdownMenuCheckboxItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - -)); -DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName; - -const DropdownMenuRadioItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - - - - {children} - -)); -DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; - -const DropdownMenuLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, ...props }, ref) => ( - -)); -DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName; - -const DropdownMenuSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; - -const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { - return ( - - ); -}; -DropdownMenuShortcut.displayName = 'DropdownMenuShortcut'; - -export { - DropdownMenu, - DropdownMenuTrigger, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuCheckboxItem, - DropdownMenuRadioItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuGroup, - DropdownMenuPortal, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuRadioGroup, -}; diff --git a/src/components/ui/dropdown-menu/index.ts b/src/components/ui/dropdown-menu/index.ts deleted file mode 100644 index 9c087d5..0000000 --- a/src/components/ui/dropdown-menu/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -export { - DropdownMenu, - DropdownMenuCheckboxItem, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuPortal, - DropdownMenuRadioGroup, - DropdownMenuRadioItem, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuTrigger, -} from './dropdown-menu'; diff --git a/src/components/ui/form/form.stories.tsx b/src/components/ui/form/form.stories.tsx deleted file mode 100644 index aca5b42..0000000 --- a/src/components/ui/form/form.stories.tsx +++ /dev/null @@ -1,342 +0,0 @@ -import { zodResolver } from '@hookform/resolvers/zod'; -import type { Meta, StoryObj } from '@storybook/react'; -import { useForm } from 'react-hook-form'; -import * as z from 'zod'; -import { Button } from '@/components/ui/button'; -import { Checkbox } from '@/components/ui/checkbox'; -import { Input } from '@/components/ui/input'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from '@/components/ui/select'; -import { Textarea } from '@/components/ui/textarea'; -import { - Form, - FormControl, - FormDescription, - FormField, - FormItem, - FormLabel, - FormMessage, -} from './form'; - -const meta: Meta = { - title: 'Components/Form', - parameters: { - layout: 'centered', - }, - tags: ['autodocs'], -}; - -export default meta; -type Story = StoryObj; - -const basicSchema = z.object({ - username: z.string().min(2, { - message: 'Username must be at least 2 characters.', - }), - email: z.string().email({ - message: 'Please enter a valid email address.', - }), -}); - -export const BasicForm: Story = { - render: function BasicFormExample() { - const form = useForm>({ - resolver: zodResolver(basicSchema), - defaultValues: { - username: '', - email: '', - }, - }); - - function onSubmit(values: z.infer) { - console.log(values); - alert(JSON.stringify(values, null, 2)); - } - - return ( -
- - ( - - Username - - - - Your public display name. - - - )} - /> - ( - - Email - - - - We'll never share your email. - - - )} - /> - - - - ); - }, -}; - -const vimConfigSchema = z.object({ - leader: z.string().min(1, 'Leader key is required'), - colorscheme: z.string().min(1, 'Select a colorscheme'), - relativenumber: z.boolean(), - tabstop: z.coerce.number().min(1).max(8), - notes: z.string().optional(), -}); - -export const VimConfigForm: Story = { - render: function VimConfigExample() { - const form = useForm>({ - resolver: zodResolver(vimConfigSchema), - defaultValues: { - leader: ' ', - colorscheme: '', - relativenumber: true, - tabstop: 2, - notes: '', - }, - }); - - function onSubmit(values: z.infer) { - console.log(values); - alert(`:set applied!\n${JSON.stringify(values, null, 2)}`); - } - - return ( -
- - ( - - Leader Key - - - - vim.g.mapleader = "{field.value}" - - - )} - /> - ( - - Colorscheme - - Select your preferred color theme. - - - )} - /> - ( - - - - -
- Relative numbers - :set relativenumber -
-
- )} - /> - ( - - Tab Stop - - - - :set tabstop={field.value} - - - )} - /> - ( - - Notes - -